Skip to content

Commit 6bf8653

Browse files
authored
Merge pull request #515 from Xilinx/bump_to_3986cffe
[AutoBump] Merge with 3986cff (Jan 15) (44)
2 parents 11597fd + 0d2f86f commit 6bf8653

File tree

298 files changed

+16244
-10761
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

298 files changed

+16244
-10761
lines changed

.github/CODEOWNERS

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @nikic
2828
/llvm/lib/Transforms/InstCombine/ @nikic
2929

30-
/clang/include/clang/Sema/Sema.h @Endilll
3130
/clang/test/CXX/drs/ @Endilll
3231
/clang/www/cxx_dr_status.html @Endilll
3332
/clang/www/make_cxx_dr_status @Endilll

clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ getNewFieldsOrder(const RecordDecl *Definition,
6363
NameToIndex[Field->getName()] = Field->getFieldIndex();
6464

6565
if (DesiredFieldsOrder.size() != NameToIndex.size()) {
66-
llvm::errs() << "Number of provided fields doesn't match definition.\n";
66+
llvm::errs() << "Number of provided fields (" << DesiredFieldsOrder.size()
67+
<< ") doesn't match definition (" << NameToIndex.size()
68+
<< ").\n";
6769
return {};
6870
}
6971
SmallVector<unsigned, 4> NewFieldsOrder;
@@ -116,26 +118,77 @@ findMembersUsedInInitExpr(const CXXCtorInitializer *Initializer,
116118
return Results;
117119
}
118120

119-
/// Returns the full source range for the field declaration up to (not
120-
/// including) the trailing semicolumn, including potential macro invocations,
121-
/// e.g. `int a GUARDED_BY(mu);`.
121+
/// Returns the next token after `Loc` (including comment tokens).
122+
static std::optional<Token> getTokenAfter(SourceLocation Loc,
123+
const SourceManager &SM,
124+
const LangOptions &LangOpts) {
125+
if (Loc.isMacroID()) {
126+
return std::nullopt;
127+
}
128+
Loc = Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts);
129+
130+
// Break down the source location.
131+
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
132+
133+
// Try to load the file buffer.
134+
bool InvalidTemp = false;
135+
StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp);
136+
if (InvalidTemp)
137+
return std::nullopt;
138+
139+
const char *TokenBegin = File.data() + LocInfo.second;
140+
141+
Lexer lexer(SM.getLocForStartOfFile(LocInfo.first), LangOpts, File.begin(),
142+
TokenBegin, File.end());
143+
lexer.SetCommentRetentionState(true);
144+
// Find the token.
145+
Token Tok;
146+
lexer.LexFromRawLexer(Tok);
147+
return Tok;
148+
}
149+
150+
/// Returns the end of the trailing comments after `Loc`.
151+
static SourceLocation getEndOfTrailingComment(SourceLocation Loc,
152+
const SourceManager &SM,
153+
const LangOptions &LangOpts) {
154+
// We consider any following comment token that is indented more than the
155+
// first comment to be part of the trailing comment.
156+
const unsigned Column = SM.getPresumedColumnNumber(Loc);
157+
std::optional<Token> Tok = getTokenAfter(Loc, SM, LangOpts);
158+
while (Tok && Tok->is(tok::comment) &&
159+
SM.getPresumedColumnNumber(Tok->getLocation()) > Column) {
160+
Loc = Tok->getEndLoc();
161+
Tok = getTokenAfter(Loc, SM, LangOpts);
162+
}
163+
return Loc;
164+
}
165+
166+
/// Returns the full source range for the field declaration up to (including)
167+
/// the trailing semicolumn, including potential macro invocations,
168+
/// e.g. `int a GUARDED_BY(mu);`. If there is a trailing comment, include it.
122169
static SourceRange getFullFieldSourceRange(const FieldDecl &Field,
123170
const ASTContext &Context) {
124-
SourceRange Range = Field.getSourceRange();
171+
const SourceRange Range = Field.getSourceRange();
172+
SourceLocation Begin = Range.getBegin();
125173
SourceLocation End = Range.getEnd();
126174
const SourceManager &SM = Context.getSourceManager();
127175
const LangOptions &LangOpts = Context.getLangOpts();
128176
while (true) {
129177
std::optional<Token> CurrentToken = Lexer::findNextToken(End, SM, LangOpts);
130178

131-
if (!CurrentToken || CurrentToken->is(tok::semi))
132-
break;
179+
if (!CurrentToken)
180+
return SourceRange(Begin, End);
133181

134182
if (CurrentToken->is(tok::eof))
135183
return Range; // Something is wrong, return the original range.
184+
136185
End = CurrentToken->getLastLoc();
186+
187+
if (CurrentToken->is(tok::semi))
188+
break;
137189
}
138-
return SourceRange(Range.getBegin(), End);
190+
End = getEndOfTrailingComment(End, SM, LangOpts);
191+
return SourceRange(Begin, End);
139192
}
140193

141194
/// Reorders fields in the definition of a struct/class.

clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import tempfile
3636
import threading
3737
import traceback
38+
from pathlib import Path
3839

3940
try:
4041
import yaml
@@ -124,6 +125,23 @@ def merge_replacement_files(tmpdir, mergefile):
124125
open(mergefile, "w").close()
125126

126127

128+
def get_compiling_files(args):
129+
"""Read a compile_commands.json database and return a set of file paths"""
130+
current_dir = Path.cwd()
131+
compile_commands_json = (
132+
(current_dir / args.build_path) if args.build_path else current_dir
133+
)
134+
compile_commands_json = compile_commands_json / "compile_commands.json"
135+
files = set()
136+
with open(compile_commands_json) as db_file:
137+
db_json = json.load(db_file)
138+
for entry in db_json:
139+
if "file" not in entry:
140+
continue
141+
files.add(Path(entry["file"]))
142+
return files
143+
144+
127145
def main():
128146
parser = argparse.ArgumentParser(
129147
description="Run clang-tidy against changed files, and "
@@ -234,6 +252,13 @@ def main():
234252
action="store_true",
235253
help="Allow empty enabled checks.",
236254
)
255+
parser.add_argument(
256+
"-only-check-in-db",
257+
dest="skip_non_compiling",
258+
default=False,
259+
action="store_true",
260+
help="Only check files in the compilation database",
261+
)
237262

238263
clang_tidy_args = []
239264
argv = sys.argv[1:]
@@ -243,11 +268,13 @@ def main():
243268

244269
args = parser.parse_args(argv)
245270

271+
compiling_files = get_compiling_files(args) if args.skip_non_compiling else None
272+
246273
# Extract changed lines for each file.
247274
filename = None
248275
lines_by_file = {}
249276
for line in sys.stdin:
250-
match = re.search('^\\+\\+\\+\\ "?(.*?/){%s}([^ \t\n"]*)' % args.p, line)
277+
match = re.search(r'^\+\+\+\ "?(.*?/){%s}([^ \t\n"]*)' % args.p, line)
251278
if match:
252279
filename = match.group(2)
253280
if filename is None:
@@ -260,6 +287,13 @@ def main():
260287
if not re.match("^%s$" % args.iregex, filename, re.IGNORECASE):
261288
continue
262289

290+
# Skip any files not in the compiling list
291+
if (
292+
compiling_files is not None
293+
and (Path.cwd() / filename) not in compiling_files
294+
):
295+
continue
296+
263297
match = re.search(r"^@@.*\+(\d+)(,(\d+))?", line)
264298
if match:
265299
start_line = int(match.group(1))

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,14 +1867,41 @@ class CodeCompleteFlow {
18671867
CodeCompleteResult Output;
18681868

18691869
// Convert the results to final form, assembling the expensive strings.
1870+
// If necessary, search the index for documentation comments.
1871+
LookupRequest Req;
1872+
llvm::DenseMap<SymbolID, uint32_t> SymbolToCompletion;
18701873
for (auto &C : Scored) {
18711874
Output.Completions.push_back(toCodeCompletion(C.first));
18721875
Output.Completions.back().Score = C.second;
18731876
Output.Completions.back().CompletionTokenRange = ReplacedRange;
1877+
if (Opts.Index && !Output.Completions.back().Documentation) {
1878+
for (auto &Cand : C.first) {
1879+
if (Cand.SemaResult &&
1880+
Cand.SemaResult->Kind == CodeCompletionResult::RK_Declaration) {
1881+
auto ID = clangd::getSymbolID(Cand.SemaResult->getDeclaration());
1882+
if (!ID)
1883+
continue;
1884+
Req.IDs.insert(ID);
1885+
SymbolToCompletion[ID] = Output.Completions.size() - 1;
1886+
}
1887+
}
1888+
}
18741889
}
18751890
Output.HasMore = Incomplete;
18761891
Output.Context = CCContextKind;
18771892
Output.CompletionRange = ReplacedRange;
1893+
1894+
// Look up documentation from the index.
1895+
if (Opts.Index) {
1896+
Opts.Index->lookup(Req, [&](const Symbol &S) {
1897+
if (S.Documentation.empty())
1898+
return;
1899+
auto &C = Output.Completions[SymbolToCompletion.at(S.ID)];
1900+
C.Documentation.emplace();
1901+
parseDocumentation(S.Documentation, *C.Documentation);
1902+
});
1903+
}
1904+
18781905
return Output;
18791906
}
18801907

clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,87 @@ int x = foo^
11361136
Contains(AllOf(named("foo"), doc("This comment should be retained!"))));
11371137
}
11381138

1139+
TEST(CompletionTest, CommentsOnMembersFromHeader) {
1140+
MockFS FS;
1141+
MockCompilationDatabase CDB;
1142+
1143+
auto Opts = ClangdServer::optsForTest();
1144+
Opts.BuildDynamicSymbolIndex = true;
1145+
1146+
ClangdServer Server(CDB, FS, Opts);
1147+
1148+
FS.Files[testPath("foo.h")] = R"cpp(
1149+
struct alpha {
1150+
/// This is a member field.
1151+
int gamma;
1152+
1153+
/// This is a member function.
1154+
int delta();
1155+
};
1156+
)cpp";
1157+
1158+
auto File = testPath("foo.cpp");
1159+
Annotations Test(R"cpp(
1160+
#include "foo.h"
1161+
alpha a;
1162+
int x = a.^
1163+
)cpp");
1164+
runAddDocument(Server, File, Test.code());
1165+
auto CompletionList =
1166+
llvm::cantFail(runCodeComplete(Server, File, Test.point(), {}));
1167+
1168+
EXPECT_THAT(CompletionList.Completions,
1169+
Contains(AllOf(named("gamma"), doc("This is a member field."))));
1170+
EXPECT_THAT(
1171+
CompletionList.Completions,
1172+
Contains(AllOf(named("delta"), doc("This is a member function."))));
1173+
}
1174+
1175+
TEST(CompletionTest, CommentsOnMembersFromHeaderOverloadBundling) {
1176+
using testing::AnyOf;
1177+
MockFS FS;
1178+
MockCompilationDatabase CDB;
1179+
1180+
auto Opts = ClangdServer::optsForTest();
1181+
Opts.BuildDynamicSymbolIndex = true;
1182+
1183+
ClangdServer Server(CDB, FS, Opts);
1184+
1185+
FS.Files[testPath("foo.h")] = R"cpp(
1186+
struct alpha {
1187+
/// bool overload.
1188+
int delta(bool b);
1189+
1190+
/// int overload.
1191+
int delta(int i);
1192+
1193+
void epsilon(long l);
1194+
1195+
/// This one has a comment.
1196+
void epsilon(int i);
1197+
};
1198+
)cpp";
1199+
1200+
auto File = testPath("foo.cpp");
1201+
Annotations Test(R"cpp(
1202+
#include "foo.h"
1203+
alpha a;
1204+
int x = a.^
1205+
)cpp");
1206+
runAddDocument(Server, File, Test.code());
1207+
clangd::CodeCompleteOptions CCOpts;
1208+
CCOpts.BundleOverloads = true;
1209+
auto CompletionList =
1210+
llvm::cantFail(runCodeComplete(Server, File, Test.point(), CCOpts));
1211+
1212+
EXPECT_THAT(
1213+
CompletionList.Completions,
1214+
Contains(AllOf(named("epsilon"), doc("This one has a comment."))));
1215+
EXPECT_THAT(CompletionList.Completions,
1216+
Contains(AllOf(named("delta"), AnyOf(doc("bool overload."),
1217+
doc("int overload.")))));
1218+
}
1219+
11391220
TEST(CompletionTest, GlobalCompletionFiltering) {
11401221

11411222
Symbol Class = cls("XYZ");

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ Improvements to clang-query
108108
Improvements to clang-tidy
109109
--------------------------
110110

111+
- Improved :program:`clang-tidy-diff.py` script. Add the `-only-check-in-db`
112+
option to exclude files not present in the compilation database, avoiding
113+
false-negative results.
114+
111115
- Improved :program:`run-clang-tidy.py` script. Fixed minor shutdown noise
112116
happening on certain platforms when interrupting the script.
113117

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: clang-reorder-fields -record-name Foo -fields-order e1,e3,e2,a,c,b %s -- | FileCheck %s
2+
3+
class Foo {
4+
int a; // Trailing comment for a.
5+
int b; // Multiline
6+
// trailing for b.
7+
// Prefix comments for c.
8+
int c;
9+
10+
/*c-like*/ int e1;
11+
int /*c-like*/ e2;
12+
int e3 /*c-like*/;
13+
};
14+
15+
// CHECK: /*c-like*/ int e1;
16+
// CHECK-NEXT: int e3 /*c-like*/;
17+
// CHECK-NEXT: int /*c-like*/ e2;
18+
// CHECK-NEXT: int a; // Trailing comment for a.
19+
// CHECK-NEXT: // Prefix comments for c.
20+
// CHECK-NEXT: int c;
21+
// CHECK-NEXT: int b; // Multiline
22+
// CHECK-NEXT: // trailing for b.
23+

clang/bindings/python/clang/cindex.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2133,6 +2133,14 @@ def get_field_offsetof(self):
21332133
"""Returns the offsetof the FIELD_DECL pointed by this Cursor."""
21342134
return conf.lib.clang_Cursor_getOffsetOfField(self) # type: ignore [no-any-return]
21352135

2136+
def get_base_offsetof(self, parent):
2137+
"""Returns the offsetof the CXX_BASE_SPECIFIER pointed by this Cursor."""
2138+
return conf.lib.clang_getOffsetOfBase(parent, self) # type: ignore [no-any-return]
2139+
2140+
def is_virtual_base(self):
2141+
"""Returns whether the CXX_BASE_SPECIFIER pointed by this Cursor is virtual."""
2142+
return conf.lib.clang_isVirtualBase(self) # type: ignore [no-any-return]
2143+
21362144
def is_anonymous(self):
21372145
"""
21382146
Check whether this is a record type without a name, or a field where
@@ -2687,6 +2695,21 @@ def visitor(field, children):
26872695
conf.lib.clang_Type_visitFields(self, fields_visit_callback(visitor), fields)
26882696
return iter(fields)
26892697

2698+
def get_bases(self):
2699+
"""Return an iterator for accessing the base classes of this type."""
2700+
2701+
def visitor(base, children):
2702+
assert base != conf.lib.clang_getNullCursor()
2703+
2704+
# Create reference to TU so it isn't GC'd before Cursor.
2705+
base._tu = self._tu
2706+
bases.append(base)
2707+
return 1 # continue
2708+
2709+
bases: list[Cursor] = []
2710+
conf.lib.clang_visitCXXBaseClasses(self, fields_visit_callback(visitor), bases)
2711+
return iter(bases)
2712+
26902713
def get_exception_specification_kind(self):
26912714
"""
26922715
Return the kind of the exception specification; a value from
@@ -3940,6 +3963,7 @@ def set_property(self, property, value):
39403963
("clang_getNumDiagnosticsInSet", [c_object_p], c_uint),
39413964
("clang_getNumElements", [Type], c_longlong),
39423965
("clang_getNumOverloadedDecls", [Cursor], c_uint),
3966+
("clang_getOffsetOfBase", [Cursor, Cursor], c_longlong),
39433967
("clang_getOverloadedDecl", [Cursor, c_uint], Cursor),
39443968
("clang_getPointeeType", [Type], Type),
39453969
("clang_getRange", [SourceLocation, SourceLocation], SourceRange),
@@ -3992,6 +4016,7 @@ def set_property(self, property, value):
39924016
[TranslationUnit, SourceRange, POINTER(POINTER(Token)), POINTER(c_uint)],
39934017
),
39944018
("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], c_uint),
4019+
("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], c_uint),
39954020
("clang_Cursor_getNumArguments", [Cursor], c_int),
39964021
("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
39974022
("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),

0 commit comments

Comments
 (0)