]> granicus.if.org Git - clang/commitdiff
Explicitly link macro instantiations to macro definitions in the
authorDouglas Gregor <dgregor@apple.com>
Thu, 18 Mar 2010 18:23:03 +0000 (18:23 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 18 Mar 2010 18:23:03 +0000 (18:23 +0000)
preprocessing record. Use that link with clang_getCursorReferenced()
and clang_getCursorDefinition() to match instantiations of a macro to
the definition of the macro.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98842 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/PreprocessingRecord.h
lib/Lex/PreprocessingRecord.cpp
test/Index/annotate-tokens-pp.c
tools/CIndex/CIndex.cpp

index 12a6e9c71cf4b74c77d7d911e6d7278e6eecac90..e673b4a7caae92a362e072fbce0083d868c508bc 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "clang/Lex/PPCallbacks.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/PointerUnion.h"
 #include "llvm/Support/Allocator.h"
 #include <vector>
@@ -34,6 +35,8 @@ void operator delete(void* ptr, clang::PreprocessingRecord& PR,
                      unsigned) throw();
 
 namespace clang {
+  class MacroDefinition;
+
   /// \brief Base class that describes a preprocessed entity, which may be a
   /// preprocessor directive or macro instantiation.
   class PreprocessedEntity {
@@ -108,22 +111,20 @@ namespace clang {
     /// \brief The name of the macro being instantiation.
     IdentifierInfo *Name;
     
-    /// \brief The location of the definition of the macro being instantiated.
-    SourceLocation DefinitionLocation;
+    /// \brief The definition of this macro.
+    MacroDefinition *Definition;
     
   public:
     MacroInstantiation(IdentifierInfo *Name, SourceRange Range,
-                       SourceLocation DefinitionLocation)
+                       MacroDefinition *Definition)
       : PreprocessedEntity(MacroInstantiationKind, Range), Name(Name), 
-        DefinitionLocation(DefinitionLocation) { }
+        Definition(Definition) { }
     
     /// \brief The name of the macro being instantiated.
     IdentifierInfo *getName() const { return Name; }
     
-    /// \brief The location of the definition of the macro being instantiated.
-    /// FIXME: Could we just provide MacroInfo pointers instead, by teaching
-    /// the preprocessor to hold on to them when we care to keep them around?
-    SourceLocation getDefinitionLocation() const { return DefinitionLocation; }
+    /// \brief The definition of the macro being instantiated.
+    MacroDefinition *getDefinition() const { return Definition; }
 
     // Implement isa/cast/dyncast/etc.
     static bool classof(const PreprocessedEntity *PE) {
@@ -212,6 +213,9 @@ namespace clang {
     /// \brief The preprocessing record this action will populate.
     PreprocessingRecord &Record;
     
+    /// \brief Mapping from MacroInfo structures to their definitions.
+    llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
+
   public:
     explicit PopulatePreprocessingRecord(PreprocessingRecord &Record)
       : Record(Record) { }
index fe081b69bbbde1025335dcabf020ae1f672f4b9d..3e0a03b74f823d9444b839b0bc7330715981f98c 100644 (file)
@@ -26,12 +26,14 @@ void PopulatePreprocessingRecord::MacroExpands(const Token &Id,
   Record.addPreprocessedEntity(
                         new (Record) MacroInstantiation(Id.getIdentifierInfo(),
                                                        Id.getLocation(),
-                                                      MI->getDefinitionLoc()));
+                                                        MacroDefinitions[MI]));
 }
 
 void PopulatePreprocessingRecord::MacroDefined(const IdentifierInfo *II, 
                                                const MacroInfo *MI) {
   SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
-  Record.addPreprocessedEntity(
-                  new (Record) MacroDefinition(II, MI->getDefinitionLoc(), R));
+  MacroDefinition *Def
+    = new (Record) MacroDefinition(II, MI->getDefinitionLoc(), R);
+  MacroDefinitions[MI] = Def;
+  Record.addPreprocessedEntity(Def);
 }
index a88e561747431e197b252c165669d0f39ec4f5ec..485786e1c4e8de06e29dde0ca6559e0e2be2cb99 100644 (file)
@@ -32,14 +32,14 @@ int BAR STILL_NOTHING;
 // CHECK: Identifier: "X" [4:22 - 4:23] preprocessing directive=
 // CHECK: Punctuation: "##" [4:23 - 4:25] preprocessing directive=
 // CHECK: Identifier: "Y" [4:25 - 4:26] preprocessing directive=
-// CHECK: Identifier: "NOTHING" [5:1 - 5:8] macro instantiation=NOTHING
+// CHECK: Identifier: "NOTHING" [5:1 - 5:8] macro instantiation=NOTHING:1:9
 // CHECK: Punctuation: "(" [5:8 - 5:9]
 // CHECK: Identifier: "more" [5:9 - 5:13]
 // CHECK: Punctuation: "," [5:13 - 5:14]
 // CHECK: Identifier: "junk" [5:14 - 5:18]
 // CHECK: Punctuation: ")" [5:18 - 5:19]
 // CHECK: Keyword: "float" [5:20 - 5:25]
-// CHECK: Identifier: "WIBBLE" [5:26 - 5:32] macro instantiation=WIBBLE
+// CHECK: Identifier: "WIBBLE" [5:26 - 5:32] macro instantiation=WIBBLE:4:9
 // CHECK: Punctuation: "(" [5:32 - 5:33]
 // CHECK: Keyword: "int" [5:33 - 5:36]
 // CHECK: Punctuation: "," [5:36 - 5:37]
@@ -47,8 +47,8 @@ int BAR STILL_NOTHING;
 // CHECK: Punctuation: ")" [5:43 - 5:44]
 // CHECK: Punctuation: ";" [5:44 - 5:45]
 // CHECK: Keyword: "int" [6:1 - 6:4]
-// CHECK: Identifier: "BAR" [6:5 - 6:8] macro instantiation=BAR
-// CHECK: Identifier: "STILL_NOTHING" [6:9 - 6:22] macro instantiation=STILL_NOTHING
+// CHECK: Identifier: "BAR" [6:5 - 6:8] macro instantiation=BAR:3:9
+// CHECK: Identifier: "STILL_NOTHING" [6:9 - 6:22] macro instantiation=STILL_NOTHING:2:9
 // CHECK: Punctuation: ";" [6:22 - 6:23]
 // CHECK: Punctuation: "#" [7:1 - 7:2] preprocessing directive=
 // CHECK: Identifier: "include" [7:2 - 7:9] preprocessing directive=
index ce2188550bd28a8e1fc4a5f0ad9c0a8917b3d832..47d156c6ceb0d08d315e762e36ebcdfc7bb532f6 100644 (file)
@@ -1765,6 +1765,11 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
     return clang_getNullCursor();
   }
 
+  if (C.kind == CXCursor_MacroInstantiation) {
+    if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
+      return MakeMacroDefinitionCursor(Def, CXXUnit);
+  }
+
   if (!clang_isReference(C.kind))
     return clang_getNullCursor();
 
@@ -1803,6 +1808,9 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
     WasReference = true;
   }
 
+  if (C.kind == CXCursor_MacroInstantiation)
+    return clang_getCursorReferenced(C);
+
   if (!clang_isDeclaration(C.kind))
     return clang_getNullCursor();