From: Douglas Gregor Date: Fri, 5 Nov 2010 21:11:19 +0000 (+0000) Subject: Teach clang_getCursorReferenced() that a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=93798e25d68e2d146cff9bd0355d4b7b1ca765f1;p=clang Teach clang_getCursorReferenced() that a CXXConstructorExpr/CXXTemporaryObjectExpr references the constructor it calls. Then, tweak clang_getCursor() to prefer such a call over a type reference to the type being called. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118297 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Index/get-cursor.cpp b/test/Index/get-cursor.cpp index a1974b63a5..ae39e63fcc 100644 --- a/test/Index/get-cursor.cpp +++ b/test/Index/get-cursor.cpp @@ -23,8 +23,11 @@ X getX(int value) { // RUN: c-index-test -cursor-at=%s:14:23 %s | FileCheck -check-prefix=CHECK-VALUE-REF %s // CHECK-VALUE-REF: DeclRefExpr=value:10:12 -// FIXME: c-index-test -cursor-at=%s:12:18 %s | FileCheck -check-prefix=CHECK-TYPE-REF %s -// RUN: c-index-test -cursor-at=%s:13:18 %s | FileCheck -check-prefix=CHECK-TYPE-REF %s -// FIXME: c-index-test -cursor-at=%s:14:19 %s | FileCheck -check-prefix=CHECK-TYPE-REF %s -// RUN: c-index-test -cursor-at=%s:17:10 %s | FileCheck -check-prefix=CHECK-TYPE-REF %s +// RUN: c-index-test -cursor-at=%s:12:18 %s | FileCheck -check-prefix=CHECK-CONSTRUCTOR1 %s +// RUN: c-index-test -cursor-at=%s:13:18 %s | FileCheck -check-prefix=CHECK-CONSTRUCTOR2 %s +// RUN: c-index-test -cursor-at=%s:14:19 %s | FileCheck -check-prefix=CHECK-CONSTRUCTOR1 %s +// RUN: c-index-test -cursor-at=%s:17:10 %s | FileCheck -check-prefix=CHECK-CONSTRUCTOR3 %s // CHECK-TYPE-REF: TypeRef=struct X:3:8 +// CHECK-CONSTRUCTOR1: CallExpr=X:5:3 +// CHECK-CONSTRUCTOR2: CallExpr=X:6:3 +// CHECK-CONSTRUCTOR3: CallExpr=X:4:3 diff --git a/test/Index/index-templates.cpp b/test/Index/index-templates.cpp index 7d78b4a256..3def6001a1 100644 --- a/test/Index/index-templates.cpp +++ b/test/Index/index-templates.cpp @@ -162,7 +162,7 @@ struct SuperPair : Pair, Pair { }; // CHECK-LOAD: index-templates.cpp:54:15: DeclRefExpr=OneDimension:35:16 Extent=[54:15 - 54:27] // CHECK-LOAD: index-templates.cpp:54:29: TemplateRef=array:37:8 Extent=[54:29 - 54:34] // CHECK-LOAD: index-templates.cpp:55:8: MemberRefExpr=getAs:50:26 Extent=[55:3 - 55:23] -// CHECK-LOAD: index-templates.cpp:55:3: CallExpr= Extent=[55:3 - 55:7] +// CHECK-LOAD: index-templates.cpp:55:3: CallExpr=Z4:49:8 Extent=[55:3 - 55:7] // CHECK-LOAD: index-templates.cpp:55:14: TypeRef=Unsigned:42:18 Extent=[55:14 - 55:22] // CHECK-LOAD: index-templates.cpp:68:6: FunctionTemplate=unresolved_exprs:68:6 (Definition) // CHECK-LOAD: index-templates.cpp:69:3: OverloadedDeclRef=swap[60:6, 59:39, 58:27] diff --git a/test/Index/load-stmts.cpp b/test/Index/load-stmts.cpp index d4febab667..6f01c1343b 100644 --- a/test/Index/load-stmts.cpp +++ b/test/Index/load-stmts.cpp @@ -215,7 +215,7 @@ void considered_harmful(int x) { // CHECK: load-stmts.cpp:104:5: MemberRef=member:100:7 Extent=[104:5 - 104:11] // CHECK: load-stmts.cpp:104:12: DeclRefExpr=x:103:22 Extent=[104:12 - 104:13] // CHECK: load-stmts.cpp:104:16: TypeRef=struct Base:94:8 Extent=[104:16 - 104:2 -// CHECK: load-stmts.cpp:104:16: CallExpr= Extent=[104:16 - 104:23] +// CHECK: load-stmts.cpp:104:16: CallExpr=Base:95:3 Extent=[104:16 - 104:23] // CHECK: load-stmts.cpp:104:21: DeclRefExpr=x:103:22 Extent=[104:21 - 104:22] // CHECK: load-stmts.cpp:107:6: FunctionDecl=considered_harmful:107:6 (Definition) // CHECK: load-stmts.cpp:108:2: LabelStmt=start_over Extent=[108:2 - 109:28] diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 30d1c28758..9ecaa1f7be 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2435,6 +2435,9 @@ static Decl *getDeclFromExpr(Stmt *E) { if (CallExpr *CE = dyn_cast(E)) return getDeclFromExpr(CE->getCallee()); + if (CXXConstructExpr *CE = llvm::dyn_cast(E)) + if (!CE->isElidable()) + return CE->getConstructor(); if (ObjCMessageExpr *OME = dyn_cast(E)) return OME->getMethodDecl(); @@ -2870,6 +2873,15 @@ enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) { CXCursor *BestCursor = static_cast(client_data); + + // If our current best cursor is the construction of a temporary object, + // don't replace that cursor with a type reference, because we want + // clang_getCursor() to point at the constructor. + if (clang_isExpression(BestCursor->kind) && + isa(getCursorExpr(*BestCursor)) && + cursor.kind == CXCursor_TypeRef) + return CXChildVisit_Recurse; + *BestCursor = cursor; return CXChildVisit_Recurse; }