[clang] d694594 - [clang][IFS] Allow 2 output files when using -o and -c with clang IFS stubs.

Puyan Lotfi via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 9 11:49:07 PST 2019


Author: Puyan Lotfi
Date: 2019-12-09T14:47:17-05:00
New Revision: d694594d7650571dec40cc0ef9db6087963d62a0

URL: https://github.com/llvm/llvm-project/commit/d694594d7650571dec40cc0ef9db6087963d62a0
DIFF: https://github.com/llvm/llvm-project/commit/d694594d7650571dec40cc0ef9db6087963d62a0.diff

LOG: [clang][IFS] Allow 2 output files when using -o and -c with clang IFS stubs.

This patch allows for -o to be used with -c when compiling with clang
interface stubs enabled. This is because the second file will be an
intermediate ifs stubs file that is the text stub analog of the .o file.
Both get produces in this case, so two files.

Why are we doing this? Because we want to support the case where
interface stubs are used bu first invoking clang like so:

clang -c <other flags> -emit-interface-stubs foo.c -o foo.o
...
clang -emit-interface-stubs <.o files> -o libfoo.so

This should generate N .ifs files, and one .ifso file. Prior to this
patch, using -o with the -c invocation was not possible. Currently the
clang driver supports generating a a.out/.so file at the same time as a
merged ifs file / ifso file, but this is done by checking that the final
job is the IfsMerge job. When -c is used, the final job is a Compile job
so what this patch does is check to figure out of the job type is
TY_IFS_CPP.

Differential Revision: https://reviews.llvm.org/D70763

Added: 
    clang/test/InterfaceStubs/driver-test3.c

Modified: 
    clang/lib/Driver/Driver.cpp
    clang/lib/Driver/ToolChains/Clang.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index c1173e3ddbf0..9139915761d1 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -3689,16 +3689,27 @@ void Driver::BuildJobs(Compilation &C) const {
   Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
 
   // It is an error to provide a -o option if we are making multiple output
-  // files. There is one exception, IfsMergeJob: when generating interface stubs
-  // enabled we want to be able to generate the stub file at the same time that
-  // we generate the real library/a.out. So when a .o, .so, etc are the output,
-  // with clang interface stubs there will also be a .ifs and .ifso at the same
-  // location.
+  // files. There are exceptions:
+  //
+  // IfsMergeJob: when generating interface stubs enabled we want to be able to
+  // generate the stub file at the same time that we generate the real
+  // library/a.out. So when a .o, .so, etc are the output, with clang interface
+  // stubs there will also be a .ifs and .ifso at the same location.
+  //
+  // CompileJob of type TY_IFS_CPP: when generating interface stubs is enabled
+  // and -c is passed, we still want to be able to generate a .ifs file while
+  // we are also generating .o files. So we allow more than one output file in
+  // this case as well.
+  //
   if (FinalOutput) {
     unsigned NumOutputs = 0;
+    unsigned NumIfsOutputs = 0;
     for (const Action *A : C.getActions())
       if (A->getType() != types::TY_Nothing &&
           !(A->getKind() == Action::IfsMergeJobClass ||
+            (A->getType() == clang::driver::types::TY_IFS_CPP &&
+             A->getKind() == clang::driver::Action::CompileJobClass &&
+             0 == NumIfsOutputs++) ||
             (A->getKind() == Action::BindArchClass && A->getInputs().size() &&
              A->getInputs().front()->getKind() == Action::IfsMergeJobClass)))
         ++NumOutputs;

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 02a365fa4969..7fb1c846e0b2 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5828,8 +5828,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (Output.getType() == types::TY_Dependencies) {
     // Handled with other dependency code.
   } else if (Output.isFilename()) {
-    CmdArgs.push_back("-o");
-    CmdArgs.push_back(Output.getFilename());
+    if (Output.getType() == clang::driver::types::TY_IFS_CPP ||
+        Output.getType() == clang::driver::types::TY_IFS) {
+      SmallString<128> OutputFilename(Output.getFilename());
+      llvm::sys::path::replace_extension(OutputFilename, "ifs");
+      CmdArgs.push_back("-o");
+      CmdArgs.push_back(Args.MakeArgString(OutputFilename));
+    } else {
+      CmdArgs.push_back("-o");
+      CmdArgs.push_back(Output.getFilename());
+    }
   } else {
     assert(Output.isNothing() && "Invalid output.");
   }

diff  --git a/clang/test/InterfaceStubs/driver-test3.c b/clang/test/InterfaceStubs/driver-test3.c
new file mode 100644
index 000000000000..bccd1c9bccd4
--- /dev/null
+++ b/clang/test/InterfaceStubs/driver-test3.c
@@ -0,0 +1,19 @@
+// REQUIRES: x86-registered-target
+// REQUIRES: shell
+
+// RUN: mkdir -p %t; cd %t
+// RUN: %clang -target x86_64-unknown-linux-gnu -c -emit-interface-stubs %s -o %t/driver-test3.o
+// RUN: llvm-nm %t/driver-test3.o | FileCheck --check-prefix=CHECK-OBJ %s
+// RUN: cat %t/driver-test3.ifs | FileCheck --check-prefix=CHECK-IFS %s
+
+// CHECK-OBJ: bar
+
+// CHECK-IFS: --- !experimental-ifs-v1
+// CHECK-IFS-NEXT: IfsVersion:
+// CHECK-IFS-NEXT: Triple:
+// CHECK-IFS-NEXT: ObjectFileFormat:
+// CHECK-IFS-NEXT: Symbols:
+// CHECK-IFS-NEXT:   "bar" : { Type: Func }
+// CHECK-IFS-NEXT: ...
+
+int bar(int a) { return a; }


        


More information about the cfe-commits mailing list