This made me think, is there a way to automatically find out redundant deserializations? Eg. switch to text mode, build dependency graph and compare against the dependency graph in -fmodules mode. Or even a more brute force: store the states of the key objects (AST, identifiers, lookups, directives ...) and compare?
Vassil
On 11/03/15 02:44, Richard Smith wrote:
Author: rsmith
Date: Tue Mar 10 20:44:51 2015
New Revision: 231901

URL: http://llvm.org/viewvc/llvm-project?rev=231901&view=rev
Log:
[modules] Avoid accidentally completing the redeclaration chain when updating
all the existing declarations of a record-like entity with a pointer to its
definition.

Modified:
     cfe/trunk/include/clang/Serialization/ASTReader.h
     cfe/trunk/lib/Serialization/ASTReader.cpp
     cfe/trunk/lib/Serialization/ASTReaderDecl.cpp

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=231901&r1=231900&r2=231901&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Tue Mar 10 20:44:51 2015
@@ -1159,6 +1159,12 @@ private:
    void LoadedDecl(unsigned Index, Decl *D);
    Decl *ReadDeclRecord(serialization::DeclID ID);
    void markIncompleteDeclChain(Decl *Canon);
+
+  /// \brief Returns the most recent declaration of a declaration (which must 
be
+  /// of a redeclarable kind) that is either local or has already been loaded
+  /// merged into its redecl chain.
+  Decl *getMostRecentExistingDecl(Decl *D);
+
    RecordLocation DeclCursorForID(serialization::DeclID ID,
                                   unsigned &RawLocation);
    void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D);

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=231901&r1=231900&r2=231901&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Mar 10 20:44:51 2015
@@ -8369,10 +8369,12 @@ void ASTReader::finishPendingActions() {
          // Make sure that the TagType points at the definition.
          const_cast<TagType*>(TagT)->decl = TD;
        }
-
+
        if (auto RD = dyn_cast<CXXRecordDecl>(D)) {
-        for (auto R : RD->redecls()) {
-          assert((R == D) == R->isThisDeclarationADefinition() &&
+        for (auto *R = getMostRecentExistingDecl(RD); R;
+             R = R->getPreviousDecl()) {
+          assert((R == D) ==
+                     cast<CXXRecordDecl>(R)->isThisDeclarationADefinition() &&
                   "declaration thinks it's the definition but it isn't");
            cast<CXXRecordDecl>(R)->DefinitionData = RD->DefinitionData;
          }
@@ -8380,34 +8382,36 @@ void ASTReader::finishPendingActions() {
continue;
      }
-
+
      if (auto ID = dyn_cast<ObjCInterfaceDecl>(D)) {
        // Make sure that the ObjCInterfaceType points at the definition.
        const_cast<ObjCInterfaceType 
*>(cast<ObjCInterfaceType>(ID->TypeForDecl))
          ->Decl = ID;
-
-      for (auto R : ID->redecls())
-        R->Data = ID->Data;
-
+
+      for (auto *R = getMostRecentExistingDecl(ID); R; R = 
R->getPreviousDecl())
+        cast<ObjCInterfaceDecl>(R)->Data = ID->Data;
+
        continue;
      }
-
+
      if (auto PD = dyn_cast<ObjCProtocolDecl>(D)) {
-      for (auto R : PD->redecls())
-        R->Data = PD->Data;
-
+      for (auto *R = getMostRecentExistingDecl(PD); R; R = 
R->getPreviousDecl())
+        cast<ObjCProtocolDecl>(R)->Data = PD->Data;
+
        continue;
      }
-
+
      auto RTD = cast<RedeclarableTemplateDecl>(D)->getCanonicalDecl();
-    for (auto R : RTD->redecls())
-      R->Common = RTD->Common;
+    for (auto *R = getMostRecentExistingDecl(RTD); R; R = R->getPreviousDecl())
+      cast<RedeclarableTemplateDecl>(R)->Common = RTD->Common;
    }
    PendingDefinitions.clear();
// Load the bodies of any functions or methods we've encountered. We do
    // this now (delayed) so that we can be sure that the declaration chains
    // have been fully wired up.
+  // FIXME: There seems to be no point in delaying this, it does not depend
+  // on the redecl chains having been wired up.
    for (PendingBodiesMap::iterator PB = PendingBodies.begin(),
                                 PBEnd = PendingBodies.end();
         PB != PBEnd; ++PB) {

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=231901&r1=231900&r2=231901&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Mar 10 20:44:51 2015
@@ -2799,6 +2799,10 @@ Decl *ASTDeclReader::getMostRecentDecl(D
    llvm_unreachable("unknown decl kind");
  }
+Decl *ASTReader::getMostRecentExistingDecl(Decl *D) {
+  return ASTDeclReader::getMostRecentDecl(D->getCanonicalDecl());
+}
+
  template<typename DeclT>
  void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
                                             Redeclarable<DeclT> *D,


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to