зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
380c213995
Коммит
465d41b92b
|
@ -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
|
||||
|
|
110
lib/AST/Type.cpp
110
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)
|
||||
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 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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче