summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r--lib/Sema/SemaType.cpp84
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 {
OpenPOWER on IntegriCloud