Revert r107374, which broke bootstrap.

llvm-svn: 107378
This commit is contained in:
Douglas Gregor 2010-07-01 03:28:42 +00:00
parent 722f5fc567
commit 3671ad4571
6 changed files with 19 additions and 34 deletions

View File

@ -2672,7 +2672,7 @@ public:
QualType CheckConstructorDeclarator(Declarator &D, QualType R, QualType CheckConstructorDeclarator(Declarator &D, QualType R,
FunctionDecl::StorageClass& SC); FunctionDecl::StorageClass& SC);
void CheckConstructor(CXXConstructorDecl *Constructor); void CheckConstructor(CXXConstructorDecl *Constructor);
QualType CheckDestructorDeclarator(Declarator &D, QualType R, QualType CheckDestructorDeclarator(Declarator &D,
FunctionDecl::StorageClass& SC); FunctionDecl::StorageClass& SC);
bool CheckDestructor(CXXDestructorDecl *Destructor); bool CheckDestructor(CXXDestructorDecl *Destructor);
void CheckConversionDeclarator(Declarator &D, QualType &R, void CheckConversionDeclarator(Declarator &D, QualType &R,

View File

@ -3023,7 +3023,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
} else if (Name.getNameKind() == DeclarationName::CXXDestructorName) { } else if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
// This is a C++ destructor declaration. // This is a C++ destructor declaration.
if (DC->isRecord()) { if (DC->isRecord()) {
R = CheckDestructorDeclarator(D, R, SC); R = CheckDestructorDeclarator(D, SC);
NewFD = CXXDestructorDecl::Create(Context, NewFD = CXXDestructorDecl::Create(Context,
cast<CXXRecordDecl>(DC), cast<CXXRecordDecl>(DC),

View File

@ -2990,7 +2990,9 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
// Rebuild the function type "R" without any type qualifiers (in // Rebuild the function type "R" without any type qualifiers (in
// case any of the errors above fired) and with "void" as the // case any of the errors above fired) and with "void" as the
// return type, since constructors don't have return types. // return type, since constructors don't have return types. We
// *always* have to do this, because GetTypeForDeclarator will
// put in a result type of "int" when none was specified.
const FunctionProtoType *Proto = R->getAs<FunctionProtoType>(); const FunctionProtoType *Proto = R->getAs<FunctionProtoType>();
return Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(), return Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(),
Proto->getNumArgs(), Proto->getNumArgs(),
@ -3085,7 +3087,7 @@ FTIHasSingleVoidArgument(DeclaratorChunk::FunctionTypeInfo &FTI) {
/// emit diagnostics and set the declarator to invalid. Even if this happens, /// emit diagnostics and set the declarator to invalid. Even if this happens,
/// will be updated to reflect a well-formed type for the destructor and /// will be updated to reflect a well-formed type for the destructor and
/// returned. /// returned.
QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R, QualType Sema::CheckDestructorDeclarator(Declarator &D,
FunctionDecl::StorageClass& SC) { FunctionDecl::StorageClass& SC) {
// C++ [class.dtor]p1: // C++ [class.dtor]p1:
// [...] A typedef-name that names a class is a class-name // [...] A typedef-name that names a class is a class-name
@ -3093,9 +3095,11 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
// be used as the identifier in the declarator for a destructor // be used as the identifier in the declarator for a destructor
// declaration. // declaration.
QualType DeclaratorType = GetTypeFromParser(D.getName().DestructorName); QualType DeclaratorType = GetTypeFromParser(D.getName().DestructorName);
if (isa<TypedefType>(DeclaratorType)) if (isa<TypedefType>(DeclaratorType)) {
Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name) Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name)
<< DeclaratorType; << DeclaratorType;
D.setInvalidType();
}
// C++ [class.dtor]p2: // C++ [class.dtor]p2:
// A destructor is used to destroy objects of its class type. A // A destructor is used to destroy objects of its class type. A
@ -3109,10 +3113,9 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
if (!D.isInvalidType()) if (!D.isInvalidType())
Diag(D.getIdentifierLoc(), diag::err_destructor_cannot_be) Diag(D.getIdentifierLoc(), diag::err_destructor_cannot_be)
<< "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc()) << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
<< SourceRange(D.getIdentifierLoc()) << SourceRange(D.getIdentifierLoc());
<< FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
SC = FunctionDecl::None; SC = FunctionDecl::None;
D.setInvalidType();
} }
if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) { if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
// Destructors don't have return types, but the parser will // Destructors don't have return types, but the parser will
@ -3160,17 +3163,11 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
// Rebuild the function type "R" without any type qualifiers or // Rebuild the function type "R" without any type qualifiers or
// parameters (in case any of the errors above fired) and with // parameters (in case any of the errors above fired) and with
// "void" as the return type, since destructors don't have return // "void" as the return type, since destructors don't have return
// types. // types. We *always* have to do this, because GetTypeForDeclarator
const FunctionProtoType *Proto = R->getAs<FunctionProtoType>(); // will put in a result type of "int" when none was specified.
if (!Proto) // FIXME: Exceptions!
return QualType();
return Context.getFunctionType(Context.VoidTy, 0, 0, false, 0, return Context.getFunctionType(Context.VoidTy, 0, 0, false, 0,
Proto->hasExceptionSpec(), false, false, 0, 0, FunctionType::ExtInfo());
Proto->hasAnyExceptionSpec(),
Proto->getNumExceptions(),
Proto->exception_begin(),
Proto->getExtInfo());
} }
/// CheckConversionDeclarator - Called by ActOnDeclarator to check the /// CheckConversionDeclarator - Called by ActOnDeclarator to check the

View File

@ -32,17 +32,6 @@ struct C {
C::~C() { } C::~C() { }
namespace PR7526 {
extern void foo();
struct allocator {
~allocator() throw();
};
// CHECK: define void @_ZN6PR75269allocatorD2Ev
// CHECK: call void @__cxa_call_unexpected
allocator::~allocator() throw() { foo(); }
}
// PR5084 // PR5084
template<typename T> template<typename T>
class A1 { class A1 {

View File

@ -19,9 +19,7 @@ struct D {
// expected-error{{type qualifier is not allowed on this function}} \ // expected-error{{type qualifier is not allowed on this function}} \
// expected-error{{destructor cannot be declared 'static'}} \ // expected-error{{destructor cannot be declared 'static'}} \
// expected-error{{destructor cannot have any parameters}} \ // expected-error{{destructor cannot have any parameters}} \
// expected-error{{destructor cannot be variadic}} \ // expected-error{{destructor cannot be variadic}}
// expected-error{{destructor cannot have a return type}} \
// expected-error{{'const' qualifier is not allowed on a destructor}}
}; };
struct D2 { struct D2 {

View File

@ -590,8 +590,9 @@ void g(Base *base) {
downcast.mm:6:3: error: no matching function for call to 'f' downcast.mm:6:3: error: no matching function for call to 'f'
f(base); f(base);
^ ^
downcast.mm:4:6: note: candidate function not viable: cannot convert from downcast.mm:4:6: note: candidate function not viable: cannot convert from base
superclass 'Base *' to subclass 'Derived *' for 1st argument class pointer 'Base *' to derived class pointer 'Derived *' for 1st
argument
void f(Derived *); void f(Derived *);
^ ^
</pre> </pre>