diff options
Diffstat (limited to 'lib/Sema/SemaType.cpp')
| -rw-r--r-- | lib/Sema/SemaType.cpp | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 967f650d13b4..c6bcdc36f132 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -121,16 +121,18 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, if (DeclLoc.isInvalid()) DeclLoc = DS.getSourceRange().getBegin(); - if (getLangOptions().CPlusPlus && !getLangOptions().Microsoft) + if (getLangOptions().CPlusPlus && !getLangOptions().Microsoft) { Diag(DeclLoc, diag::err_missing_type_specifier) << DS.getSourceRange(); - else + + // When this occurs in C++ code, often something is very broken with the + // value being declared, poison it as invalid so we don't get chains of + // errors. + isInvalid = true; + } else { Diag(DeclLoc, diag::ext_missing_type_specifier) << DS.getSourceRange(); - - // FIXME: If we could guarantee that the result would be well-formed, it - // would be useful to have a code insertion hint here. However, after - // emitting this warning/error, we often emit other errors. + } } // FALL THROUGH. @@ -236,6 +238,19 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, Result = Context.getTypeOfExprType(E); break; } + case DeclSpec::TST_decltype: { + Expr *E = static_cast<Expr *>(DS.getTypeRep()); + assert(E && "Didn't get an expression for decltype?"); + // TypeQuals handled by caller. + Result = Context.getDecltypeType(E); + break; + } + case DeclSpec::TST_auto: { + // TypeQuals handled by caller. + Result = Context.UndeducedAutoTy; + break; + } + case DeclSpec::TST_error: Result = Context.IntTy; isInvalid = true; @@ -483,6 +498,12 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, return QualType(); } + if (Context.getCanonicalType(T) == Context.UndeducedAutoTy) { + Diag(Loc, diag::err_illegal_decl_array_of_auto) + << getPrintableNameForEntity(Entity); + return QualType(); + } + if (const RecordType *EltTy = T->getAsRecordType()) { // If the element type is a struct or union that contains a variadic // array, accept it as a GNU extension: C99 6.7.2.1p2. @@ -786,6 +807,52 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip, break; } + if (T == Context.UndeducedAutoTy) { + int Error = -1; + + switch (D.getContext()) { + case Declarator::KNRTypeListContext: + assert(0 && "K&R type lists aren't allowed in C++"); + break; + default: + printf("context: %d\n", D.getContext()); + assert(0); + case Declarator::PrototypeContext: + Error = 0; // Function prototype + break; + case Declarator::MemberContext: + switch (cast<TagDecl>(CurContext)->getTagKind()) { + case TagDecl::TK_enum: assert(0 && "unhandled tag kind"); break; + case TagDecl::TK_struct: Error = 1; /* Struct member */ break; + case TagDecl::TK_union: Error = 2; /* Union member */ break; + case TagDecl::TK_class: Error = 3; /* Class member */ break; + } + break; + case Declarator::CXXCatchContext: + Error = 4; // Exception declaration + break; + case Declarator::TemplateParamContext: + Error = 5; // Template parameter + break; + case Declarator::BlockLiteralContext: + Error = 6; // Block literal + break; + case Declarator::FileContext: + case Declarator::BlockContext: + case Declarator::ForContext: + case Declarator::ConditionContext: + case Declarator::TypeNameContext: + break; + } + + if (Error != -1) { + Diag(D.getDeclSpec().getTypeSpecTypeLoc(), diag::err_auto_not_allowed) + << Error; + T = Context.IntTy; + D.setInvalidType(true); + } + } + // The name we're declaring, if any. DeclarationName Name; if (D.getIdentifier()) |
