diff --git a/clang/include/clang/Lex/PreprocessingRecord.h b/clang/include/clang/Lex/PreprocessingRecord.h index 12a6e9c71cf4..e673b4a7caae 100644 --- a/clang/include/clang/Lex/PreprocessingRecord.h +++ b/clang/include/clang/Lex/PreprocessingRecord.h @@ -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 @@ -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 MacroDefinitions; + public: explicit PopulatePreprocessingRecord(PreprocessingRecord &Record) : Record(Record) { } diff --git a/clang/lib/Lex/PreprocessingRecord.cpp b/clang/lib/Lex/PreprocessingRecord.cpp index fe081b69bbbd..3e0a03b74f82 100644 --- a/clang/lib/Lex/PreprocessingRecord.cpp +++ b/clang/lib/Lex/PreprocessingRecord.cpp @@ -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); } diff --git a/clang/test/Index/annotate-tokens-pp.c b/clang/test/Index/annotate-tokens-pp.c index a88e56174743..485786e1c4e8 100644 --- a/clang/test/Index/annotate-tokens-pp.c +++ b/clang/test/Index/annotate-tokens-pp.c @@ -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= diff --git a/clang/tools/CIndex/CIndex.cpp b/clang/tools/CIndex/CIndex.cpp index ce2188550bd2..47d156c6ceb0 100644 --- a/clang/tools/CIndex/CIndex.cpp +++ b/clang/tools/CIndex/CIndex.cpp @@ -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();