Revert 98907 since it is breaking buildbots.

--- Reverse-merging r98907 into '.':
D    test/Index/c-index-getCursor-pp.c
U    tools/CIndex/CIndex.cpp

llvm-svn: 98929
This commit is contained in:
Bob Wilson 2010-03-19 03:57:57 +00:00
parent 857955243e
commit 4f559a3042
2 changed files with 106 additions and 63 deletions

View File

@ -1,18 +0,0 @@
#define OBSCURE(X) X
#define DECORATION
typedef int T;
void OBSCURE(func)(int x) {
OBSCURE(T) DECORATION value;
}
// RUN: c-index-test -cursor-at=%s:1:11 %s | FileCheck -check-prefix=CHECK-1 %s
// CHECK-1: macro definition=OBSCURE
// RUN: c-index-test -cursor-at=%s:2:14 %s | FileCheck -check-prefix=CHECK-2 %s
// CHECK-2: macro definition=DECORATION
// RUN: c-index-test -cursor-at=%s:5:7 %s | FileCheck -check-prefix=CHECK-3 %s
// CHECK-3: macro instantiation=OBSCURE:1:9
// RUN: c-index-test -cursor-at=%s:6:6 %s | FileCheck -check-prefix=CHECK-4 %s
// CHECK-4: macro instantiation=OBSCURE:1:9
// RUN: c-index-test -cursor-at=%s:6:19 %s | FileCheck -check-prefix=CHECK-5 %s
// CHECK-5: macro instantiation=DECORATION:2:9

View File

@ -425,31 +425,11 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
if (Visit(MakeCXCursor(*it, CXXUnit), true))
return true;
}
} else if (VisitDeclContext(
CXXUnit->getASTContext().getTranslationUnitDecl()))
return true;
// Walk the preprocessing record.
if (CXXUnit->hasPreprocessingRecord()) {
// FIXME: Once we have the ability to deserialize a preprocessing record,
// do so.
PreprocessingRecord &PPRec = CXXUnit->getPreprocessingRecord();
for (PreprocessingRecord::iterator E = PPRec.begin(), EEnd = PPRec.end();
E != EEnd; ++E) {
if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
if (Visit(MakeMacroInstantiationCursor(MI, CXXUnit)))
return true;
continue;
}
if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
if (Visit(MakeMacroDefinitionCursor(MD, CXXUnit)))
return true;
continue;
}
}
} else {
return VisitDeclContext(
CXXUnit->getASTContext().getTranslationUnitDecl());
}
return false;
}
@ -2079,6 +2059,51 @@ void clang_enableStackTraces(void) {
// Token-based Operations.
//===----------------------------------------------------------------------===//
namespace {
class ComparePreprocessedEntityLocation {
SourceManager &SM;
public:
explicit ComparePreprocessedEntityLocation(SourceManager &SM) : SM(SM) { }
bool operator()(const PreprocessedEntity *Entity, SourceLocation Loc) const{
return SM.isBeforeInTranslationUnit(Entity->getSourceRange().getEnd(),
Loc);
}
bool operator()(SourceLocation Loc, const PreprocessedEntity *Entity) const{
return SM.isBeforeInTranslationUnit(Loc,
Entity->getSourceRange().getBegin());
}
bool operator()(const PreprocessedEntity *Entity, SourceRange R) const {
return SM.isBeforeInTranslationUnit(Entity->getSourceRange().getEnd(),
R.getBegin());
}
bool operator()(SourceRange R, const PreprocessedEntity *Entity) const {
return SM.isBeforeInTranslationUnit(R.getEnd(),
Entity->getSourceRange().getBegin());
}
bool operator()(const PreprocessedEntity *Entity1,
const PreprocessedEntity *Entity2) const {
return SM.isBeforeInTranslationUnit(Entity1->getSourceRange().getEnd(),
Entity2->getSourceRange().getBegin());
}
bool operator()(SourceRange R1, SourceRange R2) const {
return SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin());
}
bool operator()(SourceLocation Loc1, SourceLocation Loc2) const {
return SM.isBeforeInTranslationUnit(Loc1, Loc2);
}
};
}
/* CXToken layout:
* int_data[0]: a CXTokenKind
* int_data[1]: starting token location
@ -2268,8 +2293,6 @@ enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
return CXChildVisit_Recurse;
// Okay: we can annotate the location of this expression
} else if (clang_isPreprocessing(cursor.kind)) {
// We can always annotate a preprocessing directive/macro instantiation.
} else {
// Nothing to annotate
return CXChildVisit_Recurse;
@ -2296,32 +2319,47 @@ void clang_annotateTokens(CXTranslationUnit TU,
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
// Determine the region of interest, which contains all of the tokens.
// Annotate all of the source locations in the region of interest that map to
// a specific cursor.
SourceRange RegionOfInterest;
RegionOfInterest.setBegin(
cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
SourceLocation End
= cxloc::translateSourceLocation(clang_getTokenLocation(TU,
Tokens[NumTokens - 1]));
= cxloc::translateSourceLocation(clang_getTokenLocation(TU,
Tokens[NumTokens - 1]));
RegionOfInterest.setEnd(CXXUnit->getPreprocessor().getLocForEndOfToken(End));
// A mapping from the source locations found when re-lexing or traversing the
// region of interest to the corresponding cursors.
AnnotateTokensData Annotated;
CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit);
CursorVisitor AnnotateVis(CXXUnit, AnnotateTokensVisitor, &Annotated,
Decl::MaxPCHLevel, RegionOfInterest);
AnnotateVis.VisitChildren(Parent);
// Relex the tokens within the source range to look for preprocessing
// directives.
// Look for macro instantiations and preprocessing directives in the
// source range containing the annotated tokens. We do this by re-lexing the
// tokens in the source range.
SourceManager &SourceMgr = CXXUnit->getSourceManager();
std::pair<FileID, unsigned> BeginLocInfo
= SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
std::pair<FileID, unsigned> EndLocInfo
= SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
bool RelexOkay = true;
// Cannot re-tokenize across files.
if (BeginLocInfo.first != EndLocInfo.first)
RelexOkay = false;
llvm::StringRef Buffer;
bool Invalid = false;
if (BeginLocInfo.first == EndLocInfo.first &&
((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
!Invalid) {
if (RelexOkay) {
// Create a lexer
bool Invalid = false;
Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
if (Invalid)
RelexOkay = false;
}
if (RelexOkay) {
Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
CXXUnit->getASTContext().getLangOptions(),
Buffer.begin(), Buffer.data() + BeginLocInfo.second,
@ -2330,6 +2368,7 @@ void clang_annotateTokens(CXTranslationUnit TU,
// Lex tokens in raw mode until we hit the end of the range, to avoid
// entering #includes or expanding macros.
std::vector<Token> TokenStream;
while (true) {
Token Tok;
Lex.LexFromRawLexer(Tok);
@ -2368,13 +2407,35 @@ void clang_annotateTokens(CXTranslationUnit TU,
break;
}
}
// Annotate all of the source locations in the region of interest that map to
// a specific cursor.
CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit);
CursorVisitor AnnotateVis(CXXUnit, AnnotateTokensVisitor, &Annotated,
Decl::MaxPCHLevel, RegionOfInterest);
AnnotateVis.VisitChildren(Parent);
if (CXXUnit->hasPreprocessingRecord()) {
PreprocessingRecord &PPRec = CXXUnit->getPreprocessingRecord();
std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
Entities = std::equal_range(PPRec.begin(), PPRec.end(), RegionOfInterest,
ComparePreprocessedEntityLocation(SourceMgr));
for (; Entities.first != Entities.second; ++Entities.first) {
PreprocessedEntity *Entity = *Entities.first;
if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(Entity)) {
SourceLocation Loc = MI->getSourceRange().getBegin();
if (Loc.isFileID()) {
Annotated[Loc.getRawEncoding()]
= MakeMacroInstantiationCursor(MI, CXXUnit);
}
continue;
}
if (MacroDefinition *MD = dyn_cast<MacroDefinition>(Entity)) {
SourceLocation Loc = MD->getLocation();
if (Loc.isFileID()) {
Annotated[Loc.getRawEncoding()]
= MakeMacroDefinitionCursor(MD, CXXUnit);
}
continue;
}
}
}
for (unsigned I = 0; I != NumTokens; ++I) {
// Determine whether we saw a cursor at this token's location.