Skip to content

Commit ce9a9cc

Browse files
committed
[AutoBump] Merge with 357c197 (Sep 30)
2 parents b28576b + 357c197 commit ce9a9cc

File tree

935 files changed

+46302
-26706
lines changed

Some content is hidden

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

935 files changed

+46302
-26706
lines changed

.github/workflows/release-binaries-all.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ on:
4343
- '.github/workflows/release-binaries.yml'
4444
- '.github/workflows/release-binaries-setup-stage/*'
4545
- '.github/workflows/release-binaries-save-stage/*'
46+
- 'clang/cmake/caches/Release.cmake'
4647

4748
concurrency:
4849
group: ${{ github.workflow }}-${{ github.event.pull_request.number || 'dispatch' }}

clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,52 +7,58 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "PosixReturnCheck.h"
10-
#include "../utils/Matchers.h"
1110
#include "clang/AST/ASTContext.h"
1211
#include "clang/ASTMatchers/ASTMatchFinder.h"
12+
#include "clang/ASTMatchers/ASTMatchers.h"
1313
#include "clang/Lex/Lexer.h"
1414

1515
using namespace clang::ast_matchers;
1616

1717
namespace clang::tidy::bugprone {
1818

19-
static StringRef getFunctionSpelling(const MatchFinder::MatchResult &Result,
20-
const char *BindingStr) {
21-
const CallExpr *MatchedCall = cast<CallExpr>(
22-
(Result.Nodes.getNodeAs<BinaryOperator>(BindingStr))->getLHS());
19+
static StringRef getFunctionSpelling(const MatchFinder::MatchResult &Result) {
20+
const auto *MatchedCall = Result.Nodes.getNodeAs<CallExpr>("call");
2321
const SourceManager &SM = *Result.SourceManager;
2422
return Lexer::getSourceText(CharSourceRange::getTokenRange(
2523
MatchedCall->getCallee()->getSourceRange()),
2624
SM, Result.Context->getLangOpts());
2725
}
2826

2927
void PosixReturnCheck::registerMatchers(MatchFinder *Finder) {
28+
const auto PosixCall =
29+
callExpr(callee(functionDecl(
30+
anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
31+
unless(hasName("::posix_openpt")))))
32+
.bind("call");
33+
const auto ZeroIntegerLiteral = integerLiteral(equals(0));
34+
const auto NegIntegerLiteral =
35+
unaryOperator(hasOperatorName("-"), hasUnaryOperand(integerLiteral()));
36+
3037
Finder->addMatcher(
3138
binaryOperator(
32-
hasOperatorName("<"),
33-
hasLHS(callExpr(callee(functionDecl(
34-
anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
35-
unless(hasName("::posix_openpt")))))),
36-
hasRHS(integerLiteral(equals(0))))
39+
anyOf(allOf(hasOperatorName("<"), hasLHS(PosixCall),
40+
hasRHS(ZeroIntegerLiteral)),
41+
allOf(hasOperatorName(">"), hasLHS(ZeroIntegerLiteral),
42+
hasRHS(PosixCall))))
3743
.bind("ltzop"),
3844
this);
3945
Finder->addMatcher(
4046
binaryOperator(
41-
hasOperatorName(">="),
42-
hasLHS(callExpr(callee(functionDecl(
43-
anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
44-
unless(hasName("::posix_openpt")))))),
45-
hasRHS(integerLiteral(equals(0))))
47+
anyOf(allOf(hasOperatorName(">="), hasLHS(PosixCall),
48+
hasRHS(ZeroIntegerLiteral)),
49+
allOf(hasOperatorName("<="), hasLHS(ZeroIntegerLiteral),
50+
hasRHS(PosixCall))))
4651
.bind("atop"),
4752
this);
53+
Finder->addMatcher(binaryOperator(hasAnyOperatorName("==", "!="),
54+
hasOperands(PosixCall, NegIntegerLiteral))
55+
.bind("binop"),
56+
this);
4857
Finder->addMatcher(
49-
binaryOperator(
50-
hasAnyOperatorName("==", "!=", "<=", "<"),
51-
hasLHS(callExpr(callee(functionDecl(
52-
anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
53-
unless(hasName("::posix_openpt")))))),
54-
hasRHS(unaryOperator(hasOperatorName("-"),
55-
hasUnaryOperand(integerLiteral()))))
58+
binaryOperator(anyOf(allOf(hasAnyOperatorName("<=", "<"),
59+
hasLHS(PosixCall), hasRHS(NegIntegerLiteral)),
60+
allOf(hasAnyOperatorName(">", ">="),
61+
hasLHS(NegIntegerLiteral), hasRHS(PosixCall))))
5662
.bind("binop"),
5763
this);
5864
}
@@ -61,23 +67,26 @@ void PosixReturnCheck::check(const MatchFinder::MatchResult &Result) {
6167
if (const auto *LessThanZeroOp =
6268
Result.Nodes.getNodeAs<BinaryOperator>("ltzop")) {
6369
SourceLocation OperatorLoc = LessThanZeroOp->getOperatorLoc();
70+
StringRef NewBinOp =
71+
LessThanZeroOp->getOpcode() == BinaryOperator::Opcode::BO_LT ? ">"
72+
: "<";
6473
diag(OperatorLoc, "the comparison always evaluates to false because %0 "
6574
"always returns non-negative values")
66-
<< getFunctionSpelling(Result, "ltzop")
67-
<< FixItHint::CreateReplacement(OperatorLoc, Twine(">").str());
75+
<< getFunctionSpelling(Result)
76+
<< FixItHint::CreateReplacement(OperatorLoc, NewBinOp);
6877
return;
6978
}
7079
if (const auto *AlwaysTrueOp =
7180
Result.Nodes.getNodeAs<BinaryOperator>("atop")) {
7281
diag(AlwaysTrueOp->getOperatorLoc(),
7382
"the comparison always evaluates to true because %0 always returns "
7483
"non-negative values")
75-
<< getFunctionSpelling(Result, "atop");
84+
<< getFunctionSpelling(Result);
7685
return;
7786
}
7887
const auto *BinOp = Result.Nodes.getNodeAs<BinaryOperator>("binop");
7988
diag(BinOp->getOperatorLoc(), "%0 only returns non-negative values")
80-
<< getFunctionSpelling(Result, "binop");
89+
<< getFunctionSpelling(Result);
8190
}
8291

8392
} // namespace clang::tidy::bugprone

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ AST_MATCHER_P(DeducedTemplateSpecializationType, refsToTemplatedDecl,
2525
return false;
2626
}
2727

28+
AST_MATCHER_P(Type, asTagDecl, clang::ast_matchers::internal::Matcher<TagDecl>,
29+
DeclMatcher) {
30+
if (const TagDecl *ND = Node.getAsTagDecl())
31+
return DeclMatcher.matches(*ND, Finder, Builder);
32+
return false;
33+
}
34+
2835
} // namespace
2936

3037
// A function that helps to tell whether a TargetDecl in a UsingDecl will be
@@ -61,7 +68,8 @@ void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) {
6168
Finder->addMatcher(userDefinedLiteral().bind("used"), this);
6269
Finder->addMatcher(
6370
loc(elaboratedType(unless(hasQualifier(nestedNameSpecifier())),
64-
hasUnqualifiedDesugaredType(type().bind("usedType")))),
71+
hasUnqualifiedDesugaredType(
72+
type(asTagDecl(tagDecl().bind("used")))))),
6573
this);
6674
// Cases where we can identify the UsingShadowDecl directly, rather than
6775
// just its target.
@@ -139,12 +147,6 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
139147
return;
140148
}
141149

142-
if (const auto *T = Result.Nodes.getNodeAs<Type>("usedType")) {
143-
if (const auto *ND = T->getAsTagDecl())
144-
RemoveNamedDecl(ND);
145-
return;
146-
}
147-
148150
if (const auto *UsedShadow =
149151
Result.Nodes.getNodeAs<UsingShadowDecl>("usedShadow")) {
150152
removeFromFoundDecls(UsedShadow->getTargetDecl());

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,9 @@ bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
14091409
Clang->getPreprocessorOpts().SingleFileParseMode = CompletingInPreamble;
14101410
Clang->setCodeCompletionConsumer(Consumer.release());
14111411

1412+
if (Input.Preamble.RequiredModules)
1413+
Input.Preamble.RequiredModules->adjustHeaderSearchOptions(Clang->getHeaderSearchOpts());
1414+
14121415
SyntaxOnlyAction Action;
14131416
if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
14141417
log("BeginSourceFile() failed when running codeComplete for {0}",
@@ -2122,7 +2125,7 @@ clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
21222125
// When an is used, Sema is responsible for completing the main file,
21232126
// the index can provide results from the preamble.
21242127
// Tell Sema not to deserialize the preamble to look for results.
2125-
Result.LoadExternal = !Index;
2128+
Result.LoadExternal = ForceLoadPreamble || !Index;
21262129
Result.IncludeFixIts = IncludeFixIts;
21272130

21282131
return Result;

clang-tools-extra/clangd/CodeComplete.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ struct CodeCompleteOptions {
5252
/// For example, private members are usually inaccessible.
5353
bool IncludeIneligibleResults = false;
5454

55+
/// Force sema to load decls from preamble even if an index is provided.
56+
/// This is helpful for cases the index can't provide symbols, e.g. with
57+
/// experimental c++20 modules
58+
bool ForceLoadPreamble = false;
59+
5560
/// Combine overloads into a single completion item where possible.
5661
/// If none, the implementation may choose an appropriate behavior.
5762
/// (In practice, ClangdLSPServer enables bundling if the client claims

clang-tools-extra/clangd/index/SymbolCollector.cpp

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "llvm/ADT/DenseMap.h"
4242
#include "llvm/ADT/SmallVector.h"
4343
#include "llvm/ADT/StringRef.h"
44+
#include "llvm/Support/Casting.h"
4445
#include "llvm/Support/ErrorHandling.h"
4546
#include "llvm/Support/FileSystem.h"
4647
#include "llvm/Support/Path.h"
@@ -75,18 +76,62 @@ bool isPrivateProtoDecl(const NamedDecl &ND) {
7576
if (ND.getIdentifier() == nullptr)
7677
return false;
7778
auto Name = ND.getIdentifier()->getName();
78-
if (!Name.contains('_'))
79-
return false;
80-
// Nested proto entities (e.g. Message::Nested) have top-level decls
81-
// that shouldn't be used (Message_Nested). Ignore them completely.
82-
// The nested entities are dangling type aliases, we may want to reconsider
83-
// including them in the future.
84-
// For enum constants, SOME_ENUM_CONSTANT is not private and should be
85-
// indexed. Outer_INNER is private. This heuristic relies on naming style, it
86-
// will include OUTER_INNER and exclude some_enum_constant.
87-
// FIXME: the heuristic relies on naming style (i.e. no underscore in
88-
// user-defined names) and can be improved.
89-
return (ND.getKind() != Decl::EnumConstant) || llvm::any_of(Name, islower);
79+
// There are some internal helpers like _internal_set_foo();
80+
if (Name.contains("_internal_"))
81+
return true;
82+
83+
// https://protobuf.dev/reference/cpp/cpp-generated/#nested-types
84+
// Nested entities (messages/enums) has two names, one at the top-level scope,
85+
// with a mangled name created by prepending all the outer types. These names
86+
// are almost never preferred by the developers, so exclude them from index.
87+
// e.g.
88+
// message Foo {
89+
// message Bar {}
90+
// enum E { A }
91+
// }
92+
//
93+
// yields:
94+
// class Foo_Bar {};
95+
// enum Foo_E { Foo_E_A };
96+
// class Foo {
97+
// using Bar = Foo_Bar;
98+
// static constexpr Foo_E A = Foo_E_A;
99+
// };
100+
101+
// We get rid of Foo_Bar and Foo_E by discarding any top-level entries with
102+
// `_` in the name. This relies on original message/enum not having `_` in the
103+
// name. Hence might go wrong in certain cases.
104+
if (ND.getDeclContext()->isNamespace()) {
105+
// Strip off some known public suffix helpers for enums, rest of the helpers
106+
// are generated inside record decls so we don't care.
107+
// https://protobuf.dev/reference/cpp/cpp-generated/#enum
108+
Name.consume_back("_descriptor");
109+
Name.consume_back("_IsValid");
110+
Name.consume_back("_Name");
111+
Name.consume_back("_Parse");
112+
Name.consume_back("_MIN");
113+
Name.consume_back("_MAX");
114+
Name.consume_back("_ARRAYSIZE");
115+
return Name.contains('_');
116+
}
117+
118+
// EnumConstantDecls need some special attention, despite being nested in a
119+
// TagDecl, they might still have mangled names. We filter those by checking
120+
// if it has parent's name as a prefix.
121+
// This might go wrong if a nested entity has a name that starts with parent's
122+
// name, e.g: enum Foo { Foo_X }.
123+
if (llvm::isa<EnumConstantDecl>(&ND)) {
124+
auto *DC = llvm::cast<EnumDecl>(ND.getDeclContext());
125+
if (!DC || !DC->getIdentifier())
126+
return false;
127+
auto CtxName = DC->getIdentifier()->getName();
128+
return !CtxName.empty() && Name.consume_front(CtxName) &&
129+
Name.consume_front("_");
130+
}
131+
132+
// Now we're only left with fields/methods without an `_internal_` in the
133+
// name, they're intended for public use.
134+
return false;
90135
}
91136

92137
// We only collect #include paths for symbols that are suitable for global code

clang-tools-extra/clangd/tool/ClangdMain.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,9 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
919919
Opts.CodeComplete.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
920920
Opts.CodeComplete.RunParser = CodeCompletionParse;
921921
Opts.CodeComplete.RankingModel = RankingModel;
922+
// FIXME: If we're using C++20 modules, force the lookup process to load
923+
// external decls, since currently the index doesn't support C++20 modules.
924+
Opts.CodeComplete.ForceLoadPreamble = ExperimentalModulesSupport;
922925

923926
RealThreadsafeFS TFS;
924927
std::vector<std::unique_ptr<config::Provider>> ProviderStack;

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

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,86 @@ import A;
402402
EXPECT_TRUE(D.isFromASTFile());
403403
}
404404

405+
// An end to end test for code complete in modules
406+
TEST_F(PrerequisiteModulesTests, CodeCompleteTest) {
407+
MockDirectoryCompilationDatabase CDB(TestDir, FS);
408+
409+
CDB.addFile("A.cppm", R"cpp(
410+
export module A;
411+
export void printA();
412+
)cpp");
413+
414+
llvm::StringLiteral UserContents = R"cpp(
415+
import A;
416+
void func() {
417+
print^
418+
}
419+
)cpp";
420+
421+
CDB.addFile("Use.cpp", UserContents);
422+
Annotations Test(UserContents);
423+
424+
ModulesBuilder Builder(CDB);
425+
426+
ParseInputs Use = getInputs("Use.cpp", CDB);
427+
Use.ModulesManager = &Builder;
428+
429+
std::unique_ptr<CompilerInvocation> CI =
430+
buildCompilerInvocation(Use, DiagConsumer);
431+
EXPECT_TRUE(CI);
432+
433+
auto Preamble =
434+
buildPreamble(getFullPath("Use.cpp"), *CI, Use, /*InMemory=*/true,
435+
/*Callback=*/nullptr);
436+
EXPECT_TRUE(Preamble);
437+
EXPECT_TRUE(Preamble->RequiredModules);
438+
439+
auto Result = codeComplete(getFullPath("Use.cpp"), Test.point(),
440+
Preamble.get(), Use, {});
441+
EXPECT_FALSE(Result.Completions.empty());
442+
EXPECT_EQ(Result.Completions[0].Name, "printA");
443+
}
444+
445+
TEST_F(PrerequisiteModulesTests, SignatureHelpTest) {
446+
MockDirectoryCompilationDatabase CDB(TestDir, FS);
447+
448+
CDB.addFile("A.cppm", R"cpp(
449+
export module A;
450+
export void printA(int a);
451+
)cpp");
452+
453+
llvm::StringLiteral UserContents = R"cpp(
454+
import A;
455+
void func() {
456+
printA(^);
457+
}
458+
)cpp";
459+
460+
CDB.addFile("Use.cpp", UserContents);
461+
Annotations Test(UserContents);
462+
463+
ModulesBuilder Builder(CDB);
464+
465+
ParseInputs Use = getInputs("Use.cpp", CDB);
466+
Use.ModulesManager = &Builder;
467+
468+
std::unique_ptr<CompilerInvocation> CI =
469+
buildCompilerInvocation(Use, DiagConsumer);
470+
EXPECT_TRUE(CI);
471+
472+
auto Preamble =
473+
buildPreamble(getFullPath("Use.cpp"), *CI, Use, /*InMemory=*/true,
474+
/*Callback=*/nullptr);
475+
EXPECT_TRUE(Preamble);
476+
EXPECT_TRUE(Preamble->RequiredModules);
477+
478+
auto Result = signatureHelp(getFullPath("Use.cpp"), Test.point(),
479+
*Preamble.get(), Use, MarkupKind::PlainText);
480+
EXPECT_FALSE(Result.signatures.empty());
481+
EXPECT_EQ(Result.signatures[0].label, "printA(int a) -> void");
482+
EXPECT_EQ(Result.signatures[0].parameters[0].labelString, "int a");
483+
}
484+
405485
} // namespace
406486
} // namespace clang::clangd
407487

0 commit comments

Comments
 (0)