diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-08-28 05:44:07 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-08-28 05:44:07 +0000 |
| commit | 01bdb7a971513549979abc48596cf6741189b5de (patch) | |
| tree | 4bfcff792d168b04e6277dcedce84a139f231313 | |
| parent | ee978203e6fad870e045a44bcef028bd97910ba3 (diff) | |
| download | bcm5719-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.cpp | 18 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-a.h | 3 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-b.h | 5 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-common.h | 1 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-d.h | 3 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/module.map | 4 | ||||
| -rw-r--r-- | clang/test/Modules/cxx-templates.cpp | 7 |
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; |

