diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-01-03 14:35:48 +0000 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-01-03 14:35:48 +0000 |
commit | 6387c4574ec668f75713af89c72cb8f37d8e3469 (patch) | |
tree | e30269c308a8a730e840b8d5fdaa6f3626859942 /tools | |
parent | 9db9336933a8a29170ed23a0dafa2d53ceb399c8 (diff) |
[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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321709 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/libclang/CIndex.cpp | 22 |
1 files changed, 19 insertions, 3 deletions
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? } |