diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-02-13 18:33:28 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-02-13 18:33:28 +0000 |
commit | 5d47a9b253e48662840528e8d2a8e812b840b05a (patch) | |
tree | c8f5b73c9392633a11b3355023bbeb2c37dcb17d /clang | |
parent | 142c5a4f66a36eb36253facd98c3fbf7f62dc308 (diff) | |
download | bcm5719-llvm-5d47a9b253e48662840528e8d2a8e812b840b05a.tar.gz bcm5719-llvm-5d47a9b253e48662840528e8d2a8e812b840b05a.zip |
[libclang] Fix annotation of a range where the begin or end location
is inside a macro argument.
Previously we would give up and not annotate anything in the range.
rdar://11891550
llvm-svn: 175062
Diffstat (limited to 'clang')
-rw-r--r-- | clang/test/Index/annotate-tokens.c | 64 | ||||
-rw-r--r-- | clang/tools/libclang/CIndex.cpp | 32 |
2 files changed, 87 insertions, 9 deletions
diff --git a/clang/test/Index/annotate-tokens.c b/clang/test/Index/annotate-tokens.c index 39c9f354a0d..ffe3f632f93 100644 --- a/clang/test/Index/annotate-tokens.c +++ b/clang/test/Index/annotate-tokens.c @@ -35,6 +35,28 @@ enum Color g(int i, ...) { __attribute__((unavailable)) Int __attribute__((unavailable)) test() __attribute__((unavailable)); +#define HEADER() \ + int x; \ + int y; \ + int z + +#define TYPE_INST(name, ...) \ + static const struct { \ + HEADER(); \ + } name = { \ + __VA_ARGS__ \ + } + +void func1(void); + +TYPE_INST(Foo, + .x = 0, + .y = 1, + .z = 2, +); + +void func2(void); + // RUN: c-index-test -test-annotate-tokens=%s:4:1:37:1 %s | FileCheck %s // CHECK: Identifier: "T" [4:3 - 4:4] TypeRef=T:1:13 // CHECK: Punctuation: "*" [4:4 - 4:5] VarDecl=t_ptr:4:6 (Definition) @@ -160,3 +182,45 @@ __attribute__((unavailable)) Int __attribute__((unavailable)) test() __attribute // 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:50:1:55:1 %s | FileCheck %s -check-prefix=CHECK-RANGE1 +// CHECK-RANGE1: Keyword: "void" [50:1 - 50:5] FunctionDecl=func1:50:6 +// CHECK-RANGE1: Identifier: "func1" [50:6 - 50:11] FunctionDecl=func1:50:6 +// CHECK-RANGE1: Punctuation: "(" [50:11 - 50:12] FunctionDecl=func1:50:6 +// CHECK-RANGE1: Keyword: "void" [50:12 - 50:16] FunctionDecl=func1:50:6 +// CHECK-RANGE1: Punctuation: ")" [50:16 - 50:17] FunctionDecl=func1:50:6 +// CHECK-RANGE1: Punctuation: ";" [50:17 - 50:18] +// CHECK-RANGE1: Identifier: "TYPE_INST" [52:1 - 52:10] macro expansion=TYPE_INST:43:9 +// CHECK-RANGE1: Punctuation: "(" [52:10 - 52:11] +// CHECK-RANGE1: Identifier: "Foo" [52:11 - 52:14] VarDecl=Foo:52:11 (Definition) +// CHECK-RANGE1: Punctuation: "," [52:14 - 52:15] +// CHECK-RANGE1: Punctuation: "." [53:5 - 53:6] UnexposedExpr= +// CHECK-RANGE1: Identifier: "x" [53:6 - 53:7] MemberRef=x:52:1 +// CHECK-RANGE1: Punctuation: "=" [53:8 - 53:9] UnexposedExpr= +// CHECK-RANGE1: Literal: "0" [53:10 - 53:11] IntegerLiteral= +// CHECK-RANGE1: Punctuation: "," [53:11 - 53:12] InitListExpr= +// CHECK-RANGE1: Punctuation: "." [54:5 - 54:6] UnexposedExpr= +// CHECK-RANGE1: Identifier: "y" [54:6 - 54:7] MemberRef=y:52:1 +// CHECK-RANGE1: Punctuation: "=" [54:8 - 54:9] UnexposedExpr= +// CHECK-RANGE1: Literal: "1" [54:10 - 54:11] IntegerLiteral= +// CHECK-RANGE1: Punctuation: "," [54:11 - 54:12] InitListExpr= + +// RUN: c-index-test -test-annotate-tokens=%s:54:1:59:1 %s | FileCheck %s -check-prefix=CHECK-RANGE2 +// CHECK-RANGE2: Punctuation: "." [54:5 - 54:6] UnexposedExpr= +// CHECK-RANGE2: Identifier: "y" [54:6 - 54:7] MemberRef=y:52:1 +// CHECK-RANGE2: Punctuation: "=" [54:8 - 54:9] UnexposedExpr= +// CHECK-RANGE2: Literal: "1" [54:10 - 54:11] IntegerLiteral= +// CHECK-RANGE2: Punctuation: "," [54:11 - 54:12] InitListExpr= +// CHECK-RANGE2: Punctuation: "." [55:5 - 55:6] UnexposedExpr= +// CHECK-RANGE2: Identifier: "z" [55:6 - 55:7] MemberRef=z:52:1 +// CHECK-RANGE2: Punctuation: "=" [55:8 - 55:9] UnexposedExpr= +// CHECK-RANGE2: Literal: "2" [55:10 - 55:11] IntegerLiteral= +// CHECK-RANGE2: Punctuation: "," [55:11 - 55:12] InitListExpr= +// CHECK-RANGE2: Punctuation: ")" [56:1 - 56:2] +// CHECK-RANGE2: Punctuation: ";" [56:2 - 56:3] +// CHECK-RANGE2: Keyword: "void" [58:1 - 58:5] FunctionDecl=func2:58:6 +// CHECK-RANGE2: Identifier: "func2" [58:6 - 58:11] FunctionDecl=func2:58:6 +// CHECK-RANGE2: Punctuation: "(" [58:11 - 58:12] FunctionDecl=func2:58:6 +// CHECK-RANGE2: Keyword: "void" [58:12 - 58:16] FunctionDecl=func2:58:6 +// CHECK-RANGE2: Punctuation: ")" [58:16 - 58:17] FunctionDecl=func2:58:6 +// CHECK-RANGE2: Punctuation: ";" [58:17 - 58:18] diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 65d29012919..1a19a004df5 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -4827,9 +4827,9 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range, SmallVectorImpl<CXToken> &CXTokens) { SourceManager &SourceMgr = CXXUnit->getSourceManager(); std::pair<FileID, unsigned> BeginLocInfo - = SourceMgr.getDecomposedLoc(Range.getBegin()); + = SourceMgr.getDecomposedSpellingLoc(Range.getBegin()); std::pair<FileID, unsigned> EndLocInfo - = SourceMgr.getDecomposedLoc(Range.getEnd()); + = SourceMgr.getDecomposedSpellingLoc(Range.getEnd()); // Cannot tokenize across files. if (BeginLocInfo.first != EndLocInfo.first) @@ -5172,14 +5172,18 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { case RangeAfter: break; case RangeOverlap: + // For macro expansions, just note where the beginning of the macro + // expansion occurs. + if (cursor.kind == CXCursor_MacroExpansion) { + if (TokLoc == cursorRange.getBegin()) + Cursors[I] = cursor; + AdvanceToken(); + break; + } // We may have already annotated macro names inside macro definitions. if (Cursors[I].kind != CXCursor_MacroExpansion) Cursors[I] = cursor; AdvanceToken(); - // For macro expansions, just note where the beginning of the macro - // expansion occurs. - if (cursor.kind == CXCursor_MacroExpansion) - break; continue; } break; @@ -5388,9 +5392,9 @@ static void annotatePreprocessorTokens(CXTranslationUnit TU, Preprocessor &PP = CXXUnit->getPreprocessor(); SourceManager &SourceMgr = CXXUnit->getSourceManager(); std::pair<FileID, unsigned> BeginLocInfo - = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin()); + = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin()); std::pair<FileID, unsigned> EndLocInfo - = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd()); + = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd()); if (BeginLocInfo.first != EndLocInfo.first) return; @@ -5504,7 +5508,17 @@ static void clang_annotateTokensImpl(void *UserData) { // Relex the tokens within the source range to look for preprocessing // directives. annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens); - + + // If begin location points inside a macro argument, set it to the expansion + // location so we can have the full context when annotating semantically. + { + SourceManager &SM = CXXUnit->getSourceManager(); + SourceLocation Loc = + SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin()); + if (Loc.isMacroID()) + RegionOfInterest.setBegin(SM.getExpansionLoc(Loc)); + } + if (CXXUnit->getPreprocessor().getPreprocessingRecord()) { // Search and mark tokens that are macro argument expansions. MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), |