From: Richard Smith Date: Thu, 28 Aug 2014 05:44:07 +0000 (+0000) Subject: [modules] When completing the redecl chain for an anonymous declaration in a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f1323370a723211a614579d444d3a35afe595f6a;p=clang [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216652 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index aaea0687b2..b65b5641ad 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/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(DC) || isa(DC) || isa(DC) || isa(DC)) { @@ -6080,6 +6078,9 @@ void ASTReader::CompleteRedeclChain(const Decl *D) { updateOutOfDateIdentifier(*II); } else DC->lookup(Name); + } else if (needsAnonymousDeclarationNumber(cast(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 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/test/Modules/Inputs/cxx-templates-a.h b/test/Modules/Inputs/cxx-templates-a.h index b1ea6a9c24..c2ce74d195 100644 --- a/test/Modules/Inputs/cxx-templates-a.h +++ b/test/Modules/Inputs/cxx-templates-a.h @@ -87,4 +87,5 @@ template struct PartiallyInstantiatePartialSpec { typedef PartiallyInstantiatePartialSpec PartiallyInstantiatePartialSpecHelper; void InstantiateWithAliasTemplate(WithAliasTemplate::X); -inline int InstantiateWithAnonymousDeclsA(WithAnonymousDecls x) { return (x.k ? x.a : x.b) + (x.k ? x.s.c : x.s.d); } +inline int InstantiateWithAnonymousDeclsA(WithAnonymousDecls x) { return (x.k ? x.a : x.b) + (x.k ? x.s.c : x.s.d) + x.e; } +inline int InstantiateWithAnonymousDeclsB2(WithAnonymousDecls x); diff --git a/test/Modules/Inputs/cxx-templates-b.h b/test/Modules/Inputs/cxx-templates-b.h index 632a55b72e..1fd6fd4231 100644 --- a/test/Modules/Inputs/cxx-templates-b.h +++ b/test/Modules/Inputs/cxx-templates-b.h @@ -71,7 +71,10 @@ template using AliasTemplate = U; void InstantiateWithAliasTemplate(WithAliasTemplate::X); inline int InstantiateWithAnonymousDeclsB(WithAnonymousDecls 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 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/test/Modules/Inputs/cxx-templates-common.h b/test/Modules/Inputs/cxx-templates-common.h index f1cf260fb0..a9ca624486 100644 --- a/test/Modules/Inputs/cxx-templates-common.h +++ b/test/Modules/Inputs/cxx-templates-common.h @@ -49,6 +49,7 @@ template struct WithAnonymousDecls { struct { bool k; }; union { int a, b; }; struct { int c, d; } s; + enum { e = 123 }; typedef int X; }; diff --git a/test/Modules/Inputs/cxx-templates-d.h b/test/Modules/Inputs/cxx-templates-d.h new file mode 100644 index 0000000000..6aefdeca64 --- /dev/null +++ b/test/Modules/Inputs/cxx-templates-d.h @@ -0,0 +1,3 @@ +@import cxx_templates_common; + +inline int InstantiateWithAnonymousDeclsD(WithAnonymousDecls x) { return (x.k ? x.a : x.b) + (x.k ? x.s.c : x.s.d) + x.e; } diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map index 0081c1ca00..72a65cf871 100644 --- a/test/Modules/Inputs/module.map +++ b/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/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp index b3ef3f6497..3833e995c5 100644 --- a/test/Modules/cxx-templates.cpp +++ b/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 struct Tmpl_T_C {}; @@ -145,9 +146,11 @@ MergeSpecializations::explicitly_specialized_in_c spec_in_c_2; using AliasTemplateMergingTest = WithAliasTemplate::X; -int AnonymousDeclsMergingTest(WithAnonymousDecls WAD) { +int AnonymousDeclsMergingTest(WithAnonymousDecls WAD, WithAnonymousDecls WADC) { return InstantiateWithAnonymousDeclsA(WAD) + - InstantiateWithAnonymousDeclsB(WAD); + InstantiateWithAnonymousDeclsB(WAD) + + InstantiateWithAnonymousDeclsB2(WADC) + + InstantiateWithAnonymousDeclsD(WADC); } @import cxx_templates_common;