зеркало из https://github.com/microsoft/clang-1.git
Rework clang_annotateTokens() to annotate tokens with information that more closely matches
clang_getCursor(). Tokens are now annotated with the cursor (for the matching AST element) that most closely encompasses that token. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103064 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
aa8a66de0e
Коммит
fbd84caf62
|
@ -11,55 +11,55 @@ void f(void *ptr) {
|
||||||
|
|
||||||
// RUN: c-index-test -test-annotate-tokens=%s:4:1:9:32 %s | FileCheck %s
|
// RUN: c-index-test -test-annotate-tokens=%s:4:1:9:32 %s | FileCheck %s
|
||||||
// CHECK: Identifier: "T" [4:3 - 4:4] TypeRef=T:1:13
|
// CHECK: Identifier: "T" [4:3 - 4:4] TypeRef=T:1:13
|
||||||
// CHECK: Punctuation: "*" [4:4 - 4:5]
|
// CHECK: Punctuation: "*" [4:4 - 4:5] VarDecl=t_ptr:4:6 (Definition)
|
||||||
// CHECK: Identifier: "t_ptr" [4:6 - 4:11] VarDecl=t_ptr:4:6 (Definition)
|
// CHECK: Identifier: "t_ptr" [4:6 - 4:11] VarDecl=t_ptr:4:6 (Definition)
|
||||||
// CHECK: Punctuation: "=" [4:12 - 4:13]
|
// CHECK: Punctuation: "=" [4:12 - 4:13] VarDecl=t_ptr:4:6 (Definition)
|
||||||
// CHECK: Punctuation: "(" [4:14 - 4:15]
|
// CHECK: Punctuation: "(" [4:14 - 4:15] UnexposedExpr=ptr:3:14
|
||||||
// CHECK: Identifier: "T" [4:15 - 4:16] TypeRef=T:1:13
|
// CHECK: Identifier: "T" [4:15 - 4:16] TypeRef=T:1:13
|
||||||
// CHECK: Punctuation: "*" [4:17 - 4:18]
|
// CHECK: Punctuation: "*" [4:17 - 4:18] UnexposedExpr=ptr:3:14
|
||||||
// CHECK: Punctuation: ")" [4:18 - 4:19]
|
// CHECK: Punctuation: ")" [4:18 - 4:19] UnexposedExpr=ptr:3:14
|
||||||
// CHECK: Identifier: "ptr" [4:19 - 4:22] DeclRefExpr=ptr:3:14
|
// CHECK: Identifier: "ptr" [4:19 - 4:22] DeclRefExpr=ptr:3:14
|
||||||
// CHECK: Punctuation: ";" [4:22 - 4:23]
|
// CHECK: Punctuation: ";" [4:22 - 4:23] UnexposedStmt=
|
||||||
// CHECK: Punctuation: "(" [5:3 - 5:4]
|
// CHECK: Punctuation: "(" [5:3 - 5:4] UnexposedExpr=
|
||||||
// CHECK: Keyword: "void" [5:4 - 5:8]
|
// CHECK: Keyword: "void" [5:4 - 5:8] UnexposedExpr=
|
||||||
// CHECK: Punctuation: ")" [5:8 - 5:9]
|
// CHECK: Punctuation: ")" [5:8 - 5:9] UnexposedExpr=
|
||||||
// CHECK: Keyword: "sizeof" [5:9 - 5:15]
|
// CHECK: Keyword: "sizeof" [5:9 - 5:15] UnexposedExpr=
|
||||||
// CHECK: Punctuation: "(" [5:15 - 5:16]
|
// CHECK: Punctuation: "(" [5:15 - 5:16] UnexposedExpr=
|
||||||
// CHECK: Identifier: "T" [5:16 - 5:17] TypeRef=T:1:13
|
// CHECK: Identifier: "T" [5:16 - 5:17] TypeRef=T:1:13
|
||||||
// CHECK: Punctuation: ")" [5:17 - 5:18]
|
// CHECK: Punctuation: ")" [5:17 - 5:18] UnexposedExpr=
|
||||||
// CHECK: Punctuation: ";" [5:18 - 5:19]
|
// CHECK: Punctuation: ";" [5:18 - 5:19] UnexposedStmt=
|
||||||
// CHECK: Comment: "/* A comment */" [6:3 - 6:18]
|
// CHECK: Comment: "/* A comment */" [6:3 - 6:18] UnexposedStmt=
|
||||||
// CHECK: Keyword: "struct" [7:3 - 7:9]
|
// CHECK: Keyword: "struct" [7:3 - 7:9] UnexposedStmt=
|
||||||
// CHECK: Identifier: "X" [7:10 - 7:11] TypeRef=struct X:2:8
|
// CHECK: Identifier: "X" [7:10 - 7:11] TypeRef=struct X:2:8
|
||||||
// CHECK: Identifier: "x" [7:12 - 7:13] VarDecl=x:7:12 (Definition)
|
// CHECK: Identifier: "x" [7:12 - 7:13] VarDecl=x:7:12 (Definition)
|
||||||
// CHECK: Punctuation: "=" [7:14 - 7:15]
|
// CHECK: Punctuation: "=" [7:14 - 7:15] VarDecl=x:7:12 (Definition)
|
||||||
// CHECK: Punctuation: "(" [7:16 - 7:17]
|
// CHECK: Punctuation: "(" [7:16 - 7:17] UnexposedExpr=
|
||||||
// CHECK: Keyword: "struct" [7:17 - 7:23]
|
// CHECK: Keyword: "struct" [7:17 - 7:23] UnexposedExpr=
|
||||||
// CHECK: Identifier: "X" [7:24 - 7:25] TypeRef=struct X:2:8
|
// CHECK: Identifier: "X" [7:24 - 7:25] TypeRef=struct X:2:8
|
||||||
// CHECK: Punctuation: ")" [7:25 - 7:26]
|
// CHECK: Punctuation: ")" [7:25 - 7:26] UnexposedExpr=
|
||||||
// CHECK: Punctuation: "{" [7:26 - 7:27]
|
// CHECK: Punctuation: "{" [7:26 - 7:27] UnexposedExpr=
|
||||||
// CHECK: Literal: "1" [7:27 - 7:28]
|
// CHECK: Literal: "1" [7:27 - 7:28] UnexposedExpr=
|
||||||
// CHECK: Punctuation: "," [7:28 - 7:29]
|
// CHECK: Punctuation: "," [7:28 - 7:29] UnexposedExpr=
|
||||||
// CHECK: Literal: "2" [7:30 - 7:31]
|
// CHECK: Literal: "2" [7:30 - 7:31] UnexposedExpr=
|
||||||
// CHECK: Punctuation: "}" [7:31 - 7:32]
|
// CHECK: Punctuation: "}" [7:31 - 7:32] UnexposedExpr=
|
||||||
// CHECK: Punctuation: ";" [7:32 - 7:33]
|
// CHECK: Punctuation: ";" [7:32 - 7:33] UnexposedStmt=
|
||||||
// CHECK: Keyword: "void" [8:3 - 8:7]
|
// CHECK: Keyword: "void" [8:3 - 8:7] VarDecl=xx:8:9 (Definition)
|
||||||
// CHECK: Punctuation: "*" [8:8 - 8:9]
|
// CHECK: Punctuation: "*" [8:8 - 8:9] VarDecl=xx:8:9 (Definition)
|
||||||
// CHECK: Identifier: "xx" [8:9 - 8:11] VarDecl=xx:8:9 (Definition)
|
// CHECK: Identifier: "xx" [8:9 - 8:11] VarDecl=xx:8:9 (Definition)
|
||||||
// CHECK: Punctuation: "=" [8:12 - 8:13]
|
// CHECK: Punctuation: "=" [8:12 - 8:13] VarDecl=xx:8:9 (Definition)
|
||||||
// CHECK: Identifier: "ptr" [8:14 - 8:17] DeclRefExpr=ptr:3:14
|
// CHECK: Identifier: "ptr" [8:14 - 8:17] DeclRefExpr=ptr:3:14
|
||||||
// CHECK: Punctuation: "?" [8:18 - 8:19]
|
// CHECK: Punctuation: "?" [8:18 - 8:19] UnexposedExpr=
|
||||||
// CHECK: Punctuation: ":" [8:20 - 8:21]
|
// CHECK: Punctuation: ":" [8:20 - 8:21] UnexposedExpr=
|
||||||
// CHECK: Punctuation: "&" [8:22 - 8:23]
|
// CHECK: Punctuation: "&" [8:22 - 8:23] UnexposedExpr=
|
||||||
// CHECK: Identifier: "x" [8:23 - 8:24] DeclRefExpr=x:7:12
|
// CHECK: Identifier: "x" [8:23 - 8:24] DeclRefExpr=x:7:12
|
||||||
// CHECK: Punctuation: ";" [8:24 - 8:25]
|
// CHECK: Punctuation: ";" [8:24 - 8:25] UnexposedStmt=
|
||||||
// CHECK: Keyword: "const" [9:3 - 9:8]
|
// CHECK: Keyword: "const" [9:3 - 9:8] UnexposedStmt=
|
||||||
// CHECK: Keyword: "char" [9:9 - 9:13]
|
// CHECK: Keyword: "char" [9:9 - 9:13] VarDecl=hello:9:16 (Definition)
|
||||||
// CHECK: Punctuation: "*" [9:14 - 9:15]
|
// CHECK: Punctuation: "*" [9:14 - 9:15] VarDecl=hello:9:16 (Definition)
|
||||||
// CHECK: Identifier: "hello" [9:16 - 9:21] VarDecl=hello:9:16 (Definition)
|
// CHECK: Identifier: "hello" [9:16 - 9:21] VarDecl=hello:9:16 (Definition)
|
||||||
// CHECK: Punctuation: "=" [9:22 - 9:23]
|
// CHECK: Punctuation: "=" [9:22 - 9:23] VarDecl=hello:9:16 (Definition)
|
||||||
// CHECK: Literal: ""Hello"" [9:24 - 9:31]
|
// CHECK: Literal: ""Hello"" [9:24 - 9:31] UnexposedExpr=
|
||||||
// CHECK: Punctuation: ";" [9:31 - 9:32]
|
// CHECK: Punctuation: ";" [9:31 - 9:32] UnexposedStmt=
|
||||||
// CHECK: Punctuation: "}" [10:1 - 10:2]
|
// CHECK: Punctuation: "}" [10:1 - 10:2] UnexposedStmt=
|
||||||
// RUN: c-index-test -test-annotate-tokens=%s:4:1:165:32 %s | FileCheck %s
|
// RUN: c-index-test -test-annotate-tokens=%s:4:1:165:32 %s | FileCheck %s
|
||||||
// RUN: c-index-test -test-annotate-tokens=%s:4:1:165:38 %s | FileCheck %s
|
// RUN: c-index-test -test-annotate-tokens=%s:4:1:165:38 %s | FileCheck %s
|
||||||
|
|
|
@ -10,50 +10,50 @@
|
||||||
@end
|
@end
|
||||||
|
|
||||||
// RUN: c-index-test -test-annotate-tokens=%s:1:1:10:5 %s | FileCheck %s
|
// RUN: c-index-test -test-annotate-tokens=%s:1:1:10:5 %s | FileCheck %s
|
||||||
// CHECK: Punctuation: "@" [1:1 - 1:2]
|
// CHECK: Punctuation: "@" [1:1 - 1:2] ObjCInterfaceDecl=Foo:1:12
|
||||||
// CHECK: Identifier: "interface" [1:2 - 1:11]
|
// CHECK: Keyword: "interface" [1:2 - 1:11] ObjCInterfaceDecl=Foo:1:12
|
||||||
// CHECK: Identifier: "Foo" [1:12 - 1:15] ObjCInterfaceDecl=Foo:1:12
|
// CHECK: Identifier: "Foo" [1:12 - 1:15] ObjCInterfaceDecl=Foo:1:12
|
||||||
// CHECK: Punctuation: "-" [2:1 - 2:2] ObjCInstanceMethodDecl=compare::2:1
|
// CHECK: Punctuation: "-" [2:1 - 2:2] ObjCInstanceMethodDecl=compare::2:1
|
||||||
// CHECK: Punctuation: "(" [2:3 - 2:4]
|
// CHECK: Punctuation: "(" [2:3 - 2:4] ObjCInstanceMethodDecl=compare::2:1
|
||||||
// CHECK: Keyword: "int" [2:4 - 2:7]
|
// CHECK: Keyword: "int" [2:4 - 2:7] ObjCInstanceMethodDecl=compare::2:1
|
||||||
// CHECK: Punctuation: ")" [2:7 - 2:8]
|
// CHECK: Punctuation: ")" [2:7 - 2:8] ObjCInstanceMethodDecl=compare::2:1
|
||||||
// CHECK: Identifier: "compare" [2:8 - 2:15]
|
// CHECK: Identifier: "compare" [2:8 - 2:15] ObjCInstanceMethodDecl=compare::2:1
|
||||||
// CHECK: Punctuation: ":" [2:15 - 2:16]
|
// CHECK: Punctuation: ":" [2:15 - 2:16] ObjCInstanceMethodDecl=compare::2:1
|
||||||
// CHECK: Punctuation: "(" [2:16 - 2:17]
|
// CHECK: Punctuation: "(" [2:16 - 2:17] ObjCInstanceMethodDecl=compare::2:1
|
||||||
// CHECK: Identifier: "Foo" [2:17 - 2:20] ObjCClassRef=Foo:1:12
|
// CHECK: Identifier: "Foo" [2:17 - 2:20] ObjCClassRef=Foo:1:12
|
||||||
// CHECK: Punctuation: "*" [2:20 - 2:21]
|
// CHECK: Punctuation: "*" [2:20 - 2:21] ParmDecl=other:2:22 (Definition)
|
||||||
// CHECK: Punctuation: ")" [2:21 - 2:22]
|
// CHECK: Punctuation: ")" [2:21 - 2:22] ParmDecl=other:2:22 (Definition)
|
||||||
// CHECK: Identifier: "other" [2:22 - 2:27] ParmDecl=other:2:22 (Definition)
|
// CHECK: Identifier: "other" [2:22 - 2:27] ParmDecl=other:2:22 (Definition)
|
||||||
// CHECK: Punctuation: ";" [2:27 - 2:28]
|
// CHECK: Punctuation: ";" [2:27 - 2:28] ObjCInstanceMethodDecl=compare::2:1
|
||||||
// CHECK: Punctuation: "@" [3:1 - 3:2]
|
// CHECK: Punctuation: "@" [3:1 - 3:2] ObjCInterfaceDecl=Foo:1:12
|
||||||
// CHECK: Identifier: "end" [3:2 - 3:5]
|
// CHECK: Keyword: "end" [3:2 - 3:5] ObjCInterfaceDecl=Foo:1:12
|
||||||
// CHECK: Punctuation: "@" [5:1 - 5:2] ObjCImplementationDecl=Foo:5:1 (Definition)
|
// CHECK: Punctuation: "@" [5:1 - 5:2] ObjCImplementationDecl=Foo:5:1 (Definition)
|
||||||
// CHECK: Identifier: "implementation" [5:2 - 5:16]
|
// CHECK: Keyword: "implementation" [5:2 - 5:16] ObjCImplementationDecl=Foo:5:1 (Definition)
|
||||||
// CHECK: Identifier: "Foo" [5:17 - 5:20]
|
// CHECK: Identifier: "Foo" [5:17 - 5:20] ObjCImplementationDecl=Foo:5:1 (Definition)
|
||||||
// CHECK: Punctuation: "-" [6:1 - 6:2] ObjCInstanceMethodDecl=compare::6:1 (Definition)
|
// CHECK: Punctuation: "-" [6:1 - 6:2] ObjCInstanceMethodDecl=compare::6:1 (Definition)
|
||||||
// CHECK: Punctuation: "(" [6:3 - 6:4]
|
// CHECK: Punctuation: "(" [6:3 - 6:4] ObjCInstanceMethodDecl=compare::6:1 (Definition)
|
||||||
// CHECK: Keyword: "int" [6:4 - 6:7]
|
// CHECK: Keyword: "int" [6:4 - 6:7] ObjCInstanceMethodDecl=compare::6:1 (Definition)
|
||||||
// CHECK: Punctuation: ")" [6:7 - 6:8]
|
// CHECK: Punctuation: ")" [6:7 - 6:8] ObjCInstanceMethodDecl=compare::6:1 (Definition)
|
||||||
// CHECK: Identifier: "compare" [6:8 - 6:15]
|
// CHECK: Identifier: "compare" [6:8 - 6:15] ObjCInstanceMethodDecl=compare::6:1 (Definition)
|
||||||
// CHECK: Punctuation: ":" [6:15 - 6:16]
|
// CHECK: Punctuation: ":" [6:15 - 6:16] ObjCInstanceMethodDecl=compare::6:1 (Definition)
|
||||||
// CHECK: Punctuation: "(" [6:16 - 6:17]
|
// CHECK: Punctuation: "(" [6:16 - 6:17] ObjCInstanceMethodDecl=compare::6:1 (Definition)
|
||||||
// CHECK: Identifier: "Foo" [6:17 - 6:20] ObjCClassRef=Foo:1:12
|
// CHECK: Identifier: "Foo" [6:17 - 6:20] ObjCClassRef=Foo:1:12
|
||||||
// CHECK: Punctuation: "*" [6:20 - 6:21]
|
// CHECK: Punctuation: "*" [6:20 - 6:21] ParmDecl=other:6:22 (Definition)
|
||||||
// CHECK: Punctuation: ")" [6:21 - 6:22]
|
// CHECK: Punctuation: ")" [6:21 - 6:22] ParmDecl=other:6:22 (Definition)
|
||||||
// CHECK: Identifier: "other" [6:22 - 6:27] ParmDecl=other:6:22 (Definition)
|
// CHECK: Identifier: "other" [6:22 - 6:27] ParmDecl=other:6:22 (Definition)
|
||||||
// CHECK: Punctuation: "{" [6:28 - 6:29]
|
// CHECK: Punctuation: "{" [6:28 - 6:29] UnexposedStmt=
|
||||||
// CHECK: Keyword: "return" [7:3 - 7:9]
|
// CHECK: Keyword: "return" [7:3 - 7:9] UnexposedStmt=
|
||||||
// CHECK: Literal: "0" [7:10 - 7:11]
|
// CHECK: Literal: "0" [7:10 - 7:11] UnexposedExpr=
|
||||||
// CHECK: Punctuation: ";" [7:11 - 7:12]
|
// CHECK: Punctuation: ";" [7:11 - 7:12] UnexposedStmt=
|
||||||
// CHECK: Punctuation: "(" [8:3 - 8:4]
|
// CHECK: Punctuation: "(" [8:3 - 8:4] UnexposedExpr=
|
||||||
// CHECK: Keyword: "void" [8:4 - 8:8]
|
// CHECK: Keyword: "void" [8:4 - 8:8] UnexposedExpr=
|
||||||
// CHECK: Punctuation: ")" [8:8 - 8:9]
|
// CHECK: Punctuation: ")" [8:8 - 8:9] UnexposedExpr=
|
||||||
// CHECK: Punctuation: "@" [8:9 - 8:10]
|
// CHECK: Punctuation: "@" [8:9 - 8:10] UnexposedExpr=
|
||||||
// CHECK: Identifier: "encode" [8:10 - 8:16]
|
// CHECK: Keyword: "encode" [8:10 - 8:16] UnexposedExpr=
|
||||||
// CHECK: Punctuation: "(" [8:16 - 8:17]
|
// CHECK: Punctuation: "(" [8:16 - 8:17] UnexposedExpr=
|
||||||
// CHECK: Identifier: "Foo" [8:17 - 8:20] ObjCClassRef=Foo:1:12
|
// CHECK: Identifier: "Foo" [8:17 - 8:20] ObjCClassRef=Foo:1:12
|
||||||
// CHECK: Punctuation: ")" [8:20 - 8:21]
|
// CHECK: Punctuation: ")" [8:20 - 8:21] UnexposedExpr=
|
||||||
// CHECK: Punctuation: ";" [8:21 - 8:22]
|
// CHECK: Punctuation: ";" [8:21 - 8:22] UnexposedStmt=
|
||||||
// CHECK: Punctuation: "}" [9:1 - 9:2]
|
// CHECK: Punctuation: "}" [9:1 - 9:2] UnexposedStmt=
|
||||||
// CHECK: Punctuation: "@" [10:1 - 10:2]
|
// CHECK: Punctuation: "@" [10:1 - 10:2] ObjCImplementationDecl=Foo:5:1 (Definition)
|
||||||
// CHECK: Identifier: "end" [10:2 - 10:5]
|
// CHECK: Keyword: "end" [10:2 - 10:5]
|
||||||
|
|
|
@ -152,6 +152,23 @@ static RangeComparisonResult RangeCompare(SourceManager &SM,
|
||||||
return RangeOverlap;
|
return RangeOverlap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Determine if a source location falls within, before, or after a
|
||||||
|
/// a given source range.
|
||||||
|
static RangeComparisonResult LocationCompare(SourceManager &SM,
|
||||||
|
SourceLocation L, SourceRange R) {
|
||||||
|
assert(R.isValid() && "First range is invalid?");
|
||||||
|
assert(L.isValid() && "Second range is invalid?");
|
||||||
|
if (L == R.getBegin())
|
||||||
|
return RangeOverlap;
|
||||||
|
if (L == R.getEnd())
|
||||||
|
return RangeAfter;
|
||||||
|
if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
|
||||||
|
return RangeBefore;
|
||||||
|
if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
|
||||||
|
return RangeAfter;
|
||||||
|
return RangeOverlap;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Translate a Clang source range into a CIndex source range.
|
/// \brief Translate a Clang source range into a CIndex source range.
|
||||||
///
|
///
|
||||||
/// Clang internally represents ranges where the end location points to the
|
/// Clang internally represents ranges where the end location points to the
|
||||||
|
@ -2326,65 +2343,148 @@ void clang_disposeTokens(CXTranslationUnit TU,
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
|
typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
|
||||||
|
static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
|
||||||
|
CXCursor parent,
|
||||||
|
CXClientData client_data);
|
||||||
namespace {
|
namespace {
|
||||||
class AnnotateTokensWorker {
|
class AnnotateTokensWorker {
|
||||||
AnnotateTokensData &Annotated;
|
AnnotateTokensData &Annotated;
|
||||||
CXToken *Tokens;
|
CXToken *Tokens;
|
||||||
CXCursor *Cursors;
|
CXCursor *Cursors;
|
||||||
unsigned NumTokens;
|
unsigned NumTokens;
|
||||||
|
unsigned TokIdx;
|
||||||
|
CursorVisitor AnnotateVis;
|
||||||
|
SourceManager &SrcMgr;
|
||||||
|
|
||||||
|
bool MoreTokens() const { return TokIdx < NumTokens; }
|
||||||
|
unsigned NextToken() const { return TokIdx; }
|
||||||
|
void AdvanceToken() { ++TokIdx; }
|
||||||
|
SourceLocation GetTokenLoc(unsigned tokI) {
|
||||||
|
return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AnnotateTokensWorker(AnnotateTokensData &annotated,
|
AnnotateTokensWorker(AnnotateTokensData &annotated,
|
||||||
CXToken *tokens, CXCursor *cursors, unsigned numTokens)
|
CXToken *tokens, CXCursor *cursors, unsigned numTokens,
|
||||||
|
ASTUnit *CXXUnit, SourceRange RegionOfInterest)
|
||||||
: Annotated(annotated), Tokens(tokens), Cursors(cursors),
|
: Annotated(annotated), Tokens(tokens), Cursors(cursors),
|
||||||
NumTokens(numTokens) {}
|
NumTokens(numTokens), TokIdx(0),
|
||||||
|
AnnotateVis(CXXUnit, AnnotateTokensVisitor, this,
|
||||||
void CompleteAnnotations();
|
Decl::MaxPCHLevel, RegionOfInterest),
|
||||||
|
SrcMgr(CXXUnit->getSourceManager()) {}
|
||||||
|
|
||||||
|
void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
|
||||||
enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
|
enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
|
||||||
|
void AnnotateTokens(CXCursor parent);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnnotateTokensWorker::CompleteAnnotations() {
|
void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
|
||||||
for (unsigned I = 0; I != NumTokens; ++I) {
|
// Walk the AST within the region of interest, annotating tokens
|
||||||
// Determine whether we saw a cursor at this token's location.
|
// along the way.
|
||||||
AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
|
VisitChildren(parent);
|
||||||
if (Pos == Annotated.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
for (unsigned I = 0 ; I < TokIdx ; ++I) {
|
||||||
|
AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
|
||||||
|
if (Pos != Annotated.end())
|
||||||
Cursors[I] = Pos->second;
|
Cursors[I] = Pos->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finish up annotating any tokens left.
|
||||||
|
if (!MoreTokens())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const CXCursor &C = clang_getNullCursor();
|
||||||
|
for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
|
||||||
|
AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
|
||||||
|
Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CXChildVisitResult
|
enum CXChildVisitResult
|
||||||
AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
|
AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
|
||||||
// We only annotate the locations of declarations, simple
|
CXSourceLocation Loc = clang_getCursorLocation(cursor);
|
||||||
// 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 if (clang_isPreprocessing(cursor.kind)) {
|
|
||||||
// We can always annotate a preprocessing directive/macro instantiation.
|
// We can always annotate a preprocessing directive/macro instantiation.
|
||||||
} else {
|
if (clang_isPreprocessing(cursor.kind)) {
|
||||||
// Nothing to annotate
|
Annotated[Loc.int_data] = cursor;
|
||||||
return CXChildVisit_Recurse;
|
return CXChildVisit_Recurse;
|
||||||
}
|
}
|
||||||
|
|
||||||
CXSourceLocation Loc = clang_getCursorLocation(cursor);
|
CXSourceRange cursorExtent = clang_getCursorExtent(cursor);
|
||||||
Annotated[Loc.int_data] = cursor;
|
SourceRange cursorRange = cxloc::translateCXSourceRange(cursorExtent);
|
||||||
return CXChildVisit_Recurse;
|
|
||||||
|
if (cursorRange.isInvalid())
|
||||||
|
return CXChildVisit_Continue;
|
||||||
|
|
||||||
|
SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
|
||||||
|
|
||||||
|
const enum CXCursorKind K = clang_getCursorKind(parent);
|
||||||
|
const CXCursor updateC =
|
||||||
|
(clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
|
||||||
|
L.isMacroID())
|
||||||
|
? clang_getNullCursor() : parent;
|
||||||
|
|
||||||
|
while (MoreTokens()) {
|
||||||
|
const unsigned I = NextToken();
|
||||||
|
SourceLocation TokLoc = GetTokenLoc(I);
|
||||||
|
switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
|
||||||
|
case RangeBefore:
|
||||||
|
Cursors[I] = updateC;
|
||||||
|
AdvanceToken();
|
||||||
|
continue;
|
||||||
|
case RangeAfter:
|
||||||
|
return CXChildVisit_Continue;
|
||||||
|
case RangeOverlap:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visit children to get their cursor information.
|
||||||
|
const unsigned BeforeChildren = NextToken();
|
||||||
|
VisitChildren(cursor);
|
||||||
|
const unsigned AfterChildren = NextToken();
|
||||||
|
|
||||||
|
// Adjust 'Last' to the last token within the extent of the cursor.
|
||||||
|
while (MoreTokens()) {
|
||||||
|
const unsigned I = NextToken();
|
||||||
|
SourceLocation TokLoc = GetTokenLoc(I);
|
||||||
|
switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
|
||||||
|
case RangeBefore:
|
||||||
|
assert(0 && "Infeasible");
|
||||||
|
case RangeAfter:
|
||||||
|
break;
|
||||||
|
case RangeOverlap:
|
||||||
|
Cursors[I] = updateC;
|
||||||
|
AdvanceToken();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const unsigned Last = NextToken();
|
||||||
|
|
||||||
|
// Scan the tokens that are at the beginning of the cursor, but are not
|
||||||
|
// capture by the child cursors.
|
||||||
|
|
||||||
|
// For AST elements within macros, rely on a post-annotate pass to
|
||||||
|
// to correctly annotate the tokens with cursors. Otherwise we can
|
||||||
|
// get confusing results of having tokens that map to cursors that really
|
||||||
|
// are expanded by an instantiation.
|
||||||
|
if (L.isMacroID())
|
||||||
|
cursor = clang_getNullCursor();
|
||||||
|
|
||||||
|
for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
|
||||||
|
if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
|
||||||
|
break;
|
||||||
|
Cursors[I] = cursor;
|
||||||
|
}
|
||||||
|
// Scan the tokens that are at the end of the cursor, but are not captured
|
||||||
|
// but the child cursors.
|
||||||
|
for (unsigned I = AfterChildren; I != Last; ++I)
|
||||||
|
Cursors[I] = cursor;
|
||||||
|
|
||||||
|
TokIdx = Last;
|
||||||
|
return CXChildVisit_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
|
static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
|
||||||
|
@ -2398,23 +2498,26 @@ extern "C" {
|
||||||
void clang_annotateTokens(CXTranslationUnit TU,
|
void clang_annotateTokens(CXTranslationUnit TU,
|
||||||
CXToken *Tokens, unsigned NumTokens,
|
CXToken *Tokens, unsigned NumTokens,
|
||||||
CXCursor *Cursors) {
|
CXCursor *Cursors) {
|
||||||
if (NumTokens == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Any token we don't specifically annotate will have a NULL cursor.
|
if (NumTokens == 0 || !Tokens || !Cursors)
|
||||||
for (unsigned I = 0; I != NumTokens; ++I)
|
return;
|
||||||
Cursors[I] = clang_getNullCursor();
|
|
||||||
|
|
||||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
||||||
if (!CXXUnit || !Tokens)
|
if (!CXXUnit) {
|
||||||
|
// Any token we don't specifically annotate will have a NULL cursor.
|
||||||
|
const CXCursor &C = clang_getNullCursor();
|
||||||
|
for (unsigned I = 0; I != NumTokens; ++I)
|
||||||
|
Cursors[I] = C;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
|
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
|
||||||
|
|
||||||
// Determine the region of interest, which contains all of the tokens.
|
// Determine the region of interest, which contains all of the tokens.
|
||||||
SourceRange RegionOfInterest;
|
SourceRange RegionOfInterest;
|
||||||
RegionOfInterest.setBegin(
|
RegionOfInterest.setBegin(cxloc::translateSourceLocation(
|
||||||
cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
|
clang_getTokenLocation(TU, Tokens[0])));
|
||||||
|
|
||||||
SourceLocation End
|
SourceLocation End
|
||||||
= cxloc::translateSourceLocation(clang_getTokenLocation(TU,
|
= cxloc::translateSourceLocation(clang_getTokenLocation(TU,
|
||||||
Tokens[NumTokens - 1]));
|
Tokens[NumTokens - 1]));
|
||||||
|
@ -2486,12 +2589,9 @@ void clang_annotateTokens(CXTranslationUnit TU,
|
||||||
|
|
||||||
// Annotate all of the source locations in the region of interest that map to
|
// Annotate all of the source locations in the region of interest that map to
|
||||||
// a specific cursor.
|
// a specific cursor.
|
||||||
CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit);
|
AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
|
||||||
AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens);
|
CXXUnit, RegionOfInterest);
|
||||||
CursorVisitor AnnotateVis(CXXUnit, AnnotateTokensVisitor, &W,
|
W.AnnotateTokens(clang_getTranslationUnitCursor(CXXUnit));
|
||||||
Decl::MaxPCHLevel, RegionOfInterest);
|
|
||||||
AnnotateVis.VisitChildren(Parent);
|
|
||||||
W.CompleteAnnotations();
|
|
||||||
}
|
}
|
||||||
} // end: extern "C"
|
} // end: extern "C"
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче