Merged Elaborated and QualifiedName types.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103517 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Abramo Bagnara 2010-05-11 21:36:43 +00:00
Родитель 380c213995
Коммит 465d41b92b
37 изменённых файлов: 453 добавлений и 522 удалений

Просмотреть файл

@ -96,11 +96,10 @@ class ASTContext {
llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<DependentNameType> DependentNameTypes;
llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
@ -613,8 +612,9 @@ public:
const TemplateArgumentListInfo &Args,
QualType Canon = QualType());
QualType getQualifiedNameType(NestedNameSpecifier *NNS,
QualType NamedType);
QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
QualType NamedType);
QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
@ -623,8 +623,6 @@ public:
NestedNameSpecifier *NNS,
const TemplateSpecializationType *TemplateId,
QualType Canon = QualType());
QualType getElaboratedType(QualType UnderlyingType,
ElaboratedType::TagKind Tag);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
ObjCProtocolDecl **Protocols = 0,

Просмотреть файл

@ -1648,11 +1648,7 @@ class TagDecl
: public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
public:
// This is really ugly.
typedef ElaboratedType::TagKind TagKind;
static const TagKind TK_struct = ElaboratedType::TK_struct;
static const TagKind TK_union = ElaboratedType::TK_union;
static const TagKind TK_class = ElaboratedType::TK_class;
static const TagKind TK_enum = ElaboratedType::TK_enum;
typedef TagTypeKind TagKind;
private:
// FIXME: This can be packed into the bitfields in Decl.
@ -1703,7 +1699,8 @@ protected:
TagDecl *PrevDecl, SourceLocation TKL = SourceLocation())
: TypeDecl(DK, DC, L, Id), DeclContext(DK), TagKeywordLoc(TKL),
TypedefDeclOrQualifier((TypedefDecl*) 0) {
assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
assert((DK != Enum || TK == TTK_Enum) &&
"EnumDecl not matched with TTK_Enum");
TagDeclKind = TK;
IsDefinition = false;
IsEmbeddedInDeclarator = false;
@ -1776,24 +1773,19 @@ public:
void setDefinition(bool V) { IsDefinition = V; }
const char *getKindName() const {
return ElaboratedType::getNameForTagKind(getTagKind());
return TypeWithKeyword::getTagTypeKindName(getTagKind());
}
/// getTagKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
/// into a tag kind. It is an error to provide a type specifier
/// which *isn't* a tag kind here.
static TagKind getTagKindForTypeSpec(unsigned TypeSpec);
TagKind getTagKind() const {
return TagKind(TagDeclKind);
}
void setTagKind(TagKind TK) { TagDeclKind = TK; }
bool isStruct() const { return getTagKind() == TK_struct; }
bool isClass() const { return getTagKind() == TK_class; }
bool isUnion() const { return getTagKind() == TK_union; }
bool isEnum() const { return getTagKind() == TK_enum; }
bool isStruct() const { return getTagKind() == TTK_Struct; }
bool isClass() const { return getTagKind() == TTK_Class; }
bool isUnion() const { return getTagKind() == TTK_Union; }
bool isEnum() const { return getTagKind() == TTK_Enum; }
TypedefDecl *getTypedefForAnonDecl() const {
return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
@ -1852,7 +1844,7 @@ class EnumDecl : public TagDecl {
EnumDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL)
: TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
: TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
IntegerType = QualType();
}
public:

Просмотреть файл

@ -566,14 +566,6 @@ case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS, S);
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitor<Derived>::VisitElaboratedType(ElaboratedType *T) {
if (Visit(T->getUnderlyingType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitor<Derived>::VisitTemplateTypeParmType(
TemplateTypeParmType *T) {
@ -603,12 +595,13 @@ case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS, S);
}
template<typename Derived>
bool RecursiveASTVisitor<Derived>::VisitQualifiedNameType(
QualifiedNameType *T) {
if (getDerived().VisitNestedNameSpecifier(T->getQualifier()) ||
Visit(T->getNamedType()))
bool RecursiveASTVisitor<Derived>::VisitElaboratedType(ElaboratedType *T) {
if (T->getQualifier() &&
getDerived().VisitNestedNameSpecifier(T->getQualifier()))
return true;
if (Visit(T->getNamedType()))
return true;
return getDerived().VisitType(T);
}

Просмотреть файл

@ -188,7 +188,7 @@ const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
/// declaration for "vector". The QualifiedTemplateName class is only
/// used to provide "sugar" for template names that were expressed
/// with a qualified name, and has no semantic meaning. In this
/// manner, it is to TemplateName what QualifiedNameType is to Type,
/// manner, it is to TemplateName what ElaboratedType is to Type,
/// providing extra syntactic sugar for downstream clients.
class QualifiedTemplateName : public llvm::FoldingSetNode {
/// \brief The nested name specifier that qualifies the template name.

Просмотреть файл

@ -92,7 +92,7 @@ namespace clang {
class TemplateArgumentLoc;
class TemplateArgumentListInfo;
class Type;
class QualifiedNameType;
class ElaboratedType;
struct PrintingPolicy;
template <typename> class CanQual;
@ -2264,68 +2264,6 @@ public:
static bool classof(const EnumType *) { return true; }
};
/// ElaboratedType - A non-canonical type used to represents uses of
/// elaborated type specifiers in C++. For example:
///
/// void foo(union MyUnion);
/// ^^^^^^^^^^^^^
///
/// At the moment, for efficiency we do not create elaborated types in
/// C, since outside of typedefs all references to structs would
/// necessarily be elaborated.
class ElaboratedType : public Type, public llvm::FoldingSetNode {
public:
enum TagKind {
TK_struct,
TK_union,
TK_class,
TK_enum
};
private:
/// The tag that was used in this elaborated type specifier.
TagKind Tag;
/// The underlying type.
QualType UnderlyingType;
explicit ElaboratedType(QualType Ty, TagKind Tag, QualType Canon)
: Type(Elaborated, Canon, Canon->isDependentType()),
Tag(Tag), UnderlyingType(Ty) { }
friend class ASTContext; // ASTContext creates these.
public:
TagKind getTagKind() const { return Tag; }
QualType getUnderlyingType() const { return UnderlyingType; }
/// \brief Remove a single level of sugar.
QualType desugar() const { return getUnderlyingType(); }
/// \brief Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
static const char *getNameForTagKind(TagKind Kind) {
switch (Kind) {
default: assert(0 && "Unknown TagKind!");
case TK_struct: return "struct";
case TK_union: return "union";
case TK_class: return "class";
case TK_enum: return "enum";
}
}
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getUnderlyingType(), getTagKind());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType T, TagKind Tag) {
ID.AddPointer(T.getAsOpaquePtr());
ID.AddInteger(Tag);
}
static bool classof(const ElaboratedType*) { return true; }
static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; }
};
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
unsigned Depth : 15;
unsigned Index : 16;
@ -2592,46 +2530,116 @@ public:
static bool classof(const InjectedClassNameType *T) { return true; }
};
/// \brief The kind of a tag type.
enum TagTypeKind {
/// \brief The "struct" keyword.
TTK_Struct,
/// \brief The "union" keyword.
TTK_Union,
/// \brief The "class" keyword.
TTK_Class,
/// \brief The "enum" keyword.
TTK_Enum
};
/// \brief The elaboration keyword that precedes a qualified type name or
/// introduces an elaborated-type-specifier.
enum ElaboratedTypeKeyword {
/// \brief No keyword precedes the qualified type name.
ETK_None,
/// \brief The "typename" keyword precedes the qualified type name, e.g.,
/// \c typename T::type.
ETK_Typename,
/// \brief The "class" keyword introduces the elaborated-type-specifier.
ETK_Class,
/// \brief The "struct" keyword introduces the elaborated-type-specifier.
ETK_Struct,
/// \brief The "union" keyword introduces the elaborated-type-specifier.
ETK_Union,
/// \brief The "class" keyword introduces the elaborated-type-specifier.
ETK_Class,
/// \brief The "enum" keyword introduces the elaborated-type-specifier.
ETK_Enum
ETK_Enum,
/// \brief The "typename" keyword precedes the qualified type name, e.g.,
/// \c typename T::type.
ETK_Typename,
/// \brief No keyword precedes the qualified type name.
ETK_None
};
/// \brief Represents a type that was referred to via a qualified
/// name, e.g., N::M::type.
/// A helper class for Type nodes having an ElaboratedTypeKeyword.
/// The keyword in stored in the free bits of the base class.
/// Also provides a few static helpers for converting and printing
/// elaborated type keyword and tag type kind enumerations.
class TypeWithKeyword : public Type {
/// Keyword - Encodes an ElaboratedTypeKeyword enumeration constant.
unsigned Keyword : 3;
protected:
TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
QualType Canonical, bool dependent)
: Type(tc, Canonical, dependent), Keyword(Keyword) {}
public:
virtual ~TypeWithKeyword(); // pin vtable to Type.cpp
ElaboratedTypeKeyword getKeyword() const {
return static_cast<ElaboratedTypeKeyword>(Keyword);
}
/// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST)
/// into an elaborated type keyword.
static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
/// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
/// into a tag type kind. It is an error to provide a type specifier
/// which *isn't* a tag kind here.
static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
/// getKeywordForTagDeclKind - Converts a TagTypeKind into an
/// elaborated type keyword.
static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
/// getTagTypeKindForKeyword - Converts an elaborated type keyword into
// a TagTypeKind. It is an error to provide an elaborated type keyword
/// which *isn't* a tag kind here.
static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
static const char *getKeywordName(ElaboratedTypeKeyword Keyword);
static const char *getTagTypeKindName(TagTypeKind Kind) {
return getKeywordName(getKeywordForTagTypeKind(Kind));
}
class CannotCastToThisType {};
static CannotCastToThisType classof(const Type *);
};
/// \brief Represents a type that was referred to using an elaborated type
/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type,
/// or both.
///
/// This type is used to keep track of a type name as written in the
/// source code, including any nested-name-specifiers. The type itself
/// is always "sugar", used to express what was written in the source
/// code but containing no additional semantic information.
class QualifiedNameType : public Type, public llvm::FoldingSetNode {
/// source code, including tag keywords and any nested-name-specifiers.
/// The type itself is always "sugar", used to express what was written
/// in the source code but containing no additional semantic information.
class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
/// \brief The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
/// \brief The type that this qualified name refers to.
QualType NamedType;
QualifiedNameType(NestedNameSpecifier *NNS, QualType NamedType,
QualType CanonType)
: Type(QualifiedName, CanonType, NamedType->isDependentType()),
NNS(NNS), NamedType(NamedType) { }
ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
QualType NamedType, QualType CanonType)
: TypeWithKeyword(Keyword, Elaborated, CanonType,
NamedType->isDependentType()),
NNS(NNS), NamedType(NamedType) {
assert(!(Keyword == ETK_None && NNS == 0) &&
"ElaboratedType cannot have elaborated type keyword "
"and name qualifier both null.");
}
friend class ASTContext; // ASTContext creates these
public:
/// \brief Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@ -2645,19 +2653,20 @@ public:
bool isSugared() const { return true; }
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, NNS, NamedType);
Profile(ID, getKeyword(), NNS, NamedType);
}
static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
QualType NamedType) {
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, QualType NamedType) {
ID.AddInteger(Keyword);
ID.AddPointer(NNS);
NamedType.Profile(ID);
}
static bool classof(const Type *T) {
return T->getTypeClass() == QualifiedName;
return T->getTypeClass() == Elaborated;
}
static bool classof(const QualifiedNameType *T) { return true; }
static bool classof(const ElaboratedType *T) { return true; }
};
/// \brief Represents a qualified type name for which the type name is
@ -2669,10 +2678,8 @@ public:
/// typename-specifier), "class", "struct", "union", or "enum" (for a
/// dependent elaborated-type-specifier), or nothing (in contexts where we
/// know that we must be referring to a type, e.g., in a base class specifier).
class DependentNameType : public Type, public llvm::FoldingSetNode {
/// \brief The keyword used to elaborate this type.
ElaboratedTypeKeyword Keyword;
class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
/// \brief The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
@ -2684,16 +2691,16 @@ class DependentNameType : public Type, public llvm::FoldingSetNode {
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, QualType CanonType)
: Type(DependentName, CanonType, true),
Keyword(Keyword), NNS(NNS), Name(Name) {
: TypeWithKeyword(Keyword, DependentName, CanonType, true),
NNS(NNS), Name(Name) {
assert(NNS->isDependent() &&
"DependentNameType requires a dependent nested-name-specifier");
}
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const TemplateSpecializationType *Ty, QualType CanonType)
: Type(DependentName, CanonType, true),
Keyword(Keyword), NNS(NNS), Name(Ty) {
: TypeWithKeyword(Keyword, DependentName, CanonType, true),
NNS(NNS), Name(Ty) {
assert(NNS->isDependent() &&
"DependentNameType requires a dependent nested-name-specifier");
}
@ -2701,9 +2708,7 @@ class DependentNameType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
public:
/// \brief Retrieve the keyword used to elaborate this type.
ElaboratedTypeKeyword getKeyword() const { return Keyword; }
/// \brief Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@ -2727,7 +2732,7 @@ public:
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, Keyword, NNS, Name);
Profile(ID, getKeyword(), NNS, Name);
}
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,

Просмотреть файл

@ -1231,18 +1231,12 @@ class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DecltypeType> {
};
// FIXME: location of the tag keyword.
class ElaboratedTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
ElaboratedTypeLoc,
ElaboratedType> {
};
// FIXME: locations for the nested name specifier; at the very least,
// a SourceRange.
class QualifiedNameTypeLoc :
class ElaboratedTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
QualifiedNameTypeLoc,
QualifiedNameType> {
ElaboratedTypeLoc,
ElaboratedType> {
};
// FIXME: locations for the typename keyword and nested name specifier.

Просмотреть файл

@ -90,7 +90,6 @@ NON_CANONICAL_TYPE(Elaborated, Type)
DEPENDENT_TYPE(TemplateTypeParm, Type)
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
NON_CANONICAL_TYPE(QualifiedName, Type)
DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
TYPE(ObjCInterface, Type)

Просмотреть файл

@ -211,22 +211,13 @@ NODE_XML(RecordType, "Record")
ID_ATTRIBUTE_XML
ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // string
ATTRIBUTE_ENUM_XML(getDecl()->getTagKind(), "kind")
ENUM_XML(TagDecl::TK_struct, "struct")
ENUM_XML(TagDecl::TK_union, "union")
ENUM_XML(TagDecl::TK_class, "class")
ENUM_XML(TTK_Struct, "struct")
ENUM_XML(TTK_Union, "union")
ENUM_XML(TTK_Class, "class")
END_ENUM_XML
CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
END_NODE_XML
NODE_XML(ElaboratedType, "Elaborated")
ID_ATTRIBUTE_XML
ATTRIBUTE_ENUM_XML(getTagKind(), "kind")
ENUM_XML(ElaboratedType::TK_struct, "struct")
ENUM_XML(ElaboratedType::TK_union, "union")
ENUM_XML(ElaboratedType::TK_class, "class")
END_ENUM_XML
END_NODE_XML
NODE_XML(EnumType, "Enum")
ID_ATTRIBUTE_XML
ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // string
@ -241,8 +232,16 @@ NODE_XML(TemplateSpecializationType, "TemplateSpecializationType")
ID_ATTRIBUTE_XML
END_NODE_XML
NODE_XML(QualifiedNameType, "QualifiedNameType")
NODE_XML(ElaboratedType, "ElaboratedType")
ID_ATTRIBUTE_XML
ATTRIBUTE_ENUM_XML(getKeyword(), "keyword")
ENUM_XML(ETK_None, "none")
ENUM_XML(ETK_Typename, "typename")
ENUM_XML(ETK_Struct, "struct")
ENUM_XML(ETK_Union, "union")
ENUM_XML(ETK_Class, "class")
ENUM_XML(ETK_Enum, "enum")
END_ENUM_XML
TYPE_ATTRIBUTE_XML(getNamedType())
END_NODE_XML

Просмотреть файл

@ -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[] = {

Просмотреть файл

@ -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)) {

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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);
}
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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)
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;
}
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;
}
return false;
}
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;
}
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 {

Просмотреть файл

@ -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);

Просмотреть файл

@ -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>();

Просмотреть файл

@ -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:

Просмотреть файл

@ -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"));

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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:

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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));

Просмотреть файл

@ -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));
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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");

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -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"),

Просмотреть файл

@ -2742,8 +2742,8 @@ static void TryValueInitialization(Sema &S,
// without a user-provided constructor, then the object is
// zero-initialized and, if Ts 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);

Просмотреть файл

@ -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,

Просмотреть файл

@ -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

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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;

Просмотреть файл

@ -314,10 +314,10 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
VisitDeclContext(D->getDeclContext());
switch (D->getTagKind()) {
case TagDecl::TK_struct: Out << "@S"; break;
case TagDecl::TK_class: Out << "@C"; break;
case TagDecl::TK_union: Out << "@U"; break;
case TagDecl::TK_enum: Out << "@E"; break;
case TTK_Struct: Out << "@S"; break;
case TTK_Class: Out << "@C"; break;
case TTK_Union: Out << "@U"; break;
case TTK_Enum: Out << "@E"; break;
}
Out << '@';

Просмотреть файл

@ -60,10 +60,10 @@ static CXCursorKind GetCursorKind(Decl *D) {
default:
if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
switch (TD->getTagKind()) {
case TagDecl::TK_struct: return CXCursor_StructDecl;
case TagDecl::TK_class: return CXCursor_ClassDecl;
case TagDecl::TK_union: return CXCursor_UnionDecl;
case TagDecl::TK_enum: return CXCursor_EnumDecl;
case TTK_Struct: return CXCursor_StructDecl;
case TTK_Class: return CXCursor_ClassDecl;
case TTK_Union: return CXCursor_UnionDecl;
case TTK_Enum: return CXCursor_EnumDecl;
}
}