]> granicus.if.org Git - clang/commitdiff
Improve the representation of template type parameters. We now
authorDouglas Gregor <dgregor@apple.com>
Thu, 5 Feb 2009 23:33:38 +0000 (23:33 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 5 Feb 2009 23:33:38 +0000 (23:33 +0000)
canonicalize by template parameter depth, index, and name, and the
unnamed version of a template parameter serves as the canonical.

TemplateTypeParmDecl no longer needs to inherit from
TemplateParmPosition, since depth and index information is present
within the type.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63899 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
include/clang/AST/Decl.h
include/clang/AST/DeclTemplate.h
include/clang/AST/Type.h
lib/AST/ASTContext.cpp
lib/AST/DeclSerialization.cpp
lib/AST/DeclTemplate.cpp
lib/AST/Type.cpp
lib/AST/TypeSerialization.cpp

index bf6fa99f2c5d3acc2f878108ed36c9fea802d362..616b548269091a5ba6179f83ff99d2b77657903f 100644 (file)
@@ -68,6 +68,7 @@ class ASTContext {
   llvm::FoldingSet<VectorType> VectorTypes;
   llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
   llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
+  llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
   llvm::FoldingSet<ObjCQualifiedInterfaceType> ObjCQualifiedInterfaceTypes;
   llvm::FoldingSet<ObjCQualifiedIdType> ObjCQualifiedIdTypes;
   /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts.
@@ -256,9 +257,11 @@ public:
   /// getTypedefType - Return the unique reference to the type for the
   /// specified typename decl.
   QualType getTypedefType(TypedefDecl *Decl);
-  QualType getTemplateTypeParmType(TemplateTypeParmDecl *Decl);
   QualType getObjCInterfaceType(ObjCInterfaceDecl *Decl);
-  
+
+  QualType getTemplateTypeParmType(unsigned Depth, unsigned Index, 
+                                   IdentifierInfo *Name = 0);
+
   /// getObjCQualifiedInterfaceType - Return a 
   /// ObjCQualifiedInterfaceType type for the given interface decl and
   /// the conforming protocol list.
index b3ec04936d7115f268e69f617223d3f75e1f134e..15945affce456fd1af01e8a48c5542be0123060c 100644 (file)
@@ -762,13 +762,15 @@ protected:
 /// TypeDecl - Represents a declaration of a type.
 ///
 class TypeDecl : public NamedDecl {
-  /// TypeForDecl - This indicates the Type object that represents this
-  /// TypeDecl.  It is a cache maintained by ASTContext::getTypedefType,
-  /// ASTContext::getTagDeclType, and ASTContext::getTemplateTypeParmType.
+  /// TypeForDecl - This indicates the Type object that represents
+  /// this TypeDecl.  It is a cache maintained by
+  /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
+  /// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl.
   Type *TypeForDecl;
   friend class ASTContext;
   friend class DeclContext;
   friend class TagDecl;
+  friend class TemplateTypeParmDecl;
 
 protected:
   TypeDecl(Kind DK, DeclContext *DC, SourceLocation L,
index 98fd42df4345d0b70a18d7dfc703a082ddd9ca46..64e4ea95b5deda39a86b392041d9a9b36a9ebcdc 100644 (file)
@@ -201,30 +201,28 @@ public:
 /// @code
 /// template<typename T> class vector;
 /// @endcode
-class TemplateTypeParmDecl
-  : public TypeDecl, protected TemplateParmPosition {
-  /// Typename - Whether this template type parameter was declaration
-  /// with the 'typename' keyword. If false, it was declared with the
+class TemplateTypeParmDecl : public TypeDecl {
+  /// \brief Whether this template type parameter was declaration with
+  /// the 'typename' keyword. If false, it was declared with the
   /// 'class' keyword.
   bool Typename : 1;
 
-  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
-                       unsigned P, IdentifierInfo *Id, bool Typename)
-    : TypeDecl(TemplateTypeParm, DC, L, Id), TemplateParmPosition(D, P),
-      Typename(Typename) { }
+  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 
+                       bool Typename, QualType Type)
+    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename) { 
+    TypeForDecl = Type.getTypePtr();
+  }
+
 public:
   static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
                                       SourceLocation L, unsigned D, unsigned P,
                                       IdentifierInfo *Id, bool Typename);
 
-  /// wasDeclarationWithTypename - Whether this template type
-  /// parameter was declared with the 'typename' keyword. If not, it
-  /// was declared with the 'class' keyword.
+  /// \brief Whether this template type parameter was declared with
+  /// the 'typename' keyword. If not, it was declared with the 'class'
+  /// keyword.
   bool wasDeclaredWithTypename() const { return Typename; }
 
-  using TemplateParmPosition::getDepth;
-  using TemplateParmPosition::getPosition;
-
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {
     return D->getKind() == TemplateTypeParm;
@@ -232,10 +230,10 @@ public:
   static bool classof(const TemplateTypeParmDecl *D) { return true; }
 
 protected:
-  /// EmitImpl - Serialize this TemplateTypeParmDecl.  Called by Decl::Emit.
+  /// Serialize this TemplateTypeParmDecl.  Called by Decl::Emit.
   virtual void EmitImpl(llvm::Serializer& S) const;
 
-  /// CreateImpl - Deserialize a TemplateTypeParmDecl.  Called by Decl::Create.
+  /// Deserialize a TemplateTypeParmDecl.  Called by Decl::Create.
   static TemplateTypeParmDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
 
   friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
index 6b2797307f8a5688f2c904f5d5167dc240b9e2da..666d952645e4947c084934c76dc4c95a9aff57cd 100644 (file)
@@ -1188,7 +1188,7 @@ public:
   TypedefDecl *getDecl() const { return Decl; }
   
   /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
-  /// potentially looking through *all* consequtive typedefs.  This returns the
+  /// potentially looking through *all* consecutive typedefs.  This returns the
   /// sum of the type qualifiers, so if you have:
   ///   typedef const int A;
   ///   typedef volatile A B;
@@ -1350,20 +1350,40 @@ public:
   static bool classof(const EnumType *) { return true; }
 };
 
-class TemplateTypeParmType : public Type {
-  TemplateTypeParmDecl *Decl;
+class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+  unsigned Depth : 16;
+  unsigned Index : 16;
+  IdentifierInfo *Name;
 
-protected:
-  TemplateTypeParmType(TemplateTypeParmDecl *D)
-    : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true), Decl(D) { }
+  TemplateTypeParmType(unsigned D, unsigned I, IdentifierInfo *N, 
+                       QualType Canon) 
+    : Type(TemplateTypeParm, Canon, /*Dependent=*/true),
+      Depth(D), Index(I), Name(N) { }
 
-  friend class ASTContext; // ASTContext creates these
+  TemplateTypeParmType(unsigned D, unsigned I) 
+    : Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true),
+      Depth(D), Index(I), Name(0) { }
 
-public:
-  TemplateTypeParmDecl *getDecl() const { return Decl; }
+  friend class ASTContext;  // ASTContext creates these
 
+public:
+  unsigned getDepth() const { return Depth; }
+  unsigned getIndex() const { return Index; }
+  IdentifierInfo *getName() const { return Name; }
+  
   virtual void getAsStringInternal(std::string &InnerString) const;
 
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Depth, Index, Name);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth, 
+                      unsigned Index, IdentifierInfo *Name) {
+    ID.AddInteger(Depth);
+    ID.AddInteger(Index);
+    ID.AddPointer(Name);
+  }
+
   static bool classof(const Type *T) { 
     return T->getTypeClass() == TemplateTypeParm; 
   }
@@ -1374,7 +1394,7 @@ protected:
   static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
   friend class Type;
 };
-  
+
 /// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
 /// object oriented design.  They basically correspond to C++ classes.  There
 /// are two kinds of interface types, normal interfaces like "NSString" and
index 7784aed764ceb82f2a9ef888d3b641efec658f75..a87a902d062dc4bcdb8cc1d4b00a358b27479132 100644 (file)
@@ -1144,9 +1144,9 @@ QualType ASTContext::getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl) {
   
   if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl))
     return getTypedefType(Typedef);
-  else if (TemplateTypeParmDecl *TP = dyn_cast<TemplateTypeParmDecl>(Decl))
-    return getTemplateTypeParmType(TP);
-  else if (ObjCInterfaceDecl *ObjCInterface = dyn_cast<ObjCInterfaceDecl>(Decl))
+  else if (isa<TemplateTypeParmDecl>(Decl)) {
+    assert(false && "Template type parameter types are always available.");
+  else if (ObjCInterfaceDecl *ObjCInterface = dyn_cast<ObjCInterfaceDecl>(Decl))
     return getObjCInterfaceType(ObjCInterface);
 
   if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Decl)) {
@@ -1185,16 +1185,6 @@ QualType ASTContext::getTypedefType(TypedefDecl *Decl) {
   return QualType(Decl->TypeForDecl, 0);
 }
 
-/// getTemplateTypeParmType - Return the unique reference to the type
-/// for the specified template type parameter declaration. 
-QualType ASTContext::getTemplateTypeParmType(TemplateTypeParmDecl *Decl) {
-  if (!Decl->TypeForDecl) {
-    Decl->TypeForDecl = new (*this,8) TemplateTypeParmType(Decl);
-    Types.push_back(Decl->TypeForDecl);
-  }
-  return QualType(Decl->TypeForDecl, 0);
-}
-
 /// getObjCInterfaceType - Return the unique reference to the type for the
 /// specified ObjC interface decl.
 QualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) {
@@ -1205,6 +1195,31 @@ QualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) {
   return QualType(Decl->TypeForDecl, 0);
 }
 
+/// \brief Retrieve the template type parameter type for a template
+/// parameter with the given depth, index, and (optionally) name.
+QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, 
+                                             IdentifierInfo *Name) {
+  llvm::FoldingSetNodeID ID;
+  TemplateTypeParmType::Profile(ID, Depth, Index, Name);
+  void *InsertPos = 0;
+  TemplateTypeParmType *TypeParm 
+    = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (TypeParm)
+    return QualType(TypeParm, 0);
+  
+  if (Name)
+    TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, Name,
+                                         getTemplateTypeParmType(Depth, Index));
+  else
+    TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index);
+
+  Types.push_back(TypeParm);
+  TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos);
+
+  return QualType(TypeParm, 0);
+}
+
 /// CmpProtocolNames - Comparison predicate for sorting protocols
 /// alphabetically.
 static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,
index dcb8cda33bfd4454c6299dbfa4a60a1491af6adc..ea027df1df9ed7165d6dafc1edd442b1c4e676d2 100644 (file)
@@ -598,21 +598,17 @@ TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D, ASTContext& C) {
 //===----------------------------------------------------------------------===//
 
 void TemplateTypeParmDecl::EmitImpl(Serializer& S) const {
-  S.EmitInt(Depth);
-  S.EmitInt(Position);
   S.EmitBool(Typename);
-  NamedDecl::EmitInRec(S);
+  TypeDecl::EmitInRec(S);
 }
 
 TemplateTypeParmDecl *
 TemplateTypeParmDecl::CreateImpl(Deserializer& D, ASTContext& C) {
-  unsigned Depth = D.ReadInt();
-  unsigned Position = D.ReadInt();
   bool Typename = D.ReadBool();
   TemplateTypeParmDecl *decl
-    = new (C) TemplateTypeParmDecl(0, SourceLocation(), Depth, Position,
-                                   0, Typename);
-  decl->NamedDecl::ReadInRec(D, C);
+    = new (C) TemplateTypeParmDecl(0, SourceLocation(), 0, Typename, 
+                                   QualType());
+  decl->TypeDecl::ReadInRec(D, C);
   return decl;
 }
 
index 08cd5b377d21533091f954f4aaec3b096232b0e6..394939569ea86eceef99b796e5da0e6f4a5e3ab5 100644 (file)
@@ -78,7 +78,8 @@ TemplateTypeParmDecl *
 TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
                              SourceLocation L, unsigned D, unsigned P,
                              IdentifierInfo *Id, bool Typename) {
-  return new (C) TemplateTypeParmDecl(DC, L, D, P, Id, Typename);
+  QualType Type = C.getTemplateTypeParmType(D, P, Id);
+  return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type);
 }
 
 //===----------------------------------------------------------------------===//
index f39a325e0d3821c16f9a4568daf526941b02220c..199ad29ec60057d8ffaad25ffebf837e7e343665 100644 (file)
@@ -1138,7 +1138,12 @@ void TypedefType::getAsStringInternal(std::string &InnerString) const {
 void TemplateTypeParmType::getAsStringInternal(std::string &InnerString) const {
   if (!InnerString.empty())    // Prefix the basic type, e.g. 'parmname X'.
     InnerString = ' ' + InnerString;
-  InnerString = getDecl()->getIdentifier()->getName() + InnerString;
+
+  if (!Name)
+    InnerString = "type-parameter-" + llvm::utostr_32(Depth) + '-' + 
+      llvm::utostr_32(Index) + InnerString;
+  else
+    InnerString = Name->getName() + InnerString;
 }
 
 void ObjCInterfaceType::getAsStringInternal(std::string &InnerString) const {
index 12c3d03c1214383189b60a2c47b85f14d93c6d96..57598d3afcaa6a978295e75515a448e24849926d 100644 (file)
@@ -127,7 +127,7 @@ void Type::Create(ASTContext& Context, unsigned i, Deserializer& D) {
       break;
 
     case Type::TemplateTypeParm:
-      D.RegisterPtr(PtrID,TemplateTypeParmType::CreateImpl(Context, D));
+      D.RegisterPtr(PtrID, TemplateTypeParmType::CreateImpl(Context, D));
       break;
 
     case Type::VariableArray:
@@ -364,20 +364,18 @@ Type* TypeOfType::CreateImpl(ASTContext& Context, Deserializer& D) {
 //===----------------------------------------------------------------------===//
 
 void TemplateTypeParmType::EmitImpl(Serializer& S) const {
-  S.EmitPtr(getDecl());
+  S.EmitInt(Depth);
+  S.EmitInt(Index);
+  S.EmitPtr(Name);
 }
 
 Type* TemplateTypeParmType::CreateImpl(ASTContext& Context, Deserializer& D) {
-  std::vector<Type*>& Types = 
-    const_cast<std::vector<Type*>&>(Context.getTypes());
-  
-  TemplateTypeParmType* T = new TemplateTypeParmType(NULL);
-  Types.push_back(T);
-  
-  D.ReadPtr(T->Decl); // May be backpatched.
-  return T;
+  unsigned Depth = D.ReadInt();
+  unsigned Index = D.ReadInt();
+  IdentifierInfo *Name = D.ReadPtr<IdentifierInfo>();
+  return Context.getTemplateTypeParmType(Depth, Index, Name).getTypePtr();
 }
-  
+
 //===----------------------------------------------------------------------===//
 // VariableArrayType
 //===----------------------------------------------------------------------===//