r239454 - [modules] Reconstruct template default argument inheritance on reload rather

Richard Smith richard-llvm at metafoo.co.uk
Tue Jun 9 18:47:59 PDT 2015


Author: rsmith
Date: Tue Jun  9 20:47:58 2015
New Revision: 239454

URL: http://llvm.org/viewvc/llvm-project?rev=239454&view=rev
Log:
[modules] Reconstruct template default argument inheritance on reload rather
than wasting storage and triggering eager deserializations by serializing it.

Modified:
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=239454&r1=239453&r2=239454&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Jun  9 20:47:58 2015
@@ -2034,11 +2034,6 @@ void ASTDeclReader::VisitTemplateTypePar
   D->setDeclaredWithTypename(Record[Idx++]);
 
   if (Record[Idx++])
-    // FIXME: Rebuild inherited default argument chain when linking together
-    // the redecl chain.
-    D->setInheritedDefaultArgument(
-        Reader.getContext(), ReadDeclAs<TemplateTypeParmDecl>(Record, Idx));
-  else
     D->setDefaultArgument(GetTypeSourceInfo(Record, Idx));
 }
 
@@ -2057,12 +2052,6 @@ void ASTDeclReader::VisitNonTypeTemplate
     // Rest of NonTypeTemplateParmDecl.
     D->ParameterPack = Record[Idx++];
     if (Record[Idx++])
-      // FIXME: Rebuild inherited default argument chain when linking together
-      // the redecl chain.
-      D->setInheritedDefaultArgument(
-          Reader.getContext(),
-          ReadDeclAs<NonTypeTemplateParmDecl>(Record, Idx));
-    else
       D->setDefaultArgument(Reader.ReadExpr(F));
   }
 }
@@ -2081,12 +2070,6 @@ void ASTDeclReader::VisitTemplateTemplat
     // Rest of TemplateTemplateParmDecl.
     D->ParameterPack = Record[Idx++];
     if (Record[Idx++])
-      // FIXME: Rebuild inherited default argument chain when linking together
-      // the redecl chain.
-      D->setInheritedDefaultArgument(
-          Reader.getContext(),
-          ReadDeclAs<TemplateTemplateParmDecl>(Record, Idx));
-    else
       D->setDefaultArgument(Reader.getContext(),
                             Reader.ReadTemplateArgumentLoc(F, Record, Idx));
   }
@@ -2917,6 +2900,44 @@ void ASTDeclReader::attachPreviousDeclIm
   llvm_unreachable("attachPreviousDecl on non-redeclarable declaration");
 }
 
+/// Inherit the default template argument from \p From to \p To. Returns
+/// \c false if there is no default template for \p From.
+template <typename ParmDecl>
+static bool inheritDefaultTemplateArgument(ASTContext &Context, ParmDecl *From,
+                                           Decl *ToD) {
+  auto *To = cast<ParmDecl>(ToD);
+  if (!From->hasDefaultArgument())
+    return false;
+  if (!To->hasDefaultArgument())
+    To->setInheritedDefaultArgument(Context, From);
+  return true;
+}
+
+static void inheritDefaultTemplateArguments(ASTContext &Context,
+                                            TemplateDecl *From,
+                                            TemplateDecl *To) {
+  auto *FromTP = From->getTemplateParameters();
+  auto *ToTP = To->getTemplateParameters();
+  assert(FromTP->size() == ToTP->size() && "merged mismatched templates?");
+
+  for (unsigned I = 0, N = FromTP->size(); I != N; ++I) {
+    NamedDecl *FromParam = FromTP->getParam(N - I - 1);
+    NamedDecl *ToParam = ToTP->getParam(N - I - 1);
+
+    if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam)) {
+      if (inheritDefaultTemplateArgument(Context, FTTP, ToParam))
+        break;
+    } else if (auto *FNTTP = dyn_cast<NonTypeTemplateParmDecl>(FromParam)) {
+      if (inheritDefaultTemplateArgument(Context, FNTTP, ToParam))
+        break;
+    } else {
+      if (inheritDefaultTemplateArgument(
+              Context, cast<TemplateTemplateParmDecl>(FromParam), ToParam))
+        break;
+    }
+  }
+}
+
 void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
                                        Decl *Previous, Decl *Canon) {
   assert(D && Previous);
@@ -2943,6 +2964,12 @@ void ASTDeclReader::attachPreviousDecl(A
   // be too.
   if (Previous->Used)
     D->Used = true;
+
+  // If the declaration declares a template, it may inherit default arguments
+  // from the previous declaration.
+  if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))
+    inheritDefaultTemplateArguments(Reader.getContext(),
+                                    cast<TemplateDecl>(Previous), TD);
 }
 
 template<typename DeclT>

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=239454&r1=239453&r2=239454&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Tue Jun  9 20:47:58 2015
@@ -1380,10 +1380,11 @@ void ASTDeclWriter::VisitTemplateTypePar
   VisitTypeDecl(D);
 
   Record.push_back(D->wasDeclaredWithTypename());
-  Record.push_back(D->defaultArgumentWasInherited());
-  if (D->defaultArgumentWasInherited())
-    Writer.AddDeclRef(D->getDefaultArgStorage().getInheritedFrom(), Record);
-  else
+
+  bool OwnsDefaultArg = D->hasDefaultArgument() &&
+                        !D->defaultArgumentWasInherited();
+  Record.push_back(OwnsDefaultArg);
+  if (OwnsDefaultArg)
     Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record);
 
   Code = serialization::DECL_TEMPLATE_TYPE_PARM;
@@ -1411,10 +1412,10 @@ void ASTDeclWriter::VisitNonTypeTemplate
   } else {
     // Rest of NonTypeTemplateParmDecl.
     Record.push_back(D->isParameterPack());
-    Record.push_back(D->defaultArgumentWasInherited());
-    if (D->defaultArgumentWasInherited())
-      Writer.AddDeclRef(D->getDefaultArgStorage().getInheritedFrom(), Record);
-    else
+    bool OwnsDefaultArg = D->hasDefaultArgument() &&
+                          !D->defaultArgumentWasInherited();
+    Record.push_back(OwnsDefaultArg);
+    if (OwnsDefaultArg)
       Writer.AddStmt(D->getDefaultArgument());
     Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
   }
@@ -1441,10 +1442,10 @@ void ASTDeclWriter::VisitTemplateTemplat
   } else {
     // Rest of TemplateTemplateParmDecl.
     Record.push_back(D->isParameterPack());
-    Record.push_back(D->defaultArgumentWasInherited());
-    if (D->defaultArgumentWasInherited())
-      Writer.AddDeclRef(D->getDefaultArgStorage().getInheritedFrom(), Record);
-    else
+    bool OwnsDefaultArg = D->hasDefaultArgument() &&
+                          !D->defaultArgumentWasInherited();
+    Record.push_back(OwnsDefaultArg);
+    if (OwnsDefaultArg)
       Writer.AddTemplateArgumentLoc(D->getDefaultArgument(), Record);
     Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
   }





More information about the cfe-commits mailing list