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