[clang-tools-extra] r371504 - [clangd] Collect location of macro definition in the ParsedAST

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 10 03:10:36 PDT 2019


Author: hokein
Date: Tue Sep 10 03:10:36 2019
New Revision: 371504

URL: http://llvm.org/viewvc/llvm-project?rev=371504&view=rev
Log:
[clangd] Collect location of macro definition in the ParsedAST

allows semantic hightlighting macro definition

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67264

Modified:
    clang-tools-extra/trunk/clangd/ParsedAST.cpp
    clang-tools-extra/trunk/clangd/ParsedAST.h
    clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp
    clang-tools-extra/trunk/clangd/unittests/ParsedASTTests.cpp
    clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp

Modified: clang-tools-extra/trunk/clangd/ParsedAST.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ParsedAST.cpp?rev=371504&r1=371503&r2=371504&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ParsedAST.cpp (original)
+++ clang-tools-extra/trunk/clangd/ParsedAST.cpp Tue Sep 10 03:10:36 2019
@@ -98,23 +98,30 @@ private:
   std::vector<Decl *> 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 {
+class CollectMainFileMacros : public PPCallbacks {
   const SourceManager &SM;
   std::vector<SourceLocation> &MainFileMacroLocs;
 
+  void addLoc(SourceLocation Loc) {
+    if (!Loc.isMacroID() && isInsideMainFile(Loc, SM))
+      MainFileMacroLocs.push_back(Loc);
+  }
+
 public:
-  CollectMainFileMacroExpansions(const SourceManager &SM,
-                                 std::vector<SourceLocation> &MainFileMacroLocs)
+  CollectMainFileMacros(const SourceManager &SM,
+                        std::vector<SourceLocation> &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());
   }
 };
 
@@ -358,8 +365,8 @@ ParsedAST::build(std::unique_ptr<clang::
   // Collect the macro expansions in the main file.
   std::vector<SourceLocation> MainFileMacroExpLocs;
   Clang->getPreprocessor().addPPCallbacks(
-      std::make_unique<CollectMainFileMacroExpansions>(
-          Clang->getSourceManager(), MainFileMacroExpLocs));
+      std::make_unique<CollectMainFileMacros>(Clang->getSourceManager(),
+                                              MainFileMacroExpLocs));
 
   // Copy over the includes from the preamble, then combine with the
   // non-preamble includes below.
@@ -453,8 +460,8 @@ llvm::ArrayRef<Decl *> ParsedAST::getLoc
   return LocalTopLevelDecls;
 }
 
-llvm::ArrayRef<SourceLocation> ParsedAST::getMainFileExpansions() const {
-  return MainFileMacroExpLocs;
+llvm::ArrayRef<SourceLocation> ParsedAST::getMacros() const {
+  return MacroIdentifierLocs;
 }
 
 const std::vector<Diag> &ParsedAST::getDiagnostics() const { return Diags; }
@@ -503,13 +510,13 @@ ParsedAST::ParsedAST(std::shared_ptr<con
                      std::unique_ptr<CompilerInstance> Clang,
                      std::unique_ptr<FrontendAction> Action,
                      syntax::TokenBuffer Tokens,
-                     std::vector<SourceLocation> MainFileMacroExpLocs,
+                     std::vector<SourceLocation> MacroIdentifierLocs,
                      std::vector<Decl *> LocalTopLevelDecls,
                      std::vector<Diag> Diags, IncludeStructure Includes,
                      CanonicalIncludes CanonIncludes)
     : Preamble(std::move(Preamble)), Clang(std::move(Clang)),
       Action(std::move(Action)), Tokens(std::move(Tokens)),
-      MainFileMacroExpLocs(std::move(MainFileMacroExpLocs)),
+      MacroIdentifierLocs(std::move(MacroIdentifierLocs)),
       Diags(std::move(Diags)),
       LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
       Includes(std::move(Includes)), CanonIncludes(std::move(CanonIncludes)) {

Modified: clang-tools-extra/trunk/clangd/ParsedAST.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ParsedAST.h?rev=371504&r1=371503&r2=371504&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ParsedAST.h (original)
+++ clang-tools-extra/trunk/clangd/ParsedAST.h Tue Sep 10 03:10:36 2019
@@ -89,9 +89,10 @@ public:
   const IncludeStructure &getIncludeStructure() const;
   const CanonicalIncludes &getCanonicalIncludes() const;
 
-  /// The start locations of all macro expansions spelled inside the main file.
-  /// Does not include expansions from inside other macro expansions.
-  llvm::ArrayRef<SourceLocation> getMainFileExpansions() const;
+  /// Gets all macro locations (definition, expansions) present in the main
+  /// file.
+  /// NOTE: macros inside the preamble are not included.
+  llvm::ArrayRef<SourceLocation> getMacros() const;
   /// Tokens recorded while parsing the main file.
   /// (!) does not have tokens from the preamble.
   const syntax::TokenBuffer &getTokens() const { return Tokens; }
@@ -120,9 +121,10 @@ private:
   ///   - 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.
-  /// Does not include expansions from inside other macro expansions.
-  std::vector<SourceLocation> MainFileMacroExpLocs;
+  /// The start locations of all macro definitions/expansions spelled **after**
+  /// preamble.
+  /// Does not include locations from inside other macro expansions.
+  std::vector<SourceLocation> MacroIdentifierLocs;
   // Data, stored after parsing.
   std::vector<Diag> Diags;
   // Top-level decls inside the current file. Not that this does not include

Modified: clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp?rev=371504&r1=371503&r2=371504&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp (original)
+++ clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp Tue Sep 10 03:10:36 2019
@@ -38,10 +38,8 @@ public:
     TraverseAST(AST.getASTContext());
     // Add highlightings for macro expansions as they are not traversed by the
     // visitor.
-    // FIXME: Should add highlighting to the macro definitions as well. But this
-    // information is not collected in ParsedAST right now.
-    for (const SourceLocation &L : AST.getMainFileExpansions())
-      addToken(L, HighlightingKind::Macro);
+    for (SourceLocation Loc : AST.getMacros())
+      addToken(Loc, HighlightingKind::Macro);
     // Initializer lists can give duplicates of tokens, therefore all tokens
     // must be deduplicated.
     llvm::sort(Tokens);

Modified: clang-tools-extra/trunk/clangd/unittests/ParsedASTTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/ParsedASTTests.cpp?rev=371504&r1=371503&r2=371504&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/ParsedASTTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/ParsedASTTests.cpp Tue Sep 10 03:10:36 2019
@@ -230,26 +230,28 @@ TEST(ParsedASTTest, CanBuildInvocationWi
 TEST(ParsedASTTest, CollectsMainFileMacroExpansions) {
   Annotations TestCase(R"cpp(
     #define MACRO_ARGS(X, Y) X Y
+    // - premable ends, macros inside preamble are not considered in main file.
     ^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
@@ -268,8 +270,7 @@ TEST(ParsedASTTest, CollectsMainFileMacr
     int D = DEF;
   )cpp";
   ParsedAST AST = TU.build();
-  const std::vector<SourceLocation> &MacroExpansionLocations =
-      AST.getMainFileExpansions();
+  const std::vector<SourceLocation> &MacroExpansionLocations = AST.getMacros();
   std::vector<Position> MacroExpansionPositions;
   for (const auto &L : MacroExpansionLocations)
     MacroExpansionPositions.push_back(

Modified: clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp?rev=371504&r1=371503&r2=371504&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/SemanticHighlightingTests.cpp Tue Sep 10 03:10:36 2019
@@ -427,18 +427,19 @@ TEST(SemanticHighlighting, GetsCorrectTo
       R"cpp(
       #define DEF_MULTIPLE(X) namespace X { class X { int X; }; }
       #define DEF_CLASS(T) class T {};
+      // Preamble ends.
       $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]]);
@@ -457,8 +458,8 @@ TEST(SemanticHighlighting, GetsCorrectTo
       $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]]);
       }
@@ -466,6 +467,7 @@ TEST(SemanticHighlighting, GetsCorrectTo
       R"cpp(
       #define fail(expr) expr
       #define assert(COND) if (!(COND)) { fail("assertion failed" #COND); }
+      // Preamble ends.
       $Primitive[[int]] $Variable[[x]];
       $Primitive[[int]] $Variable[[y]];
       $Primitive[[int]] $Function[[f]]();




More information about the cfe-commits mailing list