diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 0807d8877591a..b13181f6e7089 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 2768e2f5df1a9..04fa8b01b418f 100644 --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -59,7 +59,6 @@ class Action { PreprocessJobClass, PrecompileJobClass, ExtractAPIJobClass, - InstallAPIJobClass, AnalyzeJobClass, MigrateJobClass, CompileJobClass, @@ -449,17 +448,6 @@ class ExtractAPIJobAction : public JobAction { 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 36a42b1b050c2..3a028fadb25b1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -336,8 +336,6 @@ class AnalyzerOpts : KeyPathAndMacro<"AnalyzerOpts->", base, "ANALYZER_"> {} class MigratorOpts : KeyPathAndMacro<"MigratorOpts.", base, "MIGRATOR_"> {} -class InstallAPIOpts - : 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, Visibility<[ClangOption, CLOption]>; def cpp_precomp : Flag<["-"], "cpp-precomp">, Group; -def current__version : JoinedOrSeparate<["-"], "current_version">, - Visibility<[ClangOption, CC1Option]>; +def current__version : JoinedOrSeparate<["-"], "current_version">; def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, 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; def fasm : Flag<["-"], "fasm">, Group; -def installapi : Flag<["-"], "installapi">, - Visibility<[ClangOption, CC1Option]>, 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, 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>; +def install__name : Separate<["-"], "install_name">; def iprefix : JoinedOrSeparate<["-"], "iprefix">, Group, Visibility<[ClangOption, CC1Option]>, HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">, MetaVarName<"">; diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def index 570a53441d1c7..f72c27e1ee701 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 6eb7972f86ca5..ac2f940769fbe 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -294,13 +294,6 @@ class CompilerInstance : public ModuleLoader { 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 a01d9695dce20..c6528779bde7b 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 #include @@ -112,9 +111,6 @@ class CompilerInvocationBase { /// Options controlling preprocessed output. std::shared_ptr PreprocessorOutputOpts; - /// Options controlling InstallAPI operations and output. - std::shared_ptr 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 @@ class CompilerInvocationBase { const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { return *PreprocessorOutputOpts; } - const InstallAPIOptions &getInstallAPIOpts() const { return *InstallAPIOpts; } /// @} /// Command line generation. @@ -242,7 +237,6 @@ class CompilerInvocation : public CompilerInvocationBase { using CompilerInvocationBase::getFrontendOpts; using CompilerInvocationBase::getDependencyOutputOpts; using CompilerInvocationBase::getPreprocessorOutputOpts; - using CompilerInvocationBase::getInstallAPIOpts; /// @} /// Mutable getters. @@ -264,7 +258,6 @@ class CompilerInvocation : public CompilerInvocationBase { 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 b8229252f5ed2..fcce31ac0590f 100644 --- a/clang/include/clang/Frontend/FrontendActions.h +++ b/clang/include/clang/Frontend/FrontendActions.h @@ -130,16 +130,6 @@ class GenerateModuleAction : public ASTFrontendAction { bool shouldEraseOutputFiles() override; }; -class InstallAPIAction : public ASTFrontendAction { -protected: - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override; - -public: - static std::unique_ptr - CreateOutputFile(CompilerInstance &CI, StringRef InFile); -}; - class GenerateInterfaceStubsAction : public ASTFrontendAction { protected: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 62d16ba542ea4..53a8681cfdbba 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 cf65a3350c6de..0000000000000 --- 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 a1ff7c12a2f83..b06168918a613 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 OS = nullptr; - - /// DiagnosticsEngine to report errors. - llvm::IntrusiveRefCntPtr 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 7b1a1bb0228c4..849bf6035ebd2 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 5a323bf4c0c5f..00e14071a4afe 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(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(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(*InputArg, InputType); - Actions.push_back( - C.MakeAction(Current, types::TY_TextAPI)); } for (auto Opt : {options::OPT_print_supported_cpus, @@ -4774,8 +4762,6 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction(Input, types::TY_Nothing); if (Args.hasArg(options::OPT_extract_api)) return C.MakeAction(Input, types::TY_API_INFO); - if (Args.hasArg(options::OPT_installapi)) - return C.MakeAction(Input, types::TY_TextAPI); return C.MakeAction(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(JA) && !isa(JA) && !isa(JA) && !isa(JA) && - !isa(JA) && !isa(JA)) + !isa(JA)) return false; return true; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 657577cea6c7d..388030592b483 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 7daf945ae1271..7c0409f0c3097 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(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(JA) || isa(JA)) && "Invalid action for clang tool."); diff --git a/clang/lib/Frontend/CMakeLists.txt b/clang/lib/Frontend/CMakeLists.txt index f443d88b5d30c..a916667208845 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 bcb31243056b7..8d7b75b56d612 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -149,8 +149,7 @@ CompilerInvocationBase::CompilerInvocationBase() FSOpts(std::make_shared()), FrontendOpts(std::make_shared()), DependencyOutputOpts(std::make_shared()), - PreprocessorOutputOpts(std::make_shared()), - InstallAPIOpts(std::make_shared()) {} + PreprocessorOutputOpts(std::make_shared()) {} 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 CompilerInvocationBase::getCC1CommandLine() const { diff --git a/clang/lib/Frontend/InstallAPIConsumer.cpp b/clang/lib/Frontend/InstallAPIConsumer.cpp deleted file mode 100644 index c0f22c1a589f3..0000000000000 --- 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 -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(std::move(Ctx)); -} - -std::unique_ptr -InstallAPIAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile) { - std::unique_ptr 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 a47c474e520a0..925879a68cbd0 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(); case InitOnly: return std::make_unique(); - case InstallAPI: - return std::make_unique(); case ParseSyntaxOnly: return std::make_unique(); case ModuleFileInfo: return std::make_unique(); case VerifyPCH: return std::make_unique(); diff --git a/clang/lib/InstallAPI/CMakeLists.txt b/clang/lib/InstallAPI/CMakeLists.txt index 6c9cb4b559f67..fdc4f064f29e9 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 d4df52f66560c..0000000000000 --- 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 841317cef880a..6b5cb0a18457b 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 99379b44d1379..0000000000000 --- 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 8035166d076da..22b04792ca2c3 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 0000000000000..a2e008e1eb03e --- /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 f93b5d9c94588..e5630a07424c7 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -90,6 +90,7 @@ "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 f60db6ef0ba34..bdd8004be3e02 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 0000000000000..c8dd56db101da --- /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 0000000000000..fc23ffd7ae6b9 --- /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 Args, const char *ProgName) { + // Setup Diagnostics engine. + IntrusiveRefCntPtr 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 Diag = new clang::DiagnosticsEngine( + new clang::DiagnosticIDs(), DiagOpts.get(), + new clang::TextDiagnosticPrinter(llvm::errs(), DiagOpts.get())); + + // Create file manager for all file operations. + IntrusiveRefCntPtr 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 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 0000000000000..08d1c0e8e660f --- /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 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 0000000000000..4a84166a6c91b --- /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 +#include +#include + +namespace clang { +namespace installapi { +using Macro = std::pair; + +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 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