[PATCH] D40561: [libclang] Fix cursors for functions with trailing return type

Nikolai Kosjar via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 28 08:09:27 PST 2017


nik created this revision.

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.


https://reviews.llvm.org/D40561

Files:
  test/Index/annotate-tokens.cpp
  tools/libclang/CIndex.cpp


Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -783,6 +783,16 @@
   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) {
@@ -802,14 +812,16 @@
     // 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))
@@ -825,7 +837,11 @@
     // 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?
   }
   
Index: test/Index/annotate-tokens.cpp
===================================================================
--- test/Index/annotate-tokens.cpp
+++ test/Index/annotate-tokens.cpp
@@ -37,7 +37,9 @@
   ~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 @@
 // 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=


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40561.124576.patch
Type: text/x-patch
Size: 3468 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171128/321eb491/attachment-0001.bin>


More information about the cfe-commits mailing list