зеркало из https://github.com/microsoft/clang-1.git
[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
This commit is contained in:
Родитель
5471bc85b6
Коммит
8f7c540ac4
|
@ -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 <vector>
|
||||
|
@ -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<IdentifierInfo *, MacroDefinition *> 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<IdentifierInfo *>(); }
|
||||
|
||||
/// \brief The name of the macro being expanded.
|
||||
const IdentifierInfo *getName() const {
|
||||
if (MacroDefinition *Def = getDefinition())
|
||||
return Def->getName();
|
||||
return NameOrDef.get<IdentifierInfo*>();
|
||||
}
|
||||
|
||||
/// \brief The definition of the macro being expanded. May return null if
|
||||
/// this is a builtin macro.
|
||||
MacroDefinition *getDefinition() const {
|
||||
return NameOrDef.dyn_cast<MacroDefinition *>();
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче