diff options
author | Abramo Bagnara <abramo.bagnara@gmail.com> | 2010-05-11 21:36:43 +0000 |
---|---|---|
committer | Abramo Bagnara <abramo.bagnara@gmail.com> | 2010-05-11 21:36:43 +0000 |
commit | 465d41b92b2c862f3062c412a0538db65c6a2661 (patch) | |
tree | 0743a1451f3715b8acabca167d0a0bcc357550bd /lib/Sema | |
parent | 380c2139959d8608782292984b457640a143a70d (diff) |
Merged Elaborated and QualifiedName types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103517 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 39 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 78 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 26 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 41 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 97 |
12 files changed, 135 insertions, 173 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index a432978604..0c713e7c9a 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -40,11 +40,11 @@ BlockScopeInfo::~BlockScopeInfo() { } static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name) { if (C.getLangOptions().CPlusPlus) - return CXXRecordDecl::Create(C, TagDecl::TK_struct, + return CXXRecordDecl::Create(C, TTK_Struct, C.getTranslationUnitDecl(), SourceLocation(), &C.Idents.get(Name)); - return RecordDecl::Create(C, TagDecl::TK_struct, + return RecordDecl::Create(C, TTK_Struct, C.getTranslationUnitDecl(), SourceLocation(), &C.Idents.get(Name)); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 3bea485c8f..fa8976fdc4 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -768,7 +768,8 @@ public: bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID); - QualType getQualifiedNameType(const CXXScopeSpec &SS, QualType T); + QualType getElaboratedType(ElaboratedTypeKeyword Keyword, + const CXXScopeSpec &SS, QualType T); QualType BuildTypeofExprType(Expr *E); QualType BuildDecltypeType(Expr *E); diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index c075d16170..77bf91946c 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -672,8 +672,8 @@ bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const { ND = ClassTemplate->getTemplatedDecl(); if (RecordDecl *RD = dyn_cast<RecordDecl>(ND)) - return RD->getTagKind() == TagDecl::TK_class || - RD->getTagKind() == TagDecl::TK_struct; + return RD->getTagKind() == TTK_Class || + RD->getTagKind() == TTK_Struct; return false; } @@ -685,7 +685,7 @@ bool ResultBuilder::IsUnion(NamedDecl *ND) const { ND = ClassTemplate->getTemplatedDecl(); if (RecordDecl *RD = dyn_cast<RecordDecl>(ND)) - return RD->getTagKind() == TagDecl::TK_union; + return RD->getTagKind() == TTK_Union; return false; } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 40ba8ffc19..b4f5d13d2a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -191,7 +191,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, T = Context.getTypeDeclType(TD); if (SS) - T = getQualifiedNameType(*SS, T); + T = getElaboratedType(ETK_None, *SS, T); } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) { T = Context.getObjCInterfaceType(IDecl); @@ -223,10 +223,11 @@ DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) { if (R.getResultKind() == LookupResult::Found) if (const TagDecl *TD = R.getAsSingle<TagDecl>()) { switch (TD->getTagKind()) { - case TagDecl::TK_struct: return DeclSpec::TST_struct; - case TagDecl::TK_union: return DeclSpec::TST_union; - case TagDecl::TK_class: return DeclSpec::TST_class; - case TagDecl::TK_enum: return DeclSpec::TST_enum; + default: return DeclSpec::TST_unspecified; + case TTK_Struct: return DeclSpec::TST_struct; + case TTK_Union: return DeclSpec::TST_union; + case TTK_Class: return DeclSpec::TST_class; + case TTK_Enum: return DeclSpec::TST_enum; } } @@ -4845,38 +4846,38 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, /// /// \returns true if the new tag kind is acceptable, false otherwise. bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous, - TagDecl::TagKind NewTag, + TagTypeKind NewTag, SourceLocation NewTagLoc, const IdentifierInfo &Name) { // C++ [dcl.type.elab]p3: // The class-key or enum keyword present in the // elaborated-type-specifier shall agree in kind with the - // declaration to which the name in theelaborated-type-specifier + // declaration to which the name in the elaborated-type-specifier // refers. This rule also applies to the form of // elaborated-type-specifier that declares a class-name or // friend class since it can be construed as referring to the // definition of the class. Thus, in any // elaborated-type-specifier, the enum keyword shall be used to - // refer to an enumeration (7.2), the union class-keyshall be + // refer to an enumeration (7.2), the union class-key shall be // used to refer to a union (clause 9), and either the class or // struct class-key shall be used to refer to a class (clause 9) // declared using the class or struct class-key. - TagDecl::TagKind OldTag = Previous->getTagKind(); + TagTypeKind OldTag = Previous->getTagKind(); if (OldTag == NewTag) return true; - if ((OldTag == TagDecl::TK_struct || OldTag == TagDecl::TK_class) && - (NewTag == TagDecl::TK_struct || NewTag == TagDecl::TK_class)) { + if ((OldTag == TTK_Struct || OldTag == TTK_Class) && + (NewTag == TTK_Struct || NewTag == TTK_Class)) { // Warn about the struct/class tag mismatch. bool isTemplate = false; if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Previous)) isTemplate = Record->getDescribedClassTemplate(); Diag(NewTagLoc, diag::warn_struct_class_tag_mismatch) - << (NewTag == TagDecl::TK_class) + << (NewTag == TTK_Class) << isTemplate << &Name << FixItHint::CreateReplacement(SourceRange(NewTagLoc), - OldTag == TagDecl::TK_class? "class" : "struct"); + OldTag == TTK_Class? "class" : "struct"); Diag(Previous->getLocation(), diag::note_previous_use); return true; } @@ -4898,7 +4899,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, "Nameless record must be a definition!"); OwnedDecl = false; - TagDecl::TagKind Kind = TagDecl::getTagKindForTypeSpec(TagSpec); + TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); // FIXME: Check explicit specializations more carefully. bool isExplicitSpecialization = false; @@ -4922,7 +4923,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, } else { // The "template<>" header is extraneous. Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams) - << ElaboratedType::getNameForTagKind(Kind) << Name; + << TypeWithKeyword::getTagTypeKindName(Kind) << Name; isExplicitSpecialization = true; } } @@ -5141,8 +5142,8 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // struct or something similar. if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind, KWLoc, *Name)) { bool SafeToContinue - = (PrevTagDecl->getTagKind() != TagDecl::TK_enum && - Kind != TagDecl::TK_enum); + = (PrevTagDecl->getTagKind() != TTK_Enum && + Kind != TTK_Enum); if (SafeToContinue) Diag(KWLoc, diag::err_use_with_wrong_tag) << Name @@ -5296,7 +5297,7 @@ CreateNewDecl: // PrevDecl. TagDecl *New; - if (Kind == TagDecl::TK_enum) { + if (Kind == TTK_Enum) { // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.: // enum X { A, B, C } D; D should chain to X. New = EnumDecl::Create(Context, SearchDC, Loc, Name, KWLoc, @@ -5331,7 +5332,7 @@ CreateNewDecl: New->setQualifierInfo(NNS, SS.getRange()); } - if (Kind != TagDecl::TK_enum) { + if (Kind != TTK_Enum) { // Handle #pragma pack: if the #pragma pack stack has non-default // alignment, make up a packed attribute for this decl. These // attributes are checked when the ASTContext lays out the diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 90aa9c1c13..af922d2fc3 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -150,7 +150,7 @@ static inline bool isCFStringType(QualType T, ASTContext &Ctx) { return false; const RecordDecl *RD = RT->getDecl(); - if (RD->getTagKind() != TagDecl::TK_struct) + if (RD->getTagKind() != TTK_Struct) return false; return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index e32a308af5..72a57c36bb 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -461,7 +461,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, if (BaseType->isDependentType()) return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, - Class->getTagKind() == RecordDecl::TK_class, + Class->getTagKind() == TTK_Class, Access, BaseType); // Base specifiers must be record types. @@ -505,7 +505,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, // Create the base specifier. return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, - Class->getTagKind() == RecordDecl::TK_class, + Class->getTagKind() == TTK_Class, Access, BaseType); } @@ -1191,7 +1191,7 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, static_cast<NestedNameSpecifier*>(SS.getScopeRep()); // FIXME: preserve source range information - BaseType = Context.getQualifiedNameType(Qualifier, BaseType); + BaseType = Context.getElaboratedType(ETK_None, Qualifier, BaseType); } } } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 67ad45d74b..8b17f8483d 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1173,7 +1173,7 @@ void Sema::DeclareGlobalNewDelete() { if (!StdBadAlloc) { // The "std::bad_alloc" class has not yet been declared, so build it // implicitly. - StdBadAlloc = CXXRecordDecl::Create(Context, TagDecl::TK_class, + StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class, StdNamespace, SourceLocation(), &PP.getIdentifierTable().get("bad_alloc"), diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index b2f416ca37..fea7e6129f 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2742,8 +2742,8 @@ static void TryValueInitialization(Sema &S, // without a user-provided constructor, then the object is // zero-initialized and, if T’s implicitly-declared default // constructor is non-trivial, that constructor is called. - if ((ClassDecl->getTagKind() == TagDecl::TK_class || - ClassDecl->getTagKind() == TagDecl::TK_struct) && + if ((ClassDecl->getTagKind() == TTK_Class || + ClassDecl->getTagKind() == TTK_Struct) && !ClassDecl->hasTrivialConstructor()) { Sequence.AddZeroInitializationStep(Entity.getType()); return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index d660d6a4c9..0f3f86dbfd 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -739,8 +739,8 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, if (CheckTemplateDeclScope(S, TemplateParams)) return true; - TagDecl::TagKind Kind = TagDecl::getTagKindForTypeSpec(TagSpec); - assert(Kind != TagDecl::TK_enum && "can't build template of enumerated type"); + TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); + assert(Kind != TTK_Enum && "can't build template of enumerated type"); // There is no such thing as an unnamed class template. if (!Name) { @@ -1568,7 +1568,7 @@ Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult, QualType Type = GetTypeFromParser(TypeResult.get(), &DI); // Verify the tag specifier. - TagDecl::TagKind TagKind = TagDecl::getTagKindForTypeSpec(TagSpec); + TagTypeKind TagKind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); if (const RecordType *RT = Type->getAs<RecordType>()) { RecordDecl *D = RT->getDecl(); @@ -1584,7 +1584,9 @@ Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult, } } - QualType ElabType = Context.getElaboratedType(Type, TagKind); + ElaboratedTypeKeyword Keyword + = TypeWithKeyword::getKeywordForTagTypeKind(TagKind); + QualType ElabType = Context.getElaboratedType(Keyword, /*NNS=*/0, Type); return ElabType.getAsOpaquePtr(); } @@ -3664,13 +3666,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // Check that the specialization uses the same tag kind as the // original template. - TagDecl::TagKind Kind; - switch (TagSpec) { - default: assert(0 && "Unknown tag type!"); - case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break; - case DeclSpec::TST_union: Kind = TagDecl::TK_union; break; - case DeclSpec::TST_class: Kind = TagDecl::TK_class; break; - } + TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); + assert(Kind != TTK_Enum && "Invalid enum tag in class template spec!"); if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(), Kind, KWLoc, *ClassTemplate->getIdentifier())) { @@ -4621,13 +4618,9 @@ Sema::ActOnExplicitInstantiation(Scope *S, // Check that the specialization uses the same tag kind as the // original template. - TagDecl::TagKind Kind; - switch (TagSpec) { - default: assert(0 && "Unknown tag type!"); - case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break; - case DeclSpec::TST_union: Kind = TagDecl::TK_union; break; - case DeclSpec::TST_class: Kind = TagDecl::TK_class; break; - } + TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); + assert(Kind != TTK_Enum && + "Invalid enum tag in class template explicit instantiation!"); if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(), Kind, KWLoc, *ClassTemplate->getIdentifier())) { @@ -5173,23 +5166,16 @@ Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, if (!NNS) return true; - ElaboratedTypeKeyword Keyword = ETK_None; - switch (TagDecl::getTagKindForTypeSpec(TagSpec)) { - case TagDecl::TK_struct: Keyword = ETK_Struct; break; - case TagDecl::TK_class: Keyword = ETK_Class; break; - case TagDecl::TK_union: Keyword = ETK_Union; break; - case TagDecl::TK_enum: Keyword = ETK_Enum; break; - } - assert(Keyword != ETK_None && "Invalid tag kind!"); + TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); if (TUK == TUK_Declaration || TUK == TUK_Definition) { Diag(NameLoc, diag::err_dependent_tag_decl) - << (TUK == TUK_Definition) << TagDecl::getTagKindForTypeSpec(TagSpec) - << SS.getRange(); + << (TUK == TUK_Definition) << Kind << SS.getRange(); return true; } - - return Context.getDependentNameType(Keyword, NNS, Name).getAsOpaquePtr(); + + ElaboratedTypeKeyword Kwd = TypeWithKeyword::getKeywordForTagTypeKind(Kind); + return Context.getDependentNameType(Kwd, NNS, Name).getAsOpaquePtr(); } static void FillTypeLoc(DependentNameTypeLoc TL, @@ -5199,7 +5185,7 @@ static void FillTypeLoc(DependentNameTypeLoc TL, TL.setNameLoc(TypenameLoc); } -static void FillTypeLoc(QualifiedNameTypeLoc TL, +static void FillTypeLoc(ElaboratedTypeLoc TL, SourceLocation TypenameLoc, SourceRange QualifierRange) { // FIXME: typename, qualifier range @@ -5225,7 +5211,7 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, // FIXME: fill inner type loc FillTypeLoc(TL, TypenameLoc, SS.getRange()); } else { - QualifiedNameTypeLoc TL = cast<QualifiedNameTypeLoc>(TSI->getTypeLoc()); + ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc()); // FIXME: fill inner type loc FillTypeLoc(TL, TypenameLoc, SS.getRange()); } @@ -5245,14 +5231,11 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, if (computeDeclContext(SS, false)) { // If we can compute a declaration context, then the "typename" - // keyword was superfluous. Just build a QualifiedNameType to keep + // keyword was superfluous. Just build an ElaboratedType to keep // track of the nested-name-specifier. - - // FIXME: Note that the QualifiedNameType had the "typename" keyword! - - T = Context.getQualifiedNameType(NNS, T); + T = Context.getElaboratedType(ETK_Typename, NNS, T); TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); - QualifiedNameTypeLoc TL = cast<QualifiedNameTypeLoc>(TSI->getTypeLoc()); + ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc()); // FIXME: fill inner type loc FillTypeLoc(TL, TypenameLoc, SS.getRange()); return CreateLocInfoType(T, TSI).getAsOpaquePtr(); @@ -5309,10 +5292,10 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, case LookupResult::Found: if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) { - // We found a type. Build a QualifiedNameType, since the - // typename-specifier was just sugar. FIXME: Tell - // QualifiedNameType that it has a "typename" prefix. - return Context.getQualifiedNameType(NNS, Context.getTypeDeclType(Type)); + // We found a type. Build an ElaboratedType, since the + // typename-specifier was just sugar. + return Context.getElaboratedType(ETK_Typename, NNS, + Context.getTypeDeclType(Type)); } DiagID = diag::err_typename_nested_not_type; @@ -5391,9 +5374,10 @@ namespace { /// \brief Transforms a typename type by determining whether the type now /// refers to a member of the current instantiation, and then - /// type-checking and building a QualifiedNameType (when possible). - QualType TransformDependentNameType(TypeLocBuilder &TLB, DependentNameTypeLoc TL, - QualType ObjectType); + /// type-checking and building an ElaboratedType (when possible). + QualType TransformDependentNameType(TypeLocBuilder &TLB, + DependentNameTypeLoc TL, + QualType ObjectType); }; } @@ -5422,7 +5406,7 @@ CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB, Result = QualType(T, 0); // Rebuild the typename type, which will probably turn into a - // QualifiedNameType. + // ElaboratedType. else if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) { QualType NewTemplateId = TransformType(QualType(TemplateId, 0)); @@ -5471,7 +5455,7 @@ CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB, /// Here, the type "typename X<T>::pointer" will be created as a DependentNameType, /// since we do not know that we can look into X<T> when we parsed the type. /// This function will rebuild the type, performing the lookup of "pointer" -/// in X<T> and returning a QualifiedNameType whose canonical type is the same +/// in X<T> and returning an ElaboratedType whose canonical type is the same /// as the canonical type of T*, allowing the return types of the out-of-line /// definition and the declaration to match. TypeSourceInfo *Sema::RebuildTypeInCurrentInstantiation(TypeSourceInfo *T, diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 7dab4bd8bd..06b953931f 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -601,7 +601,8 @@ namespace { /// \brief Check for tag mismatches when instantiating an /// elaborated type. - QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag); + QualType RebuildElaboratedType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, QualType T); Sema::OwningExprResult TransformPredefinedExpr(PredefinedExpr *E); Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E); @@ -719,8 +720,9 @@ VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, } QualType -TemplateInstantiator::RebuildElaboratedType(QualType T, - ElaboratedType::TagKind Tag) { +TemplateInstantiator::RebuildElaboratedType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, + QualType T) { if (const TagType *TT = T->getAs<TagType>()) { TagDecl* TD = TT->getDecl(); @@ -732,16 +734,20 @@ TemplateInstantiator::RebuildElaboratedType(QualType T, // TODO: should we even warn on struct/class mismatches for this? Seems // like it's likely to produce a lot of spurious errors. - if (!SemaRef.isAcceptableTagRedeclaration(TD, Tag, TagLocation, *Id)) { - SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag) - << Id - << FixItHint::CreateReplacement(SourceRange(TagLocation), - TD->getKindName()); - SemaRef.Diag(TD->getLocation(), diag::note_previous_use); + if (Keyword != ETK_None && Keyword != ETK_Typename) { + TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword); + if (!SemaRef.isAcceptableTagRedeclaration(TD, Kind, TagLocation, *Id)) { + SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag) + << Id + << FixItHint::CreateReplacement(SourceRange(TagLocation), + TD->getKindName()); + SemaRef.Diag(TD->getLocation(), diag::note_previous_use); + } } } - return TreeTransform<TemplateInstantiator>::RebuildElaboratedType(T, Tag); + return TreeTransform<TemplateInstantiator>::RebuildElaboratedType(Keyword, + NNS, T); } Sema::OwningExprResult diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index d1a74beb53..d926b9b61f 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -283,12 +283,11 @@ static QualType ConvertDeclSpecToType(Sema &TheSema, // In C++, make an ElaboratedType. if (TheSema.getLangOptions().CPlusPlus) { - TagDecl::TagKind Tag - = TagDecl::getTagKindForTypeSpec(DS.getTypeSpecType()); - Result = TheSema.getQualifiedNameType(DS.getTypeSpecScope(), Result); - Result = Context.getElaboratedType(Result, Tag); + ElaboratedTypeKeyword Keyword + = ElaboratedType::getKeywordForTypeSpec(DS.getTypeSpecType()); + Result = TheSema.getElaboratedType(Keyword, DS.getTypeSpecScope(), + Result); } - if (D->isInvalidDecl()) TheDeclarator.setInvalidType(true); break; @@ -995,10 +994,10 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, break; case Declarator::MemberContext: switch (cast<TagDecl>(CurContext)->getTagKind()) { - case TagDecl::TK_enum: assert(0 && "unhandled tag kind"); break; - case TagDecl::TK_struct: Error = 1; /* Struct member */ break; - case TagDecl::TK_union: Error = 2; /* Union member */ break; - case TagDecl::TK_class: Error = 3; /* Class member */ break; + 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; + case TTK_Class: Error = 3; /* Class member */ break; } break; case Declarator::CXXCatchContext: @@ -1301,7 +1300,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, case NestedNameSpecifier::TypeSpecWithTemplate: ClsType = QualType(NNS->getAsType(), 0); if (NNSPrefix) - ClsType = Context.getQualifiedNameType(NNSPrefix, ClsType); + ClsType = Context.getElaboratedType(ETK_None, NNSPrefix, ClsType); break; } } else { @@ -2082,15 +2081,21 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, 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) { - if (!SS.isSet() || SS.isInvalid() || T.isNull()) +/// \brief Retrieve a version of the type 'T' that is elaborated by Keyword +/// and qualified by the nested-name-specifier contained in SS. +QualType Sema::getElaboratedType(ElaboratedTypeKeyword Keyword, + const CXXScopeSpec &SS, QualType T) { + if (T.isNull()) return T; - - NestedNameSpecifier *NNS - = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); - return Context.getQualifiedNameType(NNS, T); + NestedNameSpecifier *NNS; + if (SS.isSet() && !SS.isInvalid()) + NNS = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); + else { + if (Keyword == ETK_None) + return T; + NNS = 0; + } + return Context.getElaboratedType(Keyword, NNS, T); } QualType Sema::BuildTypeofExprType(Expr *E) { diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 77d720b374..4923480737 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -492,11 +492,6 @@ public: return SemaRef.Context.getTypeDeclType(Enum); } - /// \brief Build a new elaborated type. - QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) { - return SemaRef.Context.getElaboratedType(T, Tag); - } - /// \brief Build a new typeof(expr) type. /// /// By default, performs semantic analysis when building the typeof type. @@ -525,11 +520,12 @@ public: /// \brief Build a new qualified name type. /// - /// By default, builds a new QualifiedNameType type from the - /// nested-name-specifier and the named type. Subclasses may override - /// this routine to provide different behavior. - QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) { - return SemaRef.Context.getQualifiedNameType(NNS, Named); + /// By default, builds a new ElaboratedType type from the keyword, + /// the nested-name-specifier and the named type. + /// Subclasses may override this routine to provide different behavior. + QualType RebuildElaboratedType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, QualType Named) { + return SemaRef.Context.getElaboratedType(Keyword, NNS, Named); } /// \brief Build a new typename type that refers to a template-id. @@ -548,9 +544,8 @@ public: return SemaRef.Context.getDependentNameType(Keyword, NNS, cast<TemplateSpecializationType>(T)); } - - // FIXME: Handle elaborated-type-specifiers separately. - return SemaRef.Context.getQualifiedNameType(NNS, T); + + return SemaRef.Context.getElaboratedType(Keyword, NNS, T); } /// \brief Build a new typename type that refers to an identifier. @@ -571,19 +566,11 @@ public: return SemaRef.Context.getDependentNameType(Keyword, NNS, Id); } - TagDecl::TagKind Kind = TagDecl::TK_enum; - switch (Keyword) { - case ETK_None: - // Fall through. - case ETK_Typename: - return SemaRef.CheckTypenameType(Keyword, NNS, *Id, SR); - - case ETK_Class: Kind = TagDecl::TK_class; break; - case ETK_Struct: Kind = TagDecl::TK_struct; break; - case ETK_Union: Kind = TagDecl::TK_union; break; - case ETK_Enum: Kind = TagDecl::TK_enum; break; - } - + if (Keyword == ETK_None || Keyword == ETK_Typename) + return SemaRef.CheckTypenameType(Keyword, NNS, *Id, SR); + + TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword); + // We had a dependent elaborated-type-specifier that as been transformed // into a non-dependent elaborated-type-specifier. Find the tag we're // referring to. @@ -619,7 +606,7 @@ public: << Kind << Id << DC; return QualType(); } - + // FIXME: Terrible location information if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, SR.getEnd(), *Id)) { SemaRef.Diag(SR.getBegin(), diag::err_use_with_wrong_tag) << Id; @@ -629,8 +616,7 @@ public: // Build the elaborated-type-specifier type. QualType T = SemaRef.Context.getTypeDeclType(Tag); - T = SemaRef.Context.getQualifiedNameType(NNS, T); - return SemaRef.Context.getElaboratedType(T, Kind); + return SemaRef.Context.getElaboratedType(Keyword, NNS, T); } /// \brief Build a new nested-name-specifier given the prefix and an @@ -3146,31 +3132,6 @@ QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB, return Result; } -template <typename Derived> -QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, - ElaboratedTypeLoc TL, - QualType ObjectType) { - ElaboratedType *T = TL.getTypePtr(); - - // FIXME: this should be a nested type. - QualType Underlying = getDerived().TransformType(T->getUnderlyingType()); - if (Underlying.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - Underlying != T->getUnderlyingType()) { - Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind()); - if (Result.isNull()) - return QualType(); - } - - ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - - return Result; -} - template<typename Derived> QualType TreeTransform<Derived>::TransformInjectedClassNameType( TypeLocBuilder &TLB, @@ -3275,16 +3236,20 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType( template<typename Derived> QualType -TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB, - QualifiedNameTypeLoc TL, - QualType ObjectType) { - QualifiedNameType *T = TL.getTypePtr(); - NestedNameSpecifier *NNS - = getDerived().TransformNestedNameSpecifier(T->getQualifier(), - SourceRange(), - ObjectType); - if (!NNS) - return QualType(); +TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, + ElaboratedTypeLoc TL, + QualType ObjectType) { + ElaboratedType *T = TL.getTypePtr(); + + NestedNameSpecifier *NNS = 0; + // NOTE: the qualifier in an ElaboratedType is optional. + if (T->getQualifier() != 0) { + NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(), + SourceRange(), + ObjectType); + if (!NNS) + return QualType(); + } QualType Named = getDerived().TransformType(T->getNamedType()); if (Named.isNull()) @@ -3294,12 +3259,12 @@ TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB, if (getDerived().AlwaysRebuild() || NNS != T->getQualifier() || Named != T->getNamedType()) { - Result = getDerived().RebuildQualifiedNameType(NNS, Named); + Result = getDerived().RebuildElaboratedType(T->getKeyword(), NNS, Named); if (Result.isNull()) return QualType(); } - QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result); + ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc()); return Result; |