zixuw created this revision. Herald added subscribers: dang, mgorny. zixuw requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This is the initial commit for the clang-extract-api RFC https://lists.llvm.org/pipermail/cfe-dev/2021-September/068768.html Add a new driver option `-extract-api` and associate it with a dummy (for now) frontend action to set up the initial structure for incremental works. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D117809 Files: clang/include/clang/Driver/Options.td clang/include/clang/Driver/Types.def clang/include/clang/Frontend/FrontendActions.h clang/include/clang/Frontend/FrontendOptions.h clang/lib/Driver/Driver.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Driver/Types.cpp clang/lib/Frontend/CMakeLists.txt clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Frontend/ExtractAPIConsumer.cpp clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp clang/test/Driver/extract-api.c
Index: clang/test/Driver/extract-api.c =================================================================== --- /dev/null +++ clang/test/Driver/extract-api.c @@ -0,0 +1,16 @@ +// RUN: %clang -target x86_64-unknown-unknown -ccc-print-phases -extract-api %s 2> %t +// RUN: echo 'END' >> %t +// RUN: FileCheck -check-prefix EXTRACT-API-PHASES -input-file %t %s + +// EXTRACT-API-PHASES: 0: input, +// EXTRACT-API-PHASES: , c +// EXTRACT-API-PHASES: 1: preprocessor, {0}, cpp-output +// EXTRACT-API-PHASES: 2: compiler, {1}, api-information +// EXTRACT-API-PHASES-NOT: 3: +// EXTRACT-API-PHASES: END + +// FIXME: Check for the dummy output now to verify that the custom action was executed. +// RUN: %clang -extract-api %s | FileCheck -check-prefix DUMMY-OUTPUT %s + +void dummy_function(); +// DUMMY-OUTPUT: dummy_function Index: clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp =================================================================== --- clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -57,6 +57,8 @@ case EmitLLVMOnly: return std::make_unique<EmitLLVMOnlyAction>(); case EmitCodeGenOnly: return std::make_unique<EmitCodeGenOnlyAction>(); case EmitObj: return std::make_unique<EmitObjAction>(); + case ExtractAPI: + return std::make_unique<ExtractAPIAction>(); case FixIt: return std::make_unique<FixItAction>(); case GenerateModule: return std::make_unique<GenerateModuleFromModuleMapAction>(); Index: clang/lib/Frontend/ExtractAPIConsumer.cpp =================================================================== --- /dev/null +++ clang/lib/Frontend/ExtractAPIConsumer.cpp @@ -0,0 +1,39 @@ +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Frontend/ASTConsumers.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" + +using namespace clang; + +namespace { +class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> { +public: + explicit ExtractAPIVisitor(ASTContext *Context) : Context(Context) {} + + bool VisitNamedDecl(NamedDecl *Decl) { + llvm::outs() << Decl->getName() << "\n"; + return true; + } + +private: + ASTContext *Context; +}; + +class ExtractAPIConsumer : public ASTConsumer { +public: + explicit ExtractAPIConsumer(ASTContext *Context) : Visitor(Context) {} + + void HandleTranslationUnit(ASTContext &Context) override { + Visitor.TraverseDecl(Context.getTranslationUnitDecl()); + } + +private: + ExtractAPIVisitor Visitor; +}; +} // namespace + +std::unique_ptr<ASTConsumer> +ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + return std::make_unique<ExtractAPIConsumer>(&CI.getASTContext()); +} Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -2405,6 +2405,7 @@ {frontend::EmitCodeGenOnly, OPT_emit_codegen_only}, {frontend::EmitCodeGenOnly, OPT_emit_codegen_only}, {frontend::EmitObj, OPT_emit_obj}, + {frontend::ExtractAPI, OPT_extract_api}, {frontend::FixIt, OPT_fixit_EQ}, {frontend::FixIt, OPT_fixit}, @@ -2428,7 +2429,7 @@ {frontend::MigrateSource, OPT_migrate}, {frontend::RunPreprocessorOnly, OPT_Eonly}, {frontend::PrintDependencyDirectivesSourceMinimizerOutput, - OPT_print_dependency_directives_minimized_source}, + OPT_print_dependency_directives_minimized_source}, }; return Table; @@ -4144,6 +4145,7 @@ case frontend::EmitLLVMOnly: case frontend::EmitCodeGenOnly: case frontend::EmitObj: + case frontend::ExtractAPI: case frontend::FixIt: case frontend::GenerateModule: case frontend::GenerateModuleInterface: Index: clang/lib/Frontend/CMakeLists.txt =================================================================== --- clang/lib/Frontend/CMakeLists.txt +++ clang/lib/Frontend/CMakeLists.txt @@ -20,6 +20,7 @@ DependencyFile.cpp DependencyGraph.cpp DiagnosticRenderer.cpp + ExtractAPIConsumer.cpp FrontendAction.cpp FrontendActions.cpp FrontendOptions.cpp Index: clang/lib/Driver/Types.cpp =================================================================== --- clang/lib/Driver/Types.cpp +++ clang/lib/Driver/Types.cpp @@ -143,6 +143,7 @@ case TY_CXXModule: case TY_PP_CXXModule: case TY_AST: case TY_ModuleFile: case TY_PCH: case TY_LLVM_IR: case TY_LLVM_BC: + case TY_API_INFO: return true; } } Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -33,6 +33,7 @@ #include "clang/Driver/InputInfo.h" #include "clang/Driver/Options.h" #include "clang/Driver/SanitizerArgs.h" +#include "clang/Driver/Types.h" #include "clang/Driver/XRayArgs.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Config/llvm-config.h" @@ -4597,6 +4598,8 @@ } else if (JA.getType() == types::TY_RewrittenLegacyObjC) { CmdArgs.push_back("-rewrite-objc"); rewriteKind = RK_Fragile; + } else if (JA.getType() == types::TY_API_INFO) { + CmdArgs.push_back("-extract-api"); } else { assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!"); } @@ -7076,6 +7079,11 @@ llvm::sys::path::replace_extension(OutputFilename, "ifs"); CmdArgs.push_back("-o"); CmdArgs.push_back(Args.MakeArgString(OutputFilename)); + } else if (Output.getType() == types::TY_API_INFO) { + SmallString<128> OutputFilename(Output.getFilename()); + llvm::sys::path::replace_extension(OutputFilename, "json"); + CmdArgs.push_back("-o"); + CmdArgs.push_back(Args.MakeArgString(OutputFilename)); } else { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -62,6 +62,7 @@ #include "clang/Driver/SanitizerArgs.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" +#include "clang/Driver/Types.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" @@ -326,7 +327,8 @@ (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) || (PhaseArg = DAL.getLastArg(options::OPT__migrate)) || (PhaseArg = DAL.getLastArg(options::OPT__analyze)) || - (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) { + (PhaseArg = DAL.getLastArg(options::OPT_emit_ast)) || + (PhaseArg = DAL.getLastArg(options::OPT_extract_api))) { FinalPhase = phases::Compile; // -S only runs up to the backend. @@ -4069,7 +4071,8 @@ OutputTy = types::TY_ModuleFile; } - if (Args.hasArg(options::OPT_fsyntax_only)) { + if (Args.hasArg(options::OPT_fsyntax_only) || + Args.hasArg(options::OPT_extract_api)) { // Syntax checks should not emit a PCH file OutputTy = types::TY_Nothing; } @@ -4097,6 +4100,8 @@ return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile); if (Args.hasArg(options::OPT_verify_pch)) return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing); + if (Args.hasArg(options::OPT_extract_api)) + return C.MakeAction<CompileJobAction>(Input, types::TY_API_INFO); return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC); } case phases::Backend: { Index: clang/include/clang/Frontend/FrontendOptions.h =================================================================== --- clang/include/clang/Frontend/FrontendOptions.h +++ clang/include/clang/Frontend/FrontendOptions.h @@ -75,6 +75,9 @@ /// Emit a .o file. EmitObj, + // Extract API information + ExtractAPI, + /// Parse and apply any fixits to the source. FixIt, Index: clang/include/clang/Frontend/FrontendActions.h =================================================================== --- clang/include/clang/Frontend/FrontendActions.h +++ clang/include/clang/Frontend/FrontendActions.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H #include "clang/Frontend/FrontendAction.h" +#include <memory> #include <string> #include <vector> @@ -270,6 +271,12 @@ bool usesPreprocessorOnly() const override { return true; } }; +class ExtractAPIAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; +}; + //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// Index: clang/include/clang/Driver/Types.def =================================================================== --- clang/include/clang/Driver/Types.def +++ clang/include/clang/Driver/Types.def @@ -100,4 +100,5 @@ TYPE("dependencies", Dependencies, INVALID, "d", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("cuda-fatbin", CUDA_FATBIN, INVALID, "fatbin", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("hip-fatbin", HIP_FATBIN, INVALID, "hipfb", phases::Compile, phases::Backend, phases::Assemble, phases::Link) +TYPE("api-information", API_INFO, INVALID, "json", phases::Compile) TYPE("none", Nothing, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link) Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1080,6 +1080,8 @@ HelpText<"Start emitting warnings for unused driver arguments">; def interface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">, Flags<[CC1Option]>; def exported__symbols__list : Separate<["-"], "exported_symbols_list">; +def extract_api : Flag<["-"], "extract-api">, Flags<[CC1Option]>, Group<Action_Group>, + HelpText<"Extract API information">; def e : JoinedOrSeparate<["-"], "e">, Flags<[LinkerInput]>, Group<Link_Group>; def fmax_tokens_EQ : Joined<["-"], "fmax-tokens=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Max total number of preprocessed tokens for -Wmax-tokens.">,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits