[cfe-commits] r70021 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/destructor.cpp
Chris Lattner
sabre at nondot.org
Sat Apr 25 01:28:22 PDT 2009
Author: lattner
Date: Sat Apr 25 03:28:21 2009
New Revision: 70021
URL: http://llvm.org/viewvc/llvm-project?rev=70021&view=rev
Log:
various "is invalid" cleanups for C++ ctors/dtors.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/SemaCXX/destructor.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=70021&r1=70020&r2=70021&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Apr 25 03:28:21 2009
@@ -1682,11 +1682,11 @@
ExprArg AssertExpr,
ExprArg AssertMessageExpr);
- bool CheckConstructorDeclarator(Declarator &D, QualType &R,
- FunctionDecl::StorageClass& SC);
+ QualType CheckConstructorDeclarator(Declarator &D, QualType R,
+ FunctionDecl::StorageClass& SC);
bool CheckConstructor(CXXConstructorDecl *Constructor);
- bool CheckDestructorDeclarator(Declarator &D, QualType &R,
- FunctionDecl::StorageClass& SC);
+ QualType CheckDestructorDeclarator(Declarator &D,
+ FunctionDecl::StorageClass& SC);
bool CheckConversionDeclarator(Declarator &D, QualType &R,
FunctionDecl::StorageClass& SC);
DeclPtrTy ActOnConversionDeclarator(CXXConversionDecl *Conversion);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=70021&r1=70020&r2=70021&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Apr 25 03:28:21 2009
@@ -1993,8 +1993,7 @@
assert(DC->isRecord() &&
"Constructors can only be declared in a member context");
- if (!D.isInvalidType())
- D.setInvalidType(CheckConstructorDeclarator(D, R, SC));
+ R = CheckConstructorDeclarator(D, R, SC);
// Create the new declaration
NewFD = CXXConstructorDecl::Create(Context,
@@ -2005,8 +2004,7 @@
} else if (D.getKind() == Declarator::DK_Destructor) {
// This is a C++ destructor declaration.
if (DC->isRecord()) {
- if (!D.isInvalidType())
- D.setInvalidType(CheckDestructorDeclarator(D, R, SC));
+ R = CheckDestructorDeclarator(D, SC);
NewFD = CXXDestructorDecl::Create(Context,
cast<CXXRecordDecl>(DC),
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=70021&r1=70020&r2=70021&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sat Apr 25 03:28:21 2009
@@ -1266,13 +1266,12 @@
/// CheckConstructorDeclarator - Called by ActOnDeclarator to check
/// the well-formedness of the constructor declarator @p D with type @p
/// R. If there are any errors in the declarator, this routine will
-/// emit diagnostics and return true. Otherwise, it will return
-/// false. Either way, the type @p R will be updated to reflect a
-/// well-formed type for the constructor.
-bool Sema::CheckConstructorDeclarator(Declarator &D, QualType &R,
- FunctionDecl::StorageClass& SC) {
+/// emit diagnostics and set the invalid bit to true. In any case, the type
+/// will be updated to reflect a well-formed type for the constructor and
+/// returned.
+QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
+ FunctionDecl::StorageClass &SC) {
bool isVirtual = D.getDeclSpec().isVirtualSpecified();
- bool isInvalid = false;
// C++ [class.ctor]p3:
// A constructor shall not be virtual (10.3) or static (9.4). A
@@ -1280,19 +1279,21 @@
// volatile object. A constructor shall not be declared const,
// volatile, or const volatile (9.3.2).
if (isVirtual) {
- Diag(D.getIdentifierLoc(), diag::err_constructor_cannot_be)
- << "virtual" << SourceRange(D.getDeclSpec().getVirtualSpecLoc())
- << SourceRange(D.getIdentifierLoc());
- isInvalid = true;
+ if (!D.isInvalidType())
+ Diag(D.getIdentifierLoc(), diag::err_constructor_cannot_be)
+ << "virtual" << SourceRange(D.getDeclSpec().getVirtualSpecLoc())
+ << SourceRange(D.getIdentifierLoc());
+ D.setInvalidType();
}
if (SC == FunctionDecl::Static) {
- Diag(D.getIdentifierLoc(), diag::err_constructor_cannot_be)
- << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
- << SourceRange(D.getIdentifierLoc());
- isInvalid = true;
+ if (!D.isInvalidType())
+ Diag(D.getIdentifierLoc(), diag::err_constructor_cannot_be)
+ << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
+ << SourceRange(D.getIdentifierLoc());
+ D.setInvalidType();
SC = FunctionDecl::None;
}
- if (D.getDeclSpec().hasTypeSpecifier()) {
+ if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
// Constructors don't have return types, but the parser will
// happily parse something like:
//
@@ -1304,9 +1305,10 @@
Diag(D.getIdentifierLoc(), diag::err_constructor_return_type)
<< SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
<< SourceRange(D.getIdentifierLoc());
- }
- if (R->getAsFunctionProtoType()->getTypeQuals() != 0) {
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ }
+
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ if (FTI.TypeQuals != 0) {
if (FTI.TypeQuals & QualType::Const)
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
<< "const" << SourceRange(D.getIdentifierLoc());
@@ -1324,12 +1326,9 @@
// *always* have to do this, because GetTypeForDeclarator will
// put in a result type of "int" when none was specified.
const FunctionProtoType *Proto = R->getAsFunctionProtoType();
- R = Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(),
- Proto->getNumArgs(),
- Proto->isVariadic(),
- 0);
-
- return isInvalid;
+ return Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(),
+ Proto->getNumArgs(),
+ Proto->isVariadic(), 0);
}
/// CheckConstructor - Checks a fully-formed constructor for
@@ -1371,23 +1370,21 @@
/// CheckDestructorDeclarator - Called by ActOnDeclarator to check
/// the well-formednes of the destructor declarator @p D with type @p
/// R. If there are any errors in the declarator, this routine will
-/// emit diagnostics and return true. Otherwise, it will return
-/// false. Either way, the type @p R will be updated to reflect a
-/// well-formed type for the destructor.
-bool Sema::CheckDestructorDeclarator(Declarator &D, QualType &R,
- FunctionDecl::StorageClass& SC) {
- bool isInvalid = false;
-
+/// 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
+/// returned.
+QualType Sema::CheckDestructorDeclarator(Declarator &D,
+ FunctionDecl::StorageClass& SC) {
// C++ [class.dtor]p1:
// [...] A typedef-name that names a class is a class-name
// (7.1.3); however, a typedef-name that names a class shall not
// be used as the identifier in the declarator for a destructor
// declaration.
QualType DeclaratorType = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
- if (DeclaratorType->getAsTypedefType()) {
- Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name)
+ if (isa<TypedefType>(DeclaratorType)) {
+ Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name)
<< DeclaratorType;
- isInvalid = true;
+ D.setInvalidType();
}
// C++ [class.dtor]p2:
@@ -1399,13 +1396,14 @@
// volatile object. A destructor shall not be declared const,
// volatile or const volatile (9.3.2).
if (SC == FunctionDecl::Static) {
- Diag(D.getIdentifierLoc(), diag::err_destructor_cannot_be)
- << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
- << SourceRange(D.getIdentifierLoc());
- isInvalid = true;
+ if (!D.isInvalidType())
+ Diag(D.getIdentifierLoc(), diag::err_destructor_cannot_be)
+ << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
+ << SourceRange(D.getIdentifierLoc());
SC = FunctionDecl::None;
+ D.setInvalidType();
}
- if (D.getDeclSpec().hasTypeSpecifier()) {
+ if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
// Destructors don't have return types, but the parser will
// happily parse something like:
//
@@ -1418,8 +1416,9 @@
<< SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
<< SourceRange(D.getIdentifierLoc());
}
- if (R->getAsFunctionProtoType()->getTypeQuals() != 0) {
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ if (FTI.TypeQuals != 0 && !D.isInvalidType()) {
if (FTI.TypeQuals & QualType::Const)
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
<< "const" << SourceRange(D.getIdentifierLoc());
@@ -1429,28 +1428,30 @@
if (FTI.TypeQuals & QualType::Restrict)
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
<< "restrict" << SourceRange(D.getIdentifierLoc());
+ D.setInvalidType();
}
// Make sure we don't have any parameters.
- if (R->getAsFunctionProtoType()->getNumArgs() > 0) {
+ if (FTI.NumArgs > 0) {
Diag(D.getIdentifierLoc(), diag::err_destructor_with_params);
// Delete the parameters.
- D.getTypeObject(0).Fun.freeArgs();
+ FTI.freeArgs();
+ D.setInvalidType();
}
// Make sure the destructor isn't variadic.
- if (R->getAsFunctionProtoType()->isVariadic())
+ if (FTI.isVariadic) {
Diag(D.getIdentifierLoc(), diag::err_destructor_variadic);
+ D.setInvalidType();
+ }
// Rebuild the function type "R" without any type qualifiers or
// parameters (in case any of the errors above fired) and with
// "void" as the return type, since destructors 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.
- R = Context.getFunctionType(Context.VoidTy, 0, 0, false, 0);
-
- return isInvalid;
+ return Context.getFunctionType(Context.VoidTy, 0, 0, false, 0);
}
/// CheckConversionDeclarator - Called by ActOnDeclarator to check the
Modified: cfe/trunk/test/SemaCXX/destructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/destructor.cpp?rev=70021&r1=70020&r2=70021&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/destructor.cpp (original)
+++ cfe/trunk/test/SemaCXX/destructor.cpp Sat Apr 25 03:28:21 2009
@@ -18,11 +18,15 @@
static void ~D(int, ...) const { } // \
// expected-error{{type qualifier is not allowed on this function}} \
// expected-error{{destructor cannot be declared 'static'}} \
- // expected-error{{destructor cannot have a return type}} \
// expected-error{{destructor cannot have any parameters}} \
// expected-error{{destructor cannot be variadic}}
};
+struct D2 {
+ void ~D2() { } // \
+ // expected-error{{destructor cannot have a return type}}
+};
+
struct E;
More information about the cfe-commits
mailing list