ioeric created this revision.
ioeric added reviewers: akyrtzi, arphaman.
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D48961

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

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(), 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/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"
@@ -406,3 +407,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);
+}
+
+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);
+}
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;
 }
 
@@ -74,6 +78,33 @@
   }
 };
 
+class IndexPPCallbacks : public PPCallbacks {
+  IndexingContext &IndexCtx;
+
+public:
+  IndexPPCallbacks(IndexingContext &IndexCtx) : IndexCtx(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;
@@ -90,6 +121,10 @@
                                                IndexCtx);
   }
 
+  std::unique_ptr<PPCallbacks> createIndexPPCallbacks() {
+    return llvm::make_unique<IndexPPCallbacks>(IndexCtx);
+  }
+
   void finish() {
     DataConsumer->finish();
   }
@@ -107,6 +142,11 @@
     return createIndexASTConsumer(CI);
   }
 
+  bool BeginSourceFileAction(clang::CompilerInstance &CI) override {
+    CI.getPreprocessor().addPPCallbacks(createIndexPPCallbacks());
+    return true;
+  }
+
   void EndSourceFileAction() override {
     FrontendAction::EndSourceFileAction();
     finish();
@@ -125,7 +165,25 @@
 
 protected:
   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
-                                                 StringRef InFile) override;
+                                                 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));
+  }
+
+  bool BeginSourceFileAction(clang::CompilerInstance &CI) override {
+    WrapperFrontendAction::BeginSourceFileAction(CI);
+    CI.getPreprocessor().addPPCallbacks(createIndexPPCallbacks());
+    return true;
+  }
+
   void EndSourceFileAction() override;
 };
 
@@ -138,20 +196,6 @@
     finish();
 }
 
-std::unique_ptr<ASTConsumer>
-WrappingIndexAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
-  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));
-}
-
 std::unique_ptr<FrontendAction>
 index::createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
                             IndexingOptions Opts,
Index: lib/Index/IndexSymbol.cpp
===================================================================
--- lib/Index/IndexSymbol.cpp
+++ lib/Index/IndexSymbol.cpp
@@ -348,6 +348,16 @@
   return Info;
 }
 
+SymbolInfo index::getSymbolInfoForMacro() {
+  SymbolInfo Info;
+  Info.Kind = SymbolKind::Macro;
+  Info.SubKind = SymbolSubKind::None;
+  Info.Properties = SymbolPropertySet();
+  // FIXME: set languages more accurately.
+  Info.Lang = SymbolLanguage::C;
+  return Info;
+}
+
 bool index::applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,
                                    llvm::function_ref<bool(SymbolRole)> Fn) {
 #define APPLY_FOR_ROLE(Role) \
Index: include/clang/Index/IndexSymbol.h
===================================================================
--- include/clang/Index/IndexSymbol.h
+++ include/clang/Index/IndexSymbol.h
@@ -135,6 +135,8 @@
 
 SymbolInfo getSymbolInfo(const Decl *D);
 
+SymbolInfo getSymbolInfoForMacro();
+
 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,9 @@
                                    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);
+  virtual bool handleMacroOccurence(const IdentifierInfo &Name,
+                                    const MacroInfo &MI, SymbolRoleSet Roles,
+                                    SourceLocation Loc, bool Undefined = false);
 
   /// \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