]> granicus.if.org Git - clang/commitdiff
PR25501: Delay loading visible updates for a declaration until after we've
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 8 Apr 2016 20:53:26 +0000 (20:53 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 8 Apr 2016 20:53:26 +0000 (20:53 +0000)
processed update records. If an update record adds a definition, we need to
merge that with any pre-existing definition to determine which the canonical
definition is before we apply the visible update, otherwise we wouldn't know
where to apply it.

Thanks to Vassil Vassilev for help reducing this and tracking down the problem.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@265848 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Serialization/ASTReaderDecl.cpp
test/Modules/Inputs/PR25501/Vector.h [new file with mode: 0644]
test/Modules/Inputs/PR25501/a0.h [new file with mode: 0644]
test/Modules/Inputs/PR25501/a1.h [new file with mode: 0644]
test/Modules/Inputs/PR25501/a2.h [new file with mode: 0644]
test/Modules/Inputs/PR25501/b.h [new file with mode: 0644]
test/Modules/Inputs/PR25501/module.modulemap [new file with mode: 0644]
test/Modules/pr25501.cpp [new file with mode: 0644]

index 47ac4076757011a86b9ba1f74331677932f67a73..efb7793ef61897f5ad0a10544a6ca2d64abf0fe1 100644 (file)
@@ -3436,20 +3436,6 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
 }
 
 void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
-  // Load the pending visible updates for this decl context, if it has any.
-  auto I = PendingVisibleUpdates.find(ID);
-  if (I != PendingVisibleUpdates.end()) {
-    auto VisibleUpdates = std::move(I->second);
-    PendingVisibleUpdates.erase(I);
-
-    auto *DC = cast<DeclContext>(D)->getPrimaryContext();
-    for (const PendingVisibleUpdate &Update : VisibleUpdates)
-      Lookups[DC].Table.add(
-          Update.Mod, Update.Data,
-          reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod));
-    DC->setHasExternalVisibleStorage(true);
-  }
-
   // The declaration may have been modified by files later in the chain.
   // If this is the case, read the record containing the updates from each file
   // and pass it to ASTDeclReader to make the modifications.
@@ -3485,6 +3471,20 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
       }
     }
   }
+
+  // Load the pending visible updates for this decl context, if it has any.
+  auto I = PendingVisibleUpdates.find(ID);
+  if (I != PendingVisibleUpdates.end()) {
+    auto VisibleUpdates = std::move(I->second);
+    PendingVisibleUpdates.erase(I);
+
+    auto *DC = cast<DeclContext>(D)->getPrimaryContext();
+    for (const PendingVisibleUpdate &Update : VisibleUpdates)
+      Lookups[DC].Table.add(
+          Update.Mod, Update.Data,
+          reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod));
+    DC->setHasExternalVisibleStorage(true);
+  }
 }
 
 void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {
@@ -3757,7 +3757,7 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
 
     case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
       auto *RD = cast<CXXRecordDecl>(D);
-      auto *OldDD = RD->DefinitionData.getNotUpdated();
+      auto *OldDD = RD->getCanonicalDecl()->DefinitionData.getNotUpdated();
       bool HadRealDefinition =
           OldDD && (OldDD->Definition != RD ||
                     !Reader.PendingFakeDefinitionData.count(OldDD));
diff --git a/test/Modules/Inputs/PR25501/Vector.h b/test/Modules/Inputs/PR25501/Vector.h
new file mode 100644 (file)
index 0000000..9da4830
--- /dev/null
@@ -0,0 +1,5 @@
+template <typename> struct _Vector_base {};
+struct vector {
+  vector() {}
+  vector(_Vector_base<int>);
+};
diff --git a/test/Modules/Inputs/PR25501/a0.h b/test/Modules/Inputs/PR25501/a0.h
new file mode 100644 (file)
index 0000000..1a0d306
--- /dev/null
@@ -0,0 +1 @@
+#include "Vector.h"
diff --git a/test/Modules/Inputs/PR25501/a1.h b/test/Modules/Inputs/PR25501/a1.h
new file mode 100644 (file)
index 0000000..1a0d306
--- /dev/null
@@ -0,0 +1 @@
+#include "Vector.h"
diff --git a/test/Modules/Inputs/PR25501/a2.h b/test/Modules/Inputs/PR25501/a2.h
new file mode 100644 (file)
index 0000000..7876f31
--- /dev/null
@@ -0,0 +1,3 @@
+#include "a0.h"
+vector aaa = vector();
+#include "a1.h"
diff --git a/test/Modules/Inputs/PR25501/b.h b/test/Modules/Inputs/PR25501/b.h
new file mode 100644 (file)
index 0000000..7b51983
--- /dev/null
@@ -0,0 +1,2 @@
+#include "Vector.h"
+vector aaa = vector();
diff --git a/test/Modules/Inputs/PR25501/module.modulemap b/test/Modules/Inputs/PR25501/module.modulemap
new file mode 100644 (file)
index 0000000..c6c8d5c
--- /dev/null
@@ -0,0 +1,4 @@
+module "a0" { header "a0.h" export * }
+module "a1" { header "a1.h" export * }
+module "a2" { header "a2.h" export * }
+module "b" { header "b.h" export * }
diff --git a/test/Modules/pr25501.cpp b/test/Modules/pr25501.cpp
new file mode 100644 (file)
index 0000000..18002d6
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR25501/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR25501 -verify %s
+
+#include "a2.h"
+#include "b.h"
+
+auto use = aaa;
+
+// expected-no-diagnostics