aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Driver/Options.td2
-rw-r--r--clang/include/clang/Driver/Types.def1
-rw-r--r--clang/include/clang/Frontend/FrontendActions.h7
-rw-r--r--clang/include/clang/Frontend/FrontendOptions.h3
-rw-r--r--clang/lib/Driver/Driver.cpp9
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp3
-rw-r--r--clang/lib/Driver/Types.cpp1
-rw-r--r--clang/lib/Frontend/CMakeLists.txt1
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--clang/lib/Frontend/ExtractAPIConsumer.cpp39
-rw-r--r--clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp2
-rw-r--r--clang/test/Driver/extract-api.c16
12 files changed, 84 insertions, 2 deletions
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 49ceebc..a57787a 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 997eea4..7adf59ca 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 8bd6509..8eceb81 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 @@ protected:
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 1d9d89a..7ce8076 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 c7314e1..2e4ebc1 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 9e10d6d..ea83551 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 1bd187a..8f6adc6 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 ca4ad8b..e147a13 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 eaca1fb..7f1ce3d 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 0000000..92a0385
--- /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 8e18f33..8a8a137 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 0000000..f58d3a4
--- /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