[cfe-commits] r77647 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/Type.cpp test/SemaTemplate/canonical-expr-type.cpp

Douglas Gregor dgregor at apple.com
Thu Jul 30 17:23:36 PDT 2009


Author: dgregor
Date: Thu Jul 30 19:23:35 2009
New Revision: 77647

URL: http://llvm.org/viewvc/llvm-project?rev=77647&view=rev
Log:
Build canonical types for dependently-sized array types.

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

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=77647&r1=77646&r2=77647&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Jul 30 19:23:35 2009
@@ -70,7 +70,7 @@
   llvm::FoldingSet<ConstantArrayType> ConstantArrayTypes;
   llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
   std::vector<VariableArrayType*> VariableArrayTypes;
-  std::vector<DependentSizedArrayType*> DependentSizedArrayTypes;
+  llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
   std::vector<DependentSizedExtVectorType*> DependentSizedExtVectorTypes;
   llvm::FoldingSet<VectorType> VectorTypes;
   llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=77647&r1=77646&r2=77647&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Jul 30 19:23:35 2009
@@ -1180,17 +1180,19 @@
 /// until template instantiation occurs, at which point this will
 /// become either a ConstantArrayType or a VariableArrayType.
 class DependentSizedArrayType : public ArrayType {
+  ASTContext &Context;
+  
   /// SizeExpr - An assignment expression that will instantiate to the
   /// size of the array.
   Stmt *SizeExpr;
   /// Brackets - The left and right array brackets.
   SourceRange Brackets;
   
-  DependentSizedArrayType(QualType et, QualType can, Expr *e,
-			  ArraySizeModifier sm, unsigned tq,
+  DependentSizedArrayType(ASTContext &Context, QualType et, QualType can, 
+                          Expr *e, ArraySizeModifier sm, unsigned tq,
                           SourceRange brackets)
     : ArrayType(DependentSizedArray, et, can, sm, tq),
-      SizeExpr((Stmt*) e), Brackets(brackets) {}
+      Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) {}
   friend class ASTContext;  // ASTContext creates these.
   virtual void Destroy(ASTContext& C);
 
@@ -1214,9 +1216,15 @@
   
   friend class StmtIteratorBase;
   
+  
   void Profile(llvm::FoldingSetNodeID &ID) {
-    assert(0 && "Cannnot unique DependentSizedArrayTypes.");
+    Profile(ID, Context, getElementType(), 
+            getSizeModifier(), getIndexTypeQualifier(), getSizeExpr());
   }
+  
+  static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context, 
+                      QualType ET, ArraySizeModifier SizeMod, 
+                      unsigned TypeQuals, Expr *E);
 };
 
 /// DependentSizedExtVectorType - This type represent an extended vector type

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=77647&r1=77646&r2=77647&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jul 30 19:23:35 2009
@@ -1371,8 +1371,7 @@
 
 /// getDependentSizedArrayType - Returns a non-unique reference to
 /// the type for a dependently-sized array of the specified element
-/// type. FIXME: We will need these to be uniqued, or at least
-/// comparable, at some point.
+/// type.
 QualType ASTContext::getDependentSizedArrayType(QualType EltTy,
                                                 Expr *NumElts,
                                                 ArrayType::ArraySizeModifier ASM,
@@ -1381,15 +1380,38 @@
   assert((NumElts->isTypeDependent() || NumElts->isValueDependent()) && 
          "Size must be type- or value-dependent!");
 
-  // Since we don't unique expressions, it isn't possible to unique
-  // dependently-sized array types.
-
-  DependentSizedArrayType *New =
-    new (*this,8) DependentSizedArrayType(EltTy, QualType(),
-                                          NumElts, ASM, EltTypeQuals,
-                                          Brackets);
+  llvm::FoldingSetNodeID ID;
+  DependentSizedArrayType::Profile(ID, *this, getCanonicalType(EltTy), ASM, 
+                                   EltTypeQuals, NumElts);
 
-  DependentSizedArrayTypes.push_back(New);
+  void *InsertPos = 0;
+  DependentSizedArrayType *Canon
+    = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
+  DependentSizedArrayType *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) DependentSizedArrayType(*this, EltTy, 
+                                                QualType(Canon, 0),
+                                                NumElts, ASM, EltTypeQuals,
+                                                Brackets);
+  } else {
+    QualType CanonEltTy = getCanonicalType(EltTy);
+    if (CanonEltTy == EltTy) {
+      New = new (*this,8) DependentSizedArrayType(*this, EltTy, QualType(),
+                                                  NumElts, ASM, EltTypeQuals,
+                                                  Brackets);
+      DependentSizedArrayTypes.InsertNode(New, InsertPos);
+    } else {
+      QualType Canon = getDependentSizedArrayType(CanonEltTy, NumElts,
+                                                  ASM, EltTypeQuals,
+                                                  SourceRange());
+      New = new (*this,8) DependentSizedArrayType(*this, EltTy, Canon,
+                                                  NumElts, ASM, EltTypeQuals,
+                                                  Brackets);      
+    }
+  }
+  
   Types.push_back(New);
   return QualType(New, 0);
 }

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=77647&r1=77646&r2=77647&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Jul 30 19:23:35 2009
@@ -64,6 +64,18 @@
   C.Deallocate(this);
 }
 
+void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID, 
+                                      ASTContext &Context,
+                                      QualType ET,
+                                      ArraySizeModifier SizeMod,
+                                      unsigned TypeQuals,
+                                      Expr *E) {
+  ID.AddPointer(ET.getAsOpaquePtr());
+  ID.AddInteger(SizeMod);
+  ID.AddInteger(TypeQuals);
+  E->Profile(ID, Context, true);
+}
+
 void DependentSizedExtVectorType::Destroy(ASTContext& C) {
   // FIXME: Deallocate size expression, once we're cloning properly.
 //  if (SizeExpr)

Modified: cfe/trunk/test/SemaTemplate/canonical-expr-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/canonical-expr-type.cpp?rev=77647&r1=77646&r2=77647&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/canonical-expr-type.cpp (original)
+++ cfe/trunk/test/SemaTemplate/canonical-expr-type.cpp Thu Jul 30 19:23:35 2009
@@ -13,4 +13,14 @@
 void f0(T x, __typeof__((f)(N)) y) { }
 
 template<typename U, U M>
-void f0(U u, __typeof__(f(M))) { } // expected-error{{redefinition}}
\ No newline at end of file
+void f0(U u, __typeof__(f(M))) { } // expected-error{{redefinition}}
+
+// Test dependently-sized array canonicalization
+template<typename T, int N, int M>
+void f1(T (&array)[N + M]) { } // expected-note{{previous}}
+
+template<typename T, int N, int M>
+void f1(T (&array)[M + N]) { }
+
+template<typename T, int M, int N>
+void f1(T (&array)[M + N]) { } // expected-error{{redefinition}}





More information about the cfe-commits mailing list