r250134 - [modules] Fix merging of __va_list_tag's implicit special member functions.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 12 17:23:25 PDT 2015


Author: rsmith
Date: Mon Oct 12 19:23:25 2015
New Revision: 250134

URL: http://llvm.org/viewvc/llvm-project?rev=250134&view=rev
Log:
[modules] Fix merging of __va_list_tag's implicit special member functions.

We model predefined declarations as not being from AST files, but in most ways
they act as if they come from some implicit prebuilt module file imported
before all others. Therefore, if we see an update to the predefined 'struct
__va_list_tag' declaration (and we've already loaded any modules), it needs a
corresponding update record, even though it didn't technically come from an AST
file.

Added:
    cfe/trunk/test/Modules/Inputs/va_list/left.h
    cfe/trunk/test/Modules/Inputs/va_list/right.h
    cfe/trunk/test/Modules/Inputs/va_list/top.h
    cfe/trunk/test/Modules/va_list.cpp
Modified:
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/Modules/Inputs/va_list/module.modulemap

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=250134&r1=250133&r2=250134&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Oct 12 19:23:25 2015
@@ -5630,27 +5630,52 @@ void ASTWriter::CompletedTagDefinition(c
   }
 }
 
+static bool isImportedDeclContext(ASTReader *Chain, const Decl *D) {
+  if (D->isFromASTFile())
+    return true;
+
+  // If we've not loaded any modules, this can't be imported.
+  if (!Chain || !Chain->getModuleManager().size())
+    return false;
+
+  // The predefined __va_list_tag struct is imported if we imported any decls.
+  // FIXME: This is a gross hack.
+  return D == D->getASTContext().getVaListTagDecl();
+}
+
 void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
   // TU and namespaces are handled elsewhere.
   if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC))
     return;
 
-  if (!(!D->isFromASTFile() && cast<Decl>(DC)->isFromASTFile()))
-    return; // Not a source decl added to a DeclContext from PCH.
+  // We're only interested in cases where a local declaration is added to an
+  // imported context.
+  if (D->isFromASTFile() || !isImportedDeclContext(Chain, cast<Decl>(DC)))
+    return;
 
   assert(DC == DC->getPrimaryContext() && "added to non-primary context");
   assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");
   assert(!WritingAST && "Already writing the AST!");
-  UpdatedDeclContexts.insert(DC);
+  if (UpdatedDeclContexts.insert(DC) && !cast<Decl>(DC)->isFromASTFile()) {
+    // We're adding a visible declaration to a predefined decl context. Ensure
+    // that we write out all of its lookup results so we don't get a nasty
+    // surprise when we try to emit its lookup table.
+    for (auto *Child : DC->decls())
+      UpdatingVisibleDecls.push_back(Child);
+  }
   UpdatingVisibleDecls.push_back(D);
 }
 
 void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
   assert(D->isImplicit());
-  if (!(!D->isFromASTFile() && RD->isFromASTFile()))
-    return; // Not a source member added to a class from PCH.
+
+  // We're only interested in cases where a local declaration is added to an
+  // imported context.
+  if (D->isFromASTFile() || !isImportedDeclContext(Chain, RD))
+    return;
+
   if (!isa<CXXMethodDecl>(D))
-    return; // We are interested in lazily declared implicit methods.
+    return;
 
   // A decl coming from PCH was modified.
   assert(RD->isCompleteDefinition());

Added: cfe/trunk/test/Modules/Inputs/va_list/left.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/va_list/left.h?rev=250134&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/va_list/left.h (added)
+++ cfe/trunk/test/Modules/Inputs/va_list/left.h Mon Oct 12 19:23:25 2015
@@ -0,0 +1,7 @@
+ at import top;
+
+template<typename T>
+void f(int k, ...) {
+  va_list va;
+  __builtin_va_start(va, k);
+}

Modified: cfe/trunk/test/Modules/Inputs/va_list/module.modulemap
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/va_list/module.modulemap?rev=250134&r1=250133&r2=250134&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/va_list/module.modulemap (original)
+++ cfe/trunk/test/Modules/Inputs/va_list/module.modulemap Mon Oct 12 19:23:25 2015
@@ -1,2 +1,5 @@
 module va_list_a { header "va_list_a.h" }
 module va_list_b { header "va_list_b.h" }
+module top { header "top.h" }
+module left { header "left.h" }
+module right { header "right.h" }

Added: cfe/trunk/test/Modules/Inputs/va_list/right.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/va_list/right.h?rev=250134&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/va_list/right.h (added)
+++ cfe/trunk/test/Modules/Inputs/va_list/right.h Mon Oct 12 19:23:25 2015
@@ -0,0 +1,7 @@
+ at import top;
+
+template<typename T>
+void f(int k, ...) {
+  va_list va;
+  __builtin_va_start(va, k);
+}

Added: cfe/trunk/test/Modules/Inputs/va_list/top.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/va_list/top.h?rev=250134&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/va_list/top.h (added)
+++ cfe/trunk/test/Modules/Inputs/va_list/top.h Mon Oct 12 19:23:25 2015
@@ -0,0 +1 @@
+typedef __builtin_va_list va_list;

Added: cfe/trunk/test/Modules/va_list.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/va_list.cpp?rev=250134&view=auto
==============================================================================
--- cfe/trunk/test/Modules/va_list.cpp (added)
+++ cfe/trunk/test/Modules/va_list.cpp Mon Oct 12 19:23:25 2015
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/va_list %s -verify
+// expected-no-diagnostics
+
+ at import left;
+ at import right;
+
+void g(int k, ...) { f<int>(k); }




More information about the cfe-commits mailing list