]> granicus.if.org Git - clang/commitdiff
[modules] When completing the redecl chain for an anonymous declaration in a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 28 Aug 2014 05:44:07 +0000 (05:44 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 28 Aug 2014 05:44:07 +0000 (05:44 +0000)
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

lib/Serialization/ASTReader.cpp
test/Modules/Inputs/cxx-templates-a.h
test/Modules/Inputs/cxx-templates-b.h
test/Modules/Inputs/cxx-templates-common.h
test/Modules/Inputs/cxx-templates-d.h [new file with mode: 0644]
test/Modules/Inputs/module.map
test/Modules/cxx-templates.cpp

index aaea0687b2644798f3f1a42ddfc407827879689e..b65b5641ad46189b1f685ef7b04476134e9b6049 100644 (file)
@@ -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()) {
index b1ea6a9c24109b8833a24fd41ff57cff9ee2be5f..c2ce74d195b65293d7493bc2430b5f2fd2f1451a 100644 (file)
@@ -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);
index 632a55b72e32a9443151127de0dbc9808eab5c7a..1fd6fd4231643196b849c3143382211e68f3874d 100644 (file)
@@ -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;
index f1cf260fb04db4eeb3dd07f28b38cb917b76d0d9..a9ca624486718692492204f4276135d2647a9012 100644 (file)
@@ -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/test/Modules/Inputs/cxx-templates-d.h b/test/Modules/Inputs/cxx-templates-d.h
new file mode 100644 (file)
index 0000000..6aefdec
--- /dev/null
@@ -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; }
index 0081c1ca000c7f25289f771242abc67161c13deb..72a65cf8718c15674728184139a86ed413a8d938 100644 (file)
@@ -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"
index b3ef3f6497b37e8340cdda6773186a905e304668..3833e995c52edf97e1799bf6c39b262255fcd787 100644 (file)
@@ -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;