summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--test/Index/annotate-tokens.cpp12
-rw-r--r--tools/libclang/CIndex.cpp22
2 files changed, 30 insertions, 4 deletions
diff --git a/test/Index/annotate-tokens.cpp b/test/Index/annotate-tokens.cpp
index 460ab51dd9..67bdf6317a 100644
--- a/test/Index/annotate-tokens.cpp
+++ b/test/Index/annotate-tokens.cpp
@@ -37,7 +37,9 @@ class C {
~C();
};
-// RUN: c-index-test -test-annotate-tokens=%s:1:1:38:1 %s -fno-delayed-template-parsing | FileCheck %s
+auto test5(X) -> X;
+
+// RUN: c-index-test -test-annotate-tokens=%s:1:1:41:1 %s -std=c++14 -fno-delayed-template-parsing | FileCheck %s
// CHECK: Keyword: "struct" [1:1 - 1:7] StructDecl=bonk:1:8 (Definition)
// CHECK: Identifier: "bonk" [1:8 - 1:12] StructDecl=bonk:1:8 (Definition)
// CHECK: Punctuation: "{" [1:13 - 1:14] StructDecl=bonk:1:8 (Definition)
@@ -184,6 +186,14 @@ class C {
// CHECK: Punctuation: "}" [29:22 - 29:23] CompoundStmt=
// CHECK: Punctuation: "~" [37:3 - 37:4] CXXDestructor=~C:37:3
// CHECK: Identifier: "C" [37:4 - 37:5] CXXDestructor=~C:37:3
+// CHECK: Keyword: "auto" [40:1 - 40:5] FunctionDecl=test5:40:6
+// CHECK: Identifier: "test5" [40:6 - 40:11] FunctionDecl=test5:40:6
+// CHECK: Punctuation: "(" [40:11 - 40:12] FunctionDecl=test5:40:6
+// CHECK: Identifier: "X" [40:12 - 40:13] TypeRef=struct X:7:8
+// CHECK: Punctuation: ")" [40:13 - 40:14] FunctionDecl=test5:40:6
+// CHECK: Punctuation: "->" [40:15 - 40:17] FunctionDecl=test5:40:6
+// CHECK: Identifier: "X" [40:18 - 40:19] TypeRef=struct X:7:8
+// CHECK: Punctuation: ";" [40:19 - 40:20]
// RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 c-index-test -test-annotate-tokens=%s:32:1:32:13 %s | FileCheck %s -check-prefix=CHECK2
// CHECK2: Keyword: "if" [32:3 - 32:5] IfStmt=
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index f4d347108c..66b6edc8b1 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -785,6 +785,16 @@ bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
return false;
}
+static bool HasTrailingReturnType(FunctionDecl *ND) {
+ const QualType Ty = ND->getType();
+ if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
+ if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
+ return FT->hasTrailingReturn();
+ }
+
+ return false;
+}
+
/// \brief Compare two base or member initializers based on their source order.
static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
CXXCtorInitializer *const *Y) {
@@ -804,14 +814,16 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
// written. This requires a bit of work.
TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
+ const bool HasTrailingRT = HasTrailingReturnType(ND);
// If we have a function declared directly (without the use of a typedef),
// visit just the return type. Otherwise, just visit the function's type
// now.
- if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
+ if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
+ Visit(FTL.getReturnLoc())) ||
(!FTL && Visit(TL)))
return true;
-
+
// Visit the nested-name-specifier, if present.
if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
if (VisitNestedNameSpecifierLoc(QualifierLoc))
@@ -827,7 +839,11 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
// Visit the function parameters, if we have a function type.
if (FTL && VisitFunctionTypeLoc(FTL, true))
return true;
-
+
+ // Visit the function's trailing return type.
+ if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
+ return true;
+
// FIXME: Attributes?
}