From: Douglas Gregor Date: Wed, 3 Nov 2010 00:35:38 +0000 (+0000) Subject: Improve source-location information for CXXConstructExpr nodes, by X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=40749ee585abc84fbb3c8fdbd8aaac062f153062;p=clang Improve source-location information for CXXConstructExpr nodes, by ensuring that they cover all of their child nodes. There's still a clang_getCursor()-related issue with CXXFunctionalCastExprs with CXXConstructExprs as children (see FIXME in the test case); I'll look at that separately. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118132 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index a07d7840f0..60785d471a 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -347,9 +347,22 @@ StmtIterator DependentScopeDeclRefExpr::child_end() { } SourceRange CXXConstructExpr::getSourceRange() const { - return ParenRange.isValid() ? - SourceRange(Loc, ParenRange.getEnd()) : - SourceRange(Loc); + if (ParenRange.isValid()) + return SourceRange(Loc, ParenRange.getEnd()); + + SourceLocation End = Loc; + for (unsigned I = getNumArgs(); I > 0; --I) { + const Expr *Arg = getArg(I-1); + if (!Arg->isDefaultArgument()) { + SourceLocation NewEnd = Arg->getLocEnd(); + if (NewEnd.isValid()) { + End = NewEnd; + break; + } + } + } + + return SourceRange(Loc, End); } SourceRange CXXOperatorCallExpr::getSourceRange() const { diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index fdc4828cf1..51bb6315e1 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4032,7 +4032,9 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, CXXCastPath &BasePath, bool FunctionalStyle) { if (getLangOptions().CPlusPlus) - return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, BasePath, + return CXXCheckCStyleCast(SourceRange(TyR.getBegin(), + castExpr->getLocEnd()), + castType, castExpr, Kind, BasePath, FunctionalStyle); DefaultFunctionArrayLvalueConversion(castExpr); diff --git a/test/Index/get-cursor.cpp b/test/Index/get-cursor.cpp new file mode 100644 index 0000000000..a1974b63a5 --- /dev/null +++ b/test/Index/get-cursor.cpp @@ -0,0 +1,30 @@ +// Test is line- and column-sensitive. Run lines are below. + +struct X { + X(); + X(int); + X(int, int); + X(const X&); +}; + +X getX(int value) { + switch (value) { + case 1: return X(value); + case 2: return X(value, value); + case 3: return (X)value; + default: break; + } + return X(); +} + +// RUN: c-index-test -cursor-at=%s:12:20 %s | FileCheck -check-prefix=CHECK-VALUE-REF %s +// RUN: c-index-test -cursor-at=%s:13:21 %s | FileCheck -check-prefix=CHECK-VALUE-REF %s +// RUN: c-index-test -cursor-at=%s:13:28 %s | FileCheck -check-prefix=CHECK-VALUE-REF %s +// 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 +// CHECK-TYPE-REF: TypeRef=struct X:3:8 diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index d825a400f9..e07c25d77a 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -1748,7 +1748,8 @@ bool CursorVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) { bool CursorVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) - return Visit(TSInfo->getTypeLoc()); + if (Visit(TSInfo->getTypeLoc())) + return true; return VisitExpr(E); } @@ -2849,6 +2850,7 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { if (SLoc.isInvalid()) return clang_getNullCursor(); + bool Logging = getenv("LIBCLANG_LOGGING"); SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(), CXXUnit->getASTContext().getLangOptions()); @@ -2862,6 +2864,31 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { Decl::MaxPCHLevel, SourceLocation(SLoc)); CursorVis.VisitChildren(Parent); } + + if (Logging) { + CXFile SearchFile; + unsigned SearchLine, SearchColumn; + CXFile ResultFile; + unsigned ResultLine, ResultColumn; + CXString SearchFileName, ResultFileName, KindSpelling; + CXSourceLocation ResultLoc = clang_getCursorLocation(Result); + + clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, + 0); + clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine, + &ResultColumn, 0); + SearchFileName = clang_getFileName(SearchFile); + ResultFileName = clang_getFileName(ResultFile); + KindSpelling = clang_getCursorKindSpelling(Result.kind); + fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d)\n", + clang_getCString(SearchFileName), SearchLine, SearchColumn, + clang_getCString(KindSpelling), + clang_getCString(ResultFileName), ResultLine, ResultColumn); + clang_disposeString(SearchFileName); + clang_disposeString(ResultFileName); + clang_disposeString(KindSpelling); + } + return Result; }