[clang] b1d946c - [clang] Add an extract-api driver option
Zixu Wang via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 26 11:31:37 PST 2022
Author: Zixu Wang
Date: 2022-01-26T11:31:12-08:00
New Revision: b1d946cbf780f1769b3a3a39ce68e462a181869e
URL: https://github.com/llvm/llvm-project/commit/b1d946cbf780f1769b3a3a39ce68e462a181869e
DIFF: https://github.com/llvm/llvm-project/commit/b1d946cbf780f1769b3a3a39ce68e462a181869e.diff
LOG: [clang] Add an extract-api driver option
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.
Differential Revision: https://reviews.llvm.org/D117809
Added:
clang/lib/Frontend/ExtractAPIConsumer.cpp
clang/test/Driver/extract-api.c
Modified:
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/FrontendTool/ExecuteCompilerInvocation.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 49ceebcb51cf5..a57787a4f4c38 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1080,6 +1080,8 @@ def end_no_unused_arguments : Flag<["--"], "end-no-unused-arguments">, Flags<[Co
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.">,
diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def
index 997eea445c225..7adf59ca5c992 100644
--- a/clang/include/clang/Driver/Types.def
+++ b/clang/include/clang/Driver/Types.def
@@ -100,4 +100,5 @@ TYPE("dSYM", dSYM, INVALID, "dSYM", phases
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)
diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h
index 8bd6509559f70..8eceb81723d23 100644
--- a/clang/include/clang/Frontend/FrontendActions.h
+++ b/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 @@ class PrintDependencyDirectivesSourceMinimizerAction : public FrontendAction {
bool usesPreprocessorOnly() const override { return true; }
};
+class ExtractAPIAction : public ASTFrontendAction {
+protected:
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+};
+
//===----------------------------------------------------------------------===//
// Preprocessor Actions
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index 1d9d89a28c6c4..7ce8076a3ee41 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -75,6 +75,9 @@ enum ActionKind {
/// Emit a .o file.
EmitObj,
+ // Extract API information
+ ExtractAPI,
+
/// Parse and apply any fixits to the source.
FixIt,
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index c7314e11c7865..2e4ebc10e9ba3 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/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 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
(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 @@ Action *Driver::ConstructPhaseAction(
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 @@ Action *Driver::ConstructPhaseAction(
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: {
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 9e10d6d890747..ea83551845070 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/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 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
} 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!");
}
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index 1bd187ad2fc0a..8f6adc6c2ad1e 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -143,6 +143,7 @@ bool types::isAcceptedByClang(ID Id) {
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;
}
}
diff --git a/clang/lib/Frontend/CMakeLists.txt b/clang/lib/Frontend/CMakeLists.txt
index ca4ad8b2dab2e..e147a1341e064 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -20,6 +20,7 @@ add_clang_library(clangFrontend
DependencyFile.cpp
DependencyGraph.cpp
DiagnosticRenderer.cpp
+ ExtractAPIConsumer.cpp
FrontendAction.cpp
FrontendActions.cpp
FrontendOptions.cpp
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index eaca1fbb9def8..7f1ce3da7e7eb 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2408,6 +2408,7 @@ static const auto &getFrontendActionTable() {
{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},
@@ -4147,6 +4148,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
case frontend::EmitLLVMOnly:
case frontend::EmitCodeGenOnly:
case frontend::EmitObj:
+ case frontend::ExtractAPI:
case frontend::FixIt:
case frontend::GenerateModule:
case frontend::GenerateModuleInterface:
diff --git a/clang/lib/Frontend/ExtractAPIConsumer.cpp b/clang/lib/Frontend/ExtractAPIConsumer.cpp
new file mode 100644
index 0000000000000..92a0385c96cc0
--- /dev/null
+++ b/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());
+}
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 8e18f33af0cbc..8a8a13743762e 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -57,6 +57,8 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
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>();
diff --git a/clang/test/Driver/extract-api.c b/clang/test/Driver/extract-api.c
new file mode 100644
index 0000000000000..f58d3a42ee241
--- /dev/null
+++ b/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
More information about the cfe-commits
mailing list