diff options
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r-- | lib/Sema/SemaType.cpp | 84 |
1 files changed, 65 insertions, 19 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index a79853a..8278691 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -183,8 +183,7 @@ static QualType ConvertDeclSpecToType(Sema &TheSema, if (DS.isEmpty()) { TheSema.Diag(DeclLoc, diag::ext_missing_declspec) << DS.getSourceRange() - << CodeModificationHint::CreateInsertion(DS.getSourceRange().getBegin(), - "int"); + << FixItHint::CreateInsertion(DS.getSourceRange().getBegin(), "int"); } } else if (!DS.hasTypeSpecifier()) { // C99 and C++ require a type specifier. For example, C99 6.7.2p2 says: @@ -680,8 +679,11 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, return QualType(); } if (ConstVal == 0) { - // GCC accepts zero sized static arrays. - Diag(ArraySize->getLocStart(), diag::ext_typecheck_zero_array_size) + // GCC accepts zero sized static arrays. We allow them when + // we're not in a SFINAE context. + Diag(ArraySize->getLocStart(), + isSFINAEContext()? diag::err_typecheck_zero_array_size + : diag::ext_typecheck_zero_array_size) << ArraySize->getSourceRange(); } T = Context.getConstantArrayType(T, ConstVal, ASM, Quals); @@ -798,7 +800,8 @@ QualType Sema::BuildFunctionType(QualType T, return QualType(); return Context.getFunctionType(T, ParamTypes, NumParamTypes, Variadic, - Quals, false, false, 0, 0, false, CC_Default); + Quals, false, false, 0, 0, + FunctionType::ExtInfo()); } /// \brief Build a member pointer type \c T Class::*. @@ -1135,7 +1138,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, FTI.hasExceptionSpec, FTI.hasAnyExceptionSpec, Exceptions.size(), Exceptions.data(), - false, CC_Default); + FunctionType::ExtInfo()); } else if (FTI.isVariadic) { // We allow a zero-parameter variadic function in C if the // function is marked with the "overloadable" @@ -1152,7 +1155,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, if (!Overloadable) Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg); T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, 0, - false, false, 0, 0, false, CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); } else { // Simple void foo(), where the incoming T is the result type. T = Context.getFunctionNoProtoType(T); @@ -1228,7 +1232,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, FTI.hasExceptionSpec, FTI.hasAnyExceptionSpec, Exceptions.size(), Exceptions.data(), - false, CC_Default); + FunctionType::ExtInfo()); } // For GCC compatibility, we allow attributes that apply only to @@ -1257,7 +1261,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, NestedNameSpecifier *NNSPrefix = NNS->getPrefix(); switch (NNS->getKind()) { case NestedNameSpecifier::Identifier: - ClsType = Context.getTypenameType(NNSPrefix, NNS->getAsIdentifier()); + ClsType = Context.getDependentNameType(ETK_None, NNSPrefix, + NNS->getAsIdentifier()); break; case NestedNameSpecifier::Namespace: @@ -1326,7 +1331,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, // Strip the cv-quals from the type. T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(), FnTy->getNumArgs(), FnTy->isVariadic(), 0, - false, false, 0, 0, false, CC_Default); + false, false, 0, 0, FunctionType::ExtInfo()); } } @@ -1734,6 +1739,30 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) { return false; } + if (Attr.getKind() == AttributeList::AT_regparm) { + // The warning is emitted elsewhere + if (Attr.getNumArgs() != 1) { + return false; + } + + // Delay if this is not a function or pointer to block. + if (!Type->isFunctionPointerType() + && !Type->isBlockPointerType() + && !Type->isFunctionType()) + return true; + + // Otherwise we can process right away. + Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); + llvm::APSInt NumParams(32); + + // The warning is emitted elsewhere + if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) + return false; + + Type = S.Context.getRegParmType(Type, NumParams.getZExtValue()); + return false; + } + // Otherwise, a calling convention. if (Attr.getNumArgs() != 0) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; @@ -1863,6 +1892,7 @@ void ProcessTypeAttributeList(Sema &S, QualType &Result, case AttributeList::AT_cdecl: case AttributeList::AT_fastcall: case AttributeList::AT_stdcall: + case AttributeList::AT_regparm: // Don't process these on the DeclSpec. if (IsDeclSpec || ProcessFnAttr(S, Result, *AL)) @@ -1942,6 +1972,16 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, if (diag == 0) return true; + const TagType *Tag = 0; + if (const RecordType *Record = T->getAs<RecordType>()) + Tag = Record; + else if (const EnumType *Enum = T->getAs<EnumType>()) + Tag = Enum; + + // Avoid diagnosing invalid decls as incomplete. + if (Tag && Tag->getDecl()->isInvalidDecl()) + return true; + // We have an incomplete type. Produce a diagnostic. Diag(Loc, PD) << T; @@ -1950,13 +1990,7 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, Diag(Note.first, Note.second); // If the type was a forward declaration of a class/struct/union - // type, produce - const TagType *Tag = 0; - if (const RecordType *Record = T->getAs<RecordType>()) - Tag = Record; - else if (const EnumType *Enum = T->getAs<EnumType>()) - Tag = Enum; - + // type, produce a note. if (Tag && !Tag->getDecl()->isInvalidDecl()) Diag(Tag->getDecl()->getLocation(), Tag->isBeingDefined() ? diag::note_type_being_defined @@ -1966,6 +2000,18 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, return true; } +bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, + const PartialDiagnostic &PD) { + return RequireCompleteType(Loc, T, PD, + std::make_pair(SourceLocation(), PDiag(0))); +} + +bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, + unsigned DiagID) { + return RequireCompleteType(Loc, T, PDiag(DiagID), + std::make_pair(SourceLocation(), PDiag(0))); +} + /// \brief Retrieve a version of the type 'T' that is qualified by the /// nested-name-specifier contained in SS. QualType Sema::getQualifiedNameType(const CXXScopeSpec &SS, QualType T) { @@ -1983,7 +2029,7 @@ QualType Sema::BuildTypeofExprType(Expr *E) { // function template specialization wherever deduction cannot occur. if (FunctionDecl *Specialization = ResolveSingleFunctionTemplateSpecialization(E)) { - E = FixOverloadedFunctionReference(E, Specialization); + E = FixOverloadedFunctionReference(E, Specialization, Specialization); if (!E) return QualType(); } else { @@ -2003,7 +2049,7 @@ QualType Sema::BuildDecltypeType(Expr *E) { // function template specialization wherever deduction cannot occur. if (FunctionDecl *Specialization = ResolveSingleFunctionTemplateSpecialization(E)) { - E = FixOverloadedFunctionReference(E, Specialization); + E = FixOverloadedFunctionReference(E, Specialization, Specialization); if (!E) return QualType(); } else { |