diff --git a/clang-tools-extra/clangd/ParsedAST.h b/clang-tools-extra/clangd/ParsedAST.h --- a/clang-tools-extra/clangd/ParsedAST.h +++ b/clang-tools-extra/clangd/ParsedAST.h @@ -120,7 +120,8 @@ /// - Does not have spelled or expanded tokens for files from preamble. syntax::TokenBuffer Tokens; - /// The start locations of all macro expansions spelled inside the main file. + /// The start locations of all macro definitions/expansions spelled **after** + /// preamble. /// Does not include expansions from inside other macro expansions. std::vector MainFileMacroExpLocs; // Data, stored after parsing. diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -98,23 +98,30 @@ std::vector TopLevelDecls; }; -// This collects macro expansions in the main file. +// This collects macro expansions/definitions in the main file. // (Contrast with CollectMainFileMacros in Preamble.cpp, which collects macro // *definitions* in the preamble region of the main file). class CollectMainFileMacroExpansions : public PPCallbacks { const SourceManager &SM; std::vector &MainFileMacroLocs; + void addLoc(SourceLocation Loc) { + if (!Loc.isMacroID() && isInsideMainFile(Loc, SM)) + MainFileMacroLocs.push_back(Loc); + } + public: CollectMainFileMacroExpansions(const SourceManager &SM, std::vector &MainFileMacroLocs) : SM(SM), MainFileMacroLocs(MainFileMacroLocs) {} + void MacroDefined(const Token &MacroNameTok, + const MacroDirective *MD) override { + addLoc(MacroNameTok.getLocation()); + } void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override { - SourceLocation L = MacroNameTok.getLocation(); - if (!L.isMacroID() && isInsideMainFile(L, SM)) - MainFileMacroLocs.push_back(L); + addLoc(MacroNameTok.getLocation()); } }; diff --git a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp --- a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp +++ b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp @@ -229,32 +229,36 @@ TEST(ParsedASTTest, CollectsMainFileMacroExpansions) { Annotations TestCase(R"cpp( - #define MACRO_ARGS(X, Y) X Y + // Preamble ends here. + namespace { + #define ^MACRO_ARGS(X, Y) X Y ^ID(int A); // Macro arguments included. ^MACRO_ARGS(^MACRO_ARGS(^MACRO_EXP(int), A), ^ID(= 2)); // Macro names inside other macros not included. - #define FOO BAR - #define BAR 1 + #define ^MACRO_ARGS2(X, Y) X Y + #define ^FOO BAR + #define ^BAR 1 int A = ^FOO; // Macros from token concatenations not included. - #define CONCAT(X) X##A() - #define PREPEND(X) MACRO##X() - #define MACROA() 123 + #define ^CONCAT(X) X##A() + #define ^PREPEND(X) MACRO##X() + #define ^MACROA() 123 int B = ^CONCAT(MACRO); int D = ^PREPEND(A) // Macros included not from preamble not included. #include "foo.inc" - #define assert(COND) if (!(COND)) { printf("%s", #COND); exit(0); } + #define ^assert(COND) if (!(COND)) { printf("%s", #COND); exit(0); } void test() { // Includes macro expansions in arguments that are expressions ^assert(0 <= ^BAR); } + } // namespace )cpp"); auto TU = TestTU::withCode(TestCase.code()); TU.HeaderCode = R"cpp( diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -390,20 +390,22 @@ // Tokens that share a source range but have conflicting Kinds are not // highlighted. R"cpp( - #define DEF_MULTIPLE(X) namespace X { class X { int X; }; } - #define DEF_CLASS(T) class T {}; + // Preamble ends here. + namespace { + #define $Macro[[DEF_MULTIPLE]](X) namespace X { class X { int X; }; } + #define $Macro[[DEF_CLASS]](T) class T {}; $Macro[[DEF_MULTIPLE]](XYZ); $Macro[[DEF_MULTIPLE]](XYZW); $Macro[[DEF_CLASS]]($Class[[A]]) - #define MACRO_CONCAT(X, V, T) T foo##X = V - #define DEF_VAR(X, V) int X = V - #define DEF_VAR_T(T, X, V) T X = V - #define DEF_VAR_REV(V, X) DEF_VAR(X, V) - #define CPY(X) X - #define DEF_VAR_TYPE(X, Y) X Y - #define SOME_NAME variable - #define SOME_NAME_SET variable2 = 123 - #define INC_VAR(X) X += 2 + #define $Macro[[MACRO_CONCAT]](X, V, T) T foo##X = V + #define $Macro[[DEF_VAR]](X, V) int X = V + #define $Macro[[DEF_VAR_T]](T, X, V) T X = V + #define $Macro[[DEF_VAR_REV]](V, X) DEF_VAR(X, V) + #define $Macro[[CPY]](X) X + #define $Macro[[DEF_VAR_TYPE]](X, Y) X Y + #define $Macro[[SOME_NAME]] variable + #define $Macro[[SOME_NAME_SET]] variable2 = 123 + #define $Macro[[INC_VAR]](X) X += 2 $Primitive[[void]] $Function[[foo]]() { $Macro[[DEF_VAR]]($LocalVariable[[X]], 123); $Macro[[DEF_VAR_REV]](908, $LocalVariable[[XY]]); @@ -422,15 +424,18 @@ $Macro[[DEF_VAR]]($Variable[[XYZ]], 567); $Macro[[DEF_VAR_REV]](756, $Variable[[AB]]); - #define CALL_FN(F) F(); - #define DEF_FN(F) void F () + #define $Macro[[CALL_FN]](F) F(); + #define $Macro[[DEF_FN]](F) void F () $Macro[[DEF_FN]]($Function[[g]]) { $Macro[[CALL_FN]]($Function[[foo]]); } + } // namespace )cpp", R"cpp( - #define fail(expr) expr - #define assert(COND) if (!(COND)) { fail("assertion failed" #COND); } + // Preamble ends here. + namespace { + #define $Macro[[fail]](expr) expr + #define $Macro[[assert]](COND) if (!(COND)) { fail("assertion failed" #COND); } $Primitive[[int]] $Variable[[x]]; $Primitive[[int]] $Variable[[y]]; $Primitive[[int]] $Function[[f]](); @@ -438,8 +443,9 @@ $Macro[[assert]]($Variable[[x]] != $Variable[[y]]); $Macro[[assert]]($Variable[[x]] != $Function[[f]]()); } + } )cpp", - R"cpp( + R"cpp( struct $Class[[S]] { $Primitive[[float]] $Field[[Value]]; $Class[[S]] *$Field[[Next]];