]> granicus.if.org Git - clang/commitdiff
Improve source-location information for CXXConstructExpr nodes, by
authorDouglas Gregor <dgregor@apple.com>
Wed, 3 Nov 2010 00:35:38 +0000 (00:35 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 3 Nov 2010 00:35:38 +0000 (00:35 +0000)
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

lib/AST/ExprCXX.cpp
lib/Sema/SemaExpr.cpp
test/Index/get-cursor.cpp [new file with mode: 0644]
tools/libclang/CIndex.cpp

index a07d7840f0c24d137ee58297dabccc77366d258a..60785d471acde1eec10933396da675b200059b90 100644 (file)
@@ -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 {
index fdc4828cf11a0cbedb033c997d84f5b36d1f59c9..51bb6315e161b4b72db0e738e8e10f2f50483250 100644 (file)
@@ -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 (file)
index 0000000..a1974b6
--- /dev/null
@@ -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
index d825a400f99cab1a8a8f0f21dba89c4496ea3404..e07c25d77a25396879b257b391d2d787ac8a4269 100644 (file)
@@ -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;
 }