aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticDriverKinds.td3
-rw-r--r--clang/include/clang/Driver/Action.h12
-rw-r--r--clang/include/clang/Driver/Options.td12
-rw-r--r--clang/include/clang/Driver/Types.def1
-rw-r--r--clang/include/clang/Frontend/CompilerInstance.h7
-rw-r--r--clang/include/clang/Frontend/CompilerInvocation.h9
-rw-r--r--clang/include/clang/Frontend/FrontendActions.h10
-rw-r--r--clang/include/clang/Frontend/FrontendOptions.h3
-rw-r--r--clang/include/clang/Frontend/InstallAPIOptions.h28
-rw-r--r--clang/include/clang/InstallAPI/Context.h25
-rw-r--r--clang/lib/Driver/Action.cpp7
-rw-r--r--clang/lib/Driver/Driver.cpp16
-rw-r--r--clang/lib/Driver/ToolChain.cpp1
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp11
-rw-r--r--clang/lib/Frontend/CMakeLists.txt3
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp41
-rw-r--r--clang/lib/Frontend/InstallAPIConsumer.cpp43
-rw-r--r--clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp2
-rw-r--r--clang/lib/InstallAPI/CMakeLists.txt1
-rw-r--r--clang/lib/InstallAPI/Context.cpp27
-rw-r--r--clang/test/CMakeLists.txt1
-rw-r--r--clang/test/Driver/installapi.h13
-rw-r--r--clang/test/InstallAPI/installapi-basic.test39
-rw-r--r--clang/test/InstallAPI/installapi-driver-invalid-options.test4
-rw-r--r--clang/test/lit.cfg.py1
-rw-r--r--clang/tools/CMakeLists.txt1
-rw-r--r--clang/tools/clang-installapi/CMakeLists.txt20
-rw-r--r--clang/tools/clang-installapi/ClangInstallAPI.cpp121
-rw-r--r--clang/tools/clang-installapi/Options.cpp129
-rw-r--r--clang/tools/clang-installapi/Options.h88
30 files changed, 408 insertions, 271 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 0807d88..b13181f 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -804,7 +804,4 @@ def warn_android_unversioned_fallback : Warning<
def err_drv_triple_version_invalid : Error<
"version '%0' in target triple '%1' is invalid">;
-
-def err_drv_installapi_unsupported : Error<
- "InstallAPI is not supported for '%0'">;
}
diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h
index 2768e2f..04fa8b0 100644
--- a/clang/include/clang/Driver/Action.h
+++ b/clang/include/clang/Driver/Action.h
@@ -59,7 +59,6 @@ public:
PreprocessJobClass,
PrecompileJobClass,
ExtractAPIJobClass,
- InstallAPIJobClass,
AnalyzeJobClass,
MigrateJobClass,
CompileJobClass,
@@ -449,17 +448,6 @@ public:
void addHeaderInput(Action *Input) { getInputs().push_back(Input); }
};
-class InstallAPIJobAction : public JobAction {
- void anchor() override;
-
-public:
- InstallAPIJobAction(Action *Input, types::ID OutputType);
-
- static bool classof(const Action *A) {
- return A->getKind() == InstallAPIJobClass;
- }
-};
-
class AnalyzeJobAction : public JobAction {
void anchor() override;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 36a42b1..3a028fa 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -336,8 +336,6 @@ class AnalyzerOpts<string base>
: KeyPathAndMacro<"AnalyzerOpts->", base, "ANALYZER_"> {}
class MigratorOpts<string base>
: KeyPathAndMacro<"MigratorOpts.", base, "MIGRATOR_"> {}
-class InstallAPIOpts<string base>
- : KeyPathAndMacro<"InstallAPIOpts.", base, "INSTALLAPI_"> {}
// A boolean option which is opt-in in CC1. The positive option exists in CC1 and
// Args.hasArg(OPT_ffoo) can be used to check that the flag is enabled.
@@ -1143,8 +1141,7 @@ def config_user_dir_EQ : Joined<["--"], "config-user-dir=">,
def coverage : Flag<["-", "--"], "coverage">, Group<Link_Group>,
Visibility<[ClangOption, CLOption]>;
def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>;
-def current__version : JoinedOrSeparate<["-"], "current_version">,
- Visibility<[ClangOption, CC1Option]>;
+def current__version : JoinedOrSeparate<["-"], "current_version">;
def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>,
HelpText<"Add directory to the C++ SYSTEM include search path">,
Visibility<[ClangOption, CC1Option]>,
@@ -1559,9 +1556,6 @@ def static_libsan : Flag<["-"], "static-libsan">,
HelpText<"Statically link the sanitizer runtime (Not supported for ASan, TSan or UBSan on darwin)">;
def : Flag<["-"], "shared-libasan">, Alias<shared_libsan>;
def fasm : Flag<["-"], "fasm">, Group<f_Group>;
-def installapi : Flag<["-"], "installapi">,
- Visibility<[ClangOption, CC1Option]>, Group<Action_Group>,
- HelpText<"Create a text-based stub file by scanning header files">;
defm assume_unique_vtables : BoolFOption<"assume-unique-vtables",
CodeGenOpts<"AssumeUniqueVTables">, DefaultTrue,
@@ -4320,9 +4314,7 @@ def verify_pch : Flag<["-"], "verify-pch">, Group<Action_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Load and verify that a pre-compiled header file is not stale">;
def init : Separate<["-"], "init">;
-def install__name : Separate<["-"], "install_name">,
- Visibility<[ClangOption, CC1Option]>,
- MarshallingInfoString<InstallAPIOpts<"InstallName">>;
+def install__name : Separate<["-"], "install_name">;
def iprefix : JoinedOrSeparate<["-"], "iprefix">, Group<clang_i_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">, MetaVarName<"<dir>">;
diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def
index 570a5344..f72c27e 100644
--- a/clang/include/clang/Driver/Types.def
+++ b/clang/include/clang/Driver/Types.def
@@ -94,7 +94,6 @@ TYPE("lto-bc", LTO_BC, INVALID, "o", phases
TYPE("ast", AST, INVALID, "ast", 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("tbd", TextAPI, INVALID, "tbd", phases::Precompile)
TYPE("pcm", ModuleFile, INVALID, "pcm", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("header-unit", HeaderUnit, INVALID, "pcm", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("plist", Plist, INVALID, "plist", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h
index 6eb7972..ac2f940 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -294,13 +294,6 @@ public:
return Invocation->getFrontendOpts();
}
- InstallAPIOptions &getInstallAPIOpts() {
- return Invocation->getInstallAPIOpts();
- }
- const InstallAPIOptions &getInstallAPIOpts() const {
- return Invocation->getInstallAPIOpts();
- }
-
HeaderSearchOptions &getHeaderSearchOpts() {
return Invocation->getHeaderSearchOpts();
}
diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h
index a01d969..c6528779 100644
--- a/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/clang/include/clang/Frontend/CompilerInvocation.h
@@ -18,12 +18,11 @@
#include "clang/Basic/LangStandard.h"
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/FrontendOptions.h"
-#include "clang/Frontend/InstallAPIOptions.h"
#include "clang/Frontend/MigratorOptions.h"
#include "clang/Frontend/PreprocessorOutputOptions.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/ArrayRef.h"
#include <memory>
#include <string>
@@ -112,9 +111,6 @@ protected:
/// Options controlling preprocessed output.
std::shared_ptr<PreprocessorOutputOptions> PreprocessorOutputOpts;
- /// Options controlling InstallAPI operations and output.
- std::shared_ptr<InstallAPIOptions> InstallAPIOpts;
-
/// Dummy tag type whose instance can be passed into the constructor to
/// prevent creation of the reference-counted option objects.
struct EmptyConstructor {};
@@ -149,7 +145,6 @@ public:
const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
return *PreprocessorOutputOpts;
}
- const InstallAPIOptions &getInstallAPIOpts() const { return *InstallAPIOpts; }
/// @}
/// Command line generation.
@@ -242,7 +237,6 @@ public:
using CompilerInvocationBase::getFrontendOpts;
using CompilerInvocationBase::getDependencyOutputOpts;
using CompilerInvocationBase::getPreprocessorOutputOpts;
- using CompilerInvocationBase::getInstallAPIOpts;
/// @}
/// Mutable getters.
@@ -264,7 +258,6 @@ public:
PreprocessorOutputOptions &getPreprocessorOutputOpts() {
return *PreprocessorOutputOpts;
}
- InstallAPIOptions &getInstallAPIOpts() { return *InstallAPIOpts; }
/// @}
/// Base class internals.
diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h
index b822925..fcce31ac 100644
--- a/clang/include/clang/Frontend/FrontendActions.h
+++ b/clang/include/clang/Frontend/FrontendActions.h
@@ -130,16 +130,6 @@ protected:
bool shouldEraseOutputFiles() override;
};
-class InstallAPIAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-
-public:
- static std::unique_ptr<llvm::raw_pwrite_stream>
- CreateOutputFile(CompilerInstance &CI, StringRef InFile);
-};
-
class GenerateInterfaceStubsAction : public ASTFrontendAction {
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index 62d16ba..53a8681 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -100,9 +100,6 @@ enum ActionKind {
/// Only execute frontend initialization.
InitOnly,
- // Create TextAPI stub.
- InstallAPI,
-
/// Dump information about a module file.
ModuleFileInfo,
diff --git a/clang/include/clang/Frontend/InstallAPIOptions.h b/clang/include/clang/Frontend/InstallAPIOptions.h
deleted file mode 100644
index cf65a33..0000000
--- a/clang/include/clang/Frontend/InstallAPIOptions.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- InstallAPIOptions.h ------------------------------------*- 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_FRONTEND_INSTALLAPIOPTIONS_H
-#define LLVM_CLANG_FRONTEND_INSTALLAPIOPTIONS_H
-
-#include "llvm/TextAPI/PackedVersion.h"
-
-namespace clang {
-
-/// InstallAPIOptions - Options for controlling InstallAPI verification and
-/// TextAPI output.
-class InstallAPIOptions {
-public:
- /// The install name which is apart of the library's ID.
- std::string InstallName;
-
- /// The current version which is apart of the library's ID.
- llvm::MachO::PackedVersion CurrentVersion;
-};
-} // namespace clang
-
-#endif
diff --git a/clang/include/clang/InstallAPI/Context.h b/clang/include/clang/InstallAPI/Context.h
index a1ff7c1..b061689 100644
--- a/clang/include/clang/InstallAPI/Context.h
+++ b/clang/include/clang/InstallAPI/Context.h
@@ -5,18 +5,10 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// Top level types for interacting with the generic clang driver and frontend
-// for InstallAPI operations.
-//
-//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_INSTALLAPI_CONTEXT_H
#define LLVM_CLANG_INSTALLAPI_CONTEXT_H
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/TextAPI/InterfaceFile.h"
#include "llvm/TextAPI/RecordVisitor.h"
#include "llvm/TextAPI/RecordsSlice.h"
@@ -35,12 +27,6 @@ struct InstallAPIContext {
/// Active target triple to parse.
llvm::Triple TargetTriple{};
- /// Output stream to write TextAPI file to.
- std::unique_ptr<llvm::raw_pwrite_stream> OS = nullptr;
-
- /// DiagnosticsEngine to report errors.
- llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags = nullptr;
-
/// File Path of output location.
StringRef OutputLoc{};
@@ -48,17 +34,6 @@ struct InstallAPIContext {
llvm::MachO::FileType FT = llvm::MachO::FileType::TBD_V5;
};
-class InstallAPIConsumer : public ASTConsumer {
-public:
- InstallAPIConsumer(InstallAPIContext InstallAPICtx)
- : Ctx(std::move(InstallAPICtx)) {}
-
- void HandleTranslationUnit(ASTContext &ASTContext) override;
-
-private:
- InstallAPIContext Ctx;
-};
-
} // namespace installapi
} // namespace clang
diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp
index 7b1a1bb..849bf60 100644
--- a/clang/lib/Driver/Action.cpp
+++ b/clang/lib/Driver/Action.cpp
@@ -32,8 +32,6 @@ const char *Action::getClassName(ActionClass AC) {
case CompileJobClass: return "compiler";
case BackendJobClass: return "backend";
case AssembleJobClass: return "assembler";
- case InstallAPIJobClass:
- return "installapi";
case IfsMergeJobClass: return "interface-stub-merger";
case LinkJobClass: return "linker";
case LipoJobClass: return "lipo";
@@ -364,11 +362,6 @@ void ExtractAPIJobAction::anchor() {}
ExtractAPIJobAction::ExtractAPIJobAction(Action *Inputs, types::ID OutputType)
: JobAction(ExtractAPIJobClass, Inputs, OutputType) {}
-void InstallAPIJobAction::anchor() {}
-
-InstallAPIJobAction::InstallAPIJobAction(Action *Inputs, types::ID OutputType)
- : JobAction(InstallAPIJobClass, Inputs, OutputType) {}
-
void AnalyzeJobAction::anchor() {}
AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 5a323bf..00e1407 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4189,11 +4189,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
break;
}
- if (isa<InstallAPIJobAction>(Current)) {
- Current = nullptr;
- break;
- }
-
// FIXME: Should we include any prior module file outputs as inputs of
// later actions in the same command line?
@@ -4324,13 +4319,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
if (!MergerInputs.empty())
Actions.push_back(
C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
- } else if (Args.hasArg(options::OPT_installapi)) {
- // TODO: Lift restriction once operation can handle multiple inputs.
- assert(Inputs.size() == 1 && "InstallAPI action can only handle 1 input");
- const auto [InputType, InputArg] = Inputs.front();
- Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
- Actions.push_back(
- C.MakeAction<InstallAPIJobAction>(Current, types::TY_TextAPI));
}
for (auto Opt : {options::OPT_print_supported_cpus,
@@ -4774,8 +4762,6 @@ Action *Driver::ConstructPhaseAction(
return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing);
if (Args.hasArg(options::OPT_extract_api))
return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO);
- if (Args.hasArg(options::OPT_installapi))
- return C.MakeAction<InstallAPIJobAction>(Input, types::TY_TextAPI);
return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC);
}
case phases::Backend: {
@@ -6455,7 +6441,7 @@ bool Driver::ShouldUseClangCompiler(const JobAction &JA) const {
// And say "no" if this is not a kind of action clang understands.
if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
!isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA) &&
- !isa<ExtractAPIJobAction>(JA) && !isa<InstallAPIJobAction>(JA))
+ !isa<ExtractAPIJobAction>(JA))
return false;
return true;
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 657577c..3880305 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -532,7 +532,6 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const {
case Action::PrecompileJobClass:
case Action::PreprocessJobClass:
case Action::ExtractAPIJobClass:
- case Action::InstallAPIJobClass:
case Action::AnalyzeJobClass:
case Action::MigrateJobClass:
case Action::VerifyPCHJobClass:
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 7daf945a..7c0409f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4939,17 +4939,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *ExtractAPIIgnoresFileArg =
Args.getLastArg(options::OPT_extract_api_ignores_EQ))
ExtractAPIIgnoresFileArg->render(Args, CmdArgs);
- } else if (isa<InstallAPIJobAction>(JA)) {
- if (!Triple.isOSDarwin())
- D.Diag(diag::err_drv_installapi_unsupported) << Triple.str();
-
- CmdArgs.push_back("-installapi");
- // Add necessary library arguments for InstallAPI.
- if (const Arg *A = Args.getLastArg(options::OPT_install__name))
- A->render(Args, CmdArgs);
- if (const Arg *A = Args.getLastArg(options::OPT_current__version))
- A->render(Args, CmdArgs);
-
} else {
assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
"Invalid action for clang tool.");
diff --git a/clang/lib/Frontend/CMakeLists.txt b/clang/lib/Frontend/CMakeLists.txt
index f443d88..a916667 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -7,7 +7,6 @@ set(LLVM_LINK_COMPONENTS
ProfileData
Support
TargetParser
- TextAPI
)
add_clang_library(clangFrontend
@@ -28,7 +27,6 @@ add_clang_library(clangFrontend
HeaderIncludeGen.cpp
InitPreprocessor.cpp
LayoutOverrideSource.cpp
- InstallAPIConsumer.cpp
LogDiagnosticPrinter.cpp
ModuleDependencyCollector.cpp
MultiplexConsumer.cpp
@@ -55,7 +53,6 @@ add_clang_library(clangFrontend
clangBasic
clangDriver
clangEdit
- clangInstallAPI
clangLex
clangParse
clangSema
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index bcb3124..8d7b75b 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -149,8 +149,7 @@ CompilerInvocationBase::CompilerInvocationBase()
FSOpts(std::make_shared<FileSystemOptions>()),
FrontendOpts(std::make_shared<FrontendOptions>()),
DependencyOutputOpts(std::make_shared<DependencyOutputOptions>()),
- PreprocessorOutputOpts(std::make_shared<PreprocessorOutputOptions>()),
- InstallAPIOpts(std::make_shared<InstallAPIOptions>()) {}
+ PreprocessorOutputOpts(std::make_shared<PreprocessorOutputOptions>()) {}
CompilerInvocationBase &
CompilerInvocationBase::deep_copy_assign(const CompilerInvocationBase &X) {
@@ -168,7 +167,6 @@ CompilerInvocationBase::deep_copy_assign(const CompilerInvocationBase &X) {
FrontendOpts = make_shared_copy(X.getFrontendOpts());
DependencyOutputOpts = make_shared_copy(X.getDependencyOutputOpts());
PreprocessorOutputOpts = make_shared_copy(X.getPreprocessorOutputOpts());
- InstallAPIOpts = make_shared_copy(X.getInstallAPIOpts());
}
return *this;
}
@@ -189,7 +187,6 @@ CompilerInvocationBase::shallow_copy_assign(const CompilerInvocationBase &X) {
FrontendOpts = X.FrontendOpts;
DependencyOutputOpts = X.DependencyOutputOpts;
PreprocessorOutputOpts = X.PreprocessorOutputOpts;
- InstallAPIOpts = X.InstallAPIOpts;
}
return *this;
}
@@ -2161,34 +2158,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
return Diags.getNumErrors() == NumErrorsBefore;
}
-static bool ParseInstallAPIArgs(InstallAPIOptions &Opts, ArgList &Args,
- DiagnosticsEngine &Diags,
- frontend::ActionKind Action) {
- unsigned NumErrorsBefore = Diags.getNumErrors();
-
- InstallAPIOptions &InstallAPIOpts = Opts;
-#define INSTALLAPI_OPTION_WITH_MARSHALLING(...) \
- PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
-#include "clang/Driver/Options.inc"
-#undef INSTALLAPI_OPTION_WITH_MARSHALLING
- if (Arg *A = Args.getLastArg(options::OPT_current__version))
- Opts.CurrentVersion.parse64(A->getValue());
-
- return Diags.getNumErrors() == NumErrorsBefore;
-}
-
-static void GenerateInstallAPIArgs(const InstallAPIOptions &Opts,
- ArgumentConsumer Consumer) {
- const InstallAPIOptions &InstallAPIOpts = Opts;
-#define INSTALLAPI_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
-#include "clang/Driver/Options.inc"
-#undef INSTALLAPI_OPTION_WITH_MARSHALLING
- if (!Opts.CurrentVersion.empty())
- GenerateArg(Consumer, OPT_current__version,
- std::string(Opts.CurrentVersion));
-}
-
static void GenerateDependencyOutputArgs(const DependencyOutputOptions &Opts,
ArgumentConsumer Consumer) {
const DependencyOutputOptions &DependencyOutputOpts = Opts;
@@ -2588,7 +2557,6 @@ static const auto &getFrontendActionTable() {
{frontend::GeneratePCH, OPT_emit_pch},
{frontend::GenerateInterfaceStubs, OPT_emit_interface_stubs},
{frontend::InitOnly, OPT_init_only},
- {frontend::InstallAPI, OPT_installapi},
{frontend::ParseSyntaxOnly, OPT_fsyntax_only},
{frontend::ModuleFileInfo, OPT_module_file_info},
{frontend::VerifyPCH, OPT_verify_pch},
@@ -4312,7 +4280,6 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
case frontend::GenerateHeaderUnit:
case frontend::GeneratePCH:
case frontend::GenerateInterfaceStubs:
- case frontend::InstallAPI:
case frontend::ParseSyntaxOnly:
case frontend::ModuleFileInfo:
case frontend::VerifyPCH:
@@ -4687,11 +4654,6 @@ bool CompilerInvocation::CreateFromArgsImpl(
Res.getDependencyOutputOpts().Targets.empty())
Diags.Report(diag::err_fe_dependency_file_requires_MT);
- if (Args.hasArg(OPT_installapi)) {
- ParseInstallAPIArgs(Res.getInstallAPIOpts(), Args, Diags,
- Res.getFrontendOpts().ProgramAction);
- }
-
// If sanitizer is enabled, disable OPT_ffine_grained_bitfield_accesses.
if (Res.getCodeGenOpts().FineGrainedBitfieldAccesses &&
!Res.getLangOpts().Sanitize.empty()) {
@@ -4882,7 +4844,6 @@ void CompilerInvocationBase::generateCC1CommandLine(
GeneratePreprocessorOutputArgs(getPreprocessorOutputOpts(), Consumer,
getFrontendOpts().ProgramAction);
GenerateDependencyOutputArgs(getDependencyOutputOpts(), Consumer);
- GenerateInstallAPIArgs(getInstallAPIOpts(), Consumer);
}
std::vector<std::string> CompilerInvocationBase::getCC1CommandLine() const {
diff --git a/clang/lib/Frontend/InstallAPIConsumer.cpp b/clang/lib/Frontend/InstallAPIConsumer.cpp
deleted file mode 100644
index c0f22c1..0000000
--- a/clang/lib/Frontend/InstallAPIConsumer.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//===--- InstallAPIConsumer.cpp -------------------------------------------===//
-//
-// 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 "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendActions.h"
-#include "clang/InstallAPI/Context.h"
-
-using namespace clang;
-using namespace clang::installapi;
-
-std::unique_ptr<ASTConsumer>
-InstallAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
- const InstallAPIOptions &Opts = CI.getInstallAPIOpts();
- InstallAPIContext Ctx;
- Ctx.BA.InstallName = Opts.InstallName;
- Ctx.BA.AppExtensionSafe = CI.getLangOpts().AppExt;
- Ctx.BA.CurrentVersion = Opts.CurrentVersion;
- // InstallAPI requires two level namespacing.
- Ctx.BA.TwoLevelNamespace = true;
- Ctx.TargetTriple = CI.getTarget().getTriple();
-
- Ctx.Diags = &CI.getDiagnostics();
- Ctx.OutputLoc = CI.getFrontendOpts().OutputFile;
- Ctx.OS = CreateOutputFile(CI, InFile);
- if (!Ctx.OS)
- return nullptr;
- return std::make_unique<InstallAPIConsumer>(std::move(Ctx));
-}
-
-std::unique_ptr<llvm::raw_pwrite_stream>
-InstallAPIAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile) {
- std::unique_ptr<raw_pwrite_stream> OS =
- CI.createDefaultOutputFile(/*Binary=*/false, InFile, /*Extension=*/"tbd",
- /*RemoveFileOnSignal=*/false);
- if (!OS)
- return nullptr;
- return OS;
-}
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index a47c474..925879a 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -71,8 +71,6 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
case GenerateInterfaceStubs:
return std::make_unique<GenerateInterfaceStubsAction>();
case InitOnly: return std::make_unique<InitOnlyAction>();
- case InstallAPI:
- return std::make_unique<InstallAPIAction>();
case ParseSyntaxOnly: return std::make_unique<SyntaxOnlyAction>();
case ModuleFileInfo: return std::make_unique<DumpModuleInfoAction>();
case VerifyPCH: return std::make_unique<VerifyPCHAction>();
diff --git a/clang/lib/InstallAPI/CMakeLists.txt b/clang/lib/InstallAPI/CMakeLists.txt
index 6c9cb4b..fdc4f06 100644
--- a/clang/lib/InstallAPI/CMakeLists.txt
+++ b/clang/lib/InstallAPI/CMakeLists.txt
@@ -4,7 +4,6 @@ set(LLVM_LINK_COMPONENTS
)
add_clang_library(clangInstallAPI
- Context.cpp
FileList.cpp
HeaderFile.cpp
diff --git a/clang/lib/InstallAPI/Context.cpp b/clang/lib/InstallAPI/Context.cpp
deleted file mode 100644
index d4df52f..0000000
--- a/clang/lib/InstallAPI/Context.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//===--- InstallAPI/Context.cpp -------------------------------------------===//
-//
-// 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 "clang/InstallAPI/Context.h"
-#include "clang/AST/ASTContext.h"
-#include "llvm/TextAPI/TextAPIWriter.h"
-
-using namespace clang;
-using namespace clang::installapi;
-using namespace llvm::MachO;
-
-void InstallAPIConsumer::HandleTranslationUnit(ASTContext &Context) {
- if (Context.getDiagnostics().hasErrorOccurred())
- return;
- InterfaceFile IF;
- // Set library attributes captured through cc1 args.
- Target T(Ctx.TargetTriple);
- IF.addTarget(T);
- IF.setFromBinaryAttrs(Ctx.BA, T);
- if (auto Err = TextAPIWriter::writeToStream(*Ctx.OS, IF, Ctx.FT))
- Ctx.Diags->Report(diag::err_cannot_open_file) << Ctx.OutputLoc;
-}
diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt
index 841317c..6b5cb0a 100644
--- a/clang/test/CMakeLists.txt
+++ b/clang/test/CMakeLists.txt
@@ -71,6 +71,7 @@ list(APPEND CLANG_TEST_DEPS
clang-rename
clang-refactor
clang-diff
+ clang-installapi
clang-scan-deps
clang-linker-wrapper
clang-offload-bundler
diff --git a/clang/test/Driver/installapi.h b/clang/test/Driver/installapi.h
deleted file mode 100644
index 99379b44d..0000000
--- a/clang/test/Driver/installapi.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// Check non-darwin triple is rejected.
-// RUN: not %clang -target x86_64-unknown-unknown -installapi %s 2> %t
-// RUN: FileCheck --check-prefix INVALID_INSTALLAPI -input-file %t %s
-
-// INVALID_INSTALLAPI: error: InstallAPI is not supported for 'x86_64-unknown-unknown'
-
-// Check installapi phases.
-// RUN: %clang -target x86_64-apple-macos11 -ccc-print-phases -installapi %s 2> %t
-// RUN: FileCheck --check-prefix INSTALLAPI_PHASES -input-file %t %s
-
-// INSTALLAPI_PHASES: 0: input,
-// INSTALLAPI_PHASES: installapi,
-// INSTALLAPI_PHASES-SAME: tbd
diff --git a/clang/test/InstallAPI/installapi-basic.test b/clang/test/InstallAPI/installapi-basic.test
index 8035166..22b0479 100644
--- a/clang/test/InstallAPI/installapi-basic.test
+++ b/clang/test/InstallAPI/installapi-basic.test
@@ -1,10 +1,17 @@
// RUN: rm -rf %t
// RUN: split-file %s %t
-// RUN: %clang_cc1 -x objective-c -triple arm64-apple-ios13.0.0 -installapi \
+/// Check basic arguments are captured.
+// RUN: clang-installapi -x objective-c -target arm64-apple-ios13.0.0 \
// RUN: -fapplication-extension -current_version 1 -install_name /usr/lib/basic.dylib \
// RUN: %t/basic_inputs.json -o %t/basic.tbd 2>&1 | FileCheck %s --allow-empty
// RUN: llvm-readtapi -compare %t/basic.tbd %t/expected.tbd 2>&1 | FileCheck %s --allow-empty
+/// Check multiple targets are captured.
+// RUN: clang-installapi -x objective-c -target arm64-apple-ios14.1 -target arm64e-apple-ios14.1 \
+// RUN: -fapplication-extension -install_name /usr/lib/basic.dylib \
+// RUN: %t/basic_inputs.json -o %t/multi-targets.tbd 2>&1 | FileCheck %s --allow-empty
+// RUN: llvm-readtapi -compare %t/multi-targets.tbd %t/expected-multi.tbd 2>&1 | FileCheck %s --allow-empty
+
// CHECK-NOT: error:
// CHECK-NOT: warning:
@@ -32,3 +39,33 @@
},
"tapi_tbd_version": 5
}
+
+//--- expected-multi.tbd
+{
+ "main_library": {
+ "compatibility_versions": [
+ {
+ "version": "0"
+ }],
+ "current_versions": [
+ {
+ "version": "0"
+ }],
+ "install_names": [
+ {
+ "name": "/usr/lib/basic.dylib"
+ }
+ ],
+ "target_info": [
+ {
+ "min_deployment": "14.1",
+ "target": "arm64-ios"
+ },
+ {
+ "min_deployment": "14.1",
+ "target": "arm64e-ios"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
diff --git a/clang/test/InstallAPI/installapi-driver-invalid-options.test b/clang/test/InstallAPI/installapi-driver-invalid-options.test
new file mode 100644
index 0000000..a2e008e
--- /dev/null
+++ b/clang/test/InstallAPI/installapi-driver-invalid-options.test
@@ -0,0 +1,4 @@
+/// Check non-darwin triple is rejected.
+// RUN: not clang-installapi -target x86_64-unknown-unknown %s 2> %t
+// RUN: FileCheck --check-prefix INVALID_INSTALLAPI -input-file %t %s
+// INVALID_INSTALLAPI: error: unsupported option 'installapi' for target 'x86_64-unknown-unknown'
diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py
index f93b5d9..e5630a0 100644
--- a/clang/test/lit.cfg.py
+++ b/clang/test/lit.cfg.py
@@ -90,6 +90,7 @@ tools = [
"clang-offload-packager",
"clang-tblgen",
"clang-scan-deps",
+ "clang-installapi",
"opt",
"llvm-ifs",
"yaml2obj",
diff --git a/clang/tools/CMakeLists.txt b/clang/tools/CMakeLists.txt
index f60db6e..bdd8004 100644
--- a/clang/tools/CMakeLists.txt
+++ b/clang/tools/CMakeLists.txt
@@ -12,6 +12,7 @@ add_clang_subdirectory(clang-linker-wrapper)
add_clang_subdirectory(clang-offload-packager)
add_clang_subdirectory(clang-offload-bundler)
add_clang_subdirectory(clang-scan-deps)
+add_clang_subdirectory(clang-installapi)
if(HAVE_CLANG_REPL_SUPPORT)
add_clang_subdirectory(clang-repl)
endif()
diff --git a/clang/tools/clang-installapi/CMakeLists.txt b/clang/tools/clang-installapi/CMakeLists.txt
new file mode 100644
index 0000000..c8dd56d
--- /dev/null
+++ b/clang/tools/clang-installapi/CMakeLists.txt
@@ -0,0 +1,20 @@
+set(LLVM_LINK_COMPONENTS
+ Support
+ TargetParser
+ TextAPI
+ )
+
+add_clang_tool(clang-installapi
+ ClangInstallAPI.cpp
+ Options.cpp
+
+ GENERATE_DRIVER
+ )
+
+clang_target_link_libraries(clang-installapi
+ PRIVATE
+ clangInstallAPI
+ clangDriver
+ clangFrontend
+ clangTooling
+ )
diff --git a/clang/tools/clang-installapi/ClangInstallAPI.cpp b/clang/tools/clang-installapi/ClangInstallAPI.cpp
new file mode 100644
index 0000000..fc23ffd
--- /dev/null
+++ b/clang/tools/clang-installapi/ClangInstallAPI.cpp
@@ -0,0 +1,121 @@
+//===-- ClangInstallAPI.cpp ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the entry point to clang-installapi; it is a wrapper
+// for functionality in the InstallAPI clang library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Options.h"
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/InstallAPI/Context.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/LLVMDriver.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/TargetParser/Host.h"
+#include "llvm/TextAPI/TextAPIWriter.h"
+
+using namespace clang;
+using namespace clang::installapi;
+using namespace clang::driver::options;
+using namespace llvm::opt;
+using namespace llvm::MachO;
+
+static bool run(ArrayRef<const char *> Args, const char *ProgName) {
+ // Setup Diagnostics engine.
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+ const llvm::opt::OptTable &ClangOpts = clang::driver::getDriverOptTable();
+ unsigned MissingArgIndex, MissingArgCount;
+ llvm::opt::InputArgList ParsedArgs = ClangOpts.ParseArgs(
+ ArrayRef(Args).slice(1), MissingArgIndex, MissingArgCount);
+ ParseDiagnosticArgs(*DiagOpts, ParsedArgs);
+
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diag = new clang::DiagnosticsEngine(
+ new clang::DiagnosticIDs(), DiagOpts.get(),
+ new clang::TextDiagnosticPrinter(llvm::errs(), DiagOpts.get()));
+
+ // Create file manager for all file operations.
+ IntrusiveRefCntPtr<clang::FileManager> FM(
+ new FileManager(clang::FileSystemOptions()));
+
+ // Set up driver to parse input arguments.
+ auto DriverArgs = llvm::ArrayRef(Args).slice(1);
+ clang::driver::Driver Driver(ProgName, llvm::sys::getDefaultTargetTriple(),
+ *Diag, "clang installapi tool");
+ Driver.setInstalledDir(llvm::sys::path::parent_path(ProgName));
+ auto TargetAndMode =
+ clang::driver::ToolChain::getTargetAndModeFromProgramName(ProgName);
+ Driver.setTargetAndMode(TargetAndMode);
+ bool HasError = false;
+ llvm::opt::InputArgList ArgList =
+ Driver.ParseArgStrings(DriverArgs, /*UseDriverMode=*/true, HasError);
+ if (HasError)
+ return EXIT_FAILURE;
+ Driver.setCheckInputsExist(false);
+
+ // Capture InstallAPI specific options and diagnose any option errors.
+ Options Opts(*Diag, FM.get(), ArgList);
+ if (Diag->hasErrorOccurred())
+ return EXIT_FAILURE;
+ InstallAPIContext Ctx = Opts.createContext();
+
+ // Set up compilation.
+ std::unique_ptr<CompilerInstance> CI(new CompilerInstance());
+ CI->setFileManager(FM.get());
+ CI->createDiagnostics();
+ if (!CI->hasDiagnostics())
+ return EXIT_FAILURE;
+
+ auto Out = CI->createOutputFile(Ctx.OutputLoc, /*Binary=*/false,
+ /*RemoveFileOnSignal=*/false,
+ /*UseTemporary=*/false,
+ /*CreateMissingDirectories=*/false);
+ if (!Out)
+ return EXIT_FAILURE;
+
+ // Assign attributes for serialization.
+ InterfaceFile IF;
+ for (const auto &TargetInfo : Opts.DriverOpts.Targets) {
+ IF.addTarget(TargetInfo.first);
+ IF.setFromBinaryAttrs(Ctx.BA, TargetInfo.first);
+ }
+
+ // Write output file and perform CI cleanup.
+ if (auto Err = TextAPIWriter::writeToStream(*Out, IF, Ctx.FT)) {
+ Diag->Report(diag::err_cannot_open_file) << Ctx.OutputLoc;
+ CI->clearOutputFiles(/*EraseFiles=*/true);
+ return EXIT_FAILURE;
+ }
+
+ CI->clearOutputFiles(/*EraseFiles=*/false);
+ return EXIT_SUCCESS;
+}
+
+int clang_installapi_main(int argc, char **argv,
+ const llvm::ToolContext &ToolContext) {
+ // Standard set up, so program fails gracefully.
+ llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
+ llvm::PrettyStackTraceProgram StackPrinter(argc, argv);
+ llvm::llvm_shutdown_obj Shutdown;
+
+ if (llvm::sys::Process::FixupStandardFileDescriptors())
+ return EXIT_FAILURE;
+
+ const char *ProgName =
+ ToolContext.NeedsPrependArg ? ToolContext.PrependArg : ToolContext.Path;
+ return run(llvm::ArrayRef(argv, argc), ProgName);
+}
diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp
new file mode 100644
index 0000000..08d1c0e
--- /dev/null
+++ b/clang/tools/clang-installapi/Options.cpp
@@ -0,0 +1,129 @@
+//===-- Options.cpp -------------------------------------------------------===//
+//
+// 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 "Options.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/Support/Program.h"
+#include "llvm/TargetParser/Host.h"
+
+using namespace clang::driver;
+using namespace clang::driver::options;
+using namespace llvm::opt;
+using namespace llvm::MachO;
+
+namespace clang {
+namespace installapi {
+
+bool Options::processDriverOptions(InputArgList &Args) {
+ // Handle inputs.
+ llvm::vfs::Status Stat;
+ for (const auto &Path : Args.getAllArgValues(OPT_INPUT)) {
+ if (FM->getNoncachedStatValue(Path, Stat) || !Stat.exists()) {
+ Diags->Report(clang::diag::err_drv_no_such_file) << Path;
+ return false;
+ }
+ DriverOpts.FileLists.push_back(std::move(Path));
+ }
+
+ // Handle output.
+ SmallString<PATH_MAX> OutputPath;
+ if (auto *Arg = Args.getLastArg(OPT_o)) {
+ OutputPath = Arg->getValue();
+ if (OutputPath != "-")
+ FM->makeAbsolutePath(OutputPath);
+ DriverOpts.OutputPath = std::string(OutputPath);
+ }
+
+ // Do basic error checking first for mixing -target and -arch options.
+ auto *ArgArch = Args.getLastArgNoClaim(OPT_arch);
+ auto *ArgTarget = Args.getLastArgNoClaim(OPT_target);
+ auto *ArgTargetVariant =
+ Args.getLastArgNoClaim(OPT_darwin_target_variant_triple);
+ if (ArgArch && (ArgTarget || ArgTargetVariant)) {
+ Diags->Report(clang::diag::err_drv_argument_not_allowed_with)
+ << ArgArch->getAsString(Args)
+ << (ArgTarget ? ArgTarget : ArgTargetVariant)->getAsString(Args);
+ return false;
+ }
+
+ auto *ArgMinTargetOS = Args.getLastArgNoClaim(OPT_mtargetos_EQ);
+ if ((ArgTarget || ArgTargetVariant) && ArgMinTargetOS) {
+ Diags->Report(clang::diag::err_drv_cannot_mix_options)
+ << ArgTarget->getAsString(Args) << ArgMinTargetOS->getAsString(Args);
+ return false;
+ }
+
+ // Capture target triples first.
+ if (ArgTarget) {
+ for (auto *Arg : Args.filtered(OPT_target)) {
+ llvm::Triple TargetTriple(Arg->getValue());
+ Target TAPITarget = Target(TargetTriple);
+ if ((TAPITarget.Arch == AK_unknown) ||
+ (TAPITarget.Platform == PLATFORM_UNKNOWN)) {
+ Diags->Report(clang::diag::err_drv_unsupported_opt_for_target)
+ << "installapi" << TargetTriple.str();
+ return false;
+ }
+ DriverOpts.Targets[TAPITarget] = TargetTriple;
+ }
+ }
+
+ return true;
+}
+
+bool Options::processLinkerOptions(InputArgList &Args) {
+ // TODO: add error handling.
+
+ // Required arguments.
+ if (const Arg *A = Args.getLastArg(options::OPT_install__name))
+ LinkerOpts.InstallName = A->getValue();
+
+ // Defaulted or optional arguments.
+ if (auto *Arg = Args.getLastArg(OPT_current__version))
+ LinkerOpts.CurrentVersion.parse64(Arg->getValue());
+
+ LinkerOpts.IsDylib = Args.hasArg(OPT_dynamiclib);
+
+ LinkerOpts.AppExtensionSafe =
+ Args.hasFlag(OPT_fapplication_extension, OPT_fno_application_extension,
+ /*Default=*/LinkerOpts.AppExtensionSafe);
+
+ if (::getenv("LD_NO_ENCRYPT") != nullptr)
+ LinkerOpts.AppExtensionSafe = true;
+
+ if (::getenv("LD_APPLICATION_EXTENSION_SAFE") != nullptr)
+ LinkerOpts.AppExtensionSafe = true;
+ return true;
+}
+
+Options::Options(DiagnosticsEngine &Diag, FileManager *FM,
+ InputArgList &ArgList)
+ : Diags(&Diag), FM(FM) {
+ if (!processDriverOptions(ArgList))
+ return;
+
+ if (!processLinkerOptions(ArgList))
+ return;
+}
+
+InstallAPIContext Options::createContext() {
+ InstallAPIContext Ctx;
+ // InstallAPI requires two level namespacing.
+ Ctx.BA.TwoLevelNamespace = true;
+
+ Ctx.BA.InstallName = LinkerOpts.InstallName;
+ Ctx.BA.CurrentVersion = LinkerOpts.CurrentVersion;
+ Ctx.BA.AppExtensionSafe = LinkerOpts.AppExtensionSafe;
+ Ctx.FT = DriverOpts.OutFT;
+ Ctx.OutputLoc = DriverOpts.OutputPath;
+ return Ctx;
+}
+
+} // namespace installapi
+} // namespace clang
diff --git a/clang/tools/clang-installapi/Options.h b/clang/tools/clang-installapi/Options.h
new file mode 100644
index 0000000..4a84166
--- /dev/null
+++ b/clang/tools/clang-installapi/Options.h
@@ -0,0 +1,88 @@
+//===--- clang-installapi/Options.h - Options -------------------*- 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_TOOLS_CLANG_INSTALLAPI_OPTIONS_H
+#define LLVM_CLANG_TOOLS_CLANG_INSTALLAPI_OPTIONS_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/InstallAPI/Context.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/Program.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/TextAPI/Architecture.h"
+#include "llvm/TextAPI/InterfaceFile.h"
+#include "llvm/TextAPI/PackedVersion.h"
+#include "llvm/TextAPI/Platform.h"
+#include "llvm/TextAPI/Target.h"
+#include "llvm/TextAPI/Utils.h"
+#include <set>
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace installapi {
+using Macro = std::pair<std::string, bool /*isUndef*/>;
+
+struct DriverOptions {
+ /// \brief Path to input file lists (JSON).
+ llvm::MachO::PathSeq FileLists;
+
+ /// \brief Mappings of target triples & tapi targets to build for.
+ std::map<llvm::MachO::Target, llvm::Triple> Targets;
+
+ /// \brief Output path.
+ std::string OutputPath;
+
+ /// \brief File encoding to print.
+ llvm::MachO::FileType OutFT = llvm::MachO::FileType::TBD_V5;
+};
+
+struct LinkerOptions {
+ /// \brief The install name to use for the dynamic library.
+ std::string InstallName;
+
+ /// \brief The current version to use for the dynamic library.
+ llvm::MachO::PackedVersion CurrentVersion;
+
+ /// \brief Is application extension safe.
+ bool AppExtensionSafe = false;
+
+ /// \brief Set if we should scan for a dynamic library and not a framework.
+ bool IsDylib = false;
+};
+
+class Options {
+private:
+ bool processDriverOptions(llvm::opt::InputArgList &Args);
+ bool processLinkerOptions(llvm::opt::InputArgList &Args);
+
+public:
+ /// The various options grouped together.
+ DriverOptions DriverOpts;
+ LinkerOptions LinkerOpts;
+
+ Options() = delete;
+
+ /// \brief Create InstallAPIContext from processed options.
+ InstallAPIContext createContext();
+
+ /// \brief Constructor for options.
+ Options(clang::DiagnosticsEngine &Diag, FileManager *FM,
+ llvm::opt::InputArgList &Args);
+
+private:
+ DiagnosticsEngine *Diags;
+ FileManager *FM;
+};
+
+} // namespace installapi
+} // namespace clang
+#endif