ioeric updated this revision to Diff 154388.
ioeric marked 6 inline comments as done.
ioeric added a comment.

- addressed review comments.


Repository:
  rC Clang

https://reviews.llvm.org/D48961

Files:
  include/clang/Index/IndexDataConsumer.h
  include/clang/Index/IndexSymbol.h
  include/clang/Index/IndexingAction.h
  lib/Index/IndexSymbol.cpp
  lib/Index/IndexingAction.cpp
  lib/Index/IndexingContext.cpp
  lib/Index/IndexingContext.h
  lib/Sema/SemaCodeComplete.cpp
  test/Index/Core/index-macros.c
  tools/c-index-test/core_main.cpp
  unittests/Sema/CodeCompleteTest.cpp

Index: unittests/Sema/CodeCompleteTest.cpp
===================================================================
--- unittests/Sema/CodeCompleteTest.cpp
+++ unittests/Sema/CodeCompleteTest.cpp
@@ -131,4 +131,15 @@
   EXPECT_TRUE(VisitedNS.empty());
 }
 
+TEST(SemaCodeCompleteTest, VisitedNSWithoutQualifier) {
+  auto VisitedNS = runCodeCompleteOnCode(R"cpp(
+    namespace n1 {
+    namespace n2 {
+      void f(^) {}
+    }
+    }
+  )cpp");
+  EXPECT_THAT(VisitedNS, UnorderedElementsAre("n1", "n1::n2"));
+}
+
 } // namespace
Index: tools/c-index-test/core_main.cpp
===================================================================
--- tools/c-index-test/core_main.cpp
+++ tools/c-index-test/core_main.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Basic/LangOptions.h"
 #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -16,6 +17,7 @@
 #include "clang/Index/IndexDataConsumer.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Index/CodegenNameGenerator.h"
+#include "clang/Lex/Preprocessor.h"
 #include "clang/Serialization/ASTReader.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Signals.h"
@@ -77,6 +79,7 @@
 class PrintIndexDataConsumer : public IndexDataConsumer {
   raw_ostream &OS;
   std::unique_ptr<CodegenNameGenerator> CGNameGen;
+  std::shared_ptr<Preprocessor> PP;
 
 public:
   PrintIndexDataConsumer(raw_ostream &OS) : OS(OS) {
@@ -86,6 +89,10 @@
     CGNameGen.reset(new CodegenNameGenerator(Ctx));
   }
 
+  void setPreprocessor(std::shared_ptr<Preprocessor> PP) override {
+    this->PP = std::move(PP);
+  }
+
   bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
                            ArrayRef<SymbolRelation> Relations,
                            SourceLocation Loc, ASTNodeInfo ASTNode) override {
@@ -145,6 +152,42 @@
 
     return true;
   }
+
+  bool handleMacroOccurence(const IdentifierInfo &Name, const MacroInfo &MI,
+                            SymbolRoleSet Roles, SourceLocation Loc,
+                            bool Undefined) override {
+    assert(PP);
+    SourceManager &SM = PP->getSourceManager();
+
+    Loc = SM.getFileLoc(Loc);
+    FileID FID = SM.getFileID(Loc);
+    unsigned Line = SM.getLineNumber(FID, SM.getFileOffset(Loc));
+    unsigned Col = SM.getColumnNumber(FID, SM.getFileOffset(Loc));
+    OS << Line << ':' << Col << " | ";
+
+    printSymbolInfo(getSymbolInfoForMacro(MI), OS);
+    OS << " | ";
+
+    OS << Name.getName();
+    OS << " | ";
+
+    SmallString<256> USRBuf;
+    if (generateUSRForMacro(Name.getName(), MI.getDefinitionLoc(), SM,
+                            USRBuf)) {
+      OS << "<no-usr>";
+    } else {
+      OS << USRBuf;
+    }
+
+    OS << " | ";
+
+    if (Undefined)
+      OS << "(undefined)";
+    else
+      printSymbolRoles(Roles, OS);
+    OS << " |\n";
+    return true;
+  }
 };
 
 } // anonymous namespace
Index: test/Index/Core/index-macros.c
===================================================================
--- /dev/null
+++ test/Index/Core/index-macros.c
@@ -0,0 +1,12 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// CHECK: [[@LINE+1]]:9 | macro/C | X1 | c:index-macros.c@157@macro@X1 | Def |
+#define X1 1
+// CHECK: [[@LINE+1]]:9 | macro/C | DEF | c:index-macros.c@251@macro@DEF | Def |
+#define DEF(x) int x
+// CHECK: [[@LINE+1]]:8 | macro/C | X1 | c:index-macros.c@157@macro@X1 | (undefined) |
+#undef X1
+
+// CHECK: [[@LINE+2]]:1 | macro/C | DEF | c:index-macros.c@251@macro@DEF | Ref |
+// CHECK: [[@LINE+1]]:5 | variable/C | i | c:@i | i | Def | rel: 0
+DEF(i);
Index: lib/Sema/SemaCodeComplete.cpp
===================================================================
--- lib/Sema/SemaCodeComplete.cpp
+++ lib/Sema/SemaCodeComplete.cpp
@@ -3700,9 +3700,11 @@
 /// type we're looking for.
 void Sema::CodeCompleteExpression(Scope *S, 
                                   const CodeCompleteExpressionData &Data) {
-  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
-                        CodeCompleter->getCodeCompletionTUInfo(),
-                        CodeCompletionContext::CCC_Expression);
+  ResultBuilder Results(
+      *this, CodeCompleter->getAllocator(),
+      CodeCompleter->getCodeCompletionTUInfo(),
+      CodeCompletionContext(CodeCompletionContext::CCC_Expression,
+                            Data.PreferredType));
   if (Data.ObjCCollection)
     Results.setFilter(&ResultBuilder::IsObjCCollection);
   else if (Data.IntegralConstantExpression)
@@ -3741,10 +3743,8 @@
 
   if (CodeCompleter->includeMacros())
     AddMacroResults(PP, Results, false, PreferredTypeIsPointer);
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                CodeCompletionContext(CodeCompletionContext::CCC_Expression, 
-                                      Data.PreferredType),
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
@@ -4360,17 +4360,11 @@
   }
   Results.ExitScope();
 
-  //We need to make sure we're setting the right context, 
-  //so only say we include macros if the code completer says we do
-  enum CodeCompletionContext::Kind kind = CodeCompletionContext::CCC_Other;
   if (CodeCompleter->includeMacros()) {
     AddMacroResults(PP, Results, false);
-    kind = CodeCompletionContext::CCC_OtherWithMacros;
   }
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            kind,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 static bool anyNullArguments(ArrayRef<Expr *> Args) {
@@ -4773,10 +4767,9 @@
                      CodeCompleter->includeGlobals(),
                      CodeCompleter->loadExternal());
   Results.ExitScope();
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_PotentiallyQualifiedName,
-                            Results.data(),Results.size());
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteUsingDirective(Scope *S) {
@@ -4795,9 +4788,8 @@
                      CodeCompleter->includeGlobals(),
                      CodeCompleter->loadExternal());
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Namespace,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteNamespaceDecl(Scope *S)  {
@@ -4893,10 +4885,9 @@
   // Add any type specifiers
   AddTypeSpecifierResults(getLangOpts(), Results);
   Results.ExitScope();
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Type,
-                            Results.data(),Results.size());
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteConstructorInitializer(
@@ -5177,9 +5168,8 @@
   else
     AddObjCTopLevelResults(Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
@@ -5311,9 +5301,8 @@
   Results.EnterNewScope();
   AddObjCVisibilityResults(getLangOpts(), Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCAtStatement(Scope *S) {
@@ -5324,9 +5313,8 @@
   AddObjCStatementResults(Results, false);
   AddObjCExpressionResults(Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCAtExpression(Scope *S) {
@@ -5336,9 +5324,8 @@
   Results.EnterNewScope();
   AddObjCExpressionResults(Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 /// Determine whether the addition of the given flag to an Objective-C
@@ -5432,9 +5419,8 @@
     Results.AddResult(CodeCompletionResult("null_resettable"));
   }
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 /// Describes the kind of Objective-C method that we want to find
@@ -5616,9 +5602,8 @@
   AddObjCMethods(Class, true, MK_ZeroArgSelector, None, CurContext, Selectors,
                  /*AllowSameLength=*/true, Results);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter,
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCPropertySetter(Scope *S) {
@@ -5645,9 +5630,8 @@
                  Selectors, /*AllowSameLength=*/true, Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter,
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
@@ -5723,8 +5707,7 @@
   if (CodeCompleter->includeMacros())
     AddMacroResults(PP, Results, false);
 
-  HandleCodeCompleteResults(this, CodeCompleter,
-                            CodeCompletionContext::CCC_Type,
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
                             Results.data(), Results.size());
 }
 
@@ -6396,9 +6379,8 @@
     Results.AddResult(Builder.TakeString());
   }
   Results.ExitScope();
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_SelectorName,
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
                             Results.data(), Results.size());
 }
 
@@ -6441,10 +6423,9 @@
 
     Results.ExitScope();
   }
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_ObjCProtocolName,
-                            Results.data(),Results.size());
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
@@ -6461,10 +6442,9 @@
 
     Results.ExitScope();
   }
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_ObjCProtocolName,
-                            Results.data(),Results.size());
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 /// Add all of the Objective-C interface declarations that we find in
@@ -6485,23 +6465,22 @@
   }
 }
 
-void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) { 
+void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
                         CodeCompleter->getCodeCompletionTUInfo(),
-                        CodeCompletionContext::CCC_Other);
+                        CodeCompletionContext::CCC_ObjCInterfaceName);
   Results.EnterNewScope();
-  
+
   if (CodeCompleter->includeGlobals()) {
     // Add all classes.
     AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
                         false, Results);
   }
   
   Results.ExitScope();
 
-  HandleCodeCompleteResults(this, CodeCompleter,
-                            CodeCompletionContext::CCC_ObjCInterfaceName,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
@@ -6525,15 +6504,14 @@
   
   Results.ExitScope();
 
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_ObjCInterfaceName,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
-void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { 
+void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
                         CodeCompleter->getCodeCompletionTUInfo(),
-                        CodeCompletionContext::CCC_Other);
+                        CodeCompletionContext::CCC_ObjCImplementation);
   Results.EnterNewScope();
 
   if (CodeCompleter->includeGlobals()) {
@@ -6544,9 +6522,8 @@
   
   Results.ExitScope();
 
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_ObjCInterfaceName,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, 
@@ -6578,10 +6555,9 @@
                                  nullptr),
                           CurContext, nullptr, false);
   Results.ExitScope();
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_ObjCCategoryName,
-                            Results.data(),Results.size());  
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCImplementationCategory(Scope *S, 
@@ -6620,10 +6596,9 @@
     IgnoreImplemented = false;
   }
   Results.ExitScope();
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_ObjCCategoryName,
-                            Results.data(),Results.size());  
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
@@ -6660,10 +6635,9 @@
                       false, /*AllowNullaryMethods=*/false, CurContext, 
                       AddedProperties, Results);
   Results.ExitScope();
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());  
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, 
@@ -6753,10 +6727,9 @@
   }
   
   Results.ExitScope();
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 // Mapping from selectors to the methods that implement that selector, along
@@ -7686,10 +7659,9 @@
   }
   
   Results.ExitScope();
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, 
@@ -7776,9 +7748,8 @@
     }
   }
 
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_Other,
-                            Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
@@ -7934,9 +7905,8 @@
 
   // FIXME: we don't support #assert or #unassert, so don't suggest them.
   Results.ExitScope();
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_PreprocessorDirective,
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
                             Results.data(), Results.size());
 }
 
@@ -7993,10 +7963,9 @@
   Builder.AddChunk(CodeCompletionString::CK_RightParen);
   Results.AddResult(Builder.TakeString());
   Results.ExitScope();
-  
-  HandleCodeCompleteResults(this, CodeCompleter, 
-                            CodeCompletionContext::CCC_PreprocessorExpression,
-                            Results.data(), Results.size()); 
+
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
@@ -8028,9 +7997,8 @@
         Twine(Platform) + "ApplicationExtension")));
   }
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter,
-                            CodeCompletionContext::CCC_Other, Results.data(),
-                            Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
 }
 
 void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
Index: lib/Index/IndexingContext.h
===================================================================
--- lib/Index/IndexingContext.h
+++ lib/Index/IndexingContext.h
@@ -10,9 +10,11 @@
 #ifndef LLVM_CLANG_LIB_INDEX_INDEXINGCONTEXT_H
 #define LLVM_CLANG_LIB_INDEX_INDEXINGCONTEXT_H
 
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Index/IndexSymbol.h"
 #include "clang/Index/IndexingAction.h"
+#include "clang/Lex/MacroInfo.h"
 #include "llvm/ADT/ArrayRef.h"
 
 namespace clang {
@@ -80,6 +82,15 @@
                        const Expr *RefE = nullptr,
                        const Decl *RefD = nullptr);
 
+  void handleMacroDefined(const IdentifierInfo &Name, SourceLocation Loc,
+                          const MacroInfo &MI);
+
+  void handleMacroUndefined(const IdentifierInfo &Name, SourceLocation Loc,
+                            const MacroInfo &MI);
+
+  void handleMacroReference(const IdentifierInfo &Name, SourceLocation Loc,
+                            const MacroInfo &MD);
+
   bool importedModule(const ImportDecl *ImportD);
 
   bool indexDecl(const Decl *D);
Index: lib/Index/IndexingContext.cpp
===================================================================
--- lib/Index/IndexingContext.cpp
+++ lib/Index/IndexingContext.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "IndexingContext.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Index/IndexDataConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclTemplate.h"
@@ -290,6 +291,7 @@
       case SymbolRole::Dynamic:
       case SymbolRole::AddressOf:
       case SymbolRole::Implicit:
+      case SymbolRole::Undefinition:
       case SymbolRole::RelationReceivedBy:
       case SymbolRole::RelationCalledBy:
       case SymbolRole::RelationContainedBy:
@@ -406,3 +408,24 @@
   IndexDataConsumer::ASTNodeInfo Node{OrigE, OrigD, Parent, ContainerDC};
   return DataConsumer.handleDeclOccurence(D, Roles, FinalRelations, Loc, Node);
 }
+
+void IndexingContext::handleMacroDefined(const IdentifierInfo &Name,
+                                         SourceLocation Loc,
+                                         const MacroInfo &MI) {
+  SymbolRoleSet Roles = (unsigned)SymbolRole::Definition;
+  DataConsumer.handleMacroOccurence(Name, MI, Roles, Loc, /*Undefined=*/false);
+}
+
+void IndexingContext::handleMacroUndefined(const IdentifierInfo &Name,
+                                           SourceLocation Loc,
+                                           const MacroInfo &MI) {
+  SymbolRoleSet Roles = (unsigned)SymbolRole::Reference;
+  DataConsumer.handleMacroOccurence(Name, MI, Roles, Loc, /*Undefined=*/true);
+}
+
+void IndexingContext::handleMacroReference(const IdentifierInfo &Name,
+                                           SourceLocation Loc,
+                                           const MacroInfo &MI) {
+  SymbolRoleSet Roles = (unsigned)SymbolRole::Reference;
+  DataConsumer.handleMacroOccurence(Name, MI, Roles, Loc, /*Undefined=*/false);
+}
Index: lib/Index/IndexingAction.cpp
===================================================================
--- lib/Index/IndexingAction.cpp
+++ lib/Index/IndexingAction.cpp
@@ -13,8 +13,11 @@
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Index/IndexDataConsumer.h"
+#include "clang/Lex/PPCallbacks.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Serialization/ASTReader.h"
+#include "llvm/ADT/STLExtras.h"
+#include <memory>
 
 using namespace clang;
 using namespace clang::index;
@@ -28,10 +31,11 @@
   return true;
 }
 
-bool IndexDataConsumer::handleMacroOccurence(const IdentifierInfo *Name,
-                                             const MacroInfo *MI,
+bool IndexDataConsumer::handleMacroOccurence(const IdentifierInfo &Name,
+                                             const MacroInfo &MI,
                                              SymbolRoleSet Roles,
-                                             SourceLocation Loc) {
+                                             SourceLocation Loc,
+                                             bool Undefined) {
   return true;
 }
 
@@ -45,51 +49,84 @@
 
 class IndexASTConsumer : public ASTConsumer {
   std::shared_ptr<Preprocessor> PP;
-  IndexingContext &IndexCtx;
+  std::shared_ptr<IndexingContext> IndexCtx;
 
 public:
-  IndexASTConsumer(std::shared_ptr<Preprocessor> PP, IndexingContext &IndexCtx)
-      : PP(std::move(PP)), IndexCtx(IndexCtx) {}
+  IndexASTConsumer(std::shared_ptr<Preprocessor> PP,
+                   std::shared_ptr<IndexingContext> IndexCtx)
+      : PP(std::move(PP)), IndexCtx(std::move(IndexCtx)) {}
 
 protected:
   void Initialize(ASTContext &Context) override {
-    IndexCtx.setASTContext(Context);
-    IndexCtx.getDataConsumer().initialize(Context);
-    IndexCtx.getDataConsumer().setPreprocessor(PP);
+    IndexCtx->setASTContext(Context);
+    IndexCtx->getDataConsumer().initialize(Context);
+    IndexCtx->getDataConsumer().setPreprocessor(PP);
   }
 
   bool HandleTopLevelDecl(DeclGroupRef DG) override {
-    return IndexCtx.indexDeclGroupRef(DG);
+    return IndexCtx->indexDeclGroupRef(DG);
   }
 
   void HandleInterestingDecl(DeclGroupRef DG) override {
     // Ignore deserialized decls.
   }
 
   void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
-    IndexCtx.indexDeclGroupRef(DG);
+    IndexCtx->indexDeclGroupRef(DG);
   }
 
   void HandleTranslationUnit(ASTContext &Ctx) override {
   }
 };
 
+class IndexPPCallbacks : public PPCallbacks {
+  std::shared_ptr<IndexingContext> IndexCtx;
+
+public:
+  IndexPPCallbacks(std::shared_ptr<IndexingContext> IndexCtx)
+      : IndexCtx(std::move(IndexCtx)) {}
+
+  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
+                    SourceRange Range, const MacroArgs *Args) override {
+    IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(),
+                                   Range.getBegin(), *MD.getMacroInfo());
+  }
+
+  void MacroDefined(const Token &MacroNameTok,
+                    const MacroDirective *MD) override {
+    IndexCtx->handleMacroDefined(*MacroNameTok.getIdentifierInfo(),
+                                 MacroNameTok.getLocation(),
+                                 *MD->getMacroInfo());
+  }
+
+  void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD,
+                      const MacroDirective *Undef) override {
+    IndexCtx->handleMacroUndefined(*MacroNameTok.getIdentifierInfo(),
+                                   MacroNameTok.getLocation(),
+                                   *MD.getMacroInfo());
+  }
+};
+
 class IndexActionBase {
 protected:
   std::shared_ptr<IndexDataConsumer> DataConsumer;
-  IndexingContext IndexCtx;
+  std::shared_ptr<IndexingContext> IndexCtx;
 
   IndexActionBase(std::shared_ptr<IndexDataConsumer> dataConsumer,
                   IndexingOptions Opts)
-    : DataConsumer(std::move(dataConsumer)),
-      IndexCtx(Opts, *DataConsumer) {}
+      : DataConsumer(std::move(dataConsumer)),
+        IndexCtx(new IndexingContext(Opts, *DataConsumer)) {}
 
   std::unique_ptr<IndexASTConsumer>
   createIndexASTConsumer(CompilerInstance &CI) {
     return llvm::make_unique<IndexASTConsumer>(CI.getPreprocessorPtr(),
                                                IndexCtx);
   }
 
+  std::unique_ptr<PPCallbacks> createIndexPPCallbacks() {
+    return llvm::make_unique<IndexPPCallbacks>(IndexCtx);
+  }
+
   void finish() {
     DataConsumer->finish();
   }
@@ -107,6 +144,11 @@
     return createIndexASTConsumer(CI);
   }
 
+  bool BeginSourceFileAction(clang::CompilerInstance &CI) override {
+    CI.getPreprocessor().addPPCallbacks(createIndexPPCallbacks());
+    return true;
+  }
+
   void EndSourceFileAction() override {
     FrontendAction::EndSourceFileAction();
     finish();
@@ -125,32 +167,34 @@
 
 protected:
   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
-                                                 StringRef InFile) override;
-  void EndSourceFileAction() override;
-};
-
-} // anonymous namespace
+                                                 StringRef InFile) override {
+    auto OtherConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
+    if (!OtherConsumer) {
+      IndexActionFailed = true;
+      return nullptr;
+    }
+
+    std::vector<std::unique_ptr<ASTConsumer>> Consumers;
+    Consumers.push_back(std::move(OtherConsumer));
+    Consumers.push_back(createIndexASTConsumer(CI));
+    return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
+  }
 
-void WrappingIndexAction::EndSourceFileAction() {
-  // Invoke wrapped action's method.
-  WrapperFrontendAction::EndSourceFileAction();
-  if (!IndexActionFailed)
-    finish();
-}
+  bool BeginSourceFileAction(clang::CompilerInstance &CI) override {
+    WrapperFrontendAction::BeginSourceFileAction(CI);
+    CI.getPreprocessor().addPPCallbacks(createIndexPPCallbacks());
+    return true;
+  }
 
-std::unique_ptr<ASTConsumer>
-WrappingIndexAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
-  auto OtherConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
-  if (!OtherConsumer) {
-    IndexActionFailed = true;
-    return nullptr;
+  void EndSourceFileAction() override {
+    // Invoke wrapped action's method.
+    WrapperFrontendAction::EndSourceFileAction();
+    if (!IndexActionFailed)
+      finish();
   }
+};
 
-  std::vector<std::unique_ptr<ASTConsumer>> Consumers;
-  Consumers.push_back(std::move(OtherConsumer));
-  Consumers.push_back(createIndexASTConsumer(CI));
-  return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
-}
+} // anonymous namespace
 
 std::unique_ptr<FrontendAction>
 index::createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
@@ -163,7 +207,6 @@
   return llvm::make_unique<IndexAction>(std::move(DataConsumer), Opts);
 }
 
-
 static bool topLevelDeclVisitor(void *context, const Decl *D) {
   IndexingContext &IndexCtx = *static_cast<IndexingContext*>(context);
   return IndexCtx.indexTopLevelDecl(D);
@@ -195,6 +238,12 @@
   DataConsumer.finish();
 }
 
+std::unique_ptr<PPCallbacks>
+index::indexMacrosCallback(IndexDataConsumer &Consumer, IndexingOptions Opts) {
+  return llvm::make_unique<IndexPPCallbacks>(
+      std::make_shared<IndexingContext>(Opts, Consumer));
+}
+
 void index::indexModuleFile(serialization::ModuleFile &Mod, ASTReader &Reader,
                             IndexDataConsumer &DataConsumer,
                             IndexingOptions Opts) {
Index: lib/Index/IndexSymbol.cpp
===================================================================
--- lib/Index/IndexSymbol.cpp
+++ lib/Index/IndexSymbol.cpp
@@ -12,6 +12,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/PrettyPrinter.h"
+#include "clang/Lex/MacroInfo.h"
 
 using namespace clang;
 using namespace clang::index;
@@ -348,6 +349,15 @@
   return Info;
 }
 
+SymbolInfo index::getSymbolInfoForMacro(const MacroInfo &) {
+  SymbolInfo Info;
+  Info.Kind = SymbolKind::Macro;
+  Info.SubKind = SymbolSubKind::None;
+  Info.Properties = SymbolPropertySet();
+  Info.Lang = SymbolLanguage::C;
+  return Info;
+}
+
 bool index::applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,
                                    llvm::function_ref<bool(SymbolRole)> Fn) {
 #define APPLY_FOR_ROLE(Role) \
@@ -364,6 +374,7 @@
   APPLY_FOR_ROLE(Dynamic);
   APPLY_FOR_ROLE(AddressOf);
   APPLY_FOR_ROLE(Implicit);
+  APPLY_FOR_ROLE(Undefinition);
   APPLY_FOR_ROLE(RelationChildOf);
   APPLY_FOR_ROLE(RelationBaseOf);
   APPLY_FOR_ROLE(RelationOverrideOf);
@@ -405,6 +416,7 @@
     case SymbolRole::Dynamic: OS << "Dyn"; break;
     case SymbolRole::AddressOf: OS << "Addr"; break;
     case SymbolRole::Implicit: OS << "Impl"; break;
+    case SymbolRole::Undefinition: OS << "Undef"; break;
     case SymbolRole::RelationChildOf: OS << "RelChild"; break;
     case SymbolRole::RelationBaseOf: OS << "RelBase"; break;
     case SymbolRole::RelationOverrideOf: OS << "RelOver"; break;
Index: include/clang/Index/IndexingAction.h
===================================================================
--- include/clang/Index/IndexingAction.h
+++ include/clang/Index/IndexingAction.h
@@ -11,6 +11,7 @@
 #define LLVM_CLANG_INDEX_INDEXINGACTION_H
 
 #include "clang/Basic/LLVM.h"
+#include "clang/Lex/PPCallbacks.h"
 #include "llvm/ADT/ArrayRef.h"
 #include <memory>
 
@@ -40,18 +41,30 @@
   bool IndexFunctionLocals = false;
 };
 
+/// Creates a frontend action that indexes all symbols (macros and AST decls).
 /// \param WrappedAction another frontend action to wrap over or null.
 std::unique_ptr<FrontendAction>
 createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
                      IndexingOptions Opts,
                      std::unique_ptr<FrontendAction> WrappedAction);
 
+/// Recursively indexes all decls in the AST.
+/// Note that this does not index macros.
 void indexASTUnit(ASTUnit &Unit, IndexDataConsumer &DataConsumer,
                   IndexingOptions Opts);
 
+/// Recursively indexes \p Decls.
+/// Note that this does not index macros.
 void indexTopLevelDecls(ASTContext &Ctx, ArrayRef<const Decl *> Decls,
                         IndexDataConsumer &DataConsumer, IndexingOptions Opts);
 
+/// Creates a PPCallbacks that indexes macros and feeds macros to \p Consumer.
+/// The caller is responsible for calling `Consumer.setPreprocessor()`.
+std::unique_ptr<PPCallbacks> indexMacrosCallback(IndexDataConsumer &Consumer,
+                                                 IndexingOptions Opts);
+
+/// Recursively indexes all top-level decls in the module.
+/// FIXME: make this index macros as well.
 void indexModuleFile(serialization::ModuleFile &Mod, ASTReader &Reader,
                      IndexDataConsumer &DataConsumer, IndexingOptions Opts);
 
Index: include/clang/Index/IndexSymbol.h
===================================================================
--- include/clang/Index/IndexSymbol.h
+++ include/clang/Index/IndexSymbol.h
@@ -11,6 +11,7 @@
 #define LLVM_CLANG_INDEX_INDEXSYMBOL_H
 
 #include "clang/Basic/LLVM.h"
+#include "clang/Lex/MacroInfo.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/DataTypes.h"
 
@@ -93,28 +94,30 @@
 /// Low 9 bits of clang-c/include/Index.h CXSymbolRole mirrors this enum.
 enum class SymbolRole : uint32_t {
   Declaration = 1 << 0,
-  Definition  = 1 << 1,
-  Reference   = 1 << 2,
-  Read        = 1 << 3,
-  Write       = 1 << 4,
-  Call        = 1 << 5,
-  Dynamic     = 1 << 6,
-  AddressOf   = 1 << 7,
-  Implicit    = 1 << 8,
+  Definition = 1 << 1,
+  Reference = 1 << 2,
+  Read = 1 << 3,
+  Write = 1 << 4,
+  Call = 1 << 5,
+  Dynamic = 1 << 6,
+  AddressOf = 1 << 7,
+  Implicit = 1 << 8,
+  // FIXME: this is not mirrored in CXSymbolRole.
+  Undefinition = 1 << 9, // macro #undef
 
   // Relation roles.
-  RelationChildOf     = 1 << 9,
-  RelationBaseOf      = 1 << 10,
-  RelationOverrideOf  = 1 << 11,
-  RelationReceivedBy  = 1 << 12,
-  RelationCalledBy    = 1 << 13,
-  RelationExtendedBy  = 1 << 14,
-  RelationAccessorOf  = 1 << 15,
-  RelationContainedBy = 1 << 16,
-  RelationIBTypeOf    = 1 << 17,
-  RelationSpecializationOf = 1 << 18,
+  RelationChildOf = 1 << 10,
+  RelationBaseOf = 1 << 11,
+  RelationOverrideOf = 1 << 12,
+  RelationReceivedBy = 1 << 13,
+  RelationCalledBy = 1 << 14,
+  RelationExtendedBy = 1 << 15,
+  RelationAccessorOf = 1 << 16,
+  RelationContainedBy = 1 << 17,
+  RelationIBTypeOf = 1 << 18,
+  RelationSpecializationOf = 1 << 19,
 };
-static const unsigned SymbolRoleBitNum = 19;
+static const unsigned SymbolRoleBitNum = 20;
 typedef unsigned SymbolRoleSet;
 
 /// Represents a relation to another symbol for a symbol occurrence.
@@ -135,6 +138,8 @@
 
 SymbolInfo getSymbolInfo(const Decl *D);
 
+SymbolInfo getSymbolInfoForMacro(const MacroInfo &MI);
+
 bool isFunctionLocalSymbol(const Decl *D);
 
 void applyForEachSymbolRole(SymbolRoleSet Roles,
Index: include/clang/Index/IndexDataConsumer.h
===================================================================
--- include/clang/Index/IndexDataConsumer.h
+++ include/clang/Index/IndexDataConsumer.h
@@ -45,9 +45,11 @@
                                    SourceLocation Loc, ASTNodeInfo ASTNode);
 
   /// \returns true to continue indexing, or false to abort.
-  virtual bool handleMacroOccurence(const IdentifierInfo *Name,
-                                    const MacroInfo *MI, SymbolRoleSet Roles,
-                                    SourceLocation Loc);
+  /// \p Undefined is set when the occurrence is in an #undef directive where
+  /// the macro undefined.
+  virtual bool handleMacroOccurence(const IdentifierInfo &Name,
+                                    const MacroInfo &MI, SymbolRoleSet Roles,
+                                    SourceLocation Loc, bool Undefined);
 
   /// \returns true to continue indexing, or false to abort.
   virtual bool handleModuleOccurence(const ImportDecl *ImportD,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to