[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