summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-08-28 05:44:07 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-08-28 05:44:07 +0000
commit01bdb7a971513549979abc48596cf6741189b5de (patch)
tree4bfcff792d168b04e6277dcedce84a139f231313
parentee978203e6fad870e045a44bcef028bd97910ba3 (diff)
downloadbcm5719-llvm-01bdb7a971513549979abc48596cf6741189b5de.tar.gz
bcm5719-llvm-01bdb7a971513549979abc48596cf6741189b5de.zip
[modules] When completing the redecl chain for an anonymous declaration in a
merged context, pull in the lexical decls in that context, since one of them may complete the redecl chain. llvm-svn: 216652
-rw-r--r--clang/lib/Serialization/ASTReader.cpp18
-rw-r--r--clang/test/Modules/Inputs/cxx-templates-a.h3
-rw-r--r--clang/test/Modules/Inputs/cxx-templates-b.h5
-rw-r--r--clang/test/Modules/Inputs/cxx-templates-common.h1
-rw-r--r--clang/test/Modules/Inputs/cxx-templates-d.h3
-rw-r--r--clang/test/Modules/Inputs/module.map4
-rw-r--r--clang/test/Modules/cxx-templates.cpp7
7 files changed, 33 insertions, 8 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index aaea0687b26..b65b5641ad4 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -6065,9 +6065,7 @@ void ASTReader::CompleteRedeclChain(const Decl *D) {
// If this is a named declaration, complete it by looking it up
// within its context.
//
- // FIXME: We don't currently handle the cases where we can't do this;
- // merging a class definition that contains unnamed entities should merge
- // those entities. Likewise, merging a function definition should merge
+ // FIXME: Merging a function definition should merge
// all mergeable entities within it.
if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC) ||
isa<CXXRecordDecl>(DC) || isa<EnumDecl>(DC)) {
@@ -6080,6 +6078,9 @@ void ASTReader::CompleteRedeclChain(const Decl *D) {
updateOutOfDateIdentifier(*II);
} else
DC->lookup(Name);
+ } else if (needsAnonymousDeclarationNumber(cast<NamedDecl>(D))) {
+ // FIXME: It'd be nice to do something a bit more targeted here.
+ D->getDeclContext()->decls_begin();
}
}
}
@@ -8310,12 +8311,21 @@ void ASTReader::diagnoseOdrViolations() {
continue;
DeclContext *CanonDef = D->getDeclContext();
- DeclContext::lookup_result R = CanonDef->lookup(D->getDeclName());
bool Found = false;
const Decl *DCanon = D->getCanonicalDecl();
+ for (auto RI : D->redecls()) {
+ if (RI->getLexicalDeclContext() == CanonDef) {
+ Found = true;
+ break;
+ }
+ }
+ if (Found)
+ continue;
+
llvm::SmallVector<const NamedDecl*, 4> Candidates;
+ DeclContext::lookup_result R = CanonDef->lookup(D->getDeclName());
for (DeclContext::lookup_iterator I = R.begin(), E = R.end();
!Found && I != E; ++I) {
for (auto RI : (*I)->redecls()) {
diff --git a/clang/test/Modules/Inputs/cxx-templates-a.h b/clang/test/Modules/Inputs/cxx-templates-a.h
index b1ea6a9c241..c2ce74d195b 100644
--- a/clang/test/Modules/Inputs/cxx-templates-a.h
+++ b/clang/test/Modules/Inputs/cxx-templates-a.h
@@ -87,4 +87,5 @@ template<typename T> struct PartiallyInstantiatePartialSpec<T*> {
typedef PartiallyInstantiatePartialSpec<int*> PartiallyInstantiatePartialSpecHelper;
void InstantiateWithAliasTemplate(WithAliasTemplate<int>::X<char>);
-inline int InstantiateWithAnonymousDeclsA(WithAnonymousDecls<int> x) { return (x.k ? x.a : x.b) + (x.k ? x.s.c : x.s.d); }
+inline int InstantiateWithAnonymousDeclsA(WithAnonymousDecls<int> x) { return (x.k ? x.a : x.b) + (x.k ? x.s.c : x.s.d) + x.e; }
+inline int InstantiateWithAnonymousDeclsB2(WithAnonymousDecls<char> x);
diff --git a/clang/test/Modules/Inputs/cxx-templates-b.h b/clang/test/Modules/Inputs/cxx-templates-b.h
index 632a55b72e3..1fd6fd42316 100644
--- a/clang/test/Modules/Inputs/cxx-templates-b.h
+++ b/clang/test/Modules/Inputs/cxx-templates-b.h
@@ -71,7 +71,10 @@ template<typename U> using AliasTemplate = U;
void InstantiateWithAliasTemplate(WithAliasTemplate<int>::X<char>);
inline int InstantiateWithAnonymousDeclsB(WithAnonymousDecls<int> x) {
- return (x.k ? x.a : x.b) + (x.k ? x.s.c : x.s.d);
+ return (x.k ? x.a : x.b) + (x.k ? x.s.c : x.s.d) + x.e;
+}
+inline int InstantiateWithAnonymousDeclsB2(WithAnonymousDecls<char> x) {
+ return (x.k ? x.a : x.b) + (x.k ? x.s.c : x.s.d) + x.e;
}
@import cxx_templates_a;
diff --git a/clang/test/Modules/Inputs/cxx-templates-common.h b/clang/test/Modules/Inputs/cxx-templates-common.h
index f1cf260fb04..a9ca6244867 100644
--- a/clang/test/Modules/Inputs/cxx-templates-common.h
+++ b/clang/test/Modules/Inputs/cxx-templates-common.h
@@ -49,6 +49,7 @@ template<typename T> struct WithAnonymousDecls {
struct { bool k; };
union { int a, b; };
struct { int c, d; } s;
+ enum { e = 123 };
typedef int X;
};
diff --git a/clang/test/Modules/Inputs/cxx-templates-d.h b/clang/test/Modules/Inputs/cxx-templates-d.h
new file mode 100644
index 00000000000..6aefdeca64d
--- /dev/null
+++ b/clang/test/Modules/Inputs/cxx-templates-d.h
@@ -0,0 +1,3 @@
+@import cxx_templates_common;
+
+inline int InstantiateWithAnonymousDeclsD(WithAnonymousDecls<char> x) { return (x.k ? x.a : x.b) + (x.k ? x.s.c : x.s.d) + x.e; }
diff --git a/clang/test/Modules/Inputs/module.map b/clang/test/Modules/Inputs/module.map
index 0081c1ca000..72a65cf8718 100644
--- a/clang/test/Modules/Inputs/module.map
+++ b/clang/test/Modules/Inputs/module.map
@@ -233,6 +233,10 @@ module cxx_templates_c {
header "cxx-templates-c.h"
}
+module cxx_templates_d {
+ header "cxx-templates-d.h"
+}
+
module cxx_decls {
module unimported {
header "cxx-decls-unimported.h"
diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp
index b3ef3f6497b..3833e995c52 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -12,6 +12,7 @@
@import cxx_templates_a;
@import cxx_templates_b;
@import cxx_templates_c;
+@import cxx_templates_d;
@import cxx_templates_common;
template<typename, char> struct Tmpl_T_C {};
@@ -145,9 +146,11 @@ MergeSpecializations<bool>::explicitly_specialized_in_c spec_in_c_2;
using AliasTemplateMergingTest = WithAliasTemplate<int>::X<char>;
-int AnonymousDeclsMergingTest(WithAnonymousDecls<int> WAD) {
+int AnonymousDeclsMergingTest(WithAnonymousDecls<int> WAD, WithAnonymousDecls<char> WADC) {
return InstantiateWithAnonymousDeclsA(WAD) +
- InstantiateWithAnonymousDeclsB(WAD);
+ InstantiateWithAnonymousDeclsB(WAD) +
+ InstantiateWithAnonymousDeclsB2(WADC) +
+ InstantiateWithAnonymousDeclsD(WADC);
}
@import cxx_templates_common;
OpenPOWER on IntegriCloud