Please find attached a patch (including testcase) for fixing the computation of source ranges for a couple of AST nodes.

Prior to C++11, CXXFunctionalCastExpr and CXXUnresolvedConstructExpr nodes were assuming a valid RParenLoc; after C++11, the parentheses are no longer mandatory, as in the following examples:

  int foo() { return int{}; }

  typedef std::initializer_list<int> IL;
  template<class U> IL foo(U x) { return IL{x}; }

OK to commit?

Enea.
Index: test/SemaCXX/cxx0x-initializer-stdinitializerlist-ranges.cpp
===================================================================
--- test/SemaCXX/cxx0x-initializer-stdinitializerlist-ranges.cpp	(revision 0)
+++ test/SemaCXX/cxx0x-initializer-stdinitializerlist-ranges.cpp	(revision 0)
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s
+
+namespace std {
+  typedef decltype(sizeof(int)) size_t;
+
+  // libc++'s implementation
+  template <class _E>
+  class initializer_list
+  {
+    const _E* __begin_;
+    size_t    __size_;
+
+    initializer_list(const _E* __b, size_t __s)
+      : __begin_(__b),
+        __size_(__s)
+    {}
+
+  public:
+    typedef _E        value_type;
+    typedef const _E& reference;
+    typedef const _E& const_reference;
+    typedef size_t    size_type;
+
+    typedef const _E* iterator;
+    typedef const _E* const_iterator;
+
+    initializer_list() : __begin_(nullptr), __size_(0) {}
+
+    size_t    size()  const {return __size_;}
+    const _E* begin() const {return __begin_;}
+    const _E* end()   const {return __begin_ + __size_;}
+  };
+}
+
+namespace CXXFunctionalCastExpr_Range {
+
+int foo() {
+  // CHECK: CXXFunctionalCastExpr {{0x[0-9a-fA-F]+}} <col:10, col:14> 'int' functional cast to int <NoOp>
+  return int{};
+}
+
+} // namespace CXXFunctionalCastExpr_Range
+
+namespace CXXUnresolvedConstructExpr_Range {
+
+typedef std::initializer_list<int> IL;
+
+template <class U>
+IL foo(U x) {
+  // CHECK: CXXUnresolvedConstructExpr {{0x[0-9a-fA-F]+}} <col:10, col:14> 'IL':'class std::initializer_list<int>
+  return IL{x};
+}
+
+} // namespace CXXUnresolvedConstructExpr_Range
Index: include/clang/AST/ExprCXX.h
===================================================================
--- include/clang/AST/ExprCXX.h	(revision 185665)
+++ include/clang/AST/ExprCXX.h	(working copy)
@@ -1224,7 +1224,9 @@
   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
 
   SourceLocation getLocStart() const LLVM_READONLY { return TyBeginLoc; }
-  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return RParenLoc.isValid() ? RParenLoc : getSubExpr()->getLocEnd();
+  }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXFunctionalCastExprClass;
@@ -3065,7 +3067,10 @@
   }
 
   SourceLocation getLocStart() const LLVM_READONLY;
-  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    assert(RParenLoc.isValid() || NumArgs == 1);
+    return RParenLoc.isValid() ? RParenLoc : getArg(0)->getLocEnd();
+  }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXUnresolvedConstructExprClass;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to