r373538 - [clang][ifs] Clang Interface Stubs ToolChain plumbing.

Puyan Lotfi via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 2 19:01:46 PDT 2019


I committed a change to driver-test.c. Not sure if that fixes it yet. Looks like there’s failures in some cmake and tablegen stuff. I will investigate macOS this evening.

PL

Sent from ProtonMail Mobile

On Wed, Oct 2, 2019 at 6:50 PM, Nico Weber <thakis at chromium.org> wrote:

> Looks like it's passing on Linux now, but still failing on macOS:
>
> AIL: Clang :: InterfaceStubs/driver-test.c (6172 of 16012)
> ******************** TEST 'Clang :: InterfaceStubs/driver-test.c' FAILED ********************
> Script:
> --
> : 'RUN: at line 3';   /Users/thakis/src/llvm-project/out/gn/bin/clang -target x86_64-unknown-linux-gnu -x c -o /Users/thakis/src/llvm-project/out/gn/obj/clang/test/InterfaceStubs/Output/driver-test.c.tmp1.so -emit-interface-stubs /Users/thakis/src/llvm-project/clang/test/InterfaceStubs/driver-test.c /Users/thakis/src/llvm-project/clang/test/InterfaceStubs/object.c /Users/thakis/src/llvm-project/clang/test/InterfaceStubs/weak.cpp &&  llvm-nm /Users/thakis/src/llvm-project/out/gn/obj/clang/test/InterfaceStubs/Output/driver-test.c.tmp1.so 2>&1 | /Users/thakis/src/llvm-project/out/gn/bin/FileCheck --check-prefix=CHECK-IFS /Users/thakis/src/llvm-project/clang/test/InterfaceStubs/driver-test.c
> : 'RUN: at line 6';   /Users/thakis/src/llvm-project/out/gn/bin/clang -target x86_64-unknown-linux-gnu -x c -o /Users/thakis/src/llvm-project/out/gn/obj/clang/test/InterfaceStubs/Output/driver-test.c.tmp2.so -shared /Users/thakis/src/llvm-project/clang/test/InterfaceStubs/driver-test.c /Users/thakis/src/llvm-project/clang/test/InterfaceStubs/object.c /Users/thakis/src/llvm-project/clang/test/InterfaceStubs/weak.cpp &&  llvm-nm /Users/thakis/src/llvm-project/out/gn/obj/clang/test/InterfaceStubs/Output/driver-test.c.tmp2.so 2>&1 | /Users/thakis/src/llvm-project/out/gn/bin/FileCheck --check-prefix=CHECK-SO /Users/thakis/src/llvm-project/clang/test/InterfaceStubs/driver-test.c
> --
> Exit Code: 1
>
> Command Output (stderr):
> --
> ld: unknown option: --eh-frame-hdr
> clang: error: linker command failed with exit code 1 (use -v to see invocation)
>
> --
>
> ********************
> Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..
> Testing Time: 162.42s
> ********************
> Failing Tests (1):
>     Clang :: InterfaceStubs/driver-test.c
>
> On Wed, Oct 2, 2019 at 8:14 PM Puyan Lotfi <puyan at puyan.org> wrote:
>
>> Looking at this. Sorry for this. I think either the test needs to be restricted for the x86 target or the llvm-ifs tool is not being built with the distribution.
>> PL
>>
>> Sent with [ProtonMail](https://protonmail.com) Secure Email.
>>
>> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
>> On Wednesday, October 2, 2019 7:36 PM, Nico Weber <thakis at chromium.org> wrote:
>>
>>> Looks like this broke a bunch of tests:
>>>
>>> http://lab.llvm.org:8011/builders/clang-cuda-build/builds/37720/steps/ninja%20check%201/logs/FAIL%3A%20Clang%3A%3Aobject.cpp
>>> http://lab.llvm.org:8011/builders/clang-cuda-build/builds/37720/steps/ninja%20check%201/logs/FAIL%3A%20Clang%3A%3Adriver-test.c
>>>
>>> If it takes a while to fix, please revert and investigate async.
>>>
>>> On Wed, Oct 2, 2019 at 6:47 PM Puyan Lotfi via cfe-commits <cfe-commits at lists.llvm.org> wrote:
>>>
>>>> Author: zer0
>>>> Date: Wed Oct  2 15:50:07 2019
>>>> New Revision: 373538
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=373538&view=rev
>>>> Log:
>>>> [clang][ifs] Clang Interface Stubs ToolChain plumbing.
>>>>
>>>> This patch enables end to end support for generating ELF interface stubs
>>>> directly from clang. Now the following:
>>>>
>>>> clang -emit-interface-stubs -o libfoo.so a.cpp b.cpp c.cpp
>>>>
>>>> will product an ELF binary with visible symbols populated. Visibility attributes
>>>> and -fvisibility can be used to control what gets populated.
>>>>
>>>> * Adding ToolChain support for clang Driver IFS Merge Phase
>>>> * Implementing a default InterfaceStubs Merge clang Tool, used by ToolChain
>>>> * Adds support for the clang Driver to involve llvm-ifs on ifs files.
>>>> * Adds -emit-merged-ifs flag, to tell llvm-ifs to emit a merged ifs text file
>>>>   instead of the final object format (normally ELF)
>>>>
>>>> Differential Revision: https://reviews.llvm.org/D63978
>>>>
>>>> Added:
>>>>     cfe/trunk/lib/Driver/ToolChains/InterfaceStubs.cpp
>>>>     cfe/trunk/lib/Driver/ToolChains/InterfaceStubs.h
>>>>     cfe/trunk/test/InterfaceStubs/conflict-type.ifs
>>>>     cfe/trunk/test/InterfaceStubs/driver-test.c
>>>>     cfe/trunk/test/InterfaceStubs/func.ifs
>>>>     cfe/trunk/test/InterfaceStubs/merge-conflict-test.c
>>>>     cfe/trunk/test/InterfaceStubs/object-double.c
>>>>     cfe/trunk/test/InterfaceStubs/object-float.c
>>>>     cfe/trunk/test/InterfaceStubs/object.c
>>>>     cfe/trunk/test/InterfaceStubs/object.ifs
>>>> Modified:
>>>>     cfe/trunk/include/clang/Driver/Action.h
>>>>     cfe/trunk/include/clang/Driver/Options.td
>>>>     cfe/trunk/include/clang/Driver/Phases.h
>>>>     cfe/trunk/include/clang/Driver/ToolChain.h
>>>>     cfe/trunk/include/clang/Driver/Types.def
>>>>     cfe/trunk/lib/Driver/Action.cpp
>>>>     cfe/trunk/lib/Driver/CMakeLists.txt
>>>>     cfe/trunk/lib/Driver/Driver.cpp
>>>>     cfe/trunk/lib/Driver/Phases.cpp
>>>>     cfe/trunk/lib/Driver/ToolChain.cpp
>>>>     cfe/trunk/lib/Driver/ToolChains/Clang.cpp
>>>>     cfe/trunk/lib/Driver/Types.cpp
>>>>     cfe/trunk/lib/Frontend/CompilerInvocation.cpp
>>>>     cfe/trunk/test/InterfaceStubs/bad-format.cpp
>>>>     cfe/trunk/test/InterfaceStubs/class-template-specialization.cpp
>>>>     cfe/trunk/test/InterfaceStubs/externstatic.c
>>>>     cfe/trunk/test/InterfaceStubs/function-template-specialization.cpp
>>>>     cfe/trunk/test/InterfaceStubs/inline.c
>>>>     cfe/trunk/test/InterfaceStubs/template-namespace-function.cpp
>>>>     cfe/trunk/test/InterfaceStubs/weak.cpp
>>>>     cfe/trunk/test/lit.cfg.py
>>>>
>>>> Modified: cfe/trunk/include/clang/Driver/Action.h
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Action.h?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/Driver/Action.h (original)
>>>> +++ cfe/trunk/include/clang/Driver/Action.h Wed Oct  2 15:50:07 2019
>>>> @@ -65,6 +65,7 @@ public:
>>>>      BackendJobClass,
>>>>      AssembleJobClass,
>>>>      LinkJobClass,
>>>> +    IfsMergeJobClass,
>>>>      LipoJobClass,
>>>>      DsymutilJobClass,
>>>>      VerifyDebugInfoJobClass,
>>>> @@ -485,6 +486,17 @@ public:
>>>>    }
>>>>  };
>>>>
>>>> +class IfsMergeJobAction : public JobAction {
>>>> +  void anchor() override;
>>>> +
>>>> +public:
>>>> +  IfsMergeJobAction(ActionList &Inputs, types::ID Type);
>>>> +
>>>> +  static bool classof(const Action *A) {
>>>> +    return A->getKind() == IfsMergeJobClass;
>>>> +  }
>>>> +};
>>>> +
>>>>  class LinkJobAction : public JobAction {
>>>>    void anchor() override;
>>>>
>>>> Modified: cfe/trunk/include/clang/Driver/Options.td
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/Driver/Options.td (original)
>>>> +++ cfe/trunk/include/clang/Driver/Options.td Wed Oct  2 15:50:07 2019
>>>> @@ -633,6 +633,9 @@ def emit_llvm : Flag<["-"], "emit-llvm">
>>>>    HelpText<"Use the LLVM representation for assembler and object files">;
>>>>  def emit_iterface_stubs : Flag<["-"], "emit-interface-stubs">, Flags<[CC1Option]>, Group<Action_Group>,
>>>>    HelpText<"Generate Inteface Stub Files.">;
>>>> +def emit_merged_ifs : Flag<["-"], "emit-merged-ifs">,
>>>> +  Flags<[CC1Option]>, Group<Action_Group>,
>>>> +  HelpText<"Generate Interface Stub Files, emit merged text not binary.">;
>>>>  def iterface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">, Flags<[CC1Option]>;
>>>>  def exported__symbols__list : Separate<["-"], "exported_symbols_list">;
>>>>  def e : JoinedOrSeparate<["-"], "e">, Group<Link_Group>;
>>>>
>>>> Modified: cfe/trunk/include/clang/Driver/Phases.h
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Phases.h?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/Driver/Phases.h (original)
>>>> +++ cfe/trunk/include/clang/Driver/Phases.h Wed Oct  2 15:50:07 2019
>>>> @@ -20,7 +20,8 @@ namespace phases {
>>>>      Compile,
>>>>      Backend,
>>>>      Assemble,
>>>> -    Link
>>>> +    Link,
>>>> +    IfsMerge,
>>>>    };
>>>>
>>>>    enum {
>>>>
>>>> Modified: cfe/trunk/include/clang/Driver/ToolChain.h
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/Driver/ToolChain.h (original)
>>>> +++ cfe/trunk/include/clang/Driver/ToolChain.h Wed Oct  2 15:50:07 2019
>>>> @@ -136,11 +136,13 @@ private:
>>>>    mutable std::unique_ptr<Tool> Clang;
>>>>    mutable std::unique_ptr<Tool> Assemble;
>>>>    mutable std::unique_ptr<Tool> Link;
>>>> +  mutable std::unique_ptr<Tool> IfsMerge;
>>>>    mutable std::unique_ptr<Tool> OffloadBundler;
>>>>
>>>>    Tool *getClang() const;
>>>>    Tool *getAssemble() const;
>>>>    Tool *getLink() const;
>>>> +  Tool *getIfsMerge() const;
>>>>    Tool *getClangAs() const;
>>>>    Tool *getOffloadBundler() const;
>>>>
>>>> Modified: cfe/trunk/include/clang/Driver/Types.def
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Types.def?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/Driver/Types.def (original)
>>>> +++ cfe/trunk/include/clang/Driver/Types.def Wed Oct  2 15:50:07 2019
>>>> @@ -84,7 +84,8 @@ TYPE("lto-bc",                   LTO_BC,
>>>>
>>>>  // Misc.
>>>>  TYPE("ast",                      AST,          INVALID,         "ast",    phases::Compile, phases::Backend, phases::Assemble, phases::Link)
>>>> -TYPE("ifs",                      IFS,          INVALID,         "ifs",    phases::Compile, phases::Backend, phases::Assemble, phases::Link)
>>>> +TYPE("ifs",                      IFS,          INVALID,         "ifs",    phases::IfsMerge)
>>>> +TYPE("ifs-cpp",                  IFS_CPP,      INVALID,         "ifs",    phases::Compile, phases::IfsMerge)
>>>>  TYPE("pcm",                      ModuleFile,   INVALID,         "pcm",    phases::Compile, phases::Backend, phases::Assemble, phases::Link)
>>>>  TYPE("plist",                    Plist,        INVALID,         "plist",  phases::Compile, phases::Backend, phases::Assemble, phases::Link)
>>>>  TYPE("rewritten-objc",           RewrittenObjC,INVALID,         "cpp",    phases::Compile, phases::Backend, phases::Assemble, phases::Link)
>>>>
>>>> Modified: cfe/trunk/lib/Driver/Action.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Action.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Driver/Action.cpp (original)
>>>> +++ cfe/trunk/lib/Driver/Action.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -31,6 +31,7 @@ const char *Action::getClassName(ActionC
>>>>    case CompileJobClass: return "compiler";
>>>>    case BackendJobClass: return "backend";
>>>>    case AssembleJobClass: return "assembler";
>>>> +  case IfsMergeJobClass: return "interface-stub-merger";
>>>>    case LinkJobClass: return "linker";
>>>>    case LipoJobClass: return "lipo";
>>>>    case DsymutilJobClass: return "dsymutil";
>>>> @@ -357,6 +358,11 @@ void AssembleJobAction::anchor() {}
>>>>  AssembleJobAction::AssembleJobAction(Action *Input, types::ID OutputType)
>>>>      : JobAction(AssembleJobClass, Input, OutputType) {}
>>>>
>>>> +void IfsMergeJobAction::anchor() {}
>>>> +
>>>> +IfsMergeJobAction::IfsMergeJobAction(ActionList &Inputs, types::ID Type)
>>>> +    : JobAction(IfsMergeJobClass, Inputs, Type) {}
>>>> +
>>>>  void LinkJobAction::anchor() {}
>>>>
>>>>  LinkJobAction::LinkJobAction(ActionList &Inputs, types::ID Type)
>>>>
>>>> Modified: cfe/trunk/lib/Driver/CMakeLists.txt
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/CMakeLists.txt?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Driver/CMakeLists.txt (original)
>>>> +++ cfe/trunk/lib/Driver/CMakeLists.txt Wed Oct  2 15:50:07 2019
>>>> @@ -66,6 +66,7 @@ add_clang_library(clangDriver
>>>>    ToolChains/WebAssembly.cpp
>>>>    ToolChains/XCore.cpp
>>>>    ToolChains/PPCLinux.cpp
>>>> +  ToolChains/InterfaceStubs.cpp
>>>>    Types.cpp
>>>>    XRayArgs.cpp
>>>>
>>>> Modified: cfe/trunk/lib/Driver/Driver.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Driver/Driver.cpp (original)
>>>> +++ cfe/trunk/lib/Driver/Driver.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -274,11 +274,11 @@ phases::ID Driver::getFinalPhase(const D
>>>>        (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) {
>>>>      FinalPhase = phases::Preprocess;
>>>>
>>>> -    // --precompile only runs up to precompilation.
>>>> +  // --precompile only runs up to precompilation.
>>>>    } else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile))) {
>>>>      FinalPhase = phases::Precompile;
>>>>
>>>> -    // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
>>>> +  // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
>>>>    } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
>>>>               (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
>>>>               (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
>>>> @@ -286,20 +286,23 @@ phases::ID Driver::getFinalPhase(const D
>>>>               (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
>>>>               (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
>>>>               (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
>>>> -             (PhaseArg = DAL.getLastArg(options::OPT_emit_iterface_stubs)) ||
>>>>               (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
>>>>               (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
>>>>      FinalPhase = phases::Compile;
>>>>
>>>> -    // -S only runs up to the backend.
>>>> +  // clang interface stubs
>>>> +  } else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_iterface_stubs))) {
>>>> +    FinalPhase = phases::IfsMerge;
>>>> +
>>>> +  // -S only runs up to the backend.
>>>>    } else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
>>>>      FinalPhase = phases::Backend;
>>>>
>>>> -    // -c compilation only runs up to the assembler.
>>>> +  // -c compilation only runs up to the assembler.
>>>>    } else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
>>>>      FinalPhase = phases::Assemble;
>>>>
>>>> -    // Otherwise do everything.
>>>> +  // Otherwise do everything.
>>>>    } else
>>>>      FinalPhase = phases::Link;
>>>>
>>>> @@ -3323,6 +3326,7 @@ void Driver::BuildActions(Compilation &C
>>>>    // Construct the actions to perform.
>>>>    HeaderModulePrecompileJobAction *HeaderModuleAction = nullptr;
>>>>    ActionList LinkerInputs;
>>>> +  ActionList MergerInputs;
>>>>
>>>>    for (auto &I : Inputs) {
>>>>      types::ID InputType = I.first;
>>>> @@ -3360,6 +3364,17 @@ void Driver::BuildActions(Compilation &C
>>>>          break;
>>>>        }
>>>>
>>>> +      // TODO: Consider removing this because the merged may not end up being
>>>> +      // the final Phase in the pipeline. Perhaps the merged could just merge
>>>> +      // and then pass an artifact of some sort to the Link Phase.
>>>> +      // Queue merger inputs.
>>>> +      if (Phase == phases::IfsMerge) {
>>>> +        assert(Phase == PL.back() && "merging must be final compilation step.");
>>>> +        MergerInputs.push_back(Current);
>>>> +        Current = nullptr;
>>>> +        break;
>>>> +      }
>>>> +
>>>>        // Each precompiled header file after a module file action is a module
>>>>        // header of that same module file, rather than being compiled to a
>>>>        // separate PCH.
>>>> @@ -3409,6 +3424,11 @@ void Driver::BuildActions(Compilation &C
>>>>      Actions.push_back(LA);
>>>>    }
>>>>
>>>> +  // 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)) {
>>>> @@ -3445,6 +3465,8 @@ Action *Driver::ConstructPhaseAction(
>>>>    switch (Phase) {
>>>>    case phases::Link:
>>>>      llvm_unreachable("link action invalid here.");
>>>> +  case phases::IfsMerge:
>>>> +    llvm_unreachable("ifsmerge action invalid here.");
>>>>    case phases::Preprocess: {
>>>>      types::ID OutputTy;
>>>>      // -M and -MM specify the dependency file name by altering the output type,
>>>> @@ -3509,7 +3531,7 @@ Action *Driver::ConstructPhaseAction(
>>>>      if (Args.hasArg(options::OPT_verify_pch))
>>>>        return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing);
>>>>      if (Args.hasArg(options::OPT_emit_iterface_stubs))
>>>> -      return C.MakeAction<CompileJobAction>(Input, types::TY_IFS);
>>>> +      return C.MakeAction<CompileJobAction>(Input, types::TY_IFS_CPP);
>>>>      return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC);
>>>>    }
>>>>    case phases::Backend: {
>>>>
>>>> Modified: cfe/trunk/lib/Driver/Phases.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Phases.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Driver/Phases.cpp (original)
>>>> +++ cfe/trunk/lib/Driver/Phases.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -20,6 +20,7 @@ const char *phases::getPhaseName(ID Id)
>>>>    case Backend: return "backend";
>>>>    case Assemble: return "assembler";
>>>>    case Link: return "linker";
>>>> +  case IfsMerge: return "ifsmerger";
>>>>    }
>>>>
>>>>    llvm_unreachable("Invalid phase id.");
>>>>
>>>> Modified: cfe/trunk/lib/Driver/ToolChain.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChain.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Driver/ToolChain.cpp (original)
>>>> +++ cfe/trunk/lib/Driver/ToolChain.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -10,6 +10,7 @@
>>>>  #include "InputInfo.h"
>>>>  #include "ToolChains/Arch/ARM.h"
>>>>  #include "ToolChains/Clang.h"
>>>> +#include "ToolChains/InterfaceStubs.h"
>>>>  #include "clang/Basic/ObjCRuntime.h"
>>>>  #include "clang/Basic/Sanitizers.h"
>>>>  #include "clang/Config/config.h"
>>>> @@ -279,6 +280,12 @@ Tool *ToolChain::getLink() const {
>>>>    return Link.get();
>>>>  }
>>>>
>>>> +Tool *ToolChain::getIfsMerge() const {
>>>> +  if (!IfsMerge)
>>>> +    IfsMerge.reset(new tools::ifstool::Merger(*this));
>>>> +  return IfsMerge.get();
>>>> +}
>>>> +
>>>>  Tool *ToolChain::getOffloadBundler() const {
>>>>    if (!OffloadBundler)
>>>>      OffloadBundler.reset(new tools::OffloadBundler(*this));
>>>> @@ -290,6 +297,9 @@ Tool *ToolChain::getTool(Action::ActionC
>>>>    case Action::AssembleJobClass:
>>>>      return getAssemble();
>>>>
>>>> +  case Action::IfsMergeJobClass:
>>>> +    return getIfsMerge();
>>>> +
>>>>    case Action::LinkJobClass:
>>>>      return getLink();
>>>>
>>>> Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
>>>> +++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -3683,32 +3683,15 @@ void Clang::ConstructJob(Compilation &C,
>>>>      } else if (JA.getType() == types::TY_LLVM_BC ||
>>>>                 JA.getType() == types::TY_LTO_BC) {
>>>>        CmdArgs.push_back("-emit-llvm-bc");
>>>> -    } else if (JA.getType() == types::TY_IFS) {
>>>> +    } else if (JA.getType() == types::TY_IFS ||
>>>> +               JA.getType() == types::TY_IFS_CPP) {
>>>>        StringRef ArgStr =
>>>>            Args.hasArg(options::OPT_iterface_stub_version_EQ)
>>>>                ? Args.getLastArgValue(options::OPT_iterface_stub_version_EQ)
>>>> -              : "";
>>>> -      StringRef StubFormat =
>>>> -          llvm::StringSwitch<StringRef>(ArgStr)
>>>> -              .Case("experimental-ifs-v1", "experimental-ifs-v1")
>>>> -              .Default("");
>>>> -
>>>> -      if (StubFormat.empty()) {
>>>> -        std::string ErrorMessage =
>>>> -            "Invalid interface stub format: " + ArgStr.str() +
>>>> -            ((ArgStr == "experimental-yaml-elf-v1" ||
>>>> -              ArgStr == "experimental-tapi-elf-v1")
>>>> -                 ? " is deprecated."
>>>> -                 : ".");
>>>> -        D.Diag(diag::err_drv_invalid_value)
>>>> -            << "Must specify a valid interface stub format type, ie: "
>>>> -               "-interface-stub-version=experimental-ifs-v1"
>>>> -            << ErrorMessage;
>>>> -      }
>>>> -
>>>> +              : "experimental-ifs-v1";
>>>>        CmdArgs.push_back("-emit-interface-stubs");
>>>>        CmdArgs.push_back(
>>>> -          Args.MakeArgString(Twine("-interface-stub-version=") + StubFormat));
>>>> +          Args.MakeArgString(Twine("-interface-stub-version=") + ArgStr.str()));
>>>>      } else if (JA.getType() == types::TY_PP_Asm) {
>>>>        CmdArgs.push_back("-S");
>>>>      } else if (JA.getType() == types::TY_AST) {
>>>>
>>>> Added: cfe/trunk/lib/Driver/ToolChains/InterfaceStubs.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/InterfaceStubs.cpp?rev=373538&view=auto
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Driver/ToolChains/InterfaceStubs.cpp (added)
>>>> +++ cfe/trunk/lib/Driver/ToolChains/InterfaceStubs.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -0,0 +1,37 @@
>>>> +//===---  InterfaceStubs.cpp - Base InterfaceStubs Implementations C++  ---===//
>>>> +//
>>>> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
>>>> +// See https://llvm.org/LICENSE.txt for license information.
>>>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
>>>> +//
>>>> +//===----------------------------------------------------------------------===//
>>>> +
>>>> +#include "InterfaceStubs.h"
>>>> +#include "CommonArgs.h"
>>>> +#include "clang/Driver/Compilation.h"
>>>> +
>>>> +namespace clang {
>>>> +namespace driver {
>>>> +namespace tools {
>>>> +namespace ifstool {
>>>> +void Merger::ConstructJob(Compilation &C, const JobAction &JA,
>>>> +                          const InputInfo &Output, const InputInfoList &Inputs,
>>>> +                          const llvm::opt::ArgList &Args,
>>>> +                          const char *LinkingOutput) const {
>>>> +  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");
>>>> +  CmdArgs.push_back("-o");
>>>> +  CmdArgs.push_back(Output.getFilename());
>>>> +  for (const auto &Input : Inputs)
>>>> +    CmdArgs.push_back(Input.getFilename());
>>>> +  C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Merger),
>>>> +                                         CmdArgs, Inputs));
>>>> +}
>>>> +} // namespace ifstool
>>>> +} // namespace tools
>>>> +} // namespace driver
>>>> +} // namespace clang
>>>>
>>>> Added: cfe/trunk/lib/Driver/ToolChains/InterfaceStubs.h
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/InterfaceStubs.h?rev=373538&view=auto
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Driver/ToolChains/InterfaceStubs.h (added)
>>>> +++ cfe/trunk/lib/Driver/ToolChains/InterfaceStubs.h Wed Oct  2 15:50:07 2019
>>>> @@ -0,0 +1,36 @@
>>>> +//===---  InterfaceStubs.cpp - Base InterfaceStubs Implementations C++  ---===//
>>>> +//
>>>> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
>>>> +// See https://llvm.org/LICENSE.txt for license information.
>>>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
>>>> +//
>>>> +//===----------------------------------------------------------------------===//
>>>> +
>>>> +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_IFS_H
>>>> +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_IFS_H
>>>> +
>>>> +#include "clang/Driver/Tool.h"
>>>> +#include "clang/Driver/ToolChain.h"
>>>> +
>>>> +namespace clang {
>>>> +namespace driver {
>>>> +namespace tools {
>>>> +namespace ifstool {
>>>> +class LLVM_LIBRARY_VISIBILITY Merger : public Tool {
>>>> +public:
>>>> +  Merger(const ToolChain &TC) : Tool("IFS::Merger", "llvm-ifs", TC) {}
>>>> +
>>>> +  bool hasIntegratedCPP() const override { return false; }
>>>> +  bool isLinkJob() const override { return false; }
>>>> +
>>>> +  void ConstructJob(Compilation &C, const JobAction &JA,
>>>> +                    const InputInfo &Output, const InputInfoList &Inputs,
>>>> +                    const llvm::opt::ArgList &TCArgs,
>>>> +                    const char *LinkingOutput) const override;
>>>> +};
>>>> +} // end namespace ifstool
>>>> +} // end namespace tools
>>>> +} // end namespace driver
>>>> +} // end namespace clang
>>>> +
>>>> +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_IFS_H
>>>>
>>>> Modified: cfe/trunk/lib/Driver/Types.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Types.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Driver/Types.cpp (original)
>>>> +++ cfe/trunk/lib/Driver/Types.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -269,6 +269,7 @@ types::ID types::lookupTypeForExtension(
>>>>             .Case("lib", TY_Object)
>>>>             .Case("mii", TY_PP_ObjCXX)
>>>>             .Case("obj", TY_Object)
>>>> +           .Case("ifs", TY_IFS)
>>>>             .Case("pch", TY_PCH)
>>>>             .Case("pcm", TY_ModuleFile)
>>>>             .Case("c++m", TY_CXXModule)
>>>> @@ -319,6 +320,22 @@ void types::getCompilationPhases(const c
>>>>      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_iterface_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) ||
>>>> @@ -327,7 +344,6 @@ void types::getCompilationPhases(const c
>>>>             DAL.getLastArg(options::OPT_rewrite_objc) ||
>>>>             DAL.getLastArg(options::OPT_rewrite_legacy_objc) ||
>>>>             DAL.getLastArg(options::OPT__migrate) ||
>>>> -           DAL.getLastArg(options::OPT_emit_iterface_stubs) ||
>>>>             DAL.getLastArg(options::OPT__analyze) ||
>>>>             DAL.getLastArg(options::OPT_emit_ast))
>>>>      llvm::copy_if(PhaseList, std::back_inserter(P),
>>>>
>>>> Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
>>>> +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -1734,24 +1734,25 @@ static InputKind ParseFrontendArgs(Front
>>>>        StringRef ArgStr =
>>>>            Args.hasArg(OPT_iterface_stub_version_EQ)
>>>>                ? Args.getLastArgValue(OPT_iterface_stub_version_EQ)
>>>> -              : "";
>>>> -      llvm::Optional<frontend::ActionKind> ProgramAction =
>>>> -          llvm::StringSwitch<llvm::Optional<frontend::ActionKind>>(ArgStr)
>>>> -              .Case("experimental-ifs-v1", frontend::GenerateInterfaceIfsExpV1)
>>>> -              .Default(llvm::None);
>>>> -      if (!ProgramAction) {
>>>> +              : "experimental-ifs-v1";
>>>> +      if (ArgStr == "experimental-yaml-elf-v1" ||
>>>> +          ArgStr == "experimental-tapi-elf-v1") {
>>>>          std::string ErrorMessage =
>>>>              "Invalid interface stub format: " + ArgStr.str() +
>>>> -            ((ArgStr == "experimental-yaml-elf-v1" ||
>>>> -              ArgStr == "experimental-tapi-elf-v1")
>>>> -                 ? " is deprecated."
>>>> -                 : ".");
>>>> +            " is deprecated.";
>>>> +        Diags.Report(diag::err_drv_invalid_value)
>>>> +            << "Must specify a valid interface stub format type, ie: "
>>>> +               "-interface-stub-version=experimental-ifs-v1"
>>>> +            << ErrorMessage;
>>>> +      } else if (ArgStr != "experimental-ifs-v1") {
>>>> +        std::string ErrorMessage =
>>>> +            "Invalid interface stub format: " + ArgStr.str() + ".";
>>>>          Diags.Report(diag::err_drv_invalid_value)
>>>>              << "Must specify a valid interface stub format type, ie: "
>>>>                 "-interface-stub-version=experimental-ifs-v1"
>>>>              << ErrorMessage;
>>>>        } else {
>>>> -        Opts.ProgramAction = *ProgramAction;
>>>> +        Opts.ProgramAction = frontend::GenerateInterfaceIfsExpV1;
>>>>        }
>>>>        break;
>>>>      }
>>>>
>>>> Modified: cfe/trunk/test/InterfaceStubs/bad-format.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/bad-format.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/bad-format.cpp (original)
>>>> +++ cfe/trunk/test/InterfaceStubs/bad-format.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -1,28 +1,25 @@
>>>> -// REQUIRES: x86-registered-target
>>>> -// RUN: not %clang -target x86_64-linux-gnu -o - -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=bar-format %s 2>&1 | FileCheck %s
>>>> +// RUN: not %clang -emit-interface-stubs -interface-stub-version=bad-format %s 2>&1 | \
>>>> +// RUN: FileCheck %s
>>>>
>>>> -// RUN: not %clang -target x86_64-linux-gnu -o - -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s 2>&1 | \
>>>> +// RUN: not %clang -emit-interface-stubs -interface-stub-version=experimental-tapi-elf-v1 %s 2>&1 | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-TAPI-DEPRECATED %s
>>>>
>>>> -// RUN: not %clang -target x86_64-linux-gnu -o - -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=experimental-yaml-elf-v1 %s 2>&1 | \
>>>> +// RUN: not %clang -emit-interface-stubs -interface-stub-version=experimental-yaml-elf-v1 %s 2>&1 | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-YAML-DEPRECATED %s
>>>>
>>>> -// RUN: not %clang_cc1 -target x86_64-linux-gnu -o - -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=bar-format %s 2>&1 | FileCheck %s
>>>> +// RUN: not %clang -emit-interface-stubs -interface-stub-version=bad-format %s 2>&1 | \
>>>> +// RUN: FileCheck %s
>>>>
>>>> -// RUN: not %clang_cc1 -target x86_64-linux-gnu -o - -emit-interface-stubs \
>>>> +// RUN: not %clang -emit-interface-stubs \
>>>>  // RUN: -interface-stub-version=experimental-tapi-elf-v1 %s 2>&1 | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-TAPI-DEPRECATED %s
>>>>
>>>> -// RUN: not %clang_cc1 -target x86_64-linux-gnu -o - -emit-interface-stubs \
>>>> +// RUN: not %clang -emit-interface-stubs \
>>>>  // RUN: -interface-stub-version=experimental-yaml-elf-v1 %s 2>&1 | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-YAML-DEPRECATED %s
>>>>
>>>>  // CHECK: error: invalid value
>>>> -// CHECK: 'Invalid interface stub format: bar-format.' in 'Must specify a
>>>> +// CHECK: 'Invalid interface stub format: bad-format.' in 'Must specify a
>>>>  // CHECK: valid interface stub format type, ie:
>>>>  // CHECK: -interface-stub-version=experimental-ifs-v1'
>>>>
>>>> Modified: cfe/trunk/test/InterfaceStubs/class-template-specialization.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/class-template-specialization.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/class-template-specialization.cpp (original)
>>>> +++ cfe/trunk/test/InterfaceStubs/class-template-specialization.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -1,9 +1,9 @@
>>>>  // REQUIRES: x86-registered-target
>>>> -// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \
>>>> +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs -emit-merged-ifs \
>>>>  // RUN: -interface-stub-version=experimental-ifs-v1 %s | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-TAPI %s
>>>>
>>>> -// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \
>>>> +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs -emit-merged-ifs \
>>>>  // RUN: -interface-stub-version=experimental-ifs-v1 %s | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-TAPI2 %s
>>>>  // RUN: %clang -target x86_64-unknown-linux-gnu -o - -c %s | \
>>>>
>>>> Added: cfe/trunk/test/InterfaceStubs/conflict-type.ifs
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/conflict-type.ifs?rev=373538&view=auto
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/conflict-type.ifs (added)
>>>> +++ cfe/trunk/test/InterfaceStubs/conflict-type.ifs Wed Oct  2 15:50:07 2019
>>>> @@ -0,0 +1,16 @@
>>>> +# RUN: not %clang -emit-merged-ifs -emit-interface-stubs -o - %s %S/func.ifs 2>&1 | \
>>>> +# RUN: FileCheck %s --check-prefixes=CHECK-IFS
>>>> +
>>>> +# Here we are testing to see if two symbols with identical names will fail to
>>>> +# merge in conflict due to mismatched types.
>>>> +# CHECK-IFS: error: Interface Stub: Type Mismatch for a.
>>>> +# CHECK-IFS-NEXT: Filename:
>>>> +# CHECK-IFS-NEXT: Type Values: Object Func
>>>> +
>>>> +--- !experimental-ifs-v1
>>>> +IfsVersion: 1.0
>>>> +Triple: x86_64-linux-gnu
>>>> +ObjectFileFormat: ELF
>>>> +Symbols:
>>>> +  a: { Type: Object, Size: 1 }
>>>> +...
>>>>
>>>> Added: cfe/trunk/test/InterfaceStubs/driver-test.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/driver-test.c?rev=373538&view=auto
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/driver-test.c (added)
>>>> +++ cfe/trunk/test/InterfaceStubs/driver-test.c Wed Oct  2 15:50:07 2019
>>>> @@ -0,0 +1,12 @@
>>>> +// RUN: %clang -x c -o libfoo.so -emit-interface-stubs %s %S/object.c %S/weak.cpp && \
>>>> +// RUN: llvm-nm libfoo.so 2>&1 | FileCheck %s
>>>> +
>>>> +// RUN: %clang -x c -o libfoo.so -shared %s %S/object.c %S/weak.cpp && \
>>>> +// RUN: llvm-nm libfoo.so 2>&1 | FileCheck %s
>>>> +
>>>> +// CHECK-DAG: data
>>>> +// CHECK-DAG: foo
>>>> +// CHECK-DAG: strongFunc
>>>> +// CHECK-DAG: weakFunc
>>>> +
>>>> +int foo(int bar) { return 42 + 1844; }
>>>> \ No newline at end of file
>>>>
>>>> Modified: cfe/trunk/test/InterfaceStubs/externstatic.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/externstatic.c?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/externstatic.c (original)
>>>> +++ cfe/trunk/test/InterfaceStubs/externstatic.c Wed Oct  2 15:50:07 2019
>>>> @@ -1,24 +1,20 @@
>>>> -// REQUIRES: x86-registered-target
>>>> -// RUN: %clang -DSTORAGE="extern" -target x86_64-unknown-linux-gnu -o - \
>>>> -// RUN: -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=experimental-ifs-v1 -std=c99 -xc %s | \
>>>> +// RUN: %clang -c -DSTORAGE="extern" -o - -emit-interface-stubs -std=c99 -xc %s | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-EXTERN %s
>>>> -// RUN: %clang -DSTORAGE="extern" -target x86_64-linux-gnu -O0 -o - -c -std=c99 \
>>>> +
>>>> +// RUN: %clang -DSTORAGE="extern" -O0 -o - -c -std=c99 \
>>>>  // RUN: -xc %s | llvm-nm - 2>&1 | FileCheck -check-prefix=CHECK-EXTERN %s
>>>>
>>>> -// RUN: %clang -DSTORAGE="extern" -target x86_64-unknown-linux-gnu -o - \
>>>> -// RUN: -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=experimental-ifs-v1 -std=c99 -xc %s | \
>>>> +// RUN: %clang -c -DSTORAGE="extern" -o - -emit-interface-stubs -std=c99 -xc %s | \
>>>> +// RUN: FileCheck -check-prefix=CHECK-EXTERN2 %s
>>>> +
>>>> +// RUN: %clang -DSTORAGE="extern" -O0 -o - -c -std=c99 -xc %s | llvm-nm - 2>&1 | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-EXTERN2 %s
>>>> -// RUN: %clang -DSTORAGE="extern" -target x86_64-linux-gnu -O0 -o - -c -std=c99 \
>>>> -// RUN: -xc %s | llvm-nm - 2>&1 | FileCheck -check-prefix=CHECK-EXTERN2 %s
>>>>
>>>> -// RUN: %clang -DSTORAGE="static" -target x86_64-unknown-linux-gnu -o - \
>>>> -// RUN: -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=experimental-ifs-v1 -std=c99 -xc %s | \
>>>> +// RUN: %clang -c -DSTORAGE="static" -o - -emit-interface-stubs -std=c99 -xc %s | \
>>>> +// RUN: FileCheck -check-prefix=CHECK-STATIC %s
>>>> +
>>>> +// RUN: %clang -DSTORAGE="static" -O0 -o - -c -std=c99 -xc %s | llvm-nm - 2>&1 | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-STATIC %s
>>>> -// RUN: %clang -DSTORAGE="static" -target x86_64-linux-gnu -O0 -o - -c -std=c99 \
>>>> -// RUN: -xc %s | llvm-nm - 2>&1 | FileCheck -check-prefix=CHECK-STATIC %s
>>>>
>>>>  // CHECK-EXTERN-NOT: foo
>>>>  // CHECK-STATIC-NOT: foo
>>>>
>>>> Added: cfe/trunk/test/InterfaceStubs/func.ifs
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/func.ifs?rev=373538&view=auto
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/func.ifs (added)
>>>> +++ cfe/trunk/test/InterfaceStubs/func.ifs Wed Oct  2 15:50:07 2019
>>>> @@ -0,0 +1,40 @@
>>>> +# RUN: %clang -emit-interface-stubs -o - %s %S/object.ifs -emit-merged-ifs | \
>>>> +# RUN: FileCheck %s --check-prefixes=CHECK-IFS
>>>> +
>>>> +# RUN: %clang -emit-interface-stubs -o - %s %S/object.ifs | llvm-readelf --all | \
>>>> +# RUN: FileCheck %s --check-prefixes=CHECK-ELF
>>>> +
>>>> +# RUN: %clang -emit-interface-stubs -o - %s %s -emit-merged-ifs | \
>>>> +# RUN: FileCheck %s --check-prefixes=CHECK-MERGE-IFS
>>>> +
>>>> +# CHECK-IFS: --- !experimental-ifs-v1
>>>> +# CHECK-IFS-NEXT: IfsVersion:      1.0
>>>> +# CHECK-IFS-NEXT: Triple:          x86_64-linux-gnu
>>>> +# CHECK-IFS-NEXT: ObjectFileFormat: ELF
>>>> +# CHECK-IFS-NEXT: Symbols:
>>>> +# CHECK-IFS-DAG:   a:               { Type: Func }
>>>> +# CHECK-IFS-DAG:   b:               { Type: Object, Size: 4 }
>>>> +# CHECK-IFS: ...
>>>> +
>>>> +# CHECK-ELF: ELF Header:
>>>> +# CHECK-ELF:   Class:                             ELF64
>>>> +# CHECK-ELF:   Type:                              DYN (Shared object file)
>>>> +# CHECK-ELF:   FUNC    GLOBAL DEFAULT  1 a
>>>> +# CHECK-ELF:   OBJECT  GLOBAL DEFAULT  1 b
>>>> +
>>>> +# Here we are testing to see if two identical symbols will merge.
>>>> +# CHECK-MERGE-IFS: --- !experimental-ifs-v1
>>>> +# CHECK-MERGE-IFS-NEXT: IfsVersion:      1.0
>>>> +# CHECK-MERGE-IFS-NEXT: Triple:          x86_64-linux-gnu
>>>> +# CHECK-MERGE-IFS-NEXT: ObjectFileFormat: ELF
>>>> +# CHECK-MERGE-IFS-NEXT: Symbols:
>>>> +# CHECK-MERGE-IFS-NEXT:   a:               { Type: Func }
>>>> +# CHECK-MERGE-IFS-NEXT: ...
>>>> +
>>>> +--- !experimental-ifs-v1
>>>> +IfsVersion: 1.0
>>>> +Triple: x86_64-linux-gnu
>>>> +ObjectFileFormat: ELF
>>>> +Symbols:
>>>> +  a: { Type: Func }
>>>> +...
>>>>
>>>> Modified: cfe/trunk/test/InterfaceStubs/function-template-specialization.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/function-template-specialization.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/function-template-specialization.cpp (original)
>>>> +++ cfe/trunk/test/InterfaceStubs/function-template-specialization.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -1,13 +1,15 @@
>>>>  // REQUIRES: x86-registered-target
>>>> -// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \
>>>> +
>>>> +// TODO: Fix the case in llvm-ifs where it crashes on an empty Symbols list.
>>>> +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs -c \
>>>>  // RUN: -interface-stub-version=experimental-ifs-v1 %s | FileCheck %s
>>>>
>>>> -// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \
>>>> +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs -emit-merged-ifs \
>>>>  // RUN: -interface-stub-version=experimental-ifs-v1 \
>>>>  // RUN: -DUSE_TEMPLATE_FUNCTION=1 %s | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-USES-TEMPLATE-FUNCTION %s
>>>>
>>>> -// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \
>>>> +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs -emit-merged-ifs \
>>>>  // RUN: -interface-stub-version=experimental-ifs-v1 \
>>>>  // RUN: -DSPECIALIZE_TEMPLATE_FUNCTION=1 %s | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-SPECIALIZES-TEMPLATE-FUNCTION %s
>>>>
>>>> Modified: cfe/trunk/test/InterfaceStubs/inline.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/inline.c?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/inline.c (original)
>>>> +++ cfe/trunk/test/InterfaceStubs/inline.c Wed Oct  2 15:50:07 2019
>>>> @@ -1,37 +1,32 @@
>>>>  // REQUIRES: x86-registered-target
>>>> -// RUN: %clang -DINLINE=inline -target x86_64-unknown-linux-gnu -o - \
>>>> -// RUN: -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=experimental-ifs-v1 -std=gnu89 -xc %s | \
>>>> +// RUN: %clang -c -DINLINE=inline -target x86_64-unknown-linux-gnu -o - \
>>>> +// RUN: -emit-interface-stubs -std=gnu89 -xc %s | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-GNU %s
>>>>  // RUN: %clang -DINLINE=inline -target x86_64-linux-gnu -O0 -o - -c \
>>>>  // RUN: -std=gnu89 -xc %s | llvm-nm - | FileCheck -check-prefix=CHECK-GNU %s
>>>>
>>>> -// RUN: %clang -DINLINE="__attribute__((always_inline))" \
>>>> -// RUN: -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=experimental-ifs-v1 -xc %s | \
>>>> +// RUN: %clang -c -DINLINE="__attribute__((always_inline))" \
>>>> +// RUN: -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs -xc %s | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-GNU %s
>>>>  // RUN: %clang -DINLINE="__attribute__((always_inline))" \
>>>>  // RUN: -target x86_64-linux-gnu -O0 -o - -c -xc %s | \
>>>>  // RUN: llvm-nm - | FileCheck -check-prefix=CHECK-GNU %s
>>>>
>>>> -// RUN: %clang -DINLINE=inline -target x86_64-unknown-linux-gnu -o - \
>>>> -// RUN: -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=experimental-ifs-v1 -std=c99 -xc %s | \
>>>> +// RUN: %clang -c -DINLINE=inline -target x86_64-unknown-linux-gnu -o - \
>>>> +// RUN: -emit-interface-stubs -std=c99 -xc %s | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-STD %s
>>>>  // RUN: %clang -DINLINE=inline -target x86_64-linux-gnu -O0 -o - -c -std=c99 \
>>>>  // RUN: -xc %s | llvm-nm - 2>&1 | FileCheck -check-prefix=CHECK-STD %s
>>>>
>>>> -// RUN: %clang -DINLINE="__attribute__((noinline))" \
>>>> -// RUN: -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=experimental-ifs-v1 -std=c99 -xc %s | \
>>>> +// RUN: %clang -c -DINLINE="__attribute__((noinline))" \
>>>> +// RUN: -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs -std=c99 -xc %s | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-NOINLINE %s
>>>>  // RUN: %clang -DINLINE="__attribute__((noinline))" -target x86_64-linux-gnu \
>>>>  // RUN: -O0 -o - -c -std=c99 -xc %s | llvm-nm - 2>&1 | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-NOINLINE %s
>>>>
>>>> -// RUN: %clang -DINLINE="static" -target x86_64-unknown-linux-gnu -o - \
>>>> -// RUN: -emit-interface-stubs \
>>>> -// RUN: -interface-stub-version=experimental-ifs-v1 -std=c99 -xc %s | \
>>>> +// RUN: %clang -c -DINLINE="static" -target x86_64-unknown-linux-gnu -o - \
>>>> +// RUN: -emit-interface-stubs -std=c99 -xc %s | \
>>>>  // RUN: FileCheck -check-prefix=CHECK-STATIC %s
>>>>  // RUN: %clang -DINLINE="static" -target x86_64-linux-gnu -O0 -o - -c \
>>>>  // RUN: -std=c99 -xc %s | llvm-nm - 2>&1 | \
>>>> @@ -50,12 +45,12 @@ INLINE int foo() {
>>>>    return var;
>>>>  }
>>>>
>>>> -// RUN: %clang -DINLINE=inline -target x86_64-linux-gnu -o - \
>>>> -// RUN: -emit-interface-stubs -interface-stub-version=experimental-ifs-v1 \
>>>> +// RUN: %clang -c -DINLINE=inline -target x86_64-linux-gnu -o - \
>>>> +// RUN: -emit-interface-stubs \
>>>>  // RUN: -std=gnu89 -xc %s | FileCheck -check-prefix=CHECK-TAPI %s
>>>>
>>>> -// RUN: %clang -DINLINE=inline -target x86_64-linux-gnu -o - \
>>>> -// RUN: -emit-interface-stubs -interface-stub-version=experimental-ifs-v1 \
>>>> +// RUN: %clang -c -DINLINE=inline -target x86_64-linux-gnu -o - \
>>>> +// RUN: -emit-interface-stubs \
>>>>  // RUN: -std=gnu89 -xc %s | FileCheck -check-prefix=CHECK-SYMBOLS %s
>>>>  // RUN: %clang -DINLINE=inline -target x86_64-linux-gnu -o - \
>>>>  // RUN: -c -std=gnu89 -xc %s | llvm-nm - 2>&1 | \
>>>>
>>>> Added: cfe/trunk/test/InterfaceStubs/merge-conflict-test.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/merge-conflict-test.c?rev=373538&view=auto
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/merge-conflict-test.c (added)
>>>> +++ cfe/trunk/test/InterfaceStubs/merge-conflict-test.c Wed Oct  2 15:50:07 2019
>>>> @@ -0,0 +1,3 @@
>>>> +// RUN: not %clang -o libfoo.so -emit-interface-stubs %s %S/driver-test.c 2>&1 | FileCheck %s
>>>> +// CHECK: error: Interface Stub: Type Mismatch
>>>> +int foo;
>>>> \ No newline at end of file
>>>>
>>>> Added: cfe/trunk/test/InterfaceStubs/object-double.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/object-double.c?rev=373538&view=auto
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/object-double.c (added)
>>>> +++ cfe/trunk/test/InterfaceStubs/object-double.c Wed Oct  2 15:50:07 2019
>>>> @@ -0,0 +1,5 @@
>>>> +// RUN: not %clang -o - -emit-interface-stubs %s %S/object.c 2>&1 | FileCheck %s
>>>> +// Need to encode more type info or weak vs strong symbol resolution in llvm-ifs
>>>> +// XFAIL: *
>>>> +// CHECK: error: Interface Stub: Size Mismatch
>>>> +float data = 42.0;
>>>> \ No newline at end of file
>>>>
>>>> Added: cfe/trunk/test/InterfaceStubs/object-float.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/object-float.c?rev=373538&view=auto
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/object-float.c (added)
>>>> +++ cfe/trunk/test/InterfaceStubs/object-float.c Wed Oct  2 15:50:07 2019
>>>> @@ -0,0 +1,3 @@
>>>> +// RUN: not %clang -o - -emit-interface-stubs %s %S/object.c 2>&1 | FileCheck %s
>>>> +// CHECK: error: Interface Stub: Size Mismatch
>>>> +double data = 42.0;
>>>> \ No newline at end of file
>>>>
>>>> Added: cfe/trunk/test/InterfaceStubs/object.c
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/object.c?rev=373538&view=auto
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/object.c (added)
>>>> +++ cfe/trunk/test/InterfaceStubs/object.c Wed Oct  2 15:50:07 2019
>>>> @@ -0,0 +1,7 @@
>>>> +// RUN: %clang -c -o - -emit-interface-stubs %s | FileCheck -check-prefix=CHECK-TAPI %s
>>>> +// RUN: %clang -c -o - -emit-interface-stubs %s | FileCheck -check-prefix=CHECK-SYMBOLS %s
>>>> +// RUN: %clang -c -o - %s | llvm-nm - 2>&1 | FileCheck -check-prefix=CHECK-SYMBOLS %s
>>>> +
>>>> +// CHECK-TAPI: data: { Type: Object, Size: 4 }
>>>> +// CHECK-SYMBOLS: data
>>>> +int data = 42;
>>>>
>>>> Added: cfe/trunk/test/InterfaceStubs/object.ifs
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/object.ifs?rev=373538&view=auto
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/object.ifs (added)
>>>> +++ cfe/trunk/test/InterfaceStubs/object.ifs Wed Oct  2 15:50:07 2019
>>>> @@ -0,0 +1,28 @@
>>>> +# RUN: %clang -emit-interface-stubs -o - -emit-merged-ifs %s | \
>>>> +# RUN: FileCheck %s --check-prefixes=CHECK-IFS
>>>> +
>>>> +# RUN: %clang -emit-interface-stubs -o - %s | llvm-readelf --all | \
>>>> +# RUN: FileCheck %s --check-prefixes=CHECK-ELF
>>>> +
>>>> +# CHECK-IFS: --- !experimental-ifs-v1
>>>> +# CHECK-IFS-NEXT: IfsVersion:      1.0
>>>> +# CHECK-IFS-NEXT: Triple: x86_64-linux-gnu
>>>> +# CHECK-IFS-NEXT: ObjectFileFormat: ELF
>>>> +# CHECK-IFS-NEXT: Symbols:
>>>> +# CHECK-IFS-NEXT:   b:               { Type: Object, Size: 4 }
>>>> +# CHECK-IFS-NEXT: ...
>>>> +
>>>> +# CHECK-ELF: ELF Header:
>>>> +# CHECK-ELF:   Class:                             ELF64
>>>> +# CHECK-ELF:   Data:                              2's complement, little endian
>>>> +# CHECK-ELF:   Type:                              DYN (Shared object file)
>>>> +# CHECK-ELF-NOT:   FUNC    GLOBAL DEFAULT  1 a
>>>> +# CHECK-ELF:   OBJECT  GLOBAL DEFAULT  1 b
>>>> +
>>>> +--- !experimental-ifs-v1
>>>> +IfsVersion: 1.0
>>>> +Triple: x86_64-linux-gnu
>>>> +ObjectFileFormat: ELF
>>>> +Symbols:
>>>> +  b: { Type: Object, Size: 4 }
>>>> +...
>>>>
>>>> Modified: cfe/trunk/test/InterfaceStubs/template-namespace-function.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/template-namespace-function.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/template-namespace-function.cpp (original)
>>>> +++ cfe/trunk/test/InterfaceStubs/template-namespace-function.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -1,5 +1,5 @@
>>>>  // REQUIRES: x86-registered-target
>>>> -// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \
>>>> +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs -emit-merged-ifs \
>>>>  // RUN: -interface-stub-version=experimental-ifs-v1 %s | \
>>>>  // RUN: FileCheck %s
>>>>
>>>> Modified: cfe/trunk/test/InterfaceStubs/weak.cpp
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/InterfaceStubs/weak.cpp?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/InterfaceStubs/weak.cpp (original)
>>>> +++ cfe/trunk/test/InterfaceStubs/weak.cpp Wed Oct  2 15:50:07 2019
>>>> @@ -1,5 +1,5 @@
>>>>  // REQUIRES: x86-registered-target
>>>> -// RUN: %clang -target x86_64-linux-gnu -o - -emit-interface-stubs \
>>>> +// RUN: %clang -target x86_64-linux-gnu -o - -emit-interface-stubs -emit-merged-ifs \
>>>>  // RUN: -interface-stub-version=experimental-ifs-v1 %s | \
>>>>  // RUN: FileCheck %s
>>>>
>>>> Modified: cfe/trunk/test/lit.cfg.py
>>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/lit.cfg.py?rev=373538&r1=373537&r2=373538&view=diff
>>>> ==============================================================================
>>>> --- cfe/trunk/test/lit.cfg.py (original)
>>>> +++ cfe/trunk/test/lit.cfg.py Wed Oct  2 15:50:07 2019
>>>> @@ -26,7 +26,7 @@ config.test_format = lit.formats.ShTest(
>>>>
>>>>  # suffixes: A list of file extensions to treat as test files.
>>>>  config.suffixes = ['.c', '.cpp', '.cppm', '.m', '.mm', '.cu',
>>>> -                   '.ll', '.cl', '.s', '.S', '.modulemap', '.test', '.rs']
>>>> +                   '.ll', '.cl', '.s', '.S', '.modulemap', '.test', '.rs', '.ifs']
>>>>
>>>>  # excludes: A list of directories to exclude from the testsuite. The 'Inputs'
>>>>  # subdirectories contain auxiliary inputs for various tests in their parent
>>>> @@ -61,7 +61,7 @@ config.substitutions.append(('%PATH%', c
>>>>  tool_dirs = [config.clang_tools_dir, config.llvm_tools_dir]
>>>>
>>>>  tools = [
>>>> -    'c-index-test', 'clang-diff', 'clang-format', 'clang-tblgen', 'opt',
>>>> +    'c-index-test', 'clang-diff', 'clang-format', 'clang-tblgen', 'opt', 'llvm-ifs',
>>>>      ToolSubst('%clang_extdef_map', command=FindTool(
>>>>          'clang-extdef-mapping'), unresolved='ignore'),
>>>>  ]
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> cfe-commits at lists.llvm.org
>>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191003/46fd8780/attachment-0001.html>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: publicKey - puyan at puyan.org - d3f7720045476a2b20d90afa7b39326f9b4bb197.asc
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191003/46fd8780/attachment-0001.asc>


More information about the cfe-commits mailing list