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:
parent
f514592197
commit
ae01993a12
|
@ -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<
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue