aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-03-10 03:28:59 +0000
committerJohn McCall <rjmccall@apple.com>2010-03-10 03:28:59 +0000
commit3cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4 (patch)
tree84f7dae6f0d5da51df0529ca91ff0c7fdf3f152e /include/clang
parentd7fdae5ea0158f91f0683044bb3a7dee0426bfe0 (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.h7
-rw-r--r--include/clang/AST/Decl.h1
-rw-r--r--include/clang/AST/DeclTemplate.h22
-rw-r--r--include/clang/AST/Type.h41
-rw-r--r--include/clang/AST/TypeLoc.h8
-rw-r--r--include/clang/AST/TypeNodes.def1
-rw-r--r--include/clang/Frontend/PCHBitCodes.h4
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