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 | 6150c884dfcbf6fba6adb05109080de65960f34e (patch) | |
tree | a465bcafe116f7fd8a6c7efda03934f2c7c03559 /clang/lib | |
parent | 5b08a8a43254ed30bd953e869b0fd9fc1e8b82d0 (diff) | |
download | bcm5719-llvm-6150c884dfcbf6fba6adb05109080de65960f34e.tar.gz bcm5719-llvm-6150c884dfcbf6fba6adb05109080de65960f34e.zip |
Merged Elaborated and QualifiedName types.
llvm-svn: 103517
Diffstat (limited to 'clang/lib')
27 files changed, 305 insertions, 354 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 71ef09ab18c..81b56add8ee 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -626,10 +626,6 @@ ASTContext::getTypeInfo(const Type *T) { return getTypeInfo(cast<SubstTemplateTypeParmType>(T)-> getReplacementType().getTypePtr()); - case Type::Elaborated: - return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType() - .getTypePtr()); - case Type::Typedef: { const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl(); if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) { @@ -652,8 +648,8 @@ ASTContext::getTypeInfo(const Type *T) { return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType() .getTypePtr()); - case Type::QualifiedName: - return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr()); + case Type::Elaborated: + return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr()); case Type::TemplateSpecialization: assert(getCanonicalType(T) != T && @@ -1890,29 +1886,28 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, } QualType -ASTContext::getQualifiedNameType(NestedNameSpecifier *NNS, - QualType NamedType) { +ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, + QualType NamedType) { llvm::FoldingSetNodeID ID; - QualifiedNameType::Profile(ID, NNS, NamedType); + ElaboratedType::Profile(ID, Keyword, NNS, NamedType); void *InsertPos = 0; - QualifiedNameType *T - = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos); + ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos); if (T) return QualType(T, 0); QualType Canon = NamedType; if (!Canon.isCanonical()) { Canon = getCanonicalType(NamedType); - QualifiedNameType *CheckT - = QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(!CheckT && "Qualified name canonical type broken"); + ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos); + assert(!CheckT && "Elaborated canonical type broken"); (void)CheckT; } - T = new (*this) QualifiedNameType(NNS, NamedType, Canon); + T = new (*this) ElaboratedType(Keyword, NNS, NamedType, Canon); Types.push_back(T); - QualifiedNameTypes.InsertNode(T, InsertPos); + ElaboratedTypes.InsertNode(T, InsertPos); return QualType(T, 0); } @@ -1989,30 +1984,6 @@ ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword, return QualType(T, 0); } -QualType -ASTContext::getElaboratedType(QualType UnderlyingType, - ElaboratedType::TagKind Tag) { - llvm::FoldingSetNodeID ID; - ElaboratedType::Profile(ID, UnderlyingType, Tag); - - void *InsertPos = 0; - ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos); - if (T) - return QualType(T, 0); - - QualType Canon = UnderlyingType; - if (!Canon.isCanonical()) { - Canon = getCanonicalType(Canon); - ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(!CheckT && "Elaborated canonical type is broken"); (void)CheckT; - } - - T = new (*this) ElaboratedType(UnderlyingType, Tag, Canon); - Types.push_back(T); - ElaboratedTypes.InsertNode(T, InsertPos); - return QualType(T, 0); -} - /// CmpProtocolNames - Comparison predicate for sorting protocols /// alphabetically. static bool CmpProtocolNames(const ObjCProtocolDecl *LHS, @@ -2813,7 +2784,7 @@ CreateRecordDecl(ASTContext &Ctx, RecordDecl::TagKind TK, DeclContext *DC, QualType ASTContext::getCFConstantStringType() { if (!CFConstantStringTypeDecl) { CFConstantStringTypeDecl = - CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(), &Idents.get("NSConstantString")); CFConstantStringTypeDecl->startDefinition(); @@ -2855,7 +2826,7 @@ void ASTContext::setCFConstantStringType(QualType T) { QualType ASTContext::getNSConstantStringType() { if (!NSConstantStringTypeDecl) { NSConstantStringTypeDecl = - CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(), &Idents.get("__builtin_NSString")); NSConstantStringTypeDecl->startDefinition(); @@ -2894,7 +2865,7 @@ void ASTContext::setNSConstantStringType(QualType T) { QualType ASTContext::getObjCFastEnumerationStateType() { if (!ObjCFastEnumerationStateTypeDecl) { ObjCFastEnumerationStateTypeDecl = - CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(), &Idents.get("__objcFastEnumerationState")); ObjCFastEnumerationStateTypeDecl->startDefinition(); @@ -2929,7 +2900,7 @@ QualType ASTContext::getBlockDescriptorType() { RecordDecl *T; // FIXME: Needs the FlagAppleBlock bit. - T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(), &Idents.get("__block_descriptor")); T->startDefinition(); @@ -2974,7 +2945,7 @@ QualType ASTContext::getBlockDescriptorExtendedType() { RecordDecl *T; // FIXME: Needs the FlagAppleBlock bit. - T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(), &Idents.get("__block_descriptor_withcopydispose")); T->startDefinition(); @@ -3046,7 +3017,7 @@ QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) { llvm::raw_svector_ostream(Name) << "__Block_byref_" << ++UniqueBlockByRefTypeID << '_' << DeclName; RecordDecl *T; - T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(), &Idents.get(Name.str())); T->startDefinition(); QualType Int32Ty = IntTy; @@ -3097,7 +3068,7 @@ QualType ASTContext::getBlockParmType( llvm::raw_svector_ostream(Name) << "__block_literal_" << ++UniqueBlockParmTypeID; RecordDecl *T; - T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(), &Idents.get(Name.str())); T->startDefinition(); QualType FieldTypes[] = { diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index e4cd2a9c105..23aae392bbb 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -50,12 +50,6 @@ static bool ShouldAKA(ASTContext &Context, QualType QT, QT = cast<ElaboratedType>(Ty)->desugar(); continue; } - - // ...or a qualified name type... - if (isa<QualifiedNameType>(Ty)) { - QT = cast<QualifiedNameType>(Ty)->desugar(); - continue; - } // ...or a substituted template type parameter. if (isa<SubstTemplateTypeParmType>(Ty)) { diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 083c1bf7d8a..aae02a48cd8 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -68,11 +68,10 @@ namespace { // FIXME: DependentDecltypeType QualType VisitRecordType(RecordType *T); QualType VisitEnumType(EnumType *T); - QualType VisitElaboratedType(ElaboratedType *T); // FIXME: TemplateTypeParmType // FIXME: SubstTemplateTypeParmType // FIXME: TemplateSpecializationType - QualType VisitQualifiedNameType(QualifiedNameType *T); + QualType VisitElaboratedType(ElaboratedType *T); // FIXME: DependentNameType QualType VisitObjCInterfaceType(ObjCInterfaceType *T); QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T); @@ -532,19 +531,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, cast<TagType>(T2)->getDecl())) return false; break; - - case Type::Elaborated: { - const ElaboratedType *Elab1 = cast<ElaboratedType>(T1); - const ElaboratedType *Elab2 = cast<ElaboratedType>(T2); - if (Elab1->getTagKind() != Elab2->getTagKind()) - return false; - if (!IsStructurallyEquivalent(Context, - Elab1->getUnderlyingType(), - Elab2->getUnderlyingType())) - return false; - break; - } - + case Type::TemplateTypeParm: { const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1); const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2); @@ -594,16 +581,19 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, break; } - case Type::QualifiedName: { - const QualifiedNameType *Qual1 = cast<QualifiedNameType>(T1); - const QualifiedNameType *Qual2 = cast<QualifiedNameType>(T2); + case Type::Elaborated: { + const ElaboratedType *Elab1 = cast<ElaboratedType>(T1); + const ElaboratedType *Elab2 = cast<ElaboratedType>(T2); + // CHECKME: what if a keyword is ETK_None or ETK_typename ? + if (Elab1->getKeyword() != Elab2->getKeyword()) + return false; if (!IsStructurallyEquivalent(Context, - Qual1->getQualifier(), - Qual2->getQualifier())) + Elab1->getQualifier(), + Elab2->getQualifier())) return false; if (!IsStructurallyEquivalent(Context, - Qual1->getNamedType(), - Qual2->getNamedType())) + Elab1->getNamedType(), + Elab2->getNamedType())) return false; break; } @@ -1293,24 +1283,20 @@ QualType ASTNodeImporter::VisitEnumType(EnumType *T) { } QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) { - QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType()); - if (ToUnderlyingType.isNull()) - return QualType(); - - return Importer.getToContext().getElaboratedType(ToUnderlyingType, - T->getTagKind()); -} - -QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) { - NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier()); - if (!ToQualifier) - return QualType(); + NestedNameSpecifier *ToQualifier = 0; + // Note: the qualifier in an ElaboratedType is optional. + if (T->getQualifier()) { + ToQualifier = Importer.Import(T->getQualifier()); + if (!ToQualifier) + return QualType(); + } QualType ToNamedType = Importer.Import(T->getNamedType()); if (ToNamedType.isNull()) return QualType(); - return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType); + return Importer.getToContext().getElaboratedType(T->getKeyword(), + ToQualifier, ToNamedType); } QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) { diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 25f5fb77973..28332bdb9ab 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -23,7 +23,7 @@ #include "clang/AST/PrettyPrinter.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/IdentifierTable.h" -#include "clang/Parse/DeclSpec.h" +#include "clang/Basic/Specifiers.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; @@ -1520,16 +1520,6 @@ TagDecl* TagDecl::getDefinition() const { return 0; } -TagDecl::TagKind TagDecl::getTagKindForTypeSpec(unsigned TypeSpec) { - switch (TypeSpec) { - default: llvm_unreachable("unexpected type specifier"); - case DeclSpec::TST_struct: return TK_struct; - case DeclSpec::TST_class: return TK_class; - case DeclSpec::TST_union: return TK_union; - case DeclSpec::TST_enum: return TK_enum; - } -} - void TagDecl::setQualifierInfo(NestedNameSpecifier *Qualifier, SourceRange QualifierRange) { if (Qualifier) { diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index a279eda38a3..8d9be130b1b 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -137,7 +137,7 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, data().VBases[I] = CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true, - VBaseClassDecl->getTagKind() == RecordDecl::TK_class, + VBaseClassDecl->getTagKind() == TTK_Class, VBases[I]->getAccessSpecifier(), VBaseType); } } diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp index 45518e98bc1..d6594cdfd02 100644 --- a/clang/lib/AST/NestedNameSpecifier.cpp +++ b/clang/lib/AST/NestedNameSpecifier.cpp @@ -145,14 +145,14 @@ NestedNameSpecifier::print(llvm::raw_ostream &OS, InnerPolicy.SuppressScope = true; // Nested-name-specifiers are intended to contain minimally-qualified - // types. An actual QualifiedNameType will not occur, since we'll store + // types. An actual ElaboratedType will not occur, since we'll store // just the type that is referred to in the nested-name-specifier (e.g., // a TypedefType, TagType, etc.). However, when we are dealing with // dependent template-id types (e.g., Outer<T>::template Inner<U>), // the type requires its own nested-name-specifier for uniqueness, so we // suppress that nested-name-specifier during printing. - assert(!isa<QualifiedNameType>(T) && - "Qualified name type in nested-name-specifier"); + assert(!isa<ElaboratedType>(T) && + "Elaborated type in nested-name-specifier"); if (const TemplateSpecializationType *SpecType = dyn_cast<TemplateSpecializationType>(T)) { // Print the template name without its corresponding diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 73f0e91dab5..843785e634a 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -18,6 +18,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/PrettyPrinter.h" +#include "clang/Basic/Specifiers.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -764,36 +765,105 @@ bool Type::isSpecifierType() const { case TemplateTypeParm: case SubstTemplateTypeParm: case TemplateSpecialization: - case QualifiedName: + case Elaborated: case DependentName: case ObjCInterface: case ObjCObjectPointer: - case Elaborated: return true; default: return false; } } -bool Type::isElaboratedTypeSpecifier() const { - if (getTypeClass() == Elaborated) +TypeWithKeyword::~TypeWithKeyword() { +} + +ElaboratedTypeKeyword +TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) { + switch (TypeSpec) { + default: return ETK_None; + case TST_typename: return ETK_Typename; + case TST_class: return ETK_Class; + case TST_struct: return ETK_Struct; + case TST_union: return ETK_Union; + case TST_enum: return ETK_Enum; + } +} + +TagTypeKind +TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) { + switch(TypeSpec) { + case TST_class: return TTK_Class; + case TST_struct: return TTK_Struct; + case TST_union: return TTK_Union; + case TST_enum: return TTK_Enum; + default: llvm_unreachable("Type specifier is not a tag type kind."); + } +} + +ElaboratedTypeKeyword +TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) { + switch (Kind) { + case TTK_Class: return ETK_Class; + case TTK_Struct: return ETK_Struct; + case TTK_Union: return ETK_Union; + case TTK_Enum: return ETK_Enum; + } + llvm_unreachable("Unknown tag type kind."); +} + +TagTypeKind +TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) { + switch (Keyword) { + case ETK_Class: return TTK_Class; + case ETK_Struct: return TTK_Struct; + case ETK_Union: return TTK_Union; + case ETK_Enum: return TTK_Enum; + case ETK_None: // Fall through. + case ETK_Typename: + llvm_unreachable("Elaborated type keyword is not a tag type kind."); + } + llvm_unreachable("Unknown elaborated type keyword."); +} + +bool +TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) { + switch (Keyword) { + case ETK_None: + case ETK_Typename: + return false; + case ETK_Class: + case ETK_Struct: + case ETK_Union: + case ETK_Enum: return true; - - if (const DependentNameType *Dependent = dyn_cast<DependentNameType>(this)) { - switch (Dependent->getKeyword()) { - case ETK_None: - case ETK_Typename: - return false; - - case ETK_Class: - case ETK_Struct: - case ETK_Union: - case ETK_Enum: - return true; - } } - - return false; + llvm_unreachable("Unknown elaborated type keyword."); +} + +const char* +TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) { + switch (Keyword) { + default: llvm_unreachable("Unknown elaborated type keyword."); + case ETK_None: return ""; + case ETK_Typename: return "typename"; + case ETK_Class: return "class"; + case ETK_Struct: return "struct"; + case ETK_Union: return "union"; + case ETK_Enum: return "enum"; + } +} + +bool Type::isElaboratedTypeSpecifier() const { + ElaboratedTypeKeyword Keyword; + if (const ElaboratedType *Elab = dyn_cast<ElaboratedType>(this)) + Keyword = Elab->getKeyword(); + else if (const DependentNameType *DepName = dyn_cast<DependentNameType>(this)) + Keyword = DepName->getKeyword(); + else + return false; + + return TypeWithKeyword::KeywordIsTagTypeKind(Keyword); } const char *Type::getTypeClassName() const { diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 915d7af9a8c..0478d4e39cf 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -497,16 +497,6 @@ void TypePrinter::PrintEnum(const EnumType *T, std::string &S) { PrintTag(T->getDecl(), S); } -void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { - Print(T->getUnderlyingType(), S); - - // We don't actually make these in C, but the language options - // sometimes lie to us -- for example, if someone calls - // QualType::getAsString(). Just suppress the redundant tag if so. - if (Policy.LangOpts.CPlusPlus) - S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S; -} - void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, std::string &S) { if (!S.empty()) // Prefix the basic type, e.g. 'parmname X'. @@ -549,13 +539,17 @@ void TypePrinter::PrintInjectedClassName(const InjectedClassNameType *T, PrintTemplateSpecialization(T->getInjectedTST(), S); } -void TypePrinter::PrintQualifiedName(const QualifiedNameType *T, - std::string &S) { +void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { std::string MyString; { llvm::raw_string_ostream OS(MyString); - T->getQualifier()->print(OS, Policy); + OS << TypeWithKeyword::getKeywordName(T->getKeyword()); + if (T->getKeyword() != ETK_None) + OS << " "; + NestedNameSpecifier* Qualifier = T->getQualifier(); + if (Qualifier) + Qualifier->print(OS, Policy); } std::string TypeStr; @@ -575,14 +569,9 @@ void TypePrinter::PrintDependentName(const DependentNameType *T, std::string &S) { llvm::raw_string_ostream OS(MyString); - switch (T->getKeyword()) { - case ETK_None: break; - case ETK_Typename: OS << "typename "; break; - case ETK_Class: OS << "class "; break; - case ETK_Struct: OS << "struct "; break; - case ETK_Union: OS << "union "; break; - case ETK_Enum: OS << "enum "; break; - } + OS << TypeWithKeyword::getKeywordName(T->getKeyword()); + if (T->getKeyword() != ETK_None) + OS << " "; T->getQualifier()->print(OS, Policy); diff --git a/clang/lib/Checker/LLVMConventionsChecker.cpp b/clang/lib/Checker/LLVMConventionsChecker.cpp index 14f0fc1280d..39ded431279 100644 --- a/clang/lib/Checker/LLVMConventionsChecker.cpp +++ b/clang/lib/Checker/LLVMConventionsChecker.cpp @@ -47,7 +47,7 @@ static bool InStdNamespace(const Decl *D) { } static bool IsStdString(QualType T) { - if (const QualifiedNameType *QT = T->getAs<QualifiedNameType>()) + if (const ElaboratedType *QT = T->getAs<ElaboratedType>()) T = QT->getNamedType(); const TypedefType *TT = T->getAs<TypedefType>(); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index cb6efe881c3..43f47a005de 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1154,15 +1154,12 @@ static QualType UnwrapTypeForDebugInfo(QualType T) { case Type::Decltype: T = cast<DecltypeType>(T)->getUnderlyingType(); break; - case Type::QualifiedName: - T = cast<QualifiedNameType>(T)->getNamedType(); + case Type::Elaborated: + T = cast<ElaboratedType>(T)->getNamedType(); break; case Type::SubstTemplateTypeParm: T = cast<SubstTemplateTypeParmType>(T)->getReplacementType(); break; - case Type::Elaborated: - T = cast<ElaboratedType>(T)->getUnderlyingType(); - break; } assert(T != LastT && "Type unwrapping failed to unwrap!"); @@ -1253,7 +1250,6 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, case Type::TemplateSpecialization: case Type::Elaborated: - case Type::QualifiedName: case Type::SubstTemplateTypeParm: case Type::TypeOfExpr: case Type::TypeOf: diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 77eabbfd414..5140bb6d9d3 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -3669,7 +3669,7 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) // id self; // Class cls; // } - RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, + RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, Ctx.getTranslationUnitDecl(), SourceLocation(), &Ctx.Idents.get("_objc_super")); @@ -4131,7 +4131,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul // }; // First the clang type for struct _message_ref_t - RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, + RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, Ctx.getTranslationUnitDecl(), SourceLocation(), &Ctx.Idents.get("_message_ref_t")); diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 6e4e28eed1b..c329f7b64f8 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -2165,8 +2165,10 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { return QualType(); } unsigned Tag = Record[1]; - return Context->getElaboratedType(GetType(Record[0]), - (ElaboratedType::TagKind) Tag); + // FIXME: Deserialize the qualifier (C++ only) + return Context->getElaboratedType((ElaboratedTypeKeyword) Tag, + /* NNS */ 0, + GetType(Record[0])); } case pch::TYPE_OBJC_INTERFACE: { @@ -2334,9 +2336,6 @@ void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) { void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) { TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } -void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } @@ -2354,7 +2353,7 @@ void TypeLocReader::VisitTemplateSpecializationTypeLoc( Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(), Record, Idx)); } -void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) { +void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { diff --git a/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp index c4f9622db8d..3f91d0cafb7 100644 --- a/clang/lib/Frontend/PCHReaderDecl.cpp +++ b/clang/lib/Frontend/PCHReaderDecl.cpp @@ -865,7 +865,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) { D = EnumDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(), 0); break; case pch::DECL_RECORD: - D = RecordDecl::Create(*Context, TagDecl::TK_struct, 0, SourceLocation(), + D = RecordDecl::Create(*Context, TTK_Struct, 0, SourceLocation(), 0, SourceLocation(), 0); break; case pch::DECL_ENUM_CONSTANT: @@ -913,7 +913,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) { DeclarationName()); break; case pch::DECL_CXX_RECORD: - D = CXXRecordDecl::Create(*Context, TagDecl::TK_struct, 0, + D = CXXRecordDecl::Create(*Context, TTK_Struct, 0, SourceLocation(), 0, SourceLocation(), 0); break; case pch::DECL_CXX_METHOD: diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index dc1fb23ac0a..b323dcf4b89 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -213,12 +213,6 @@ void PCHTypeWriter::VisitEnumType(const EnumType *T) { Code = pch::TYPE_ENUM; } -void PCHTypeWriter::VisitElaboratedType(const ElaboratedType *T) { - Writer.AddTypeRef(T->getUnderlyingType(), Record); - Record.push_back(T->getTagKind()); - Code = pch::TYPE_ELABORATED; -} - void PCHTypeWriter::VisitSubstTemplateTypeParmType( const SubstTemplateTypeParmType *T) { @@ -234,9 +228,12 @@ PCHTypeWriter::VisitTemplateSpecializationType( assert(false && "Cannot serialize template specialization types"); } -void PCHTypeWriter::VisitQualifiedNameType(const QualifiedNameType *T) { - // FIXME: Serialize this type (C++ only) - assert(false && "Cannot serialize qualified name types"); +void PCHTypeWriter::VisitElaboratedType(const ElaboratedType *T) { + Writer.AddTypeRef(T->getNamedType(), Record); + Record.push_back(T->getKeyword()); + // FIXME: Serialize the qualifier (C++ only) + assert(T->getQualifier() == 0 && "Cannot serialize qualified name types"); + Code = pch::TYPE_ELABORATED; } void PCHTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) { @@ -383,9 +380,6 @@ void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) { void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } -void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { - Writer.AddSourceLocation(TL.getNameLoc(), Record); -} void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } @@ -401,7 +395,7 @@ void TypeLocWriter::VisitTemplateSpecializationTypeLoc( for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) Writer.AddTemplateArgumentLoc(TL.getArgLoc(i), Record); } -void TypeLocWriter::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) { +void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { diff --git a/clang/lib/Frontend/RewriteObjC.cpp b/clang/lib/Frontend/RewriteObjC.cpp index 11698325e9b..3c415c79d95 100644 --- a/clang/lib/Frontend/RewriteObjC.cpp +++ b/clang/lib/Frontend/RewriteObjC.cpp @@ -1349,7 +1349,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, std::string RecName = clsDeclared->getIdentifier()->getName(); RecName += "_IMPL"; IdentifierInfo *II = &Context->Idents.get(RecName); - RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl, + RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, SourceLocation(), II); assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); @@ -1394,7 +1394,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, std::string RecName = clsDeclared->getIdentifier()->getName(); RecName += "_IMPL"; IdentifierInfo *II = &Context->Idents.get(RecName); - RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl, + RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, SourceLocation(), II); assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); @@ -2426,7 +2426,7 @@ void RewriteObjC::SynthMsgSendFunctionDecl() { void RewriteObjC::SynthMsgSendSuperFunctionDecl() { IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); llvm::SmallVector<QualType, 16> ArgTys; - RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl, + RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, SourceLocation(), &Context->Idents.get("objc_super")); QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); @@ -2475,7 +2475,7 @@ void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper_stret"); llvm::SmallVector<QualType, 16> ArgTys; - RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl, + RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, SourceLocation(), &Context->Idents.get("objc_super")); QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); @@ -2625,7 +2625,7 @@ bool RewriteObjC::isSuperReceiver(Expr *recExpr) { // struct objc_super { struct objc_object *receiver; struct objc_class *super; }; QualType RewriteObjC::getSuperStructType() { if (!SuperStructDecl) { - SuperStructDecl = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl, + SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, SourceLocation(), &Context->Idents.get("objc_super")); QualType FieldTypes[2]; @@ -2651,7 +2651,7 @@ QualType RewriteObjC::getSuperStructType() { QualType RewriteObjC::getConstantStringStructType() { if (!ConstantStringDecl) { - ConstantStringDecl = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl, + ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, SourceLocation(), &Context->Idents.get("__NSConstantStringImpl")); QualType FieldTypes[4]; @@ -4573,7 +4573,7 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); // FTP will be null for closures that don't take arguments. - RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl, + RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, SourceLocation(), &Context->Idents.get("__block_impl")); QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); @@ -5245,7 +5245,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, RewriteByRefString(RecName, Name, ND); IdentifierInfo *II = &Context->Idents.get(RecName.c_str() + sizeof("struct")); - RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl, + RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, SourceLocation(), II); assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index a4329786048..0c713e7c9a6 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/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/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 3bea485c8fb..fa8976fdc43 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index c075d161704..77bf91946c2 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 40ba8ffc195..b4f5d13d2a5 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 90aa9c1c130..af922d2fc3e 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/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/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index e32a308af58..72a57c36bb2 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 67ad45d74b2..8b17f8483d8 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index b2f416ca374..fea7e6129f1 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/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/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index d660d6a4c90..0f3f86dbfd4 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/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/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 7dab4bd8bd5..06b953931fb 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/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/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index d1a74beb538..d926b9b61fc 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/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/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 77d720b3740..4923480737e 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/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; |