From 46e75477bd24a703da11d354587c9bea69d6888f Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 8 Feb 2012 01:21:13 +0000 Subject: [PATCH] [libclang] For CXXOperatorCallExprs, give a valid source location to the DeclRefExpr that is referencing the member function, so we can index the referenced function. Fixes rdar://10762375&10324915 & http://llvm.org/PR11192 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150033 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/DeclarationName.h | 4 +++- lib/Sema/SemaOverload.cpp | 19 ++++++++++++------- test/Index/annotate-tokens.cpp | 6 +++--- test/Index/index-refs.cpp | 23 +++++++++++++++++++++++ test/Index/recursive-cxx-member-calls.cpp | 2 +- tools/libclang/IndexBody.cpp | 6 ++++++ 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 2170f2b1ef..83594fb0c8 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -511,7 +511,9 @@ public: SourceLocation getEndLoc() const; /// getSourceRange - The range of the declaration name. SourceRange getSourceRange() const { - return SourceRange(getBeginLoc(), getEndLoc()); + SourceLocation BeginLoc = getBeginLoc(); + SourceLocation EndLoc = getEndLoc(); + return SourceRange(BeginLoc, EndLoc.isValid() ? EndLoc : BeginLoc); } }; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index b0b2a78320..54dd5f8652 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -9585,7 +9585,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, // Build the actual expression node. ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, - HadMultipleCandidates); + HadMultipleCandidates, OpLoc); if (FnExpr.isInvalid()) return ExprError(); @@ -10011,12 +10011,12 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, ResultTy = ResultTy.getNonLValueExprType(Context); // Build the actual expression node. - DeclarationNameLoc LocInfo; - LocInfo.CXXOperatorName.BeginOpNameLoc = LLoc.getRawEncoding(); - LocInfo.CXXOperatorName.EndOpNameLoc = RLoc.getRawEncoding(); + DeclarationNameInfo OpLocInfo(OpName, LLoc); + OpLocInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc)); ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, HadMultipleCandidates, - LLoc, LocInfo); + OpLocInfo.getLoc(), + OpLocInfo.getInfo()); if (FnExpr.isInvalid()) return ExprError(); @@ -10521,8 +10521,13 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) MethodArgs[ArgIdx + 1] = Args[ArgIdx]; + DeclarationNameInfo OpLocInfo( + Context.DeclarationNames.getCXXOperatorName(OO_Call), LParenLoc); + OpLocInfo.setCXXOperatorNameRange(SourceRange(LParenLoc, RParenLoc)); ExprResult NewFn = CreateFunctionRefExpr(*this, Method, - HadMultipleCandidates); + HadMultipleCandidates, + OpLocInfo.getLoc(), + OpLocInfo.getInfo()); if (NewFn.isInvalid()) return true; @@ -10698,7 +10703,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) { // Build the operator call. ExprResult FnExpr = CreateFunctionRefExpr(*this, Method, - HadMultipleCandidates); + HadMultipleCandidates, OpLoc); if (FnExpr.isInvalid()) return ExprError(); diff --git a/test/Index/annotate-tokens.cpp b/test/Index/annotate-tokens.cpp index 5a8f5e201d..3062901b7c 100644 --- a/test/Index/annotate-tokens.cpp +++ b/test/Index/annotate-tokens.cpp @@ -34,7 +34,7 @@ void test3(S2 s2) { // CHECK: Punctuation: ")" [2:17 - 2:18] FunctionDecl=test:2:6 (Definition) // CHECK: Punctuation: "{" [2:19 - 2:20] CompoundStmt= // CHECK: Identifier: "X" [3:5 - 3:6] DeclRefExpr=X:2:16 -// CHECK: Punctuation: "=" [3:7 - 3:8] CallExpr=operator=:1:8 +// CHECK: Punctuation: "=" [3:7 - 3:8] DeclRefExpr=operator=:1:8 // CHECK: Identifier: "X" [3:9 - 3:10] DeclRefExpr=X:2:16 // CHECK: Punctuation: ";" [3:10 - 3:11] CompoundStmt= // CHECK: Keyword: "__is_base_of" [4:5 - 4:17] UnexposedExpr= @@ -78,7 +78,7 @@ void test3(S2 s2) { // CHECK: Punctuation: "(" [13:3 - 13:4] ParenExpr= // CHECK: Identifier: "x" [13:4 - 13:5] DeclRefExpr=x:11:14 // CHECK: Punctuation: ")" [13:5 - 13:6] ParenExpr= -// CHECK: Punctuation: "++" [13:6 - 13:8] CallExpr=operator++:9:5 +// CHECK: Punctuation: "++" [13:6 - 13:8] DeclRefExpr=operator++:9:5 // CHECK: Punctuation: ";" [13:8 - 13:9] CompoundStmt= // CHECK: Punctuation: "}" [14:1 - 14:2] CompoundStmt= // CHECK: Keyword: "struct" [16:1 - 16:7] StructDecl=S1:16:8 (Definition) @@ -111,7 +111,7 @@ void test3(S2 s2) { // CHECK: Punctuation: ")" [18:17 - 18:18] FunctionDecl=test3:18:6 (Definition) // CHECK: Punctuation: "{" [18:19 - 18:20] CompoundStmt= // CHECK: Identifier: "s2" [19:3 - 19:5] DeclRefExpr=s2:18:15 -// CHECK: Punctuation: "->" [19:5 - 19:7] MemberRefExpr=f:16:18 +// CHECK: Punctuation: "->" [19:5 - 19:7] DeclRefExpr=operator->:17:17 // CHECK: Identifier: "f" [19:7 - 19:8] MemberRefExpr=f:16:18 // CHECK: Punctuation: "(" [19:8 - 19:9] CallExpr=f:16:18 // CHECK: Punctuation: ")" [19:9 - 19:10] CallExpr=f:16:18 diff --git a/test/Index/index-refs.cpp b/test/Index/index-refs.cpp index 0b3c0bc423..00767b061d 100644 --- a/test/Index/index-refs.cpp +++ b/test/Index/index-refs.cpp @@ -18,6 +18,22 @@ enum { SecondVal = EnumVal }; +struct S { + S& operator++(); + int operator*(); + S& operator=(int x); + S& operator!=(int x); + S& operator()(int x); +}; + +void foo2(S &s) { + (void)++s; + (void)*s; + s = 3; + (void)(s != 3); + s(3); +} + // RUN: c-index-test -index-file %s | FileCheck %s // CHECK: [indexDeclaration]: kind: namespace | name: NS // CHECK-NEXT: [indexDeclaration]: kind: variable | name: gx @@ -35,3 +51,10 @@ enum { // CHECK-NEXT: [indexDeclaration]: kind: enum // CHECK-NEXT: [indexDeclaration]: kind: enumerator | name: SecondVal // CHECK-NEXT: [indexEntityReference]: kind: enumerator | name: EnumVal + +// CHECK: [indexDeclaration]: kind: function | name: foo2 +// CHECK: [indexEntityReference]: kind: c++-instance-method | name: operator++ +// CHECK-NEXT: [indexEntityReference]: kind: c++-instance-method | name: operator* +// CHECK-NEXT: [indexEntityReference]: kind: c++-instance-method | name: operator= +// CHECK-NEXT: [indexEntityReference]: kind: c++-instance-method | name: operator!= +// CHECK-NEXT: [indexEntityReference]: kind: c++-instance-method | name: operator() diff --git a/test/Index/recursive-cxx-member-calls.cpp b/test/Index/recursive-cxx-member-calls.cpp index adaaae9cdd..b80cbf40e8 100644 --- a/test/Index/recursive-cxx-member-calls.cpp +++ b/test/Index/recursive-cxx-member-calls.cpp @@ -933,7 +933,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) { // CHECK-tokens: Punctuation: ")" [102:58 - 102:59] CallExpr=endswith:56:8 // CHECK-tokens: Punctuation: ")" [102:59 - 102:60] IfStmt= // CHECK-tokens: Identifier: "AttrName" [103:5 - 103:13] DeclRefExpr=AttrName:101:19 -// CHECK-tokens: Punctuation: "=" [103:14 - 103:15] CallExpr=operator=:38:7 +// CHECK-tokens: Punctuation: "=" [103:14 - 103:15] DeclRefExpr=operator=:38:7 // CHECK-tokens: Identifier: "AttrName" [103:16 - 103:24] DeclRefExpr=AttrName:101:19 // CHECK-tokens: Punctuation: "." [103:24 - 103:25] MemberRefExpr=substr:60:13 // CHECK-tokens: Identifier: "substr" [103:25 - 103:31] MemberRefExpr=substr:60:13 diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp index 08c7d18f69..c400491132 100644 --- a/tools/libclang/IndexBody.cpp +++ b/tools/libclang/IndexBody.cpp @@ -90,6 +90,12 @@ public: return true; } + bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) { + if (E->getOperatorLoc().isInvalid()) + return true; // implicit. + return base::TraverseCXXOperatorCallExpr(E); + } + bool VisitDeclStmt(DeclStmt *S) { if (IndexCtx.indexFunctionLocalSymbols()) IndexCtx.indexDeclGroupRef(S->getDeclGroup()); -- 2.40.0