aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorAbramo Bagnara <abramo.bagnara@gmail.com>2010-05-11 21:36:43 +0000
committerAbramo Bagnara <abramo.bagnara@gmail.com>2010-05-11 21:36:43 +0000
commit465d41b92b2c862f3062c412a0538db65c6a2661 (patch)
tree0743a1451f3715b8acabca167d0a0bcc357550bd /lib/Sema
parent380c2139959d8608782292984b457640a143a70d (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.cpp4
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaCodeComplete.cpp6
-rw-r--r--lib/Sema/SemaDecl.cpp39
-rw-r--r--lib/Sema/SemaDeclAttr.cpp2
-rw-r--r--lib/Sema/SemaDeclCXX.cpp6
-rw-r--r--lib/Sema/SemaExprCXX.cpp2
-rw-r--r--lib/Sema/SemaInit.cpp4
-rw-r--r--lib/Sema/SemaTemplate.cpp78
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp26
-rw-r--r--lib/Sema/SemaType.cpp41
-rw-r--r--lib/Sema/TreeTransform.h97
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;