diff options
Diffstat (limited to 'clang/tools')
-rw-r--r-- | clang/tools/CIndex/CIndex.cpp | 73 | ||||
-rw-r--r-- | clang/tools/c-index-test/c-index-test.c | 7 |
2 files changed, 76 insertions, 4 deletions
diff --git a/clang/tools/CIndex/CIndex.cpp b/clang/tools/CIndex/CIndex.cpp index 55061cba710..3a5977970a4 100644 --- a/clang/tools/CIndex/CIndex.cpp +++ b/clang/tools/CIndex/CIndex.cpp @@ -2056,19 +2056,86 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); *NumTokens = CXTokens.size(); } + +typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData; + +enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, + CXCursor parent, + CXClientData client_data) { + AnnotateTokensData *Data = static_cast<AnnotateTokensData *>(client_data); + + // We only annotate the locations of declarations, simple + // references, and expressions which directly reference something. + CXCursorKind Kind = clang_getCursorKind(cursor); + if (clang_isDeclaration(Kind) || clang_isReference(Kind)) { + // Okay: We can annotate the location of this declaration with the + // declaration or reference + } else if (clang_isExpression(cursor.kind)) { + if (Kind != CXCursor_DeclRefExpr && + Kind != CXCursor_MemberRefExpr && + Kind != CXCursor_ObjCMessageExpr) + return CXChildVisit_Recurse; + + CXCursor Referenced = clang_getCursorReferenced(cursor); + if (Referenced == cursor || Referenced == clang_getNullCursor()) + return CXChildVisit_Recurse; + + // Okay: we can annotate the location of this expression + } else { + // Nothing to annotate + return CXChildVisit_Recurse; + } + CXSourceLocation Loc = clang_getCursorLocation(cursor); + (*Data)[Loc.int_data] = cursor; + return CXChildVisit_Recurse; +} + void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens, unsigned NumTokens, CXCursor *Cursors) { - // FIXME: Actually perform some meaningful lookup here. + if (NumTokens == 0) + return; + + // Any token we don't specifically annotate will have a NULL cursor. for (unsigned I = 0; I != NumTokens; ++I) Cursors[I] = clang_getNullCursor(); + + ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); + if (!CXXUnit || !Tokens) + return; + + // Annotate all of the source locations in the region of interest that map + SourceRange RegionOfInterest; + RegionOfInterest.setBegin( + cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0]))); + SourceLocation End + = cxloc::translateSourceLocation(clang_getTokenLocation(TU, + Tokens[NumTokens - 1])); + RegionOfInterest.setEnd(CXXUnit->getPreprocessor().getLocForEndOfToken(End, + 1)); + // FIXME: Would be great to have a "hint" cursor, then walk from that + // hint cursor upward until we find a cursor whose source range encloses + // the region of interest, rather than starting from the translation unit. + AnnotateTokensData Annotated; + CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit); + CursorVisitor AnnotateVis(CXXUnit, AnnotateTokensVisitor, &Annotated, + Decl::MaxPCHLevel, RegionOfInterest); + AnnotateVis.VisitChildren(Parent); + + for (unsigned I = 0; I != NumTokens; ++I) { + // Determine whether we saw a cursor at this token's location. + AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); + if (Pos == Annotated.end()) + continue; + + Cursors[I] = Pos->second; + } } void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens, unsigned NumTokens) { - if (Tokens) - free(Tokens); + free(Tokens); } } // end: extern "C" diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index 1015aa5e744..243b8736f4f 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -810,8 +810,13 @@ int perform_token_annotation(int argc, const char **argv) { 0, &start_line, &start_column); clang_getInstantiationLocation(clang_getRangeEnd(extent), 0, &end_line, &end_column); - printf("%s: \"%s\" [%d:%d - %d:%d]\n", kind, clang_getCString(spelling), + printf("%s: \"%s\" [%d:%d - %d:%d]", kind, clang_getCString(spelling), start_line, start_column, end_line, end_column); + if (!clang_isInvalid(cursors[i].kind)) { + printf(" "); + PrintCursor(cursors[i]); + } + printf("\n"); } free(cursors); |