Implement more of C++0x 'auto'. A variable with an auto type specifier must have an initializer. Also, move some tests around to match the C++0x draft better.

llvm-svn: 75322
This commit is contained in:
Anders Carlsson 2009-07-11 00:34:39 +00:00
parent f514592197
commit ae01993a12
7 changed files with 21 additions and 5 deletions

View File

@ -417,6 +417,8 @@ def err_illegal_decl_array_of_auto : Error<
def err_auto_not_allowed : Error<
"'auto' not allowed in %select{function prototype|struct member|union member"
"|class member|exception declaration|template parameter|block literal}0">;
def err_auto_var_requires_init : Error<
"declaration of variable %0 with type %1 requires an initializer">;
// Objective-C++
def err_objc_decls_may_only_appear_in_global_scope : Error<

View File

@ -302,7 +302,10 @@ public:
/// ActOnUninitializedDecl - This action is called immediately after
/// ActOnDeclarator (when an initializer is *not* present).
virtual void ActOnUninitializedDecl(DeclPtrTy Dcl) {
/// If TypeContainsUndeducedAuto is true, then the type of the declarator
/// has an undeduced 'auto' type somewhere.
virtual void ActOnUninitializedDecl(DeclPtrTy Dcl,
bool TypeContainsUndeducedAuto) {
return;
}

View File

@ -1006,7 +1006,7 @@ const char *BuiltinType::getName(const LangOptions &LO) const {
case NullPtr: return "nullptr_t";
case Overload: return "<overloaded function type>";
case Dependent: return "<dependent type>";
case UndeducedAuto: return "<undeduced auto type>";
case UndeducedAuto: return "auto";
}
}

View File

@ -465,7 +465,9 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D,
CommaLocs.data(), RParenLoc);
}
} else {
Actions.ActOnUninitializedDecl(ThisDecl);
bool TypeContainsUndeducedAuto =
D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsUndeducedAuto);
}
return ThisDecl;

View File

@ -473,7 +473,7 @@ public:
virtual void AddInitializerToDecl(DeclPtrTy dcl, FullExprArg init);
void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit);
void ActOnUninitializedDecl(DeclPtrTy dcl);
void ActOnUninitializedDecl(DeclPtrTy dcl, bool TypeContainsUndeducedAuto);
virtual void SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc);
virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
DeclPtrTy *Group,

View File

@ -2756,7 +2756,8 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
return;
}
void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) {
void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
bool TypeContainsUndeducedAuto) {
Decl *RealDecl = dcl.getAs<Decl>();
// If there is no declaration, there was an error parsing it. Just ignore it.
@ -2784,6 +2785,14 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) {
return;
}
// C++0x [dcl.spec.auto]p3
if (TypeContainsUndeducedAuto) {
Diag(Var->getLocation(), diag::err_auto_var_requires_init)
<< Var->getDeclName() << Type;
Var->setInvalidDecl();
return;
}
// C++ [dcl.init]p9:
//
// If no initializer is specified for an object, and the object