[cfe-commits] r134272 - /cfe/trunk/lib/Sema/SemaType.cpp
Argyrios Kyrtzidis
akyrtzi at gmail.com
Fri Jul 1 15:22:42 PDT 2011
Author: akirtzidis
Date: Fri Jul 1 17:22:42 2011
New Revision: 134272
URL: http://llvm.org/viewvc/llvm-project?rev=134272&view=rev
Log:
Break Sema::GetTypeForDeclarator in 2 functions, one for DeclSpec processing and another for the rest.
No functionality change.
Modified:
cfe/trunk/lib/Sema/SemaType.cpp
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=134272&r1=134271&r2=134272&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Jul 1 17:22:42 2011
@@ -591,10 +591,11 @@
/// \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 @@
<< 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;
- TagDecl *OwnedTagDecl = 0;
+ ReturnTypeInfo = 0;
- TypeProcessingState state(*this, D);
-
- // In C++0x, deallocation functions (normal and array operator delete)
- // are implicitly noexcept.
- bool ImplicitlyNoexcept = false;
+ // The TagDecl owned by the DeclSpec.
+ TagDecl *OwnedTagDecl = 0;
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 @@
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 @@
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 @@
// 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 @@
}
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
// 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 @@
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 @@
}
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 @@
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 @@
// 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 @@
}
}
- if (getLangOptions().ObjCAutoRefCount) {
+ if (LangOpts.ObjCAutoRefCount) {
bool Consumed = Param->hasAttr<NSConsumedAttr>();
ConsumedArguments.push_back(Consumed);
HasAnyConsumedArguments |= Consumed;
@@ -2167,10 +2218,10 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
}
}
- 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 @@
// 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 @@
// 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 @@
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 @@
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.
More information about the cfe-commits
mailing list