[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
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 3d254a0..65d2901 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -4958,6 +4958,7 @@
struct PostChildrenInfo {
CXCursor Cursor;
SourceRange CursorRange;
+ unsigned BeforeReachingCursorIdx;
unsigned BeforeChildrenTokenIdx;
};
SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
@@ -4976,7 +4977,7 @@
}
void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
- void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
+ bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
SourceRange);
public:
@@ -5019,7 +5020,7 @@
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 @@
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 @@
}
/// \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 @@
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 @@
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 @@
PostChildrenInfo Info;
Info.Cursor = cursor;
Info.CursorRange = cursorRange;
+ Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Info.BeforeChildrenTokenIdx = NextToken();
PostChildrenInfos.push_back(Info);
@@ -5254,6 +5264,11 @@
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;
}