forked from OSchip/llvm-project
Break Sema::GetTypeForDeclarator in 2 functions, one for DeclSpec processing and another for the rest.
No functionality change. llvm-svn: 134272
This commit is contained in:
parent
774506918c
commit
e9b5c85041
|
@ -591,10 +591,11 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
|
|||
/// \param D the declarator containing the declaration specifier.
|
||||
/// \returns The type described by the declaration specifiers. This function
|
||||
/// never returns null.
|
||||
static QualType ConvertDeclSpecToType(Sema &S, TypeProcessingState &state) {
|
||||
static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
|
||||
// FIXME: Should move the logic from DeclSpec::Finish to here for validity
|
||||
// checking.
|
||||
|
||||
Sema &S = state.getSema();
|
||||
Declarator &declarator = state.getDeclarator();
|
||||
const DeclSpec &DS = declarator.getDeclSpec();
|
||||
SourceLocation DeclLoc = declarator.getIdentifierLoc();
|
||||
|
@ -1712,40 +1713,22 @@ static void DiagnoseIgnoredQualifiers(unsigned Quals,
|
|||
<< QualStr << NumQuals << ConstFixIt << VolatileFixIt << RestrictFixIt;
|
||||
}
|
||||
|
||||
/// GetTypeForDeclarator - Convert the type for the specified
|
||||
/// declarator to Type instances.
|
||||
///
|
||||
/// If OwnedDecl is non-NULL, and this declarator's decl-specifier-seq
|
||||
/// owns the declaration of a type (e.g., the definition of a struct
|
||||
/// type), then *OwnedDecl will receive the owned declaration.
|
||||
///
|
||||
/// The result of this call will never be null, but the associated
|
||||
/// type may be a null type if there's an unrecoverable error.
|
||||
TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
||||
// Determine the type of the declarator. Not all forms of declarator
|
||||
// have a type.
|
||||
static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
|
||||
TypeSourceInfo *&ReturnTypeInfo) {
|
||||
Sema &SemaRef = state.getSema();
|
||||
Declarator &D = state.getDeclarator();
|
||||
QualType T;
|
||||
TypeSourceInfo *ReturnTypeInfo = 0;
|
||||
ReturnTypeInfo = 0;
|
||||
|
||||
// The TagDecl owned by the DeclSpec.
|
||||
TagDecl *OwnedTagDecl = 0;
|
||||
|
||||
TypeProcessingState state(*this, D);
|
||||
|
||||
// In C++0x, deallocation functions (normal and array operator delete)
|
||||
// are implicitly noexcept.
|
||||
bool ImplicitlyNoexcept = false;
|
||||
|
||||
switch (D.getName().getKind()) {
|
||||
case UnqualifiedId::IK_OperatorFunctionId:
|
||||
if (getLangOptions().CPlusPlus0x) {
|
||||
OverloadedOperatorKind OO = D.getName().OperatorFunctionId.Operator;
|
||||
if (OO == OO_Delete || OO == OO_Array_Delete)
|
||||
ImplicitlyNoexcept = true;
|
||||
}
|
||||
// Intentional fall-through.
|
||||
case UnqualifiedId::IK_Identifier:
|
||||
case UnqualifiedId::IK_LiteralOperatorId:
|
||||
case UnqualifiedId::IK_TemplateId:
|
||||
T = ConvertDeclSpecToType(*this, state);
|
||||
T = ConvertDeclSpecToType(state);
|
||||
|
||||
if (!D.isInvalidType() && D.getDeclSpec().isTypeSpecOwned()) {
|
||||
OwnedTagDecl = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
|
||||
|
@ -1759,29 +1742,26 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
case UnqualifiedId::IK_DestructorName:
|
||||
// Constructors and destructors don't have return types. Use
|
||||
// "void" instead.
|
||||
T = Context.VoidTy;
|
||||
T = SemaRef.Context.VoidTy;
|
||||
break;
|
||||
|
||||
case UnqualifiedId::IK_ConversionFunctionId:
|
||||
// The result type of a conversion function is the type that it
|
||||
// converts to.
|
||||
T = GetTypeFromParser(D.getName().ConversionFunctionId,
|
||||
&ReturnTypeInfo);
|
||||
T = SemaRef.GetTypeFromParser(D.getName().ConversionFunctionId,
|
||||
&ReturnTypeInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
if (D.getAttributes())
|
||||
distributeTypeAttrsFromDeclarator(state, T);
|
||||
|
||||
if (D.isPrototypeContext() && getLangOptions().ObjCAutoRefCount)
|
||||
inferARCWriteback(state, T);
|
||||
|
||||
// C++0x [dcl.spec.auto]p5: reject 'auto' if it is not in an allowed context.
|
||||
// In C++0x, a function declarator using 'auto' must have a trailing return
|
||||
// type (this is checked later) and we can skip this. In other languages
|
||||
// using auto, we need to check regardless.
|
||||
if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto &&
|
||||
(!getLangOptions().CPlusPlus0x || !D.isFunctionDeclarator())) {
|
||||
(!SemaRef.getLangOptions().CPlusPlus0x || !D.isFunctionDeclarator())) {
|
||||
int Error = -1;
|
||||
|
||||
switch (D.getContext()) {
|
||||
|
@ -1795,7 +1775,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
case Declarator::MemberContext:
|
||||
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)
|
||||
break;
|
||||
switch (cast<TagDecl>(CurContext)->getTagKind()) {
|
||||
switch (cast<TagDecl>(SemaRef.CurContext)->getTagKind()) {
|
||||
case TTK_Enum: assert(0 && "unhandled tag kind"); break;
|
||||
case TTK_Struct: Error = 1; /* Struct member */ break;
|
||||
case TTK_Union: Error = 2; /* Union member */ break;
|
||||
|
@ -1841,7 +1821,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
// contains a trailing return type. That is only legal at the outermost
|
||||
// level. Check all declarator chunks (outermost first) anyway, to give
|
||||
// better diagnostics.
|
||||
if (getLangOptions().CPlusPlus0x && Error != -1) {
|
||||
if (SemaRef.getLangOptions().CPlusPlus0x && Error != -1) {
|
||||
for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
|
||||
unsigned chunkIndex = e - i - 1;
|
||||
state.setCurrentChunkIndex(chunkIndex);
|
||||
|
@ -1857,15 +1837,86 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
}
|
||||
|
||||
if (Error != -1) {
|
||||
Diag(D.getDeclSpec().getTypeSpecTypeLoc(), diag::err_auto_not_allowed)
|
||||
SemaRef.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
|
||||
diag::err_auto_not_allowed)
|
||||
<< Error;
|
||||
T = Context.IntTy;
|
||||
T = SemaRef.Context.IntTy;
|
||||
D.setInvalidType(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (T.isNull())
|
||||
return Context.getNullTypeSourceInfo();
|
||||
|
||||
if (SemaRef.getLangOptions().CPlusPlus &&
|
||||
OwnedTagDecl && OwnedTagDecl->isDefinition()) {
|
||||
// Check the contexts where C++ forbids the declaration of a new class
|
||||
// or enumeration in a type-specifier-seq.
|
||||
switch (D.getContext()) {
|
||||
case Declarator::FileContext:
|
||||
case Declarator::MemberContext:
|
||||
case Declarator::BlockContext:
|
||||
case Declarator::ForContext:
|
||||
case Declarator::BlockLiteralContext:
|
||||
// C++0x [dcl.type]p3:
|
||||
// A type-specifier-seq shall not define a class or enumeration unless
|
||||
// it appears in the type-id of an alias-declaration (7.1.3) that is not
|
||||
// the declaration of a template-declaration.
|
||||
case Declarator::AliasDeclContext:
|
||||
break;
|
||||
case Declarator::AliasTemplateContext:
|
||||
SemaRef.Diag(OwnedTagDecl->getLocation(),
|
||||
diag::err_type_defined_in_alias_template)
|
||||
<< SemaRef.Context.getTypeDeclType(OwnedTagDecl);
|
||||
break;
|
||||
case Declarator::TypeNameContext:
|
||||
case Declarator::TemplateParamContext:
|
||||
case Declarator::CXXNewContext:
|
||||
case Declarator::CXXCatchContext:
|
||||
case Declarator::ObjCCatchContext:
|
||||
case Declarator::TemplateTypeArgContext:
|
||||
SemaRef.Diag(OwnedTagDecl->getLocation(),
|
||||
diag::err_type_defined_in_type_specifier)
|
||||
<< SemaRef.Context.getTypeDeclType(OwnedTagDecl);
|
||||
break;
|
||||
case Declarator::PrototypeContext:
|
||||
case Declarator::ObjCPrototypeContext:
|
||||
case Declarator::KNRTypeListContext:
|
||||
// C++ [dcl.fct]p6:
|
||||
// Types shall not be defined in return or parameter types.
|
||||
SemaRef.Diag(OwnedTagDecl->getLocation(),
|
||||
diag::err_type_defined_in_param_type)
|
||||
<< SemaRef.Context.getTypeDeclType(OwnedTagDecl);
|
||||
break;
|
||||
case Declarator::ConditionContext:
|
||||
// C++ 6.4p2:
|
||||
// The type-specifier-seq shall not contain typedef and shall not declare
|
||||
// a new class or enumeration.
|
||||
SemaRef.Diag(OwnedTagDecl->getLocation(),
|
||||
diag::err_type_defined_in_condition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return T;
|
||||
}
|
||||
|
||||
static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
||||
QualType declSpecType,
|
||||
TypeSourceInfo *TInfo) {
|
||||
|
||||
QualType T = declSpecType;
|
||||
Declarator &D = state.getDeclarator();
|
||||
Sema &S = state.getSema();
|
||||
ASTContext &Context = S.Context;
|
||||
const LangOptions &LangOpts = S.getLangOptions();
|
||||
|
||||
bool ImplicitlyNoexcept = false;
|
||||
if (D.getName().getKind() == UnqualifiedId::IK_OperatorFunctionId &&
|
||||
LangOpts.CPlusPlus0x) {
|
||||
OverloadedOperatorKind OO = D.getName().OperatorFunctionId.Operator;
|
||||
/// In C++0x, deallocation functions (normal and array operator delete)
|
||||
/// are implicitly noexcept.
|
||||
if (OO == OO_Delete || OO == OO_Array_Delete)
|
||||
ImplicitlyNoexcept = true;
|
||||
}
|
||||
|
||||
// The name we're declaring, if any.
|
||||
DeclarationName Name;
|
||||
|
@ -1888,56 +1939,56 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
switch (DeclType.Kind) {
|
||||
default: assert(0 && "Unknown decltype!");
|
||||
case DeclaratorChunk::Paren:
|
||||
T = BuildParenType(T);
|
||||
T = S.BuildParenType(T);
|
||||
break;
|
||||
case DeclaratorChunk::BlockPointer:
|
||||
// If blocks are disabled, emit an error.
|
||||
if (!LangOpts.Blocks)
|
||||
Diag(DeclType.Loc, diag::err_blocks_disable);
|
||||
S.Diag(DeclType.Loc, diag::err_blocks_disable);
|
||||
|
||||
T = BuildBlockPointerType(T, D.getIdentifierLoc(), Name);
|
||||
T = S.BuildBlockPointerType(T, D.getIdentifierLoc(), Name);
|
||||
if (DeclType.Cls.TypeQuals)
|
||||
T = BuildQualifiedType(T, DeclType.Loc, DeclType.Cls.TypeQuals);
|
||||
T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Cls.TypeQuals);
|
||||
break;
|
||||
case DeclaratorChunk::Pointer:
|
||||
// Verify that we're not building a pointer to pointer to function with
|
||||
// exception specification.
|
||||
if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) {
|
||||
Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
|
||||
if (LangOpts.CPlusPlus && S.CheckDistantExceptionSpec(T)) {
|
||||
S.Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
|
||||
D.setInvalidType(true);
|
||||
// Build the type anyway.
|
||||
}
|
||||
if (getLangOptions().ObjC1 && T->getAs<ObjCObjectType>()) {
|
||||
if (LangOpts.ObjC1 && T->getAs<ObjCObjectType>()) {
|
||||
T = Context.getObjCObjectPointerType(T);
|
||||
if (DeclType.Ptr.TypeQuals)
|
||||
T = BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals);
|
||||
T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals);
|
||||
break;
|
||||
}
|
||||
T = BuildPointerType(T, DeclType.Loc, Name);
|
||||
T = S.BuildPointerType(T, DeclType.Loc, Name);
|
||||
if (DeclType.Ptr.TypeQuals)
|
||||
T = BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals);
|
||||
T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals);
|
||||
|
||||
break;
|
||||
case DeclaratorChunk::Reference: {
|
||||
// Verify that we're not building a reference to pointer to function with
|
||||
// exception specification.
|
||||
if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) {
|
||||
Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
|
||||
if (LangOpts.CPlusPlus && S.CheckDistantExceptionSpec(T)) {
|
||||
S.Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
|
||||
D.setInvalidType(true);
|
||||
// Build the type anyway.
|
||||
}
|
||||
T = BuildReferenceType(T, DeclType.Ref.LValueRef, DeclType.Loc, Name);
|
||||
T = S.BuildReferenceType(T, DeclType.Ref.LValueRef, DeclType.Loc, Name);
|
||||
|
||||
Qualifiers Quals;
|
||||
if (DeclType.Ref.HasRestrict)
|
||||
T = BuildQualifiedType(T, DeclType.Loc, Qualifiers::Restrict);
|
||||
T = S.BuildQualifiedType(T, DeclType.Loc, Qualifiers::Restrict);
|
||||
break;
|
||||
}
|
||||
case DeclaratorChunk::Array: {
|
||||
// Verify that we're not building an array of pointers to function with
|
||||
// exception specification.
|
||||
if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) {
|
||||
Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
|
||||
if (LangOpts.CPlusPlus && S.CheckDistantExceptionSpec(T)) {
|
||||
S.Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
|
||||
D.setInvalidType(true);
|
||||
// Build the type anyway.
|
||||
}
|
||||
|
@ -1954,13 +2005,13 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
// FIXME: This check isn't quite right: it allows star in prototypes
|
||||
// for function definitions, and disallows some edge cases detailed
|
||||
// in http://gcc.gnu.org/ml/gcc-patches/2009-02/msg00133.html
|
||||
Diag(DeclType.Loc, diag::err_array_star_outside_prototype);
|
||||
S.Diag(DeclType.Loc, diag::err_array_star_outside_prototype);
|
||||
ASM = ArrayType::Normal;
|
||||
D.setInvalidType(true);
|
||||
}
|
||||
T = BuildArrayType(T, ASM, ArraySize,
|
||||
Qualifiers::fromCVRMask(ATI.TypeQuals),
|
||||
SourceRange(DeclType.Loc, DeclType.EndLoc), Name);
|
||||
T = S.BuildArrayType(T, ASM, ArraySize,
|
||||
Qualifiers::fromCVRMask(ATI.TypeQuals),
|
||||
SourceRange(DeclType.Loc, DeclType.EndLoc), Name);
|
||||
break;
|
||||
}
|
||||
case DeclaratorChunk::Function: {
|
||||
|
@ -1976,27 +2027,27 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
// and not, for instance, a pointer to a function.
|
||||
if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto &&
|
||||
!FTI.TrailingReturnType && chunkIndex == 0) {
|
||||
Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
|
||||
S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
|
||||
diag::err_auto_missing_trailing_return);
|
||||
T = Context.IntTy;
|
||||
D.setInvalidType(true);
|
||||
} else if (FTI.TrailingReturnType) {
|
||||
// T must be exactly 'auto' at this point. See CWG issue 681.
|
||||
if (isa<ParenType>(T)) {
|
||||
Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
|
||||
S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
|
||||
diag::err_trailing_return_in_parens)
|
||||
<< T << D.getDeclSpec().getSourceRange();
|
||||
D.setInvalidType(true);
|
||||
} else if (T.hasQualifiers() || !isa<AutoType>(T)) {
|
||||
Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
|
||||
S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
|
||||
diag::err_trailing_return_without_auto)
|
||||
<< T << D.getDeclSpec().getSourceRange();
|
||||
D.setInvalidType(true);
|
||||
}
|
||||
|
||||
T = GetTypeFromParser(
|
||||
T = S.GetTypeFromParser(
|
||||
ParsedType::getFromOpaquePtr(FTI.TrailingReturnType),
|
||||
&ReturnTypeInfo);
|
||||
&TInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2010,7 +2061,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
if (chunkIndex == 0 &&
|
||||
D.getContext() == Declarator::BlockLiteralContext)
|
||||
diagID = diag::err_block_returning_array_function;
|
||||
Diag(DeclType.Loc, diagID) << T->isFunctionType() << T;
|
||||
S.Diag(DeclType.Loc, diagID) << T->isFunctionType() << T;
|
||||
T = Context.IntTy;
|
||||
D.setInvalidType(true);
|
||||
}
|
||||
|
@ -2019,7 +2070,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
// class type in C++.
|
||||
if (isa<PointerType>(T) && T.getLocalCVRQualifiers() &&
|
||||
(D.getName().getKind() != UnqualifiedId::IK_ConversionFunctionId) &&
|
||||
(!getLangOptions().CPlusPlus || !T->isDependentType())) {
|
||||
(!LangOpts.CPlusPlus || !T->isDependentType())) {
|
||||
assert(chunkIndex + 1 < e && "No DeclaratorChunk for the return type?");
|
||||
DeclaratorChunk ReturnTypeChunk = D.getTypeObject(chunkIndex + 1);
|
||||
assert(ReturnTypeChunk.Kind == DeclaratorChunk::Pointer);
|
||||
|
@ -2030,43 +2081,43 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
SourceLocation::getFromRawEncoding(PTI.ConstQualLoc),
|
||||
SourceLocation::getFromRawEncoding(PTI.VolatileQualLoc),
|
||||
SourceLocation::getFromRawEncoding(PTI.RestrictQualLoc),
|
||||
*this);
|
||||
S);
|
||||
|
||||
} else if (T.getCVRQualifiers() && D.getDeclSpec().getTypeQualifiers() &&
|
||||
(!getLangOptions().CPlusPlus ||
|
||||
(!LangOpts.CPlusPlus ||
|
||||
(!T->isDependentType() && !T->isRecordType()))) {
|
||||
|
||||
DiagnoseIgnoredQualifiers(D.getDeclSpec().getTypeQualifiers(),
|
||||
D.getDeclSpec().getConstSpecLoc(),
|
||||
D.getDeclSpec().getVolatileSpecLoc(),
|
||||
D.getDeclSpec().getRestrictSpecLoc(),
|
||||
*this);
|
||||
S);
|
||||
}
|
||||
|
||||
if (getLangOptions().CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) {
|
||||
if (LangOpts.CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) {
|
||||
// C++ [dcl.fct]p6:
|
||||
// Types shall not be defined in return or parameter types.
|
||||
TagDecl *Tag = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
|
||||
if (Tag->isDefinition())
|
||||
Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
|
||||
S.Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
|
||||
<< Context.getTypeDeclType(Tag);
|
||||
}
|
||||
|
||||
// Exception specs are not allowed in typedefs. Complain, but add it
|
||||
// anyway.
|
||||
if (IsTypedefName && FTI.getExceptionSpecType())
|
||||
Diag(FTI.getExceptionSpecLoc(), diag::err_exception_spec_in_typedef)
|
||||
S.Diag(FTI.getExceptionSpecLoc(), diag::err_exception_spec_in_typedef)
|
||||
<< (D.getContext() == Declarator::AliasDeclContext ||
|
||||
D.getContext() == Declarator::AliasTemplateContext);
|
||||
|
||||
if (!FTI.NumArgs && !FTI.isVariadic && !getLangOptions().CPlusPlus) {
|
||||
if (!FTI.NumArgs && !FTI.isVariadic && !LangOpts.CPlusPlus) {
|
||||
// Simple void foo(), where the incoming T is the result type.
|
||||
T = Context.getFunctionNoProtoType(T);
|
||||
} else {
|
||||
// We allow a zero-parameter variadic function in C if the
|
||||
// function is marked with the "overloadable" attribute. Scan
|
||||
// for this attribute now.
|
||||
if (!FTI.NumArgs && FTI.isVariadic && !getLangOptions().CPlusPlus) {
|
||||
if (!FTI.NumArgs && FTI.isVariadic && !LangOpts.CPlusPlus) {
|
||||
bool Overloadable = false;
|
||||
for (const AttributeList *Attrs = D.getAttributes();
|
||||
Attrs; Attrs = Attrs->getNext()) {
|
||||
|
@ -2077,13 +2128,13 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
}
|
||||
|
||||
if (!Overloadable)
|
||||
Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg);
|
||||
S.Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg);
|
||||
}
|
||||
|
||||
if (FTI.NumArgs && FTI.ArgInfo[0].Param == 0) {
|
||||
// C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function
|
||||
// definition.
|
||||
Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
|
||||
S.Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
|
||||
D.setInvalidType(true);
|
||||
break;
|
||||
}
|
||||
|
@ -2110,7 +2161,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
assert(!ArgTy.isNull() && "Couldn't parse type?");
|
||||
|
||||
// Adjust the parameter type.
|
||||
assert((ArgTy == adjustParameterType(ArgTy)) && "Unadjusted type?");
|
||||
assert((ArgTy == S.adjustParameterType(ArgTy)) && "Unadjusted type?");
|
||||
|
||||
// Look for 'void'. void is allowed only as a single argument to a
|
||||
// function with no other parameters (C99 6.7.5.3p10). We record
|
||||
|
@ -2120,19 +2171,19 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
// is an incomplete type (C99 6.2.5p19) and function decls cannot
|
||||
// have arguments of incomplete type.
|
||||
if (FTI.NumArgs != 1 || FTI.isVariadic) {
|
||||
Diag(DeclType.Loc, diag::err_void_only_param);
|
||||
S.Diag(DeclType.Loc, diag::err_void_only_param);
|
||||
ArgTy = Context.IntTy;
|
||||
Param->setType(ArgTy);
|
||||
} else if (FTI.ArgInfo[i].Ident) {
|
||||
// Reject, but continue to parse 'int(void abc)'.
|
||||
Diag(FTI.ArgInfo[i].IdentLoc,
|
||||
S.Diag(FTI.ArgInfo[i].IdentLoc,
|
||||
diag::err_param_with_void_type);
|
||||
ArgTy = Context.IntTy;
|
||||
Param->setType(ArgTy);
|
||||
} else {
|
||||
// Reject, but continue to parse 'float(const void)'.
|
||||
if (ArgTy.hasQualifiers())
|
||||
Diag(DeclType.Loc, diag::err_void_param_qualified);
|
||||
S.Diag(DeclType.Loc, diag::err_void_param_qualified);
|
||||
|
||||
// Do not add 'void' to the ArgTys list.
|
||||
break;
|
||||
|
@ -2149,7 +2200,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
}
|
||||
}
|
||||
|
||||
if (getLangOptions().ObjCAutoRefCount) {
|
||||
if (LangOpts.ObjCAutoRefCount) {
|
||||
bool Consumed = Param->hasAttr<NSConsumedAttr>();
|
||||
ConsumedArguments.push_back(Consumed);
|
||||
HasAnyConsumedArguments |= Consumed;
|
||||
|
@ -2167,10 +2218,10 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
Exceptions.reserve(FTI.NumExceptions);
|
||||
for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
|
||||
// FIXME: Preserve type source info.
|
||||
QualType ET = GetTypeFromParser(FTI.Exceptions[ei].Ty);
|
||||
QualType ET = S.GetTypeFromParser(FTI.Exceptions[ei].Ty);
|
||||
// Check that the type is valid for an exception spec, and
|
||||
// drop it if not.
|
||||
if (!CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range))
|
||||
if (!S.CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range))
|
||||
Exceptions.push_back(ET);
|
||||
}
|
||||
EPI.NumExceptions = Exceptions.size();
|
||||
|
@ -2187,7 +2238,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
if (!NoexceptExpr->isValueDependent() &&
|
||||
!NoexceptExpr->isIntegerConstantExpr(Dummy, Context, &ErrLoc,
|
||||
/*evaluated*/false))
|
||||
Diag(ErrLoc, diag::err_noexcept_needs_constant_expression)
|
||||
S.Diag(ErrLoc, diag::err_noexcept_needs_constant_expression)
|
||||
<< NoexceptExpr->getSourceRange();
|
||||
else
|
||||
EPI.NoexceptExpr = NoexceptExpr;
|
||||
|
@ -2210,8 +2261,8 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
if (SS.isInvalid()) {
|
||||
// Avoid emitting extra errors if we already errored on the scope.
|
||||
D.setInvalidType(true);
|
||||
} else if (isDependentScopeSpecifier(SS) ||
|
||||
dyn_cast_or_null<CXXRecordDecl>(computeDeclContext(SS))) {
|
||||
} else if (S.isDependentScopeSpecifier(SS) ||
|
||||
dyn_cast_or_null<CXXRecordDecl>(S.computeDeclContext(SS))) {
|
||||
NestedNameSpecifier *NNS
|
||||
= static_cast<NestedNameSpecifier*>(SS.getScopeRep());
|
||||
NestedNameSpecifier *NNSPrefix = NNS->getPrefix();
|
||||
|
@ -2240,7 +2291,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
Diag(DeclType.Mem.Scope().getBeginLoc(),
|
||||
S.Diag(DeclType.Mem.Scope().getBeginLoc(),
|
||||
diag::err_illegal_decl_mempointer_in_nonclass)
|
||||
<< (D.getIdentifier() ? D.getIdentifier()->getName() : "type name")
|
||||
<< DeclType.Mem.Scope().getRange();
|
||||
|
@ -2248,12 +2299,12 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
}
|
||||
|
||||
if (!ClsType.isNull())
|
||||
T = BuildMemberPointerType(T, ClsType, DeclType.Loc, D.getIdentifier());
|
||||
T = S.BuildMemberPointerType(T, ClsType, DeclType.Loc, D.getIdentifier());
|
||||
if (T.isNull()) {
|
||||
T = Context.IntTy;
|
||||
D.setInvalidType(true);
|
||||
} else if (DeclType.Mem.TypeQuals) {
|
||||
T = BuildQualifiedType(T, DeclType.Loc, DeclType.Mem.TypeQuals);
|
||||
T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Mem.TypeQuals);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2268,7 +2319,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
processTypeAttrs(state, T, false, attrs);
|
||||
}
|
||||
|
||||
if (getLangOptions().CPlusPlus && T->isFunctionType()) {
|
||||
if (LangOpts.CPlusPlus && T->isFunctionType()) {
|
||||
const FunctionProtoType *FnTy = T->getAs<FunctionProtoType>();
|
||||
assert(FnTy && "Why oh why is there not a FunctionProtoType here?");
|
||||
|
||||
|
@ -2285,7 +2336,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
FreeFunction = (D.getContext() != Declarator::MemberContext ||
|
||||
D.getDeclSpec().isFriendSpecified());
|
||||
} else {
|
||||
DeclContext *DC = computeDeclContext(D.getCXXScopeSpec());
|
||||
DeclContext *DC = S.computeDeclContext(D.getCXXScopeSpec());
|
||||
FreeFunction = (DC && !DC->isRecord());
|
||||
}
|
||||
|
||||
|
@ -2323,16 +2374,16 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
break;
|
||||
}
|
||||
|
||||
Diag(D.getIdentifierLoc(),
|
||||
S.Diag(D.getIdentifierLoc(),
|
||||
diag::ext_qualified_function_type_template_arg)
|
||||
<< Quals;
|
||||
} else {
|
||||
if (FnTy->getTypeQuals() != 0) {
|
||||
if (D.isFunctionDeclarator())
|
||||
Diag(D.getIdentifierLoc(),
|
||||
S.Diag(D.getIdentifierLoc(),
|
||||
diag::err_invalid_qualified_function_type);
|
||||
else
|
||||
Diag(D.getIdentifierLoc(),
|
||||
S.Diag(D.getIdentifierLoc(),
|
||||
diag::err_invalid_qualified_typedef_function_type_use)
|
||||
<< FreeFunction;
|
||||
}
|
||||
|
@ -2349,11 +2400,11 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
}
|
||||
}
|
||||
|
||||
Diag(Loc, diag::err_invalid_ref_qualifier_function_type)
|
||||
S.Diag(Loc, diag::err_invalid_ref_qualifier_function_type)
|
||||
<< (FnTy->getRefQualifier() == RQ_LValue)
|
||||
<< FixItHint::CreateRemoval(Loc);
|
||||
} else {
|
||||
Diag(D.getIdentifierLoc(),
|
||||
S.Diag(D.getIdentifierLoc(),
|
||||
diag::err_invalid_ref_qualifier_typedef_function_type_use)
|
||||
<< FreeFunction
|
||||
<< (FnTy->getRefQualifier() == RQ_LValue);
|
||||
|
@ -2406,7 +2457,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
// We represent function parameter packs as function parameters whose
|
||||
// type is a pack expansion.
|
||||
if (!T->containsUnexpandedParameterPack()) {
|
||||
Diag(D.getEllipsisLoc(),
|
||||
S.Diag(D.getEllipsisLoc(),
|
||||
diag::err_function_parameter_pack_without_parameter_packs)
|
||||
<< T << D.getSourceRange();
|
||||
D.setEllipsisLoc(SourceLocation());
|
||||
|
@ -2426,8 +2477,8 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
// it expands those parameter packs.
|
||||
if (T->containsUnexpandedParameterPack())
|
||||
T = Context.getPackExpansionType(T, llvm::Optional<unsigned>());
|
||||
else if (!getLangOptions().CPlusPlus0x)
|
||||
Diag(D.getEllipsisLoc(), diag::ext_variadic_templates);
|
||||
else if (!LangOpts.CPlusPlus0x)
|
||||
S.Diag(D.getEllipsisLoc(), diag::ext_variadic_templates);
|
||||
break;
|
||||
|
||||
case Declarator::FileContext:
|
||||
|
@ -2447,7 +2498,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
case Declarator::TemplateTypeArgContext:
|
||||
// FIXME: We may want to allow parameter packs in block-literal contexts
|
||||
// in the future.
|
||||
Diag(D.getEllipsisLoc(), diag::err_ellipsis_in_declarator_not_parameter);
|
||||
S.Diag(D.getEllipsisLoc(), diag::err_ellipsis_in_declarator_not_parameter);
|
||||
D.setEllipsisLoc(SourceLocation());
|
||||
break;
|
||||
}
|
||||
|
@ -2458,53 +2509,29 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
else if (D.isInvalidType())
|
||||
return Context.getTrivialTypeSourceInfo(T);
|
||||
|
||||
if (getLangOptions().CPlusPlus &&
|
||||
OwnedTagDecl && OwnedTagDecl->isDefinition()) {
|
||||
// Check the contexts where C++ forbids the declaration of a new class
|
||||
// or enumeration in a type-specifier-seq.
|
||||
switch (D.getContext()) {
|
||||
case Declarator::FileContext:
|
||||
case Declarator::MemberContext:
|
||||
case Declarator::BlockContext:
|
||||
case Declarator::ForContext:
|
||||
case Declarator::BlockLiteralContext:
|
||||
// C++0x [dcl.type]p3:
|
||||
// A type-specifier-seq shall not define a class or enumeration unless
|
||||
// it appears in the type-id of an alias-declaration (7.1.3) that is not
|
||||
// the declaration of a template-declaration.
|
||||
case Declarator::AliasDeclContext:
|
||||
break;
|
||||
case Declarator::AliasTemplateContext:
|
||||
Diag(OwnedTagDecl->getLocation(),diag::err_type_defined_in_alias_template)
|
||||
<< Context.getTypeDeclType(OwnedTagDecl);
|
||||
break;
|
||||
case Declarator::TypeNameContext:
|
||||
case Declarator::TemplateParamContext:
|
||||
case Declarator::CXXNewContext:
|
||||
case Declarator::CXXCatchContext:
|
||||
case Declarator::ObjCCatchContext:
|
||||
case Declarator::TemplateTypeArgContext:
|
||||
Diag(OwnedTagDecl->getLocation(),diag::err_type_defined_in_type_specifier)
|
||||
<< Context.getTypeDeclType(OwnedTagDecl);
|
||||
break;
|
||||
case Declarator::PrototypeContext:
|
||||
case Declarator::ObjCPrototypeContext:
|
||||
case Declarator::KNRTypeListContext:
|
||||
// C++ [dcl.fct]p6:
|
||||
// Types shall not be defined in return or parameter types.
|
||||
Diag(OwnedTagDecl->getLocation(), diag::err_type_defined_in_param_type)
|
||||
<< Context.getTypeDeclType(OwnedTagDecl);
|
||||
break;
|
||||
case Declarator::ConditionContext:
|
||||
// C++ 6.4p2:
|
||||
// The type-specifier-seq shall not contain typedef and shall not declare
|
||||
// a new class or enumeration.
|
||||
Diag(OwnedTagDecl->getLocation(), diag::err_type_defined_in_condition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return S.GetTypeSourceInfoForDeclarator(D, T, TInfo);
|
||||
}
|
||||
|
||||
/// GetTypeForDeclarator - Convert the type for the specified
|
||||
/// declarator to Type instances.
|
||||
///
|
||||
/// The result of this call will never be null, but the associated
|
||||
/// type may be a null type if there's an unrecoverable error.
|
||||
TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
||||
// Determine the type of the declarator. Not all forms of declarator
|
||||
// have a type.
|
||||
|
||||
TypeProcessingState state(*this, D);
|
||||
|
||||
TypeSourceInfo *ReturnTypeInfo = 0;
|
||||
QualType T = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo);
|
||||
if (T.isNull())
|
||||
return Context.getNullTypeSourceInfo();
|
||||
|
||||
if (D.isPrototypeContext() && getLangOptions().ObjCAutoRefCount)
|
||||
inferARCWriteback(state, T);
|
||||
|
||||
return GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo);
|
||||
return GetFullTypeForDeclarator(state, T, ReturnTypeInfo);
|
||||
}
|
||||
|
||||
/// Map an AttributedType::Kind to an AttributeList::Kind.
|
||||
|
|
Loading…
Reference in New Issue