plotfi created this revision.
plotfi added a reviewer: compnerd.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Up until now, clang interface stubs has replaced the standard PP -> C -> BE -> 
ASM -> LNK pipeline. With this change, it will happen in conjunction with it. 
So what when you build your code you will get an a.out or lib.so as well as an 
interface stub file.

TODO: add another test or two.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D70274

Files:
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChains/InterfaceStubs.cpp
  clang/lib/Driver/Types.cpp
  clang/test/InterfaceStubs/driver-test.c
  clang/test/InterfaceStubs/windows.cpp

Index: clang/test/InterfaceStubs/windows.cpp
===================================================================
--- clang/test/InterfaceStubs/windows.cpp
+++ clang/test/InterfaceStubs/windows.cpp
@@ -1,6 +1,7 @@
 // REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -triple x86_64-windows-msvc -o - %s -emit-interface-stubs | FileCheck -check-prefix=CHECK-CC1 %s
-// RUN: %clang -target x86_64-windows-msvc -o - %s -emit-interface-stubs -emit-merged-ifs | FileCheck -check-prefix=CHECK-IFS %s
+// RUN: %clang -target x86_64-windows-msvc -o - %s -emit-interface-stubs -emit-merged-ifs -c | FileCheck -check-prefix=CHECK-IFS %s
+// note: -c is added here to prevent clang from invoking link.exe
 
 // CHECK-CC1: Symbols:
 // CHECK-CC1-NEXT: ?helloWindowsMsvc@@YAHXZ
Index: clang/test/InterfaceStubs/driver-test.c
===================================================================
--- clang/test/InterfaceStubs/driver-test.c
+++ clang/test/InterfaceStubs/driver-test.c
@@ -1,11 +1,13 @@
 // REQUIRES: x86-registered-target
 
-// RUN: %clang -target x86_64-unknown-linux-gnu -x c -o %t1.so -emit-interface-stubs %s %S/object.c %S/weak.cpp && \
-// RUN: llvm-nm %t1.so 2>&1 | FileCheck --check-prefix=CHECK-IFS %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -x c -o %t1 -emit-interface-stubs %s %S/object.c %S/weak.cpp
+// RUN: llvm-nm %t1   2>&1 | FileCheck %s
+// RUN: llvm-nm %t1.ifso 2>&1 | FileCheck %s
 
-// CHECK-IFS-DAG: data
-// CHECK-IFS-DAG: foo
-// CHECK-IFS-DAG: strongFunc
-// CHECK-IFS-DAG: weakFunc
+// CHECK-DAG: data
+// CHECK-DAG: foo
+// CHECK-DAG: strongFunc
+// CHECK-DAG: weakFunc
 
 int foo(int bar) { return 42 + 1844; }
+int main() { return foo(23); }
Index: clang/lib/Driver/Types.cpp
===================================================================
--- clang/lib/Driver/Types.cpp
+++ clang/lib/Driver/Types.cpp
@@ -330,22 +330,6 @@
     llvm::copy_if(PhaseList, std::back_inserter(P),
                   [](phases::ID Phase) { return Phase <= phases::Precompile; });
 
-  // Treat Interface Stubs like its own compilation mode.
-  else if (DAL.getLastArg(options::OPT_emit_interface_stubs)) {
-    llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> IfsModePhaseList;
-    llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> &PL = PhaseList;
-    phases::ID LastPhase = phases::IfsMerge;
-    if (Id != types::TY_IFS) {
-      if (DAL.hasArg(options::OPT_c))
-        LastPhase = phases::Compile;
-      PL = IfsModePhaseList;
-      types::getCompilationPhases(types::TY_IFS_CPP, PL);
-    }
-    llvm::copy_if(PL, std::back_inserter(P), [&](phases::ID Phase) {
-      return Phase <= LastPhase;
-    });
-  }
-
   // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
   else if (DAL.getLastArg(options::OPT_fsyntax_only) ||
            DAL.getLastArg(options::OPT_print_supported_cpus) ||
Index: clang/lib/Driver/ToolChains/InterfaceStubs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/InterfaceStubs.cpp
+++ clang/lib/Driver/ToolChains/InterfaceStubs.cpp
@@ -21,11 +21,29 @@
   std::string Merger = getToolChain().GetProgramPath(getShortName());
   llvm::opt::ArgStringList CmdArgs;
   CmdArgs.push_back("-action");
-  CmdArgs.push_back(Args.getLastArg(options::OPT_emit_merged_ifs)
-                        ? "write-ifs"
-                        : "write-bin");
+  const bool WriteBin = !Args.getLastArg(options::OPT_emit_merged_ifs);
+  CmdArgs.push_back(WriteBin ? "write-bin" : "write-ifs");
   CmdArgs.push_back("-o");
-  CmdArgs.push_back(Output.getFilename());
+
+  std::string OutputFilename = Output.getFilename();
+
+  // Normally we want to write to a side-car file ending in ".ifso" so for
+  // example if `clang -emit-interface-stubs -shared -o libhello.so` were
+  // invoked then we would like to get libhello.so and libhello.ifso. If the
+  // stdout stream is given as the output file (ie `-o -`), that is the one
+  // exception where we will just append to the same filestream as the normal
+  // output.
+  if (OutputFilename != "-") {
+    std::string DllFileExt = ".so";
+    size_t TrimedSize = OutputFilename.size() - DllFileExt.size();
+    if (OutputFilename.size() > DllFileExt.size() &&
+        std::equal(OutputFilename.begin() + TrimedSize, OutputFilename.end(),
+                   DllFileExt.begin()))
+      OutputFilename = OutputFilename.substr(0, TrimedSize);
+
+    OutputFilename += (WriteBin ? ".ifso" : ".ifs");
+  }
+  CmdArgs.push_back(Args.MakeArgString(OutputFilename.c_str()));
   for (const auto &Input : Inputs)
     CmdArgs.push_back(Input.getFilename());
   C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Merger),
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -3491,6 +3491,51 @@
     Actions.push_back(
         C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
 
+  if (Arg *A = Args.getLastArg(options::OPT_emit_interface_stubs)) {
+    llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PhaseList;
+    llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> &PL = PhaseList;
+    types::getCompilationPhases(types::TY_IFS_CPP, PL);
+
+    ActionList MergerInputs;
+
+    for (auto &I : Inputs) {
+      types::ID InputType = I.first;
+      const Arg *InputArg = I.second;
+
+      if (InputType == types::TY_IFS)
+        continue;
+
+      Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
+
+      for (phases::ID Phase : PL) {
+        if (Phase == phases::IfsMerge) {
+          assert(Phase == PL.back() &&
+                 "merging must be final compilation step.");
+          MergerInputs.push_back(Current);
+          Current = nullptr;
+          break;
+        }
+
+        if (Phase == phases::Compile) {
+          Current = C.MakeAction<CompileJobAction>(Current, types::TY_IFS_CPP);
+          continue;
+        }
+
+        llvm_unreachable(
+            "IFS Pipeline can only consist of Compile followed by IfsMerge.");
+      }
+
+      // If we ended with something, add to the output list.
+      if (Current)
+        Actions.push_back(Current);
+    }
+
+    // Add an interface stubs merge action if necessary.
+    if (!MergerInputs.empty())
+      Actions.push_back(
+          C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
+  }
+
   // If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a custom
   // Compile phase that prints out supported cpu models and quits.
   if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) {
@@ -3592,8 +3637,6 @@
       return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile);
     if (Args.hasArg(options::OPT_verify_pch))
       return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing);
-    if (Args.hasArg(options::OPT_emit_interface_stubs))
-      return C.MakeAction<CompileJobAction>(Input, types::TY_IFS_CPP);
     return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC);
   }
   case phases::Backend: {
@@ -3626,7 +3669,8 @@
   if (FinalOutput) {
     unsigned NumOutputs = 0;
     for (const Action *A : C.getActions())
-      if (A->getType() != types::TY_Nothing)
+      if (A->getType() != types::TY_Nothing &&
+          A->getKind() != Action::IfsMergeJobClass)
         ++NumOutputs;
 
     if (NumOutputs > 1) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to