Skip to content

Commit 8694187

Browse files
committed
Merge branch 'upstream/main'
2 parents ce47d99 + 1fc6027 commit 8694187

File tree

1,663 files changed

+62978
-25676
lines changed

Some content is hidden

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

1,663 files changed

+62978
-25676
lines changed

.mailmap

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# This file allows mapping several author and committer email addresses and
2+
# names to a single canonical one for `git shortlog`, `git log --author`,
3+
# or `git check-mailmap`.
4+
#
5+
# For example, if you commit as `[email protected]` but sometimes use
6+
# "Rañdom Person" and sometimes "Random Person" as name and you want the former
7+
# to be your canonical name, add
8+
#
9+
# Rañdom Person <[email protected]>
10+
#
11+
# If you commit as both `[email protected]` and `[email protected]` and
12+
# you want the former to be your canonical email address, add
13+
#
14+
15+
#
16+
# Combinations of both are possible too, see
17+
# https://git-scm.com/docs/gitmailmap for format details.
18+
#
19+
# You can commit changes for your own names and email addresses without review.
20+
# If you want to add entries for other people, please have them review the
21+
# addition.
22+
#
23+
# Please keep this file sorted.
24+
25+
26+
27+

clang-tools-extra/clang-tidy/misc/StaticAssertCheck.cpp

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,48 @@ StaticAssertCheck::StaticAssertCheck(StringRef Name, ClangTidyContext *Context)
2727
: ClangTidyCheck(Name, Context) {}
2828

2929
void StaticAssertCheck::registerMatchers(MatchFinder *Finder) {
30-
auto NegatedString =
31-
unaryOperator(hasOperatorName("!"), hasUnaryOperand(stringLiteral()));
30+
auto NegatedString = unaryOperator(
31+
hasOperatorName("!"), hasUnaryOperand(ignoringImpCasts(stringLiteral())));
3232
auto IsAlwaysFalse =
3333
expr(anyOf(cxxBoolLiteral(equals(false)), integerLiteral(equals(0)),
3434
cxxNullPtrLiteralExpr(), gnuNullExpr(), NegatedString))
3535
.bind("isAlwaysFalse");
36-
auto IsAlwaysFalseWithCast =
37-
anyOf(IsAlwaysFalse, cStyleCastExpr(has(IsAlwaysFalse)).bind("castExpr"));
38-
auto AssertExprRoot =
39-
anyOf(binaryOperator(
40-
hasAnyOperatorName("&&", "=="),
41-
hasEitherOperand(stringLiteral().bind("assertMSG")),
42-
anyOf(binaryOperator(hasEitherOperand(IsAlwaysFalseWithCast)),
43-
anything()))
44-
.bind("assertExprRoot"),
45-
IsAlwaysFalse);
36+
auto IsAlwaysFalseWithCast = ignoringParenImpCasts(anyOf(
37+
IsAlwaysFalse, cStyleCastExpr(has(ignoringParenImpCasts(IsAlwaysFalse)))
38+
.bind("castExpr")));
39+
auto AssertExprRoot = anyOf(
40+
binaryOperator(
41+
hasAnyOperatorName("&&", "=="),
42+
hasEitherOperand(ignoringImpCasts(stringLiteral().bind("assertMSG"))),
43+
anyOf(binaryOperator(hasEitherOperand(IsAlwaysFalseWithCast)),
44+
anything()))
45+
.bind("assertExprRoot"),
46+
IsAlwaysFalse);
4647
auto NonConstexprFunctionCall =
4748
callExpr(hasDeclaration(functionDecl(unless(isConstexpr()))));
4849
auto AssertCondition =
49-
expr(optionally(expr(anyOf(AssertExprRoot,
50-
unaryOperator(hasUnaryOperand(AssertExprRoot))))),
51-
unless(findAll(NonConstexprFunctionCall)))
50+
expr(
51+
anyOf(expr(ignoringParenCasts(anyOf(
52+
AssertExprRoot, unaryOperator(hasUnaryOperand(
53+
ignoringParenCasts(AssertExprRoot)))))),
54+
anything()),
55+
unless(findAll(NonConstexprFunctionCall)))
5256
.bind("condition");
5357
auto Condition =
54-
anyOf(callExpr(traverse(TK_AsIs, callExpr(hasDeclaration(functionDecl(
55-
hasName("__builtin_expect"))))),
56-
hasArgument(0, AssertCondition)),
58+
anyOf(ignoringParenImpCasts(callExpr(
59+
hasDeclaration(functionDecl(hasName("__builtin_expect"))),
60+
hasArgument(0, AssertCondition))),
5761
AssertCondition);
5862

63+
Finder->addMatcher(conditionalOperator(hasCondition(Condition),
64+
unless(isInTemplateInstantiation()))
65+
.bind("condStmt"),
66+
this);
67+
5968
Finder->addMatcher(
60-
mapAnyOf(ifStmt, conditionalOperator).with(hasCondition(Condition)).bind("condStmt"), this);
69+
ifStmt(hasCondition(Condition), unless(isInTemplateInstantiation()))
70+
.bind("condStmt"),
71+
this);
6172
}
6273

6374
void StaticAssertCheck::check(const MatchFinder::MatchResult &Result) {

clang-tools-extra/clang-tidy/misc/StaticAssertCheck.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ class StaticAssertCheck : public ClangTidyCheck {
3030
}
3131
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
3232
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
33-
llvm::Optional<TraversalKind> getCheckTraversalKind() const override {
34-
return TK_IgnoreUnlessSpelledInSource;
35-
}
3633

3734
private:
3835
SourceLocation getLastParenLoc(const ASTContext *ASTCtx,

clang-tools-extra/clangd/ClangdLSPServer.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -748,9 +748,8 @@ void ClangdLSPServer::onCommandApplyTweak(const TweakArgs &Args,
748748
return Reply(std::move(Err));
749749

750750
WorkspaceEdit WE;
751-
WE.changes.emplace();
752751
for (const auto &It : R->ApplyEdits) {
753-
(*WE.changes)[URI::createFile(It.first()).toString()] =
752+
WE.changes[URI::createFile(It.first()).toString()] =
754753
It.second.asTextEdits();
755754
}
756755
// ApplyEdit will take care of calling Reply().
@@ -813,22 +812,20 @@ void ClangdLSPServer::onRename(const RenameParams &Params,
813812
if (!Server->getDraft(File))
814813
return Reply(llvm::make_error<LSPError>(
815814
"onRename called for non-added file", ErrorCode::InvalidParams));
816-
Server->rename(
817-
File, Params.position, Params.newName, Opts.Rename,
818-
[File, Params, Reply = std::move(Reply),
819-
this](llvm::Expected<RenameResult> R) mutable {
820-
if (!R)
821-
return Reply(R.takeError());
822-
if (auto Err = validateEdits(*Server, R->GlobalChanges))
823-
return Reply(std::move(Err));
824-
WorkspaceEdit Result;
825-
Result.changes.emplace();
826-
for (const auto &Rep : R->GlobalChanges) {
827-
(*Result.changes)[URI::createFile(Rep.first()).toString()] =
828-
Rep.second.asTextEdits();
829-
}
830-
Reply(Result);
831-
});
815+
Server->rename(File, Params.position, Params.newName, Opts.Rename,
816+
[File, Params, Reply = std::move(Reply),
817+
this](llvm::Expected<RenameResult> R) mutable {
818+
if (!R)
819+
return Reply(R.takeError());
820+
if (auto Err = validateEdits(*Server, R->GlobalChanges))
821+
return Reply(std::move(Err));
822+
WorkspaceEdit Result;
823+
for (const auto &Rep : R->GlobalChanges) {
824+
Result.changes[URI::createFile(Rep.first()).toString()] =
825+
Rep.second.asTextEdits();
826+
}
827+
Reply(Result);
828+
});
832829
}
833830

834831
void ClangdLSPServer::onDocumentDidClose(

clang-tools-extra/clangd/CodeCompletionStrings.cpp

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ void getSignature(const CodeCompletionString &CCS, std::string *Signature,
114114
}
115115
unsigned SnippetArg = 0;
116116
bool HadObjCArguments = false;
117+
bool HadInformativeChunks = false;
117118
for (const auto &Chunk : CCS) {
118119
// Informative qualifier chunks only clutter completion results, skip
119120
// them.
@@ -129,10 +130,14 @@ void getSignature(const CodeCompletionString &CCS, std::string *Signature,
129130
// reclassified as qualifiers.
130131
//
131132
// Objective-C:
132-
// Objective-C methods may have multiple typed-text chunks, so we must
133-
// treat them carefully. For Objective-C methods, all typed-text chunks
134-
// will end in ':' (unless there are no arguments, in which case we
135-
// can safely treat them as C++).
133+
// Objective-C methods expressions may have multiple typed-text chunks,
134+
// so we must treat them carefully. For Objective-C methods, all
135+
// typed-text and informative chunks will end in ':' (unless there are
136+
// no arguments, in which case we can safely treat them as C++).
137+
//
138+
// Completing a method declaration itself (not a method expression) is
139+
// similar except that we use the `RequiredQualifiers` to store the
140+
// text before the selector, e.g. `- (void)`.
136141
if (!llvm::StringRef(Chunk.Text).endswith(":")) { // Treat as C++.
137142
if (RequiredQualifiers)
138143
*RequiredQualifiers = std::move(*Signature);
@@ -147,6 +152,28 @@ void getSignature(const CodeCompletionString &CCS, std::string *Signature,
147152
// methods.
148153
if (!HadObjCArguments) {
149154
HadObjCArguments = true;
155+
// If we have no previous informative chunks (informative selector
156+
// fragments in practice), we treat any previous chunks as
157+
// `RequiredQualifiers` so they will be added as a prefix during the
158+
// completion.
159+
//
160+
// e.g. to complete `- (void)doSomething:(id)argument`:
161+
// - Completion name: `doSomething:`
162+
// - RequiredQualifiers: `- (void)`
163+
// - Snippet/Signature suffix: `(id)argument`
164+
//
165+
// This differs from the case when we're completing a method
166+
// expression with a previous informative selector fragment.
167+
//
168+
// e.g. to complete `[self doSomething:nil ^somethingElse:(id)]`:
169+
// - Previous Informative Chunk: `doSomething:`
170+
// - Completion name: `somethingElse:`
171+
// - Snippet/Signature suffix: `(id)`
172+
if (!HadInformativeChunks) {
173+
if (RequiredQualifiers)
174+
*RequiredQualifiers = std::move(*Signature);
175+
Snippet->clear();
176+
}
150177
Signature->clear();
151178
} else { // Subsequent argument, considered part of snippet/signature.
152179
*Signature += Chunk.Text;
@@ -173,6 +200,7 @@ void getSignature(const CodeCompletionString &CCS, std::string *Signature,
173200
*Snippet += '}';
174201
break;
175202
case CodeCompletionString::CK_Informative:
203+
HadInformativeChunks = true;
176204
// For example, the word "const" for a const method, or the name of
177205
// the base class for methods that are part of the base class.
178206
*Signature += Chunk.Text;

clang-tools-extra/clangd/Config.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct Config {
7070
enum class BackgroundPolicy { Build, Skip };
7171
/// Describes an external index configuration.
7272
struct ExternalIndexSpec {
73-
enum { None, File, Server } Kind;
73+
enum { None, File, Server } Kind = None;
7474
/// This is one of:
7575
/// - Address of a clangd-index-server, in the form of "ip:port".
7676
/// - Absolute path to an index produced by clangd-indexer.
@@ -83,7 +83,7 @@ struct Config {
8383
struct {
8484
/// Whether this TU should be indexed.
8585
BackgroundPolicy Background = BackgroundPolicy::Build;
86-
llvm::Optional<ExternalIndexSpec> External;
86+
ExternalIndexSpec External;
8787
} Index;
8888

8989
/// Controls warnings and errors when parsing code.

clang-tools-extra/clangd/ConfigCompile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ struct FragmentCompiler {
376376
}
377377
Out.Apply.push_back([Spec(std::move(Spec))](const Params &P, Config &C) {
378378
if (Spec.Kind == Config::ExternalIndexSpec::None) {
379-
C.Index.External.reset();
379+
C.Index.External = Spec;
380380
return;
381381
}
382382
if (P.Path.empty() || !pathStartsWith(Spec.MountPoint, P.Path,

clang-tools-extra/clangd/Diagnostics.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,7 @@ CodeAction toCodeAction(const Fix &F, const URIForFile &File) {
372372
Action.title = F.Message;
373373
Action.kind = std::string(CodeAction::QUICKFIX_KIND);
374374
Action.edit.emplace();
375-
Action.edit->changes.emplace();
376-
(*Action.edit->changes)[File.uri()] = {F.Edits.begin(), F.Edits.end()};
375+
Action.edit->changes[File.uri()] = {F.Edits.begin(), F.Edits.end()};
377376
return Action;
378377
}
379378

clang-tools-extra/clangd/FindTarget.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,6 @@ struct TargetFinder {
306306
Outer.add(OME->getMethodDecl(), Flags);
307307
}
308308
void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {
309-
// FIXME: We miss visiting the class receiver if one exists, which
310-
// means we skip the corresponding ObjCInterfaceDecl ref since it
311-
// doesn't have a corresponding node.
312309
if (OPRE->isExplicitProperty())
313310
Outer.add(OPRE->getExplicitProperty(), Flags);
314311
else {
@@ -766,13 +763,6 @@ llvm::SmallVector<ReferenceLoc> refInStmt(const Stmt *S,
766763
}
767764

768765
void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) {
769-
// There's no contained TypeLoc node for a class receiver type.
770-
if (E->isClassReceiver()) {
771-
Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
772-
E->getReceiverLocation(),
773-
/*IsDecl=*/false,
774-
{E->getClassReceiver()}});
775-
}
776766
Refs.push_back(ReferenceLoc{
777767
NestedNameSpecifierLoc(), E->getLocation(),
778768
/*IsDecl=*/false,

clang-tools-extra/clangd/HeuristicResolver.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace clangd {
1616

1717
// Convenience lambdas for use as the 'Filter' parameter of
1818
// HeuristicResolver::resolveDependentMember().
19+
const auto NoFilter = [](const NamedDecl *D) { return true; };
1920
const auto NonStaticFilter = [](const NamedDecl *D) {
2021
return D->isCXXInstanceMember();
2122
};
@@ -90,6 +91,28 @@ const Type *HeuristicResolver::getPointeeType(const Type *T) const {
9091

9192
std::vector<const NamedDecl *> HeuristicResolver::resolveMemberExpr(
9293
const CXXDependentScopeMemberExpr *ME) const {
94+
// If the expression has a qualifier, first try resolving the member
95+
// inside the qualifier's type.
96+
// Note that we cannot use a NonStaticFilter in either case, for a couple
97+
// of reasons:
98+
// 1. It's valid to access a static member using instance member syntax,
99+
// e.g. `instance.static_member`.
100+
// 2. We can sometimes get a CXXDependentScopeMemberExpr for static
101+
// member syntax too, e.g. if `X::static_member` occurs inside
102+
// an instance method, it's represented as a CXXDependentScopeMemberExpr
103+
// with `this` as the base expression as `X` as the qualifier
104+
// (which could be valid if `X` names a base class after instantiation).
105+
if (NestedNameSpecifier *NNS = ME->getQualifier()) {
106+
if (const Type *QualifierType = resolveNestedNameSpecifierToType(NNS)) {
107+
auto Decls =
108+
resolveDependentMember(QualifierType, ME->getMember(), NoFilter);
109+
if (!Decls.empty())
110+
return Decls;
111+
}
112+
}
113+
114+
// If that didn't yield any results, try resolving the member inside
115+
// the expression's base type.
93116
const Type *BaseType = ME->getBaseType().getTypePtrOrNull();
94117
if (ME->isArrow()) {
95118
BaseType = getPointeeType(BaseType);
@@ -105,7 +128,7 @@ std::vector<const NamedDecl *> HeuristicResolver::resolveMemberExpr(
105128
BaseType = resolveExprToType(Base);
106129
}
107130
}
108-
return resolveDependentMember(BaseType, ME->getMember(), NonStaticFilter);
131+
return resolveDependentMember(BaseType, ME->getMember(), NoFilter);
109132
}
110133

111134
std::vector<const NamedDecl *> HeuristicResolver::resolveDeclRefExpr(

clang-tools-extra/clangd/InlayHints.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,16 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
2222
InlayHintVisitor(std::vector<InlayHint> &Results, ParsedAST &AST)
2323
: Results(Results), AST(AST.getASTContext()),
2424
MainFileID(AST.getSourceManager().getMainFileID()),
25-
Resolver(AST.getHeuristicResolver()) {
25+
Resolver(AST.getHeuristicResolver()),
26+
TypeHintPolicy(this->AST.getPrintingPolicy()) {
2627
bool Invalid = false;
2728
llvm::StringRef Buf =
2829
AST.getSourceManager().getBufferData(MainFileID, &Invalid);
2930
MainFileBuf = Invalid ? StringRef{} : Buf;
31+
32+
TypeHintPolicy.SuppressScope = true; // keep type names short
33+
TypeHintPolicy.AnonymousTagLocations =
34+
false; // do not print lambda locations
3035
}
3136

3237
bool VisitCXXConstructExpr(CXXConstructExpr *E) {
@@ -67,6 +72,26 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
6772
return true;
6873
}
6974

75+
bool VisitVarDecl(VarDecl *D) {
76+
// Do not show hints for the aggregate in a structured binding.
77+
// In the future, we may show hints for the individual bindings.
78+
if (isa<DecompositionDecl>(D))
79+
return true;
80+
81+
if (D->getType()->getContainedAutoType()) {
82+
if (!D->getType()->isDependentType()) {
83+
// Our current approach is to place the hint on the variable
84+
// and accordingly print the full type
85+
// (e.g. for `const auto& x = 42`, print `const int&`).
86+
// Alternatively, we could place the hint on the `auto`
87+
// (and then just print the type deduced for the `auto`).
88+
addInlayHint(D->getLocation(), InlayHintKind::TypeHint,
89+
": " + D->getType().getAsString(TypeHintPolicy));
90+
}
91+
}
92+
return true;
93+
}
94+
7095
// FIXME: Handle RecoveryExpr to try to hint some invalid calls.
7196

7297
private:
@@ -278,6 +303,7 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
278303
FileID MainFileID;
279304
StringRef MainFileBuf;
280305
const HeuristicResolver *Resolver;
306+
PrintingPolicy TypeHintPolicy;
281307
};
282308

283309
std::vector<InlayHint> inlayHints(ParsedAST &AST) {

clang-tools-extra/clangd/Protocol.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -808,10 +808,8 @@ llvm::json::Value toJSON(const DocumentSymbol &S) {
808808
}
809809

810810
llvm::json::Value toJSON(const WorkspaceEdit &WE) {
811-
if (!WE.changes)
812-
return llvm::json::Object{};
813811
llvm::json::Object FileChanges;
814-
for (auto &Change : *WE.changes)
812+
for (auto &Change : WE.changes)
815813
FileChanges[Change.first] = llvm::json::Array(Change.second);
816814
return llvm::json::Object{{"changes", std::move(FileChanges)}};
817815
}
@@ -1314,6 +1312,8 @@ llvm::json::Value toJSON(InlayHintKind K) {
13141312
switch (K) {
13151313
case InlayHintKind::ParameterHint:
13161314
return "parameter";
1315+
case InlayHintKind::TypeHint:
1316+
return "type";
13171317
}
13181318
llvm_unreachable("Unknown clang.clangd.InlayHintKind");
13191319
}

0 commit comments

Comments
 (0)