summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/DeclBase.cpp13
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp5
-rw-r--r--clang/test/Modules/Inputs/merge-decl-context/a.h22
-rw-r--r--clang/test/Modules/Inputs/merge-decl-context/b.h6
-rw-r--r--clang/test/Modules/Inputs/merge-decl-context/c.h7
-rw-r--r--clang/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap13
-rw-r--r--clang/test/Modules/merge-decl-context.cpp24
7 files changed, 84 insertions, 6 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 17f542dc9a2..75a219a4370 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -1308,12 +1308,16 @@ DeclContext::lookup(DeclarationName Name) const {
if (PrimaryContext != this)
return PrimaryContext->lookup(Name);
- // If this is a namespace, ensure that any later redeclarations of it have
- // been loaded, since they may add names to the result of this lookup.
- if (auto *ND = dyn_cast<NamespaceDecl>(this))
- (void)ND->getMostRecentDecl();
+ // If we have an external source, ensure that any later redeclarations of this
+ // context have been loaded, since they may add names to the result of this
+ // lookup (or add external visible storage).
+ ExternalASTSource *Source = getParentASTContext().getExternalSource();
+ if (Source)
+ (void)cast<Decl>(this)->getMostRecentDecl();
if (hasExternalVisibleStorage()) {
+ assert(Source && "external visible storage but no external source?");
+
if (NeedToReconcileExternalVisibleStorage)
reconcileExternalVisibleStorage();
@@ -1332,7 +1336,6 @@ DeclContext::lookup(DeclarationName Name) const {
if (!R.second && !R.first->second.hasExternalDecls())
return R.first->second.getLookupResult();
- ExternalASTSource *Source = getParentASTContext().getExternalSource();
if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) {
if (StoredDeclsMap *Map = LookupPtr.getPointer()) {
StoredDeclsMap::iterator I = Map->find(Name);
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index fc97981ba22..07812bdc839 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1288,8 +1288,11 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) {
bool needsImportVisitation() const override { return true; }
void visitImport(StringRef FileName) override {
- if (!CI.ExplicitlyLoadedModuleFiles.insert(FileName).second)
+ if (!CI.ExplicitlyLoadedModuleFiles.insert(FileName).second) {
+ if (ModuleFileStack.size() == 0)
+ TopFileIsModule = true;
return;
+ }
ModuleFileStack.push_back(FileName);
if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
diff --git a/clang/test/Modules/Inputs/merge-decl-context/a.h b/clang/test/Modules/Inputs/merge-decl-context/a.h
new file mode 100644
index 00000000000..bd08ecaf417
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-decl-context/a.h
@@ -0,0 +1,22 @@
+#ifndef A_H
+#define A_H
+
+template <typename T>
+struct A {
+ template <typename I>
+ A(I i1, I i2) {
+ }
+ A(double) {}
+ A(double, double) {}
+};
+
+template <typename T1, typename T2>
+T1 fff(T2* t) {
+ return T1(t, t);
+}
+
+inline A<int> ff(int i) {
+ return fff<A<int>>(&i);
+}
+
+#endif
diff --git a/clang/test/Modules/Inputs/merge-decl-context/b.h b/clang/test/Modules/Inputs/merge-decl-context/b.h
new file mode 100644
index 00000000000..cb06ac8e27c
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-decl-context/b.h
@@ -0,0 +1,6 @@
+#ifndef B_H
+#define B_H
+
+#include "a.h"
+
+#endif
diff --git a/clang/test/Modules/Inputs/merge-decl-context/c.h b/clang/test/Modules/Inputs/merge-decl-context/c.h
new file mode 100644
index 00000000000..af3a723969b
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-decl-context/c.h
@@ -0,0 +1,7 @@
+#ifndef C_H
+#define C_H
+
+#include "a.h"
+#include "b.h"
+
+#endif
diff --git a/clang/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap b/clang/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap
new file mode 100644
index 00000000000..fedc5dfbbe4
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap
@@ -0,0 +1,13 @@
+module "a" {
+ textual header "a.h"
+}
+
+module "b" {
+ export *
+ header "b.h"
+}
+
+module "c" {
+ export *
+ header "c.h"
+}
diff --git a/clang/test/Modules/merge-decl-context.cpp b/clang/test/Modules/merge-decl-context.cpp
new file mode 100644
index 00000000000..90c234b66f5
--- /dev/null
+++ b/clang/test/Modules/merge-decl-context.cpp
@@ -0,0 +1,24 @@
+// RUN: rm -rf %t
+
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=b -o %t/b.pcm -fmodule-maps \
+// RUN: -emit-module %S/Inputs/merge-decl-context/merge-decl-context.modulemap -I%S/Inputs \
+// RUN: -I %S/Inputs/merge-decl-context
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=c -o %t/c.pcm -fmodule-maps \
+// RUN: -fmodule-file=%t/b.pcm \
+// RUN: -emit-module %S/Inputs/merge-decl-context/merge-decl-context.modulemap -I%S/Inputs \
+// RUN: -I %S/Inputs/merge-decl-context
+
+// Use the two modules in a single compile.
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%t/c.pcm -fmodule-file=%t/b.pcm \
+// RUN: -fmodule-map-file=%S/Inputs/merge-decl-context/merge-decl-context.modulemap -I%S/Inputs \
+// RUN: -emit-llvm -o %t/test.o %s
+
+#include "Inputs/merge-decl-context/a.h"
+#include "Inputs/merge-decl-context/b.h"
+#include "Inputs/merge-decl-context/c.h"
+
+void t() {
+ ff(42);
+}
+
+
OpenPOWER on IntegriCloud