]> granicus.if.org Git - clang/commitdiff
Canonicalize dependent extended vector types.
authorDouglas Gregor <dgregor@apple.com>
Fri, 31 Jul 2009 03:54:25 +0000 (03:54 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 31 Jul 2009 03:54:25 +0000 (03:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77663 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
include/clang/AST/Type.h
lib/AST/ASTContext.cpp
lib/AST/Type.cpp
test/SemaTemplate/canonical-expr-type.cpp

index 1c64f0be054af5d5da81e2477c264b1200822136..abbcb443774740bbc0f650aa50ff5b56e23e2ba9 100644 (file)
@@ -71,7 +71,7 @@ class ASTContext {
   llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
   std::vector<VariableArrayType*> VariableArrayTypes;
   llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
-  std::vector<DependentSizedExtVectorType*> DependentSizedExtVectorTypes;
+  llvm::FoldingSet<DependentSizedExtVectorType> DependentSizedExtVectorTypes;
   llvm::FoldingSet<VectorType> VectorTypes;
   llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
   llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;
index 411a279cd0c795f05c54c3fa583d2633fd1488d0..7bf877ed1ab25ebb1f6b2cba40e489099700368b 100644 (file)
@@ -1235,21 +1235,23 @@ public:
 ///   typedef T __attribute__((ext_vector_type(Size))) type;
 /// }
 /// @endcode
-class DependentSizedExtVectorType : public Type {
+class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
+  ASTContext &Context;
   Expr *SizeExpr;
   /// ElementType - The element type of the array.
   QualType ElementType;
   SourceLocation loc;
   
-  DependentSizedExtVectorType(QualType ElementType, QualType can
-                              Expr *SizeExpr, SourceLocation loc)
+  DependentSizedExtVectorType(ASTContext &Context, QualType ElementType
+                              QualType can, Expr *SizeExpr, SourceLocation loc)
     : Type (DependentSizedExtVector, can, true), 
-    SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) {}
+      Context(Context), SizeExpr(SizeExpr), ElementType(ElementType), 
+      loc(loc) {}
   friend class ASTContext;
   virtual void Destroy(ASTContext& C);
 
 public:
-  const Expr *getSizeExpr() const { return SizeExpr; }
+  Expr *getSizeExpr() const { return SizeExpr; }
   QualType getElementType() const { return ElementType; }
   SourceLocation getAttributeLoc() const { return loc; }
 
@@ -1260,6 +1262,13 @@ public:
     return T->getTypeClass() == DependentSizedExtVector; 
   }
   static bool classof(const DependentSizedExtVectorType *) { return true; } 
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Context, getElementType(), getSizeExpr());
+  }
+  
+  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+                      QualType ElementType, Expr *SizeExpr);
 };
   
 
index 912b302f74eba09fd84a6db7e13b07fce45206d4..1b73679beb7c2f7f4b285566f2871c0c9d363d61 100644 (file)
@@ -1515,11 +1515,35 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) {
 QualType ASTContext::getDependentSizedExtVectorType(QualType vecType, 
                                                     Expr *SizeExpr,
                                                     SourceLocation AttrLoc) {
-  DependentSizedExtVectorType *New =
-      new (*this,8) DependentSizedExtVectorType(vecType, QualType(), 
-                                                SizeExpr, AttrLoc);
-
-  DependentSizedExtVectorTypes.push_back(New);
+  llvm::FoldingSetNodeID ID;
+  DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType), 
+                                       SizeExpr);
+  
+  void *InsertPos = 0;
+  DependentSizedExtVectorType *Canon
+    = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+  DependentSizedExtVectorType *New;
+  if (Canon) {
+    // We already have a canonical version of this array type; use it as
+    // the canonical type for a newly-built type.
+    New = new (*this,8) DependentSizedExtVectorType(*this, vecType,
+                                                    QualType(Canon, 0),
+                                                    SizeExpr, AttrLoc);
+  } else {
+    QualType CanonVecTy = getCanonicalType(vecType);
+    if (CanonVecTy == vecType) {
+      New = new (*this,8) DependentSizedExtVectorType(*this, vecType, 
+                                                      QualType(), SizeExpr, 
+                                                      AttrLoc);
+      DependentSizedExtVectorTypes.InsertNode(New, InsertPos);
+    } else {
+      QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr,
+                                                      SourceLocation());
+      New = new (*this,8) DependentSizedExtVectorType(*this, vecType, Canon,
+                                                      SizeExpr, AttrLoc);
+    }
+  }
+  
   Types.push_back(New);
   return QualType(New, 0);
 }
index ed91e80c3e8f4dadf3c69934241efd27927b759a..bf506415ac645b83c237b3475addec1c8e3296e5 100644 (file)
@@ -76,6 +76,14 @@ void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
   E->Profile(ID, Context, true);
 }
 
+void 
+DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID, 
+                                     ASTContext &Context,
+                                     QualType ElementType, Expr *SizeExpr) {
+  ID.AddPointer(ElementType.getAsOpaquePtr());
+  SizeExpr->Profile(ID, Context, true);
+}
+
 void DependentSizedExtVectorType::Destroy(ASTContext& C) {
   // FIXME: Deallocate size expression, once we're cloning properly.
 //  if (SizeExpr)
index 767e0055d8f5c5b686090e4d2235494c4cefb9c3..48147f0e4c6e0e9cb9a5d483e7cbf3fd642a4f80 100644 (file)
@@ -24,3 +24,15 @@ void f1(T (&array)[M + N]) { }
 
 template<typename T, int M, int N>
 void f1(T (&array)[M + N]) { } // expected-error{{redefinition}}
+
+// Test dependently-sized extended vector type canonicalization
+template<typename T, int N, int M>
+struct X2 {
+  typedef T __attribute__((ext_vector_type(N))) type1;
+  typedef T __attribute__((ext_vector_type(M))) type2;
+  typedef T __attribute__((ext_vector_type(N))) type3;
+  
+  void f0(type1); // expected-note{{previous}}
+  void f0(type2);
+  void f0(type3); // expected-error{{redeclared}}
+};