Skip to content

Commit 1d18713

Browse files
author
Ivan Donchevskii
committedJan 3, 2018
[libclang] Fix cursors for functions with trailing return type
This one was rolled back as follow-up to the failing commit. Second try. For the function declaration auto foo5(Foo) -> Foo; the parameter tokens were mapped to cursors representing the FunctionDecl: Keyword: "auto" [1:1 - 1:5] FunctionDecl=test5:1:6 Identifier: "test5" [1:6 - 1:11] FunctionDecl=test5:1:6 Punctuation: "(" [1:11 - 1:12] FunctionDecl=test5:1:6 Identifier: "X" [1:12 - 1:13] FunctionDecl=test5:1:6 // Ops, not a TypeRef Punctuation: ")" [1:13 - 1:14] FunctionDecl=test5:1:6 Punctuation: "->" [1:15 - 1:17] FunctionDecl=test5:1:6 Identifier: "X" [1:18 - 1:19] TypeRef=struct X:7:8 Punctuation: ";" [1:19 - 1:20] Fix this by ensuring that the trailing return type is not visited as first. Patch by Nikolai Kosjar. Differential Revision: https://reviews.llvm.org/D40561 llvm-svn: 321709
1 parent fff4589 commit 1d18713

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed
 

‎clang/test/Index/annotate-tokens.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ class C {
3737
~C();
3838
};
3939

40-
// RUN: c-index-test -test-annotate-tokens=%s:1:1:38:1 %s -fno-delayed-template-parsing | FileCheck %s
40+
auto test5(X) -> X;
41+
42+
// RUN: c-index-test -test-annotate-tokens=%s:1:1:41:1 %s -std=c++14 -fno-delayed-template-parsing | FileCheck %s
4143
// CHECK: Keyword: "struct" [1:1 - 1:7] StructDecl=bonk:1:8 (Definition)
4244
// CHECK: Identifier: "bonk" [1:8 - 1:12] StructDecl=bonk:1:8 (Definition)
4345
// CHECK: Punctuation: "{" [1:13 - 1:14] StructDecl=bonk:1:8 (Definition)
@@ -184,6 +186,14 @@ class C {
184186
// CHECK: Punctuation: "}" [29:22 - 29:23] CompoundStmt=
185187
// CHECK: Punctuation: "~" [37:3 - 37:4] CXXDestructor=~C:37:3
186188
// CHECK: Identifier: "C" [37:4 - 37:5] CXXDestructor=~C:37:3
189+
// CHECK: Keyword: "auto" [40:1 - 40:5] FunctionDecl=test5:40:6
190+
// CHECK: Identifier: "test5" [40:6 - 40:11] FunctionDecl=test5:40:6
191+
// CHECK: Punctuation: "(" [40:11 - 40:12] FunctionDecl=test5:40:6
192+
// CHECK: Identifier: "X" [40:12 - 40:13] TypeRef=struct X:7:8
193+
// CHECK: Punctuation: ")" [40:13 - 40:14] FunctionDecl=test5:40:6
194+
// CHECK: Punctuation: "->" [40:15 - 40:17] FunctionDecl=test5:40:6
195+
// CHECK: Identifier: "X" [40:18 - 40:19] TypeRef=struct X:7:8
196+
// CHECK: Punctuation: ";" [40:19 - 40:20]
187197

188198
// RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 c-index-test -test-annotate-tokens=%s:32:1:32:13 %s | FileCheck %s -check-prefix=CHECK2
189199
// CHECK2: Keyword: "if" [32:3 - 32:5] IfStmt=

‎clang/tools/libclang/CIndex.cpp

+19-3
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,16 @@ bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
785785
return false;
786786
}
787787

788+
static bool HasTrailingReturnType(FunctionDecl *ND) {
789+
const QualType Ty = ND->getType();
790+
if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
791+
if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
792+
return FT->hasTrailingReturn();
793+
}
794+
795+
return false;
796+
}
797+
788798
/// \brief Compare two base or member initializers based on their source order.
789799
static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
790800
CXXCtorInitializer *const *Y) {
@@ -804,14 +814,16 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
804814
// written. This requires a bit of work.
805815
TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
806816
FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
817+
const bool HasTrailingRT = HasTrailingReturnType(ND);
807818

808819
// If we have a function declared directly (without the use of a typedef),
809820
// visit just the return type. Otherwise, just visit the function's type
810821
// now.
811-
if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
822+
if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
823+
Visit(FTL.getReturnLoc())) ||
812824
(!FTL && Visit(TL)))
813825
return true;
814-
826+
815827
// Visit the nested-name-specifier, if present.
816828
if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
817829
if (VisitNestedNameSpecifierLoc(QualifierLoc))
@@ -827,7 +839,11 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
827839
// Visit the function parameters, if we have a function type.
828840
if (FTL && VisitFunctionTypeLoc(FTL, true))
829841
return true;
830-
842+
843+
// Visit the function's trailing return type.
844+
if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
845+
return true;
846+
831847
// FIXME: Attributes?
832848
}
833849

0 commit comments

Comments
 (0)
Please sign in to comment.