Skip to content

Commit 8df7f1a

Browse files
committed
[clang-ifs] Clang Interface Stubs, first version.
Clang interface stubs (previously referred to as clang-ifsos) is a new frontend action in clang that allows the generation of stub files that contain mangled name info that can be used to produce a stub library. These stub libraries can be useful for breaking up build dependencies and controlling access to a library's internal symbols. Generation of these stubs can be invoked by: clang -fvisibility=<visibility> -emit-interface-stubs \ -interface-stub-version=<interface format> Notice that -fvisibility (along with use of visibility attributes) can be used to control what symbols get generated. Currently the interface format is experimental but there are a wide range of possibilities here. Differential Revision: https://reviews.llvm.org/D60974 llvm-svn: 363626
1 parent 1219561 commit 8df7f1a

23 files changed

+958
-0
lines changed

clang/include/clang/Basic/DiagnosticFrontendKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ def err_module_header_file_not_found :
220220
def err_module_header_file_invalid :
221221
Error<"unexpected module header file input '%0'">, DefaultFatal;
222222

223+
def err_interface_stubs : Error<"clang-ifs (-emit-iterface-stubs): %0">;
224+
223225
def err_test_module_file_extension_version : Error<
224226
"test module file extension '%0' has different version (%1.%2) than expected "
225227
"(%3.%4)">;

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,9 @@ def emit_ast : Flag<["-"], "emit-ast">,
623623
HelpText<"Emit Clang AST files for source inputs">;
624624
def emit_llvm : Flag<["-"], "emit-llvm">, Flags<[CC1Option]>, Group<Action_Group>,
625625
HelpText<"Use the LLVM representation for assembler and object files">;
626+
def emit_iterface_stubs : Flag<["-"], "emit-interface-stubs">, Flags<[CC1Option]>, Group<Action_Group>,
627+
HelpText<"Generate Inteface Stub Files.">;
628+
def iterface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">, Flags<[CC1Option]>;
626629
def exported__symbols__list : Separate<["-"], "exported_symbols_list">;
627630
def e : JoinedOrSeparate<["-"], "e">, Group<Link_Group>;
628631
def fPIC : Flag<["-"], "fPIC">, Group<f_Group>;

clang/include/clang/Driver/Types.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ TYPE("lto-bc", LTO_BC, INVALID, "o", "")
8888

8989
// Misc.
9090
TYPE("ast", AST, INVALID, "ast", "u")
91+
TYPE("ifs", IFS, INVALID, "ifs", "u")
9192
TYPE("pcm", ModuleFile, INVALID, "pcm", "u")
9293
TYPE("plist", Plist, INVALID, "plist", "")
9394
TYPE("rewritten-objc", RewrittenObjC,INVALID, "cpp", "")

clang/include/clang/Frontend/FrontendActions.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,26 @@ class GenerateModuleAction : public ASTFrontendAction {
119119
bool hasASTFileSupport() const override { return false; }
120120
};
121121

122+
class GenerateInterfaceStubAction : public ASTFrontendAction {
123+
protected:
124+
TranslationUnitKind getTranslationUnitKind() override { return TU_Module; }
125+
126+
bool hasASTFileSupport() const override { return false; }
127+
};
128+
129+
// Support different interface stub formats this way:
130+
class GenerateInterfaceYAMLExpV1Action : public GenerateInterfaceStubAction {
131+
protected:
132+
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
133+
StringRef InFile) override;
134+
};
135+
136+
class GenerateInterfaceTBEExpV1Action : public GenerateInterfaceStubAction {
137+
protected:
138+
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
139+
StringRef InFile) override;
140+
};
141+
122142
class GenerateModuleFromModuleMapAction : public GenerateModuleAction {
123143
private:
124144
bool BeginSourceFileAction(CompilerInstance &CI) override;

clang/include/clang/Frontend/FrontendOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ enum ActionKind {
8888
/// Generate pre-compiled header.
8989
GeneratePCH,
9090

91+
/// Generate Interface Stub Files.
92+
GenerateInterfaceYAMLExpV1,
93+
GenerateInterfaceTBEExpV1,
94+
9195
/// Only execute frontend initialization.
9296
InitOnly,
9397

clang/lib/Driver/Driver.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
285285
(PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
286286
(PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
287287
(PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
288+
(PhaseArg = DAL.getLastArg(options::OPT_emit_iterface_stubs)) ||
288289
(PhaseArg = DAL.getLastArg(options::OPT__analyze,
289290
options::OPT__analyze_auto)) ||
290291
(PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
@@ -3472,6 +3473,8 @@ Action *Driver::ConstructPhaseAction(
34723473
return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile);
34733474
if (Args.hasArg(options::OPT_verify_pch))
34743475
return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing);
3476+
if (Args.hasArg(options::OPT_emit_iterface_stubs))
3477+
return C.MakeAction<CompileJobAction>(Input, types::TY_IFS);
34753478
return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC);
34763479
}
34773480
case phases::Backend: {

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3613,6 +3613,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
36133613
} else if (JA.getType() == types::TY_LLVM_BC ||
36143614
JA.getType() == types::TY_LTO_BC) {
36153615
CmdArgs.push_back("-emit-llvm-bc");
3616+
} else if (JA.getType() == types::TY_IFS) {
3617+
StringRef StubFormat =
3618+
llvm::StringSwitch<StringRef>(
3619+
Args.hasArg(options::OPT_iterface_stub_version_EQ)
3620+
? Args.getLastArgValue(options::OPT_iterface_stub_version_EQ)
3621+
: "")
3622+
.Case("experimental-yaml-elf-v1", "experimental-yaml-elf-v1")
3623+
.Case("experimental-tapi-elf-v1", "experimental-tapi-elf-v1")
3624+
.Default("");
3625+
3626+
if (StubFormat.empty())
3627+
D.Diag(diag::err_drv_invalid_value)
3628+
<< "Must specify a valid interface stub format type using "
3629+
<< "-interface-stub-version=<experimental-tapi-elf-v1 | "
3630+
"experimental-yaml-elf-v1>";
3631+
3632+
CmdArgs.push_back("-emit-interface-stubs");
3633+
CmdArgs.push_back(
3634+
Args.MakeArgString(Twine("-interface-stub-version=") + StubFormat));
36163635
} else if (JA.getType() == types::TY_PP_Asm) {
36173636
CmdArgs.push_back("-S");
36183637
} else if (JA.getType() == types::TY_AST) {

clang/lib/Frontend/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ add_clang_library(clangFrontend
4545
TextDiagnosticBuffer.cpp
4646
TextDiagnosticPrinter.cpp
4747
VerifyDiagnosticConsumer.cpp
48+
InterfaceStubFunctionsConsumer.cpp
4849

4950
DEPENDS
5051
ClangDriverOptions
@@ -54,6 +55,7 @@ add_clang_library(clangFrontend
5455
clangAST
5556
clangBasic
5657
clangDriver
58+
clangIndex
5759
clangEdit
5860
clangLex
5961
clangParse

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,6 +1681,25 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
16811681
Opts.ProgramAction = frontend::GenerateHeaderModule; break;
16821682
case OPT_emit_pch:
16831683
Opts.ProgramAction = frontend::GeneratePCH; break;
1684+
case OPT_emit_iterface_stubs: {
1685+
llvm::Optional<frontend::ActionKind> ProgramAction =
1686+
llvm::StringSwitch<llvm::Optional<frontend::ActionKind>>(
1687+
Args.hasArg(OPT_iterface_stub_version_EQ)
1688+
? Args.getLastArgValue(OPT_iterface_stub_version_EQ)
1689+
: "")
1690+
.Case("experimental-yaml-elf-v1",
1691+
frontend::GenerateInterfaceYAMLExpV1)
1692+
.Case("experimental-tapi-elf-v1",
1693+
frontend::GenerateInterfaceTBEExpV1)
1694+
.Default(llvm::None);
1695+
if (!ProgramAction)
1696+
Diags.Report(diag::err_drv_invalid_value)
1697+
<< "Must specify a valid interface stub format type using "
1698+
<< "-interface-stub-version=<experimental-tapi-elf-v1 | "
1699+
"experimental-yaml-elf-v1>";
1700+
Opts.ProgramAction = *ProgramAction;
1701+
break;
1702+
}
16841703
case OPT_init_only:
16851704
Opts.ProgramAction = frontend::InitOnly; break;
16861705
case OPT_fsyntax_only:
@@ -3113,6 +3132,8 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
31133132
case frontend::GenerateModuleInterface:
31143133
case frontend::GenerateHeaderModule:
31153134
case frontend::GeneratePCH:
3135+
case frontend::GenerateInterfaceYAMLExpV1:
3136+
case frontend::GenerateInterfaceTBEExpV1:
31163137
case frontend::ParseSyntaxOnly:
31173138
case frontend::ModuleFileInfo:
31183139
case frontend::VerifyPCH:

0 commit comments

Comments
 (0)