[cfe-commits] r146155 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Parse/ParseExprCXX.cpp lib/Sema/SemaExprCXX.cpp test/CXX/special/class.dtor/p10-0x.cpp

David Blaikie dblaikie at gmail.com
Thu Dec 8 08:13:53 PST 2011


Author: dblaikie
Date: Thu Dec  8 10:13:53 2011
New Revision: 146155

URL: http://llvm.org/viewvc/llvm-project?rev=146155&view=rev
Log:
Decltype in non-pseudo (& non-dependent) dtor calls.

Added:
    cfe/trunk/test/CXX/special/class.dtor/p10-0x.cpp
Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=146155&r1=146154&r2=146155&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Dec  8 10:13:53 2011
@@ -3020,6 +3020,8 @@
                                ParsedType ObjectType,
                                bool EnteringContext);
 
+  ParsedType getDestructorType(const DeclSpec& DS, ParsedType ObjectType);
+
   // Checks that reinterpret casts don't have undefined behavior.
   void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
                                       bool IsDereference, SourceRange Range);

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=146155&r1=146154&r2=146155&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Dec  8 10:13:53 2011
@@ -1966,6 +1966,16 @@
     
     // Parse the '~'.
     SourceLocation TildeLoc = ConsumeToken();
+
+    if (SS.isEmpty() && Tok.is(tok::kw_decltype)) {
+      DeclSpec DS(AttrFactory);
+      SourceLocation EndLoc = ParseDecltypeSpecifier(DS);
+      if (ParsedType Type = Actions.getDestructorType(DS, ObjectType)) {
+        Result.setDestructorName(TildeLoc, Type, EndLoc);
+        return false;
+      }
+      return true;
+    }
     
     // Parse the class-name.
     if (Tok.isNot(tok::identifier)) {

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=146155&r1=146154&r2=146155&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Dec  8 10:13:53 2011
@@ -265,6 +265,22 @@
   return ParsedType();
 }
 
+ParsedType Sema::getDestructorType(const DeclSpec& DS, ParsedType ObjectType) {
+    if (DS.getTypeSpecType() == DeclSpec::TST_error)
+      return ParsedType();
+    assert(DS.getTypeSpecType() == DeclSpec::TST_decltype 
+           && "only get destructor types from declspecs");
+    QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc());
+    QualType SearchType = GetTypeFromParser(ObjectType);
+    if (SearchType->isDependentType() || Context.hasSameUnqualifiedType(SearchType, T)) {
+      return ParsedType::make(T);
+    }
+      
+    Diag(DS.getTypeSpecTypeLoc(), diag::err_destructor_expr_type_mismatch)
+      << T << SearchType;
+    return ParsedType();
+}
+
 /// \brief Build a C++ typeid expression with a type operand.
 ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
                                 SourceLocation TypeidLoc,

Added: cfe/trunk/test/CXX/special/class.dtor/p10-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.dtor/p10-0x.cpp?rev=146155&view=auto
==============================================================================
--- cfe/trunk/test/CXX/special/class.dtor/p10-0x.cpp (added)
+++ cfe/trunk/test/CXX/special/class.dtor/p10-0x.cpp Thu Dec  8 10:13:53 2011
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// PR10127/N3031
+struct A { ~A(); };
+struct B {};
+template<typename T>
+void b(const T *x, const A *y) {
+  // FIXME: this parses as a pseudo destructor call which doesn't have decltype support yet
+  x->~decltype(T())(); // expected-error{{expected a class name after '~' to name a destructor}}
+
+  y->~decltype(*y)(); // expected-error{{destructor type 'decltype(*y)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}}
+  y->~decltype(T())(); // expected-error{{destructor type 'decltype(T())' in object destruction expression does not match the type 'const A' of the object being destroyed}}
+  y->~decltype(A())();
+}
+template void b(const int*, const A*);
+template void b(const A*,const A*);
+void a(const A *x) {
+  x->~decltype(A())();
+  x->~decltype(*x)(); // expected-error{{destructor type 'decltype(*x)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}}
+  x->~decltype()(); // expected-error{{expected expression}}
+  x->~decltype(B())(); // expected-error{{destructor type 'decltype(B())' (aka 'B') in object destruction expression does not match the type 'const A' of the object being destroyed}}
+  x->~decltype(x)(); // expected-error{{destructor type 'decltype(x)' (aka 'const A *') in object destruction expression does not match the type 'const A' of the object being destroyed}}
+  // this last one could be better, mentioning that the nested-name-specifier could be removed or a type name after the ~
+  x->::A::~decltype(*x)(); // expected-error{{expected a class name after '~' to name a destructor}}
+}





More information about the cfe-commits mailing list