From a86b37e223a21647175619096e67d0f650add351 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Fri, 8 Feb 2013 01:12:25 +0000 Subject: [PATCH] [libclang] Attribute visitation happens out-of-source-order, make sure we annotate properly when there is an attribute and not skip type specs if the attribute is after the declaration. rdar://13129077 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174689 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Index/IBOutletCollection.m | 4 +++- test/Index/annotate-tokens.c | 28 +++++++++++++++++++++++++++- tools/libclang/CIndex.cpp | 31 +++++++++++++++++++++++-------- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/test/Index/IBOutletCollection.m b/test/Index/IBOutletCollection.m index 02bc7f185d..1b5d62c7ae 100644 --- a/test/Index/IBOutletCollection.m +++ b/test/Index/IBOutletCollection.m @@ -10,9 +10,11 @@ // RUN: c-index-test -test-annotate-tokens=%s:4:1:5:1 %s | FileCheck -check-prefix=CHECK-TOK %s // CHECK-TOK: Identifier: "IBOutletCollection" [4:3 - 4:21] macro expansion=IBOutletCollection:1:9 +// FIXME: The following token should belong to the macro expansion cursor. // CHECK-TOK: Punctuation: "(" [4:21 - 4:22] attribute(iboutletcollection)= [IBOutletCollection=ObjCInterface] // CHECK-TOK: Identifier: "Test" [4:22 - 4:26] ObjCClassRef=Test:3:12 -// CHECK-TOK: Punctuation: ")" [4:26 - 4:27] ObjCIvarDecl=anOutletCollection:4:34 (Definition) +// FIXME: The following token should belong to the macro expansion cursor. +// CHECK-TOK: Punctuation: ")" [4:26 - 4:27] // CHECK-TOK: Identifier: "Test" [4:28 - 4:32] ObjCClassRef=Test:3:12 // CHECK-TOK: Punctuation: "*" [4:33 - 4:34] ObjCIvarDecl=anOutletCollection:4:34 (Definition) // CHECK-TOK: Identifier: "anOutletCollection" [4:34 - 4:52] ObjCIvarDecl=anOutletCollection:4:34 (Definition) diff --git a/test/Index/annotate-tokens.c b/test/Index/annotate-tokens.c index 565283f343..39c9f354a0 100644 --- a/test/Index/annotate-tokens.c +++ b/test/Index/annotate-tokens.c @@ -33,7 +33,9 @@ enum Color g(int i, ...) { } } -// RUN: c-index-test -test-annotate-tokens=%s:4:1:34:1 %s | FileCheck %s +__attribute__((unavailable)) Int __attribute__((unavailable)) test() __attribute__((unavailable)); + +// 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) // CHECK: Identifier: "t_ptr" [4:6 - 4:11] VarDecl=t_ptr:4:6 (Definition) @@ -132,5 +134,29 @@ enum Color g(int i, ...) { // CHECK: Identifier: "Red" [32:12 - 32:15] DeclRefExpr=Red:11:14 // CHECK: Punctuation: ";" [32:15 - 32:16] CompoundStmt= +// CHECK: Keyword: "__attribute__" [36:1 - 36:14] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: "(" [36:14 - 36:15] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: "(" [36:15 - 36:16] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Identifier: "unavailable" [36:16 - 36:27] UnexposedAttr= +// CHECK: Punctuation: ")" [36:27 - 36:28] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: ")" [36:28 - 36:29] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Identifier: "Int" [36:30 - 36:33] TypeRef=Int:12:13 +// CHECK: Keyword: "__attribute__" [36:34 - 36:47] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: "(" [36:47 - 36:48] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: "(" [36:48 - 36:49] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Identifier: "unavailable" [36:49 - 36:60] UnexposedAttr= +// CHECK: Punctuation: ")" [36:60 - 36:61] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: ")" [36:61 - 36:62] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Identifier: "test" [36:63 - 36:67] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: "(" [36:67 - 36:68] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: ")" [36:68 - 36:69] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Keyword: "__attribute__" [36:70 - 36:83] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: "(" [36:83 - 36:84] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: "(" [36:84 - 36:85] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Identifier: "unavailable" [36:85 - 36:96] UnexposedAttr= +// CHECK: Punctuation: ")" [36:96 - 36:97] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: ")" [36:97 - 36:98] FunctionDecl=test:36:63 (unavailable) (always unavailable: "") +// CHECK: Punctuation: ";" [36:98 - 36:99] + // 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 diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 3d254a08c6..65d2901291 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -4958,6 +4958,7 @@ class AnnotateTokensWorker { struct PostChildrenInfo { CXCursor Cursor; SourceRange CursorRange; + unsigned BeforeReachingCursorIdx; unsigned BeforeChildrenTokenIdx; }; SmallVector PostChildrenInfos; @@ -4976,7 +4977,7 @@ class AnnotateTokensWorker { } void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange); - void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult, + bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult, SourceRange); public: @@ -5019,7 +5020,7 @@ void AnnotateTokensWorker::AnnotateTokens() { static inline void updateCursorAnnotation(CXCursor &Cursor, const CXCursor &updateC) { - if (clang_isInvalid(updateC.kind) || clang_isPreprocessing(Cursor.kind)) + if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind)) return; Cursor = updateC; } @@ -5036,7 +5037,8 @@ void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC, while (MoreTokens()) { const unsigned I = NextToken(); if (isFunctionMacroToken(I)) - return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range); + if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range)) + return; SourceLocation TokLoc = GetTokenLoc(I); if (LocationCompare(SrcMgr, TokLoc, range) == compResult) { @@ -5049,7 +5051,8 @@ void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC, } /// \brief Special annotation handling for macro argument tokens. -void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens( +/// \returns true if it advanced beyond all macro tokens, false otherwise. +bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens( CXCursor updateC, RangeComparisonResult compResult, SourceRange range) { @@ -5079,8 +5082,11 @@ void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens( atLeastOneCompFail = true; } - if (!atLeastOneCompFail) - TokIdx = I; // All of the tokens were handled, advance beyond all of them. + if (atLeastOneCompFail) + return false; + + TokIdx = I; // All of the tokens were handled, advance beyond all of them. + return true; } enum CXChildVisitResult @@ -5188,11 +5194,14 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { if (cursorRange.isInvalid()) return CXChildVisit_Continue; - + + unsigned BeforeReachingCursorIdx = NextToken(); const enum CXCursorKind cursorK = clang_getCursorKind(cursor); const enum CXCursorKind K = clang_getCursorKind(parent); const CXCursor updateC = - (clang_isInvalid(K) || K == CXCursor_TranslationUnit) + (clang_isInvalid(K) || K == CXCursor_TranslationUnit || + // Attributes are annotated out-of-order, skip tokens until we reach it. + clang_isAttribute(cursor.kind)) ? clang_getNullCursor() : parent; annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange); @@ -5224,6 +5233,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { PostChildrenInfo Info; Info.Cursor = cursor; Info.CursorRange = cursorRange; + Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx; Info.BeforeChildrenTokenIdx = NextToken(); PostChildrenInfos.push_back(Info); @@ -5254,6 +5264,11 @@ bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) { Cursors[I] = cursor; } + // Attributes are annotated out-of-order, rewind TokIdx to when we first + // encountered the attribute cursor. + if (clang_isAttribute(cursor.kind)) + TokIdx = Info.BeforeReachingCursorIdx; + PostChildrenInfos.pop_back(); return false; } -- 2.40.0