From 8f7c540ac42370c40ebcdc4b69018c938faf94ec Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Thu, 8 Sep 2011 17:18:41 +0000 Subject: [PATCH] [libclang] Fix annotation and getting a "macro expansion" cursor for a builtin macro expansion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139298 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Lex/PreprocessingRecord.h | 67 ++++++++++++++----------- lib/Lex/PreprocessingRecord.cpp | 9 ++-- lib/Serialization/ASTReader.cpp | 13 +++-- lib/Serialization/ASTWriter.cpp | 7 ++- test/Index/annotate-tokens-pp.c | 5 +- test/Index/c-index-getCursor-pp.c | 4 ++ 6 files changed, 66 insertions(+), 39 deletions(-) diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index 7bcc962739..e98a1bad22 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -16,6 +16,7 @@ #include "clang/Lex/PPCallbacks.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Allocator.h" #include @@ -110,34 +111,6 @@ namespace clang { void operator delete(void* data) throw(); }; - /// \brief Records the location of a macro expansion. - class MacroExpansion : public PreprocessedEntity { - /// \brief The name of the macro being expanded. - IdentifierInfo *Name; - - /// \brief The definition of this macro. - MacroDefinition *Definition; - - public: - MacroExpansion(IdentifierInfo *Name, SourceRange Range, - MacroDefinition *Definition) - : PreprocessedEntity(MacroExpansionKind, Range), Name(Name), - Definition(Definition) { } - - /// \brief The name of the macro being expanded. - IdentifierInfo *getName() const { return Name; } - - /// \brief The definition of the macro being expanded. - MacroDefinition *getDefinition() const { return Definition; } - - // Implement isa/cast/dyncast/etc. - static bool classof(const PreprocessedEntity *PE) { - return PE->getKind() == MacroExpansionKind; - } - static bool classof(const MacroExpansion *) { return true; } - - }; - /// \brief Records the presence of a preprocessor directive. class PreprocessingDirective : public PreprocessedEntity { public: @@ -178,6 +151,44 @@ namespace clang { } static bool classof(const MacroDefinition *) { return true; } }; + + /// \brief Records the location of a macro expansion. + class MacroExpansion : public PreprocessedEntity { + /// \brief The definition of this macro or the name of the macro if it is + /// a builtin macro. + llvm::PointerUnion NameOrDef; + + public: + MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range) + : PreprocessedEntity(MacroExpansionKind, Range), + NameOrDef(BuiltinName) { } + + MacroExpansion(MacroDefinition *Definition, SourceRange Range) + : PreprocessedEntity(MacroExpansionKind, Range), + NameOrDef(Definition) { } + + /// \brief True if it is a builtin macro. + bool isBuiltinMacro() const { return NameOrDef.is(); } + + /// \brief The name of the macro being expanded. + const IdentifierInfo *getName() const { + if (MacroDefinition *Def = getDefinition()) + return Def->getName(); + return NameOrDef.get(); + } + + /// \brief The definition of the macro being expanded. May return null if + /// this is a builtin macro. + MacroDefinition *getDefinition() const { + return NameOrDef.dyn_cast(); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const PreprocessedEntity *PE) { + return PE->getKind() == MacroExpansionKind; + } + static bool classof(const MacroExpansion *) { return true; } + }; /// \brief Record the location of an inclusion directive, such as an /// \c #include or \c #import statement. diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp index 6303c3d629..d02db25ae3 100644 --- a/lib/Lex/PreprocessingRecord.cpp +++ b/lib/Lex/PreprocessingRecord.cpp @@ -14,7 +14,6 @@ #include "clang/Lex/PreprocessingRecord.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Token.h" -#include "clang/Basic/IdentifierTable.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Capacity.h" @@ -113,10 +112,12 @@ void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI, if (!IncludeNestedMacroExpansions && Id.getLocation().isMacroID()) return; - if (MacroDefinition *Def = findMacroDefinition(MI)) + if (MI->isBuiltinMacro()) PreprocessedEntities.push_back( - new (*this) MacroExpansion(Id.getIdentifierInfo(), - Range, Def)); + new (*this) MacroExpansion(Id.getIdentifierInfo(),Range)); + else if (MacroDefinition *Def = findMacroDefinition(MI)) + PreprocessedEntities.push_back( + new (*this) MacroExpansion(Def, Range)); } void PreprocessingRecord::MacroDefined(const Token &Id, diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 251d0f6e31..e574e25f5b 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1448,11 +1448,16 @@ PreprocessedEntity *ASTReader::LoadPreprocessedEntity(Module &F) { if (PreprocessedEntity *PE = PPRec.getLoadedPreprocessedEntity(GlobalID-1)) return PE; - MacroExpansion *ME = - new (PPRec) MacroExpansion(getLocalIdentifier(F, Record[3]), + bool isBuiltin = Record[3]; + MacroExpansion *ME; + if (isBuiltin) + ME = new (PPRec) MacroExpansion(getLocalIdentifier(F, Record[4]), SourceRange(ReadSourceLocation(F, Record[1]), - ReadSourceLocation(F, Record[2])), - getLocalMacroDefinition(F, Record[4])); + ReadSourceLocation(F, Record[2]))); + else + ME = new (PPRec) MacroExpansion(getLocalMacroDefinition(F, Record[4]), + SourceRange(ReadSourceLocation(F, Record[1]), + ReadSourceLocation(F, Record[2]))); PPRec.setLoadedPreallocatedEntity(GlobalID - 1, ME); return ME; } diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index bdca689d6f..a995a70f24 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1871,8 +1871,11 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { Record.push_back(NextPreprocessorEntityID); AddSourceLocation(ME->getSourceRange().getBegin(), Record); AddSourceLocation(ME->getSourceRange().getEnd(), Record); - AddIdentifierRef(ME->getName(), Record); - Record.push_back(getMacroDefinitionID(ME->getDefinition())); + Record.push_back(ME->isBuiltinMacro()); + if (ME->isBuiltinMacro()) + AddIdentifierRef(ME->getName(), Record); + else + Record.push_back(getMacroDefinitionID(ME->getDefinition())); Stream.EmitRecord(PPD_MACRO_EXPANSION, Record); continue; } diff --git a/test/Index/annotate-tokens-pp.c b/test/Index/annotate-tokens-pp.c index a8ef8a7bdc..1d0657894e 100644 --- a/test/Index/annotate-tokens-pp.c +++ b/test/Index/annotate-tokens-pp.c @@ -28,7 +28,9 @@ void test() { #include "pragma-once.h" #include "guarded.h" -// RUN: c-index-test -test-annotate-tokens=%s:2:1:30:1 -I%S/Inputs %s | FileCheck %s +const char *fname = __FILE__; + +// RUN: c-index-test -test-annotate-tokens=%s:2:1:32:1 -I%S/Inputs %s | FileCheck %s // CHECK: Punctuation: "#" [2:1 - 2:2] preprocessing directive= // CHECK: Identifier: "define" [2:2 - 2:8] preprocessing directive= // CHECK: Identifier: "STILL_NOTHING" [2:9 - 2:22] macro definition=STILL_NOTHING @@ -189,3 +191,4 @@ void test() { // CHECK: Punctuation: "}" [26:1 - 26:2] UnexposedStmt= // CHECK: {{28:1.*inclusion directive=pragma-once.h.*multi-include guarded}} // CHECK: {{29:1.*inclusion directive=guarded.h.*multi-include guarded}} +// CHECK: Identifier: "__FILE__" [31:21 - 31:29] macro expansion=__FILE__ diff --git a/test/Index/c-index-getCursor-pp.c b/test/Index/c-index-getCursor-pp.c index df61ec0329..0a10450af5 100644 --- a/test/Index/c-index-getCursor-pp.c +++ b/test/Index/c-index-getCursor-pp.c @@ -13,6 +13,8 @@ void OBSCURE(func)(int x) { B(int x); +const char *fname = __FILE__; + // RUN: c-index-test -cursor-at=%s:1:11 -I%S/Inputs %s | FileCheck -check-prefix=CHECK-1 %s // CHECK-1: macro definition=OBSCURE // RUN: c-index-test -cursor-at=%s:2:14 -I%S/Inputs %s | FileCheck -check-prefix=CHECK-2 %s @@ -27,6 +29,8 @@ B(int x); // CHECK-6: inclusion directive=a.h // RUN: c-index-test -cursor-at=%s:14:1 -I%S/Inputs %s | FileCheck -check-prefix=CHECK-7 %s // CHECK-7: macro expansion=B:12:9 +// RUN: c-index-test -cursor-at=%s:16:25 -I%S/Inputs %s | FileCheck -check-prefix=CHECK-8 %s +// CHECK-8: macro expansion=__FILE__ // Same tests, but with "editing" optimizations // RUN: env CINDEXTEST_EDITING=1 c-index-test -cursor-at=%s:1:11 -I%S/Inputs %s | FileCheck -check-prefix=CHECK-1 %s