diff options
author | John McCall <rjmccall@apple.com> | 2010-03-10 03:28:59 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-03-10 03:28:59 +0000 |
commit | 3cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4 (patch) | |
tree | 84f7dae6f0d5da51df0529ca91ff0c7fdf3f152e /include/clang | |
parent | d7fdae5ea0158f91f0683044bb3a7dee0426bfe0 (diff) |
Create a new InjectedClassNameType to represent bare-word references to the
injected class name of a class template or class template partial specialization.
This is a non-canonical type; the canonical type is still a template
specialization type. This becomes the TypeForDecl of the pattern declaration,
which cleans up some amount of code (and complicates some other parts, but
whatever).
Fixes PR6326 and probably a few others, primarily by re-establishing a few
invariants about TypeLoc sizes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98134 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/ASTContext.h | 7 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 1 | ||||
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 22 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 41 | ||||
-rw-r--r-- | include/clang/AST/TypeLoc.h | 8 | ||||
-rw-r--r-- | include/clang/AST/TypeNodes.def | 1 | ||||
-rw-r--r-- | include/clang/Frontend/PCHBitCodes.h | 4 |
7 files changed, 77 insertions, 7 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 0838a3d0eb..fab63f556b 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -586,6 +586,8 @@ public: /// specified typename decl. QualType getTypedefType(const TypedefDecl *Decl); + QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST); + QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced, QualType Replacement); @@ -602,6 +604,11 @@ public: const TemplateArgumentListInfo &Args, QualType Canon = QualType()); + TypeSourceInfo * + getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc, + const TemplateArgumentListInfo &Args, + QualType Canon = QualType()); + QualType getQualifiedNameType(NestedNameSpecifier *NNS, QualType NamedType); QualType getTypenameType(NestedNameSpecifier *NNS, diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 91aeff3439..bd9f01b0b5 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1429,7 +1429,6 @@ class TypeDecl : public NamedDecl { friend class DeclContext; friend class TagDecl; friend class TemplateTypeParmDecl; - friend class ClassTemplateSpecializationDecl; friend class TagType; protected: diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index ced174716c..560ce46ede 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -771,6 +771,10 @@ class ClassTemplateSpecializationDecl llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *> SpecializedTemplate; + /// \brief The type-as-written of an explicit template specialization. + /// Does not apply to implicit specializations. + TypeSourceInfo *TypeAsWritten; + /// \brief The template arguments used to describe this specialization. TemplateArgumentList TemplateArgs; @@ -883,8 +887,14 @@ public: /// \brief Sets the type of this specialization as it was written by /// the user. This will be a class template specialization type. - void setTypeAsWritten(QualType T) { - TypeForDecl = T.getTypePtr(); + void setTypeAsWritten(TypeSourceInfo *T) { + TypeAsWritten = T; + } + + /// \brief Gets the type of this specialization as it was written by + /// the user, if it was so written. + TypeSourceInfo *getTypeAsWritten() const { + return TypeAsWritten; } void Profile(llvm::FoldingSetNodeID &ID) const { @@ -921,6 +931,7 @@ class ClassTemplatePartialSpecializationDecl TemplateParameterList* TemplateParams; /// \brief The source info for the template arguments as written. + /// FIXME: redundant with TypeAsWritten? TemplateArgumentLoc *ArgsAsWritten; unsigned NumArgsAsWritten; @@ -954,6 +965,7 @@ public: ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, const TemplateArgumentListInfo &ArgInfos, + QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl); /// Get the list of template parameters @@ -1139,8 +1151,8 @@ public: /// the type \p T, or NULL if no such partial specialization exists. ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T); - /// \brief Retrieve the type of the injected-class-name for this - /// class template. + /// \brief Retrieve the template specialization type of the + /// injected-class-name for this class template. /// /// The injected-class-name for a class template \c X is \c /// X<template-args>, where \c template-args is formed from the @@ -1153,7 +1165,7 @@ public: /// typedef array this_type; // "array" is equivalent to "array<T, N>" /// }; /// \endcode - QualType getInjectedClassNameType(ASTContext &Context); + QualType getInjectedClassNameSpecialization(ASTContext &Context); /// \brief Retrieve the member class template that this class template was /// derived from. diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index bd8a6bc846..111be55621 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -2440,6 +2440,47 @@ public: static bool classof(const TemplateSpecializationType *T) { return true; } }; +/// \brief The injected class name of a C++ class template. Used to +/// record that a type was spelled with a bare identifier rather than +/// as a template-id; the equivalent for non-templated classes is just +/// RecordType. +/// +/// For consistency, template instantiation turns these into RecordTypes. +/// +/// The desugared form is always a unqualified TemplateSpecializationType. +/// The canonical form is always either a TemplateSpecializationType +/// (when dependent) or a RecordType (otherwise). +class InjectedClassNameType : public Type { + CXXRecordDecl *Decl; + + QualType UnderlyingType; + + friend class ASTContext; // ASTContext creates these. + InjectedClassNameType(CXXRecordDecl *D, QualType TST, QualType Canon) + : Type(InjectedClassName, Canon, Canon->isDependentType()), + Decl(D), UnderlyingType(TST) { + assert(isa<TemplateSpecializationType>(TST)); + assert(!TST.hasQualifiers()); + assert(TST->getCanonicalTypeInternal() == Canon); + } + +public: + QualType getUnderlyingType() const { return UnderlyingType; } + const TemplateSpecializationType *getUnderlyingTST() const { + return cast<TemplateSpecializationType>(UnderlyingType.getTypePtr()); + } + + CXXRecordDecl *getDecl() const { return Decl; } + + bool isSugared() const { return true; } + QualType desugar() const { return UnderlyingType; } + + static bool classof(const Type *T) { + return T->getTypeClass() == InjectedClassName; + } + static bool classof(const InjectedClassNameType *T) { return true; } +}; + /// \brief Represents a type that was referred to via a qualified /// name, e.g., N::M::type. /// diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 6fb51edb76..27659bd02f 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -488,6 +488,14 @@ public: } }; +/// \brief Wrapper for source info for injected class names of class +/// templates. +class InjectedClassNameTypeLoc : + public InheritingConcreteTypeLoc<TypeSpecTypeLoc, + InjectedClassNameTypeLoc, + InjectedClassNameType> { +}; + /// \brief Wrapper for source info for unresolved typename using decls. class UnresolvedUsingTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def index 8187caddc6..e75202e50a 100644 --- a/include/clang/AST/TypeNodes.def +++ b/include/clang/AST/TypeNodes.def @@ -91,6 +91,7 @@ DEPENDENT_TYPE(TemplateTypeParm, Type) NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type) NON_CANONICAL_TYPE(QualifiedName, Type) +NON_CANONICAL_TYPE(InjectedClassName, Type) DEPENDENT_TYPE(Typename, Type) TYPE(ObjCInterface, Type) TYPE(ObjCObjectPointer, Type) diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index d4014b3075..e234e9838a 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -408,7 +408,9 @@ namespace clang { /// \brief A SubstTemplateTypeParmType record. TYPE_SUBST_TEMPLATE_TYPE_PARM = 25, /// \brief An UnresolvedUsingType record. - TYPE_UNRESOLVED_USING = 26 + TYPE_UNRESOLVED_USING = 26, + /// \brief An InjectedClassNameType record. + TYPE_INJECTED_CLASS_NAME = 27 }; /// \brief The type IDs for special types constructed by semantic |