r233264 - [Modules] Preserve source order for the map of late parsed templates.

Chandler Carruth chandlerc at gmail.com
Thu Mar 26 02:08:16 PDT 2015


Author: chandlerc
Date: Thu Mar 26 04:08:15 2015
New Revision: 233264

URL: http://llvm.org/viewvc/llvm-project?rev=233264&view=rev
Log:
[Modules] Preserve source order for the map of late parsed templates.

Clang was inserting these into a dense map. While it never iterated the
dense map during normal compilation, it did when emitting a module. Fix
this by using a standard MapVector to preserve the order in which we
encounter the late parsed templates.

I suspect this still isn't ideal, as we don't seem to remove things from
this map even when we mark the templates as no longer late parsed. But
I don't know enough about this particular extension to craft a nice,
subtle test case covering this. I've managed to get the stress test to
at least do some late parsing and demonstrate the core problem here.
This patch fixes the test and provides deterministic behavior which is
a strict improvement over the prior state.

I've cleaned up some of the code here as well to be explicit about
inserting when that is what is actually going on.

Modified:
    cfe/trunk/include/clang/Sema/ExternalSemaSource.h
    cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/Modules/stress1.cpp

Modified: cfe/trunk/include/clang/Sema/ExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ExternalSemaSource.h?rev=233264&r1=233263&r2=233264&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/ExternalSemaSource.h Thu Mar 26 04:08:15 2015
@@ -182,7 +182,7 @@ public:
   /// external source should take care not to introduce the same map entries
   /// repeatedly.
   virtual void ReadLateParsedTemplates(
-      llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {}
+      llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {}
 
   /// \copydoc Sema::CorrectTypo
   /// \note LookupKind must correspond to a valid Sema::LookupNameKind

Modified: cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h?rev=233264&r1=233263&r2=233264&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h Thu Mar 26 04:08:15 2015
@@ -331,8 +331,8 @@ public:
   /// external source should take care not to introduce the same map entries
   /// repeatedly.
   void ReadLateParsedTemplates(
-                         llvm::DenseMap<const FunctionDecl *,
-                                        LateParsedTemplate *> &LPTMap) override;
+      llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap)
+      override;
 
   /// \copydoc ExternalSemaSource::CorrectTypo
   /// \note Returns the first nonempty correction.

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=233264&r1=233263&r2=233264&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Mar 26 04:08:15 2015
@@ -455,8 +455,8 @@ public:
   SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2>
     DelayedDefaultedMemberExceptionSpecs;
 
-  typedef llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *>
-  LateParsedTemplateMapT;
+  typedef llvm::MapVector<const FunctionDecl *, LateParsedTemplate *>
+      LateParsedTemplateMapT;
   LateParsedTemplateMapT LateParsedTemplateMap;
 
   /// \brief Callback to the parser to parse templated functions when needed.

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=233264&r1=233263&r2=233264&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Thu Mar 26 04:08:15 2015
@@ -1832,8 +1832,8 @@ public:
                                            SourceLocation> > &Pending) override;
 
   void ReadLateParsedTemplates(
-                         llvm::DenseMap<const FunctionDecl *,
-                                        LateParsedTemplate *> &LPTMap) override;
+      llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap)
+      override;
 
   /// \brief Load a selector from disk, registering its ID if it exists.
   void LoadSelector(Selector Sel);

Modified: cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp?rev=233264&r1=233263&r2=233264&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp (original)
+++ cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp Thu Mar 26 04:08:15 2015
@@ -276,7 +276,7 @@ void MultiplexExternalSemaSource::ReadPe
 }
 
 void MultiplexExternalSemaSource::ReadLateParsedTemplates(
-    llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {
+    llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {
   for (size_t i = 0; i < Sources.size(); ++i)
     Sources[i]->ReadLateParsedTemplates(LPTMap);
 }

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=233264&r1=233263&r2=233264&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Mar 26 04:08:15 2015
@@ -8305,7 +8305,7 @@ void Sema::MarkAsLateParsedTemplate(Func
   // Take tokens to avoid allocations
   LPT->Toks.swap(Toks);
   LPT->D = FnD;
-  LateParsedTemplateMap[FD] = LPT;
+  LateParsedTemplateMap.insert(std::make_pair(FD, LPT));
 
   FD->setLateTemplateParsed(true);
 }

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=233264&r1=233263&r2=233264&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Mar 26 04:08:15 2015
@@ -7453,7 +7453,7 @@ void ASTReader::ReadPendingInstantiation
 }
 
 void ASTReader::ReadLateParsedTemplates(
-    llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {
+    llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {
   for (unsigned Idx = 0, N = LateParsedTemplates.size(); Idx < N;
        /* In loop */) {
     FunctionDecl *FD = cast<FunctionDecl>(GetDecl(LateParsedTemplates[Idx++]));
@@ -7469,7 +7469,7 @@ void ASTReader::ReadLateParsedTemplates(
     for (unsigned T = 0; T < TokN; ++T)
       LT->Toks.push_back(ReadToken(*F, LateParsedTemplates, Idx));
 
-    LPTMap[FD] = LT;
+    LPTMap.insert(std::make_pair(FD, LT));
   }
 
   LateParsedTemplates.clear();

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=233264&r1=233263&r2=233264&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Mar 26 04:08:15 2015
@@ -4089,11 +4089,10 @@ void ASTWriter::WriteLateParsedTemplates
     return;
 
   RecordData Record;
-  for (Sema::LateParsedTemplateMapT::iterator It = LPTMap.begin(),
-                                              ItEnd = LPTMap.end();
-       It != ItEnd; ++It) {
-    LateParsedTemplate *LPT = It->second;
-    AddDeclRef(It->first, Record);
+  for (auto LPTMapEntry : LPTMap) {
+    const FunctionDecl *FD = LPTMapEntry.first;
+    LateParsedTemplate *LPT = LPTMapEntry.second;
+    AddDeclRef(FD, Record);
     AddDeclRef(LPT->D, Record);
     Record.push_back(LPT->Toks.size());
 

Modified: cfe/trunk/test/Modules/stress1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/stress1.cpp?rev=233264&r1=233263&r2=233264&view=diff
==============================================================================
--- cfe/trunk/test/Modules/stress1.cpp (original)
+++ cfe/trunk/test/Modules/stress1.cpp Thu Mar 26 04:08:15 2015
@@ -17,13 +17,22 @@
 //
 // RUN: diff %t/m00.pcm %t/m00_check.pcm
 //
-// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
+// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 -fdelayed-template-parsing \
 // RUN:   -I Inputs/stress1 \
 // RUN:   -fno-implicit-modules -fno-modules-implicit-maps \
 // RUN:   -fmodule-map-file-home-is-cwd \
 // RUN:   -emit-module -fmodule-name=m01 -o %t/m01.pcm \
 // RUN:   Inputs/stress1/module.modulemap
 //
+// RUN: %clang_cc1 -fmodules -x c++ -std=c++11 -fdelayed-template-parsing \
+// RUN:   -I Inputs/stress1 \
+// RUN:   -fno-implicit-modules -fno-modules-implicit-maps \
+// RUN:   -fmodule-map-file-home-is-cwd \
+// RUN:   -emit-module -fmodule-name=m01 -o %t/m01_check.pcm \
+// RUN:   Inputs/stress1/module.modulemap
+//
+// RUN: diff %t/m01.pcm %t/m01_check.pcm
+//
 // RUN: %clang_cc1 -fmodules -x c++ -std=c++11 \
 // RUN:   -I Inputs/stress1 \
 // RUN:   -fno-implicit-modules -fno-modules-implicit-maps \





More information about the cfe-commits mailing list