<div>I have a solution, stay tuned.<br></div><div><br></div><div>So it turns out since the clang driver has special behavior on Darwin for handling Universal apps, there is a different code path that happens during BuildActions. clang::driver::Driver::BuildUniversalActions is called instead of BuildActions on Darwin, and what BuildUniversalActions ends up doing is it calls BuildActions and takes the driver actions returned and wraps them all into a BindArchAction each. So when I check for a IfsMergeAction in the driver instead I am getting a BindArchAction that has an IfsMergeAction inside of it.<br></div><div><br></div><div>I will post a fix to get Green Dragon and the Fuchsia Darwin bots green again, and also post a post-commit review on Phab for good measure. <br></div><div><br></div><div>Thanks Again for the heads up Alex.<br></div><div><br></div><div>Puyan</div><div><br></div><div class="protonmail_signature_block"><div class="protonmail_signature_block-user protonmail_signature_block-empty"><br></div><div class="protonmail_signature_block-proton">Sent with <a href="https://protonmail.com" target="_blank">ProtonMail</a> Secure Email.<br></div></div><div><br></div><div>‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐<br></div><div> On Wednesday, November 20, 2019 4:52 PM, Puyan Lotfi <puyan@puyan.org> wrote:<br></div><div> <br></div><blockquote class="protonmail_quote" type="cite"><div>Looking into this. Thanks for the heads up. <br></div><div><br></div><div>PL<br></div><div><br></div><div class="protonmail_signature_block"><div class="protonmail_signature_block-user protonmail_signature_block-empty"><br></div><div class="protonmail_signature_block-proton">Sent with <a target="_blank" href="https://protonmail.com">ProtonMail</a> Secure Email.<br></div></div><div><br></div><div>‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐<br></div><div>On Wednesday, November 20, 2019 4:12 PM, Alex L <arphaman@gmail.com> wrote:<br></div><div><br></div><blockquote type="cite" class="protonmail_quote"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Hi Puyan,<br></div><div><br></div><div>This commit caused two Clang failures on Darwin:<br></div><div><br></div><div><div>    Clang :: InterfaceStubs/merge-conflict-test.c<br></div><div>    Clang :: InterfaceStubs/object-float.c<br></div></div><div><br></div><div>Here's the build log from out bot:<br></div><div><a href="http://lab.llvm.org:8080/green/job/clang-stage1-RA/3929/console">http://lab.llvm.org:8080/green/job/clang-stage1-RA/3929/console</a><br></div><div><br></div><div>Can you please resolve the issue with the tests?<br></div><div>Thanks,<br></div><div>Alex<br></div></div></div></div><div><br></div><div class="gmail_quote"><div dir="ltr">On Wed, 20 Nov 2019 at 14:16, Puyan Lotfi via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex" class="gmail_quote"><div><br></div><div>Author: Puyan Lotfi<br></div><div>Date: 2019-11-20T16:22:50-05:00<br></div><div>New Revision: 73429126c91c2065c6f6ef29b3eec1b7798502bb<br></div><div><br></div><div>URL: <a target="_blank" rel="noreferrer" href="https://github.com/llvm/llvm-project/commit/73429126c91c2065c6f6ef29b3eec1b7798502bb">https://github.com/llvm/llvm-project/commit/73429126c91c2065c6f6ef29b3eec1b7798502bb</a><br></div><div>DIFF: <a target="_blank" rel="noreferrer" href="https://github.com/llvm/llvm-project/commit/73429126c91c2065c6f6ef29b3eec1b7798502bb.diff">https://github.com/llvm/llvm-project/commit/73429126c91c2065c6f6ef29b3eec1b7798502bb.diff</a><br></div><div><br></div><div>LOG: [clang][IFS] Driver Pipeline: generate stubs after standard pipeline (3)<br></div><div><br></div><div>Third Landing Attempt (dropping any linker invocation from clang driver):<br></div><div><br></div><div>Up until now, clang interface stubs has replaced the standard<br></div><div>PP -> C -> BE -> ASM -> LNK pipeline. With this change, it will happen in<br></div><div>conjunction with it. So what when you build your code you will get an<br></div><div>a.out or lib.so as well as an interface stub file.<br></div><div><br></div><div>Example:<br></div><div><br></div><div>clang -shared -o libfoo.so -emit-interface-stubs ...<br></div><div><br></div><div>will generate both a libfoo.so and a libfoo.ifso. The .so file will<br></div><div>contain the code from the standard compilation pipeline and the .ifso<br></div><div>file will contain the ELF stub library.<br></div><div><br></div><div>Note: For driver-test.c I've added -S in order to prevent any bot failures on<br></div><div>bots that don't have the proper linker for their native triple. You could always<br></div><div>specify a triple like x86_64-unknown-linux-gnu and on bots like x86_64-scei-ps4<br></div><div>the clang driver would invoke regular ld instead of getting the error<br></div><div>'Executable "orbis-ld" doesn't exist!' but on bots like ppc64be and s390x you'd<br></div><div>get an error "/usr/bin/ld: unrecognised emulation mode: elf_x86_64"<br></div><div><br></div><div>Differential Revision: <a target="_blank" rel="noreferrer" href="https://reviews.llvm.org/D70274">https://reviews.llvm.org/D70274</a><br></div><div><br></div><div>Added: <br></div><div>    clang/test/InterfaceStubs/driver-test2.c<br></div><div>    clang/test/InterfaceStubs/ppc.cpp<br></div><div><br></div><div>Modified: <br></div><div>    clang/lib/Driver/Driver.cpp<br></div><div>    clang/lib/Driver/ToolChains/InterfaceStubs.cpp<br></div><div>    clang/lib/Driver/Types.cpp<br></div><div>    clang/test/InterfaceStubs/driver-test.c<br></div><div>    clang/test/InterfaceStubs/windows.cpp<br></div><div><br></div><div>Removed: <br></div><div><br></div><div><br></div><div><br></div><div>################################################################################<br></div><div>diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp<br></div><div>index cdf4a579f431..83b5db3b2530 100644<br></div><div>--- a/clang/lib/Driver/Driver.cpp<br></div><div>+++ b/clang/lib/Driver/Driver.cpp<br></div><div>@@ -292,10 +292,6 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,<br></div><div>              (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {<br></div><div>     FinalPhase = phases::Compile;<br></div><div><br></div><div>-  // clang interface stubs<br></div><div>-  } else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {<br></div><div>-    FinalPhase = phases::IfsMerge;<br></div><div>-<br></div><div>   // -S only runs up to the backend.<br></div><div>   } else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {<br></div><div>     FinalPhase = phases::Backend;<br></div><div>@@ -3502,6 +3498,68 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,<br></div><div>     Actions.push_back(<br></div><div>         C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));<br></div><div><br></div><div>+  if (Arg *A = Args.getLastArg(options::OPT_emit_interface_stubs)) {<br></div><div>+    llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PhaseList;<br></div><div>+    if (Args.hasArg(options::OPT_c)) {<br></div><div>+      llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> CompilePhaseList;<br></div><div>+      types::getCompilationPhases(types::TY_IFS_CPP, CompilePhaseList);<br></div><div>+      llvm::copy_if(CompilePhaseList, std::back_inserter(PhaseList),<br></div><div>+                    [&](phases::ID Phase) { return Phase <= phases::Compile; });<br></div><div>+    } else {<br></div><div>+      types::getCompilationPhases(types::TY_IFS_CPP, PhaseList);<br></div><div>+    }<br></div><div>+<br></div><div>+    ActionList MergerInputs;<br></div><div>+<br></div><div>+    for (auto &I : Inputs) {<br></div><div>+      types::ID InputType = I.first;<br></div><div>+      const Arg *InputArg = I.second;<br></div><div>+<br></div><div>+      // Currently clang and the llvm assembler do not support generating symbol<br></div><div>+      // stubs from assembly, so we skip the input on asm files. For ifs files<br></div><div>+      // we rely on the normal pipeline setup in the pipeline setup code above.<br></div><div>+      if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||<br></div><div>+          InputType == types::TY_Asm)<br></div><div>+        continue;<br></div><div>+<br></div><div>+      Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);<br></div><div>+<br></div><div>+      for (auto Phase : PhaseList) {<br></div><div>+        switch (Phase) {<br></div><div>+        default:<br></div><div>+          llvm_unreachable(<br></div><div>+              "IFS Pipeline can only consist of Compile followed by IfsMerge.");<br></div><div>+        case phases::Compile: {<br></div><div>+          // Only IfsMerge (llvm-ifs) can handle .o files by looking for ifs<br></div><div>+          // files where the .o file is located. The compile action can not<br></div><div>+          // handle this.<br></div><div>+          if (InputType == types::TY_Object)<br></div><div>+            break;<br></div><div>+<br></div><div>+          Current = C.MakeAction<CompileJobAction>(Current, types::TY_IFS_CPP);<br></div><div>+          break;<br></div><div>+        }<br></div><div>+        case phases::IfsMerge: {<br></div><div>+          assert(Phase == PhaseList.back() &&<br></div><div>+                 "merging must be final compilation step.");<br></div><div>+          MergerInputs.push_back(Current);<br></div><div>+          Current = nullptr;<br></div><div>+          break;<br></div><div>+        }<br></div><div>+        }<br></div><div>+      }<br></div><div>+<br></div><div>+      // If we ended with something, add to the output list.<br></div><div>+      if (Current)<br></div><div>+        Actions.push_back(Current);<br></div><div>+    }<br></div><div>+<br></div><div>+    // Add an interface stubs merge action if necessary.<br></div><div>+    if (!MergerInputs.empty())<br></div><div>+      Actions.push_back(<br></div><div>+          C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));<br></div><div>+  }<br></div><div>+<br></div><div>   // If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a custom<br></div><div>   // Compile phase that prints out supported cpu models and quits.<br></div><div>   if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) {<br></div><div>@@ -3603,8 +3661,6 @@ Action *Driver::ConstructPhaseAction(<br></div><div>       return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile);<br></div><div>     if (Args.hasArg(options::OPT_verify_pch))<br></div><div>       return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing);<br></div><div>-    if (Args.hasArg(options::OPT_emit_interface_stubs))<br></div><div>-      return C.MakeAction<CompileJobAction>(Input, types::TY_IFS_CPP);<br></div><div>     return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC);<br></div><div>   }<br></div><div>   case phases::Backend: {<br></div><div>@@ -3633,11 +3689,16 @@ void Driver::BuildJobs(Compilation &C) const {<br></div><div>   Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);<br></div><div><br></div><div>   // It is an error to provide a -o option if we are making multiple output<br></div><div>-  // files.<br></div><div>+  // files. There is one exception, IfsMergeJob: when generating interface stubs<br></div><div>+  // enabled we want to be able to generate the stub file at the same time that<br></div><div>+  // we generate the real library/a.out. So when a .o, .so, etc are the output,<br></div><div>+  // with clang interface stubs there will also be a .ifs and .ifso at the same<br></div><div>+  // location.<br></div><div>   if (FinalOutput) {<br></div><div>     unsigned NumOutputs = 0;<br></div><div>     for (const Action *A : C.getActions())<br></div><div>-      if (A->getType() != types::TY_Nothing)<br></div><div>+      if (A->getType() != types::TY_Nothing &&<br></div><div>+          A->getKind() != Action::IfsMergeJobClass)<br></div><div>         ++NumOutputs;<br></div><div><br></div><div>     if (NumOutputs > 1) {<br></div><div><br></div><div>diff  --git a/clang/lib/Driver/ToolChains/InterfaceStubs.cpp b/clang/lib/Driver/ToolChains/InterfaceStubs.cpp<br></div><div>index 6677843b2c53..f441f4787097 100644<br></div><div>--- a/clang/lib/Driver/ToolChains/InterfaceStubs.cpp<br></div><div>+++ b/clang/lib/Driver/ToolChains/InterfaceStubs.cpp<br></div><div>@@ -9,6 +9,7 @@<br></div><div> #include "InterfaceStubs.h"<br></div><div> #include "CommonArgs.h"<br></div><div> #include "clang/Driver/Compilation.h"<br></div><div>+#include "llvm/Support/Path.h"<br></div><div><br></div><div> namespace clang {<br></div><div> namespace driver {<br></div><div>@@ -21,13 +22,36 @@ void Merger::ConstructJob(Compilation &C, const JobAction &JA,<br></div><div>   std::string Merger = getToolChain().GetProgramPath(getShortName());<br></div><div>   llvm::opt::ArgStringList CmdArgs;<br></div><div>   CmdArgs.push_back("-action");<br></div><div>-  CmdArgs.push_back(Args.getLastArg(options::OPT_emit_merged_ifs)<br></div><div>-                        ? "write-ifs"<br></div><div>-                        : "write-bin");<br></div><div>+  const bool WriteBin = !Args.getLastArg(options::OPT_emit_merged_ifs);<br></div><div>+  CmdArgs.push_back(WriteBin ? "write-bin" : "write-ifs");<br></div><div>   CmdArgs.push_back("-o");<br></div><div>-  CmdArgs.push_back(Output.getFilename());<br></div><div>-  for (const auto &Input : Inputs)<br></div><div>-    CmdArgs.push_back(Input.getFilename());<br></div><div>+<br></div><div>+  // Normally we want to write to a side-car file ending in ".ifso" so for<br></div><div>+  // example if `clang -emit-interface-stubs -shared -o libhello.so` were<br></div><div>+  // invoked then we would like to get libhello.so and libhello.ifso. If the<br></div><div>+  // stdout stream is given as the output file (ie `-o -`), that is the one<br></div><div>+  // exception where we will just append to the same filestream as the normal<br></div><div>+  // output.<br></div><div>+  SmallString<128> OutputFilename(Output.getFilename());<br></div><div>+  if (OutputFilename != "-") {<br></div><div>+    if (Args.hasArg(options::OPT_shared))<br></div><div>+      llvm::sys::path::replace_extension(OutputFilename,<br></div><div>+                                         (WriteBin ? "ifso" : "ifs"));<br></div><div>+    else<br></div><div>+      OutputFilename += (WriteBin ? ".ifso" : ".ifs");<br></div><div>+  }<br></div><div>+<br></div><div>+  CmdArgs.push_back(Args.MakeArgString(OutputFilename.c_str()));<br></div><div>+<br></div><div>+  // Here we append the input files. If the input files are object files, then<br></div><div>+  // we look for .ifs files present in the same location as the object files.<br></div><div>+  for (const auto &Input : Inputs) {<br></div><div>+    SmallString<128> InputFilename(Input.getFilename());<br></div><div>+    if (Input.getType() == types::TY_Object)<br></div><div>+      llvm::sys::path::replace_extension(InputFilename, ".ifs");<br></div><div>+    CmdArgs.push_back(Args.MakeArgString(InputFilename.c_str()));<br></div><div>+  }<br></div><div>+<br></div><div>   C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Merger),<br></div><div>                                          CmdArgs, Inputs));<br></div><div> }<br></div><div><br></div><div>diff  --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp<br></div><div>index 0e14e3d63fab..7d83be2521e7 100644<br></div><div>--- a/clang/lib/Driver/Types.cpp<br></div><div>+++ b/clang/lib/Driver/Types.cpp<br></div><div>@@ -330,22 +330,6 @@ void types::getCompilationPhases(const clang::driver::Driver &Driver,<br></div><div>     llvm::copy_if(PhaseList, std::back_inserter(P),<br></div><div>                   [](phases::ID Phase) { return Phase <= phases::Precompile; });<br></div><div><br></div><div>-  // Treat Interface Stubs like its own compilation mode.<br></div><div>-  else if (DAL.getLastArg(options::OPT_emit_interface_stubs)) {<br></div><div>-    llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> IfsModePhaseList;<br></div><div>-    llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> &PL = PhaseList;<br></div><div>-    phases::ID LastPhase = phases::IfsMerge;<br></div><div>-    if (Id != types::TY_IFS) {<br></div><div>-      if (DAL.hasArg(options::OPT_c))<br></div><div>-        LastPhase = phases::Compile;<br></div><div>-      PL = IfsModePhaseList;<br></div><div>-      types::getCompilationPhases(types::TY_IFS_CPP, PL);<br></div><div>-    }<br></div><div>-    llvm::copy_if(PL, std::back_inserter(P), [&](phases::ID Phase) {<br></div><div>-      return Phase <= LastPhase;<br></div><div>-    });<br></div><div>-  }<br></div><div>-<br></div><div>   // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.<br></div><div>   else if (DAL.getLastArg(options::OPT_fsyntax_only) ||<br></div><div>            DAL.getLastArg(options::OPT_print_supported_cpus) ||<br></div><div><br></div><div>diff  --git a/clang/test/InterfaceStubs/driver-test.c b/clang/test/InterfaceStubs/driver-test.c<br></div><div>index d4e50295411a..9ca5577a5c20 100644<br></div><div>--- a/clang/test/InterfaceStubs/driver-test.c<br></div><div>+++ b/clang/test/InterfaceStubs/driver-test.c<br></div><div>@@ -1,7 +1,9 @@<br></div><div> // REQUIRES: x86-registered-target<br></div><div>+// REQUIRES: shell<br></div><div><br></div><div>-// RUN: %clang -target x86_64-unknown-linux-gnu -x c -o %t1.so -emit-interface-stubs %s %S/object.c %S/weak.cpp && \<br></div><div>-// RUN: llvm-nm %t1.so 2>&1 | FileCheck --check-prefix=CHECK-IFS %s<br></div><div>+// RUN: mkdir -p %t; cd %t<br></div><div>+// RUN: %clang -target x86_64-unknown-linux-gnu -x c -S -emit-interface-stubs %s %S/object.c %S/weak.cpp && \<br></div><div>+// RUN: llvm-nm %t/a.out.ifso 2>&1 | FileCheck --check-prefix=CHECK-IFS %s<br></div><div><br></div><div> // CHECK-IFS-DAG: data<br></div><div> // CHECK-IFS-DAG: foo<br></div><div><br></div><div>diff  --git a/clang/test/InterfaceStubs/driver-test2.c b/clang/test/InterfaceStubs/driver-test2.c<br></div><div>new file mode 100644<br></div><div>index 000000000000..c3a3b31b212d<br></div><div>--- /dev/null<br></div><div>+++ b/clang/test/InterfaceStubs/driver-test2.c<br></div><div>@@ -0,0 +1,16 @@<br></div><div>+// REQUIRES: x86-registered-target<br></div><div>+// REQUIRES: shell<br></div><div>+<br></div><div>+// RUN: mkdir -p %t; cd %t<br></div><div>+// RUN: %clang -target x86_64-unknown-linux-gnu -c -emit-interface-stubs \<br></div><div>+// RUN:   %s %S/object.c %S/weak.cpp<br></div><div>+// RUN: %clang -emit-interface-stubs -emit-merged-ifs \<br></div><div>+// RUN:   %t/driver-test2.o %t/object.o %t/weak.o -S -o - 2>&1 | FileCheck %s<br></div><div>+<br></div><div>+// CHECK-DAG: data<br></div><div>+// CHECK-DAG: bar<br></div><div>+// CHECK-DAG: strongFunc<br></div><div>+// CHECK-DAG: weakFunc<br></div><div>+<br></div><div>+int bar(int a) { return a; }<br></div><div>+int main() { return 0; }<br></div><div><br></div><div>diff  --git a/clang/test/InterfaceStubs/ppc.cpp b/clang/test/InterfaceStubs/ppc.cpp<br></div><div>new file mode 100644<br></div><div>index 000000000000..9a91697d9506<br></div><div>--- /dev/null<br></div><div>+++ b/clang/test/InterfaceStubs/ppc.cpp<br></div><div>@@ -0,0 +1,14 @@<br></div><div>+// REQUIRES: powerpc-registered-target<br></div><div>+<br></div><div>+// RUN: %clang -x c++ -target powerpc64le-unknown-linux-gnu -o - %s \<br></div><div>+// RUN:   -emit-interface-stubs -emit-merged-ifs -S | \<br></div><div>+// RUN: FileCheck -check-prefix=CHECK-IFS %s<br></div><div>+<br></div><div>+ // CHECK-IFS: --- !experimental-ifs-v1<br></div><div>+ // CHECK-IFS: IfsVersion:      1.0<br></div><div>+ // CHECK-IFS: Triple: powerpc64le<br></div><div>+ // CHECK-IFS: Symbols:<br></div><div>+ // CHECK-IFS:   _Z8helloPPCv: { Type: Func }<br></div><div>+ // CHECK-IFS: ...<br></div><div>+<br></div><div>+int helloPPC();<br></div><div><br></div><div>diff  --git a/clang/test/InterfaceStubs/windows.cpp b/clang/test/InterfaceStubs/windows.cpp<br></div><div>index 9ccb771a2f39..c81c702861e4 100644<br></div><div>--- a/clang/test/InterfaceStubs/windows.cpp<br></div><div>+++ b/clang/test/InterfaceStubs/windows.cpp<br></div><div>@@ -1,6 +1,7 @@<br></div><div> // REQUIRES: x86-registered-target<br></div><div> // RUN: %clang_cc1 -triple x86_64-windows-msvc -o - %s -emit-interface-stubs | FileCheck -check-prefix=CHECK-CC1 %s<br></div><div>-// RUN: %clang -target x86_64-windows-msvc -o - %s -emit-interface-stubs -emit-merged-ifs | FileCheck -check-prefix=CHECK-IFS %s<br></div><div>+// RUN: %clang -target x86_64-windows-msvc -o - %s -emit-interface-stubs -emit-merged-ifs -S | FileCheck -check-prefix=CHECK-IFS %s<br></div><div>+// note: -S is added here to prevent clang from invoking link.exe<br></div><div><br></div><div> // CHECK-CC1: Symbols:<br></div><div> // CHECK-CC1-NEXT: ?helloWindowsMsvc@@YAHXZ<br></div><div><br></div><div><br></div><div><br></div><div>_______________________________________________<br></div><div>cfe-commits mailing list<br></div><div><a target="_blank" href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br></div><div><a target="_blank" rel="noreferrer" href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br></div></blockquote></div></blockquote><div><br></div></blockquote><div><br></div>