diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-01-03 10:04:37 +0000 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-01-03 10:04:37 +0000 |
commit | 5e3fa81ba51e6c674cf00eb1116314255d8ba83f (patch) | |
tree | bf55c4765df747fd42727769348b5812f5f2bb50 /tools | |
parent | 806baca8ec6ca20af972e6842a3448416a7ee91e (diff) |
[libclang] Fix cursors for functions with trailing return type
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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321698 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/libclang/CIndex.cpp | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 70bccc7eea..f73706dee1 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -782,12 +782,22 @@ bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { if (VisitNestedNameSpecifierLoc(QualifierLoc)) return true; - return false; -} - -/// \brief Compare two base or member initializers based on their source order. -static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X, - CXXCtorInitializer *const *Y) { + 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) {
return (*X)->getSourceOrder() - (*Y)->getSourceOrder(); } @@ -801,20 +811,22 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) { // Visit the function declaration's syntactic components in the order - // written. This requires a bit of work. - TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); - FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>(); - - // 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())) || - (!FTL && Visit(TL))) - return true; - - // Visit the nested-name-specifier, if present. - if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc()) - if (VisitNestedNameSpecifierLoc(QualifierLoc)) + // 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) && !HasTrailingRT &&
+ Visit(FTL.getReturnLoc())) ||
+ (!FTL && Visit(TL)))
+ return true;
+
+ // Visit the nested-name-specifier, if present.
+ if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
+ if (VisitNestedNameSpecifierLoc(QualifierLoc))
return true; // Visit the declaration name. @@ -824,13 +836,17 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { // FIXME: Visit explicitly-specified template arguments! - // Visit the function parameters, if we have a function type. - if (FTL && VisitFunctionTypeLoc(FTL, true)) - return true; - - // FIXME: Attributes? - } - + // 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?
+ }
+
if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) { if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) { // Find the initializers that were written in the source. |