diff options
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r-- | lib/Sema/SemaType.cpp | 372 |
1 files changed, 184 insertions, 188 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 35efa6113b64..a4fc98cd958e 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -383,8 +383,12 @@ static QualType ConvertDeclSpecToType(Sema &TheSema, } else if (DS.isTypeAltiVecVector()) { unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(Result)); assert(typeSize > 0 && "type size for vector must be greater than 0 bits"); - Result = Context.getVectorType(Result, 128/typeSize, true, - DS.isTypeAltiVecPixel()); + VectorType::AltiVecSpecific AltiVecSpec = VectorType::AltiVec; + if (DS.isTypeAltiVecPixel()) + AltiVecSpec = VectorType::Pixel; + else if (DS.isTypeAltiVecBool()) + AltiVecSpec = VectorType::Bool; + Result = Context.getVectorType(Result, 128/typeSize, AltiVecSpec); } assert(DS.getTypeSpecComplex() != DeclSpec::TSC_imaginary && @@ -472,12 +476,49 @@ static std::string getPrintableNameForEntity(DeclarationName Entity) { return "type name"; } +QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc, + Qualifiers Qs) { + // Enforce C99 6.7.3p2: "Types other than pointer types derived from + // object or incomplete types shall not be restrict-qualified." + if (Qs.hasRestrict()) { + unsigned DiagID = 0; + QualType ProblemTy; + + const Type *Ty = T->getCanonicalTypeInternal().getTypePtr(); + if (const ReferenceType *RTy = dyn_cast<ReferenceType>(Ty)) { + if (!RTy->getPointeeType()->isIncompleteOrObjectType()) { + DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee; + ProblemTy = T->getAs<ReferenceType>()->getPointeeType(); + } + } else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) { + if (!PTy->getPointeeType()->isIncompleteOrObjectType()) { + DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee; + ProblemTy = T->getAs<PointerType>()->getPointeeType(); + } + } else if (const MemberPointerType *PTy = dyn_cast<MemberPointerType>(Ty)) { + if (!PTy->getPointeeType()->isIncompleteOrObjectType()) { + DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee; + ProblemTy = T->getAs<PointerType>()->getPointeeType(); + } + } else if (!Ty->isDependentType()) { + // FIXME: this deserves a proper diagnostic + DiagID = diag::err_typecheck_invalid_restrict_invalid_pointee; + ProblemTy = T; + } + + if (DiagID) { + Diag(Loc, DiagID) << ProblemTy; + Qs.removeRestrict(); + } + } + + return Context.getQualifiedType(T, Qs); +} + /// \brief Build a pointer type. /// /// \param T The type to which we'll be building a pointer. /// -/// \param Quals The cvr-qualifiers to be applied to the pointer type. -/// /// \param Loc The location of the entity whose type involves this /// pointer type or, if there is no such entity, the location of the /// type that will have pointer type. @@ -487,7 +528,7 @@ static std::string getPrintableNameForEntity(DeclarationName Entity) { /// /// \returns A suitable pointer type, if there are no /// errors. Otherwise, returns a NULL type. -QualType Sema::BuildPointerType(QualType T, unsigned Quals, +QualType Sema::BuildPointerType(QualType T, SourceLocation Loc, DeclarationName Entity) { if (T->isReferenceType()) { // C++ 8.3.2p4: There shall be no ... pointers to references ... @@ -496,28 +537,16 @@ QualType Sema::BuildPointerType(QualType T, unsigned Quals, return QualType(); } - Qualifiers Qs = Qualifiers::fromCVRMask(Quals); - - // Enforce C99 6.7.3p2: "Types other than pointer types derived from - // object or incomplete types shall not be restrict-qualified." - if (Qs.hasRestrict() && !T->isIncompleteOrObjectType()) { - Diag(Loc, diag::err_typecheck_invalid_restrict_invalid_pointee) - << T; - Qs.removeRestrict(); - } - assert(!T->isObjCObjectType() && "Should build ObjCObjectPointerType"); // Build the pointer type. - return Context.getQualifiedType(Context.getPointerType(T), Qs); + return Context.getPointerType(T); } /// \brief Build a reference type. /// /// \param T The type to which we'll be building a reference. /// -/// \param CVR The cvr-qualifiers to be applied to the reference type. -/// /// \param Loc The location of the entity whose type involves this /// reference type or, if there is no such entity, the location of the /// type that will have reference type. @@ -528,10 +557,8 @@ QualType Sema::BuildPointerType(QualType T, unsigned Quals, /// \returns A suitable reference type, if there are no /// errors. Otherwise, returns a NULL type. QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue, - unsigned CVR, SourceLocation Loc, + SourceLocation Loc, DeclarationName Entity) { - Qualifiers Quals = Qualifiers::fromCVRMask(CVR); - bool LValueRef = SpelledAsLValue || T->getAs<LValueReferenceType>(); // C++0x [dcl.typedef]p9: If a typedef TD names a type that is a @@ -562,31 +589,10 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue, return QualType(); } - // Enforce C99 6.7.3p2: "Types other than pointer types derived from - // object or incomplete types shall not be restrict-qualified." - if (Quals.hasRestrict() && !T->isIncompleteOrObjectType()) { - Diag(Loc, diag::err_typecheck_invalid_restrict_invalid_pointee) - << T; - Quals.removeRestrict(); - } - - // C++ [dcl.ref]p1: - // [...] Cv-qualified references are ill-formed except when the - // cv-qualifiers are introduced through the use of a typedef - // (7.1.3) or of a template type argument (14.3), in which case - // the cv-qualifiers are ignored. - // - // We diagnose extraneous cv-qualifiers for the non-typedef, - // non-template type argument case within the parser. Here, we just - // ignore any extraneous cv-qualifiers. - Quals.removeConst(); - Quals.removeVolatile(); - // Handle restrict on references. if (LValueRef) - return Context.getQualifiedType( - Context.getLValueReferenceType(T, SpelledAsLValue), Quals); - return Context.getQualifiedType(Context.getRValueReferenceType(T), Quals); + return Context.getLValueReferenceType(T, SpelledAsLValue); + return Context.getRValueReferenceType(T); } /// \brief Build an array type. @@ -597,9 +603,6 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue, /// /// \param ArraySize Expression describing the size of the array. /// -/// \param Quals The cvr-qualifiers to be applied to the array's -/// element type. -/// /// \param Loc The location of the entity whose type involves this /// array type or, if there is no such entity, the location of the /// type that will have array type. @@ -815,7 +818,7 @@ QualType Sema::BuildFunctionType(QualType T, << T->isFunctionType() << T; return QualType(); } - + bool Invalid = false; for (unsigned Idx = 0; Idx < NumParamTypes; ++Idx) { QualType ParamType = adjustParameterType(ParamTypes[Idx]); @@ -846,10 +849,8 @@ QualType Sema::BuildFunctionType(QualType T, /// \returns a member pointer type, if successful, or a NULL type if there was /// an error. QualType Sema::BuildMemberPointerType(QualType T, QualType Class, - unsigned CVR, SourceLocation Loc, + SourceLocation Loc, DeclarationName Entity) { - Qualifiers Quals = Qualifiers::fromCVRMask(CVR); - // Verify that we're not building a pointer to pointer to function with // exception specification. if (CheckDistantExceptionSpec(T)) { @@ -863,7 +864,7 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, T = Context.getCanonicalType(T); } - // C++ 8.3.3p3: A pointer to member shall not pointer to ... a member + // C++ 8.3.3p3: A pointer to member shall not point to ... a member // with reference type, or "cv void." if (T->isReferenceType()) { Diag(Loc, diag::err_illegal_decl_mempointer_to_reference) @@ -877,24 +878,12 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, return QualType(); } - // Enforce C99 6.7.3p2: "Types other than pointer types derived from - // object or incomplete types shall not be restrict-qualified." - if (Quals.hasRestrict() && !T->isIncompleteOrObjectType()) { - Diag(Loc, diag::err_typecheck_invalid_restrict_invalid_pointee) - << T; - - // FIXME: If we're doing this as part of template instantiation, - // we should return immediately. - Quals.removeRestrict(); - } - if (!Class->isDependentType() && !Class->isRecordType()) { Diag(Loc, diag::err_mempointer_in_nonclass_type) << Class; return QualType(); } - return Context.getQualifiedType( - Context.getMemberPointerType(T, Class.getTypePtr()), Quals); + return Context.getMemberPointerType(T, Class.getTypePtr()); } /// \brief Build a block pointer type. @@ -912,7 +901,7 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, /// /// \returns A suitable block pointer type, if there are no /// errors. Otherwise, returns a NULL type. -QualType Sema::BuildBlockPointerType(QualType T, unsigned CVR, +QualType Sema::BuildBlockPointerType(QualType T, SourceLocation Loc, DeclarationName Entity) { if (!T->isFunctionType()) { @@ -920,8 +909,7 @@ QualType Sema::BuildBlockPointerType(QualType T, unsigned CVR, return QualType(); } - Qualifiers Quals = Qualifiers::fromCVRMask(CVR); - return Context.getQualifiedType(Context.getBlockPointerType(T), Quals); + return Context.getBlockPointerType(T); } QualType Sema::GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo) { @@ -947,9 +935,11 @@ QualType Sema::GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo) { /// 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. -QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, - TypeSourceInfo **TInfo, - TagDecl **OwnedDecl) { +/// +/// 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, + TagDecl **OwnedDecl) { // Determine the type of the declarator. Not all forms of declarator // have a type. QualType T; @@ -980,22 +970,18 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, // Constructors and destructors don't have return types. Use // "void" instead. T = Context.VoidTy; - - if (TInfo) - ReturnTypeInfo = Context.getTrivialTypeSourceInfo(T, - D.getName().StartLocation); break; case UnqualifiedId::IK_ConversionFunctionId: // The result type of a conversion function is the type that it // converts to. T = GetTypeFromParser(D.getName().ConversionFunctionId, - TInfo? &ReturnTypeInfo : 0); + &ReturnTypeInfo); break; } if (T.isNull()) - return T; + return Context.getNullTypeSourceInfo(); if (T == Context.UndeducedAutoTy) { int Error = -1; @@ -1059,8 +1045,9 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, if (!LangOpts.Blocks) Diag(DeclType.Loc, diag::err_blocks_disable); - T = BuildBlockPointerType(T, DeclType.Cls.TypeQuals, D.getIdentifierLoc(), - Name); + T = BuildBlockPointerType(T, D.getIdentifierLoc(), Name); + if (DeclType.Cls.TypeQuals) + T = BuildQualifiedType(T, DeclType.Loc, DeclType.Cls.TypeQuals); break; case DeclaratorChunk::Pointer: // Verify that we're not building a pointer to pointer to function with @@ -1072,15 +1059,15 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, } if (getLangOptions().ObjC1 && T->getAs<ObjCObjectType>()) { T = Context.getObjCObjectPointerType(T); - T = Context.getCVRQualifiedType(T, DeclType.Ptr.TypeQuals); + if (DeclType.Ptr.TypeQuals) + T = BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals); break; } - T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name); + T = BuildPointerType(T, DeclType.Loc, Name); + if (DeclType.Ptr.TypeQuals) + T = BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals); break; case DeclaratorChunk::Reference: { - Qualifiers Quals; - if (DeclType.Ref.HasRestrict) Quals.addRestrict(); - // Verify that we're not building a reference to pointer to function with // exception specification. if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { @@ -1088,8 +1075,11 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, D.setInvalidType(true); // Build the type anyway. } - T = BuildReferenceType(T, DeclType.Ref.LValueRef, Quals, - DeclType.Loc, Name); + T = BuildReferenceType(T, DeclType.Ref.LValueRef, DeclType.Loc, Name); + + Qualifiers Quals; + if (DeclType.Ref.HasRestrict) + T = BuildQualifiedType(T, DeclType.Loc, Qualifiers::Restrict); break; } case DeclaratorChunk::Array: { @@ -1139,6 +1129,48 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, D.setInvalidType(true); } + // cv-qualifiers on return types are pointless except when the type is a + // class type in C++. + if (T.getCVRQualifiers() && D.getDeclSpec().getTypeQualifiers() && + (!getLangOptions().CPlusPlus || + (!T->isDependentType() && !T->isRecordType()))) { + unsigned Quals = D.getDeclSpec().getTypeQualifiers(); + std::string QualStr; + unsigned NumQuals = 0; + SourceLocation Loc; + if (Quals & Qualifiers::Const) { + Loc = D.getDeclSpec().getConstSpecLoc(); + ++NumQuals; + QualStr = "const"; + } + if (Quals & Qualifiers::Volatile) { + if (NumQuals == 0) { + Loc = D.getDeclSpec().getVolatileSpecLoc(); + QualStr = "volatile"; + } else + QualStr += " volatile"; + ++NumQuals; + } + if (Quals & Qualifiers::Restrict) { + if (NumQuals == 0) { + Loc = D.getDeclSpec().getRestrictSpecLoc(); + QualStr = "restrict"; + } else + QualStr += " restrict"; + ++NumQuals; + } + assert(NumQuals > 0 && "No known qualifiers?"); + + SemaDiagnosticBuilder DB = Diag(Loc, diag::warn_qual_return_type); + DB << QualStr << NumQuals; + if (Quals & Qualifiers::Const) + DB << FixItHint::CreateRemoval(D.getDeclSpec().getConstSpecLoc()); + if (Quals & Qualifiers::Volatile) + DB << FixItHint::CreateRemoval(D.getDeclSpec().getVolatileSpecLoc()); + if (Quals & Qualifiers::Restrict) + DB << FixItHint::CreateRemoval(D.getDeclSpec().getRestrictSpecLoc()); + } + if (getLangOptions().CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) { // C++ [dcl.fct]p6: // Types shall not be defined in return or parameter types. @@ -1154,29 +1186,14 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) Diag(FTI.getThrowLoc(), diag::err_exception_spec_in_typedef); - if (FTI.NumArgs == 0) { - if (getLangOptions().CPlusPlus) { - // C++ 8.3.5p2: If the parameter-declaration-clause is empty, the - // function takes no arguments. - llvm::SmallVector<QualType, 4> Exceptions; - 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); - // Check that the type is valid for an exception spec, and drop it - // if not. - if (!CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range)) - Exceptions.push_back(ET); - } - T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, FTI.TypeQuals, - FTI.hasExceptionSpec, - FTI.hasAnyExceptionSpec, - Exceptions.size(), Exceptions.data(), - FunctionType::ExtInfo()); - } else if (FTI.isVariadic) { - // 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) { + // 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) { bool Overloadable = false; for (const AttributeList *Attrs = D.getAttributes(); Attrs; Attrs = Attrs->getNext()) { @@ -1188,21 +1205,20 @@ 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, - FunctionType::ExtInfo()); - } else { - // Simple void foo(), where the incoming T is the result type. - T = Context.getFunctionNoProtoType(T); } - } else if (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); - D.setInvalidType(true); - } else { + + 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); + D.setInvalidType(true); + break; + } + // Otherwise, we have a function with an argument list that is // potentially variadic. llvm::SmallVector<QualType, 16> ArgTys; + ArgTys.reserve(FTI.NumArgs); for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) { ParmVarDecl *Param = @@ -1278,13 +1294,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, break; } case DeclaratorChunk::MemberPointer: - // 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); - D.setInvalidType(true); - // Build the type anyway. - } // The scope spec must refer to a class, or be dependent. QualType ClsType; if (DeclType.Mem.Scope().isInvalid()) { @@ -1323,11 +1332,12 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, } if (!ClsType.isNull()) - T = BuildMemberPointerType(T, ClsType, DeclType.Mem.TypeQuals, - DeclType.Loc, D.getIdentifier()); + T = 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); } break; } @@ -1352,18 +1362,19 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, // for a nonstatic member function, the function type to which a pointer // to member refers, or the top-level function type of a function typedef // declaration. + bool FreeFunction = (D.getContext() != Declarator::MemberContext && + (!D.getCXXScopeSpec().isSet() || + !computeDeclContext(D.getCXXScopeSpec(), /*FIXME:*/true)->isRecord())); if (FnTy->getTypeQuals() != 0 && D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef && - ((D.getContext() != Declarator::MemberContext && - (!D.getCXXScopeSpec().isSet() || - !computeDeclContext(D.getCXXScopeSpec(), /*FIXME:*/true) - ->isRecord())) || + (FreeFunction || D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)) { if (D.isFunctionDeclarator()) Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_function_type); else Diag(D.getIdentifierLoc(), - diag::err_invalid_qualified_typedef_function_type_use); + diag::err_invalid_qualified_typedef_function_type_use) + << FreeFunction; // Strip the cv-quals from the type. T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(), @@ -1372,6 +1383,11 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, } } + // If there's a constexpr specifier, treat it as a top-level const. + if (D.getDeclSpec().isConstexprSpecified()) { + T.addConst(); + } + // Process any function attributes we might have delayed from the // declaration-specifiers. ProcessDelayedFnAttrs(*this, T, FnAttrsFromDeclSpec); @@ -1386,14 +1402,11 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, DiagnoseDelayedFnAttrs(*this, FnAttrsFromPreviousChunk); - if (TInfo) { - if (D.isInvalidType()) - *TInfo = 0; - else - *TInfo = GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo); - } - - return T; + if (T.isNull()) + return Context.getNullTypeSourceInfo(); + else if (D.isInvalidType()) + return Context.getTrivialTypeSourceInfo(T); + return GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo); } namespace { @@ -1527,6 +1540,28 @@ namespace { // FIXME: load appropriate source location. TL.setNameLoc(DS.getTypeSpecTypeLoc()); } + void VisitDependentTemplateSpecializationTypeLoc( + DependentTemplateSpecializationTypeLoc TL) { + ElaboratedTypeKeyword Keyword + = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType()); + if (Keyword == ETK_Typename) { + TypeSourceInfo *TInfo = 0; + Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo); + if (TInfo) { + TL.copy(cast<DependentTemplateSpecializationTypeLoc>( + TInfo->getTypeLoc())); + return; + } + } + TL.initializeLocal(SourceLocation()); + TL.setKeywordLoc(Keyword != ETK_None + ? DS.getTypeSpecTypeLoc() + : SourceLocation()); + const CXXScopeSpec& SS = DS.getTypeSpecScope(); + TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange()); + // FIXME: load appropriate source location. + TL.setNameLoc(DS.getTypeSpecTypeLoc()); + } void VisitTypeLoc(TypeLoc TL) { // FIXME: add other typespec types and change this to an assert. @@ -1651,53 +1686,14 @@ void LocInfoType::getAsStringInternal(std::string &Str, " GetTypeFromParser"); } -/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types that -/// may be similar (C++ 4.4), replaces T1 and T2 with the type that -/// they point to and return true. If T1 and T2 aren't pointer types -/// or pointer-to-member types, or if they are not similar at this -/// level, returns false and leaves T1 and T2 unchanged. Top-level -/// qualifiers on T1 and T2 are ignored. This function will typically -/// be called in a loop that successively "unwraps" pointer and -/// pointer-to-member types to compare them at each level. -bool Sema::UnwrapSimilarPointerTypes(QualType& T1, QualType& T2) { - const PointerType *T1PtrType = T1->getAs<PointerType>(), - *T2PtrType = T2->getAs<PointerType>(); - if (T1PtrType && T2PtrType) { - T1 = T1PtrType->getPointeeType(); - T2 = T2PtrType->getPointeeType(); - return true; - } - - const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(), - *T2MPType = T2->getAs<MemberPointerType>(); - if (T1MPType && T2MPType && - Context.getCanonicalType(T1MPType->getClass()) == - Context.getCanonicalType(T2MPType->getClass())) { - T1 = T1MPType->getPointeeType(); - T2 = T2MPType->getPointeeType(); - return true; - } - - if (getLangOptions().ObjC1) { - const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(), - *T2OPType = T2->getAs<ObjCObjectPointerType>(); - if (T1OPType && T2OPType) { - T1 = T1OPType->getPointeeType(); - T2 = T2OPType->getPointeeType(); - return true; - } - } - return false; -} - Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) { // C99 6.7.6: Type names have no identifier. This is already validated by // the parser. assert(D.getIdentifier() == 0 && "Type name should have no identifier!"); - TypeSourceInfo *TInfo = 0; TagDecl *OwnedTag = 0; - QualType T = GetTypeForDeclarator(D, S, &TInfo, &OwnedTag); + TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S, &OwnedTag); + QualType T = TInfo->getType(); if (D.isInvalidType()) return true; @@ -1714,9 +1710,7 @@ Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) { << Context.getTypeDeclType(OwnedTag); } - if (TInfo) - T = CreateLocInfoType(T, TInfo); - + T = CreateLocInfoType(T, TInfo); return T.getAsOpaquePtr(); } @@ -1934,7 +1928,8 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) { /// The raw attribute should contain precisely 1 argument, the vector size for /// the variable, measured in bytes. If curType and rawAttr are well formed, /// this routine will return a new vector type. -static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, Sema &S) { +static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, + Sema &S) { // Check the attribute arugments. if (Attr.getNumArgs() != 1) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; @@ -1977,7 +1972,8 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, S // Success! Instantiate the vector type, the number of elements is > 0, and // not required to be a power of 2, unlike GCC. - CurType = S.Context.getVectorType(CurType, vectorSize/typeSize, false, false); + CurType = S.Context.getVectorType(CurType, vectorSize/typeSize, + VectorType::NotAltiVec); } void ProcessTypeAttributeList(Sema &S, QualType &Result, |