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 a79853afdc6b..8278691a4a3b 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 {  | 
