Canonicalization for dependent typeof(expr) types.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77639 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e9bcc04..81cab92 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1876,9 +1876,26 @@
 /// on canonical type's (which are always unique).
 QualType ASTContext::getTypeOfExprType(Expr *tofExpr) {
   TypeOfExprType *toe;
-  if (tofExpr->isTypeDependent())
-    toe = new (*this, 8) TypeOfExprType(tofExpr);
-  else {
+  if (tofExpr->isTypeDependent()) {
+    llvm::FoldingSetNodeID ID;
+    DependentTypeOfExprType::Profile(ID, *this, tofExpr);
+    
+    void *InsertPos = 0;
+    DependentTypeOfExprType *Canon
+      = DependentTypeOfExprTypes.FindNodeOrInsertPos(ID, InsertPos);
+    if (Canon) {
+      // We already have a "canonical" version of an identical, dependent
+      // typeof(expr) type. Use that as our canonical type.
+      toe = new (*this, 8) TypeOfExprType(tofExpr, 
+                                          QualType((TypeOfExprType*)Canon, 0));
+    }
+    else {
+      // Build a new, canonical typeof(expr) type.
+      Canon = new (*this, 8) DependentTypeOfExprType(*this, tofExpr);
+      DependentTypeOfExprTypes.InsertNode(Canon, InsertPos);
+      toe = Canon;
+    }
+  } else {
     QualType Canonical = getCanonicalType(tofExpr->getType());
     toe = new (*this,8) TypeOfExprType(tofExpr, Canonical);
   }
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 688777d..8039d97 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -602,9 +602,9 @@
 }
 
 void StmtProfiler::VisitDecl(Decl *D) {
-  if (Canonical) {
+  if (Canonical && D) {
     if (NonTypeTemplateParmDecl *NTTP 
-        = dyn_cast_or_null<NonTypeTemplateParmDecl>(D)) {
+        = dyn_cast<NonTypeTemplateParmDecl>(D)) {
       ID.AddInteger(NTTP->getDepth());
       ID.AddInteger(NTTP->getIndex());
       VisitType(NTTP->getType());
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 789bac3..76d3546 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -958,6 +958,11 @@
   : Type(TypeOfExpr, can, E->isTypeDependent()), TOExpr(E) {
 }
 
+void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID, 
+                                      ASTContext &Context, Expr *E) {
+  E->Profile(ID, Context, true);
+}
+
 DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
   : Type(Decltype, can, E->isTypeDependent()), E(E), 
   UnderlyingType(underlyingType) {