1
- // ===--- SILFunctionExtractor .cpp - SIL function extraction utility -------===//
1
+ // ===--- sil_func_extractor_main .cpp ------------------------------- -------===//
2
2
//
3
3
// This source file is part of the Swift.org open source project
4
4
//
49
49
50
50
using namespace swift ;
51
51
52
- static llvm::cl::opt<std::string> InputFilename (llvm::cl::desc(" input file" ),
52
+ struct SILFuncExtractorOptions {
53
+ llvm::cl::opt<std::string>
54
+ InputFilename = llvm::cl::opt<std::string>(llvm::cl::desc(" input file" ),
53
55
llvm::cl::init (" -" ),
54
56
llvm::cl::Positional);
55
57
56
- static llvm::cl::opt<std::string>
57
- OutputFilename (" o" , llvm::cl::desc(" output filename" ), llvm::cl::init(" -" ));
58
+ llvm::cl::opt<std::string>
59
+ OutputFilename = llvm::cl::opt<std::string> (" o" , llvm::cl::desc(" output filename" ), llvm::cl::init(" -" ));
58
60
59
- static llvm::cl::opt<bool >
60
- EmitVerboseSIL (" emit-verbose-sil" ,
61
+ llvm::cl::opt<bool >
62
+ EmitVerboseSIL = llvm::cl::opt< bool > (" emit-verbose-sil" ,
61
63
llvm::cl::desc (" Emit locations during sil emission." ));
62
64
63
- static llvm::cl::list<std::string>
64
- CommandLineFunctionNames (" func" ,
65
+ llvm::cl::list<std::string>
66
+ CommandLineFunctionNames = llvm::cl::list<std::string> (" func" ,
65
67
llvm::cl::desc (" Function names to extract." ));
66
- static llvm::cl::opt<std::string> FunctionNameFile (
68
+ llvm::cl::opt<std::string>
69
+ FunctionNameFile = llvm::cl::opt<std::string>(
67
70
" func-file" , llvm::cl::desc(" File to load additional function names from" ));
68
71
69
- static llvm::cl::opt<bool >
70
- EmitSIB (" emit-sib" ,
72
+ llvm::cl::opt<bool >
73
+ EmitSIB = llvm::cl::opt< bool > (" emit-sib" ,
71
74
llvm::cl::desc (" Emit a sib file as output instead of a sil file" ));
72
75
73
- static llvm::cl::opt<bool > InvertMatch (
74
- " invert" ,
75
- llvm::cl::desc (" Match functions whose name do not "
76
- " match the names of the functions to be extracted" ));
76
+ llvm::cl::opt<bool >
77
+ InvertMatch = llvm::cl::opt<bool >(
78
+ " invert" ,
79
+ llvm::cl::desc (" Match functions whose name do not "
80
+ " match the names of the functions to be extracted" ));
77
81
78
- static llvm::cl::list<std::string>
79
- ImportPaths (" I" ,
82
+ llvm::cl::list<std::string>
83
+ ImportPaths = llvm::cl::list<std::string> (" I" ,
80
84
llvm::cl::desc (" add a directory to the import search path" ));
81
85
82
- static llvm::cl::opt<std::string>
83
- ModuleName (" module-name" ,
86
+ llvm::cl::opt<std::string>
87
+ ModuleName = llvm::cl::opt<std::string> (" module-name" ,
84
88
llvm::cl::desc (" The name of the module if processing"
85
89
" a module. Necessary for processing "
86
90
" stdin." ));
87
91
88
- static llvm::cl::opt<std::string>
89
- ModuleCachePath (" module-cache-path" ,
92
+ llvm::cl::opt<std::string>
93
+ ModuleCachePath = llvm::cl::opt<std::string> (" module-cache-path" ,
90
94
llvm::cl::desc (" Clang module cache path" ));
91
95
92
- static llvm::cl::opt<std::string> ResourceDir (
93
- " resource-dir" ,
94
- llvm::cl::desc (" The directory that holds the compiler resource files" ));
96
+ llvm::cl::opt<std::string>
97
+ ResourceDir = llvm::cl::opt<std::string>(
98
+ " resource-dir" ,
99
+ llvm::cl::desc (" The directory that holds the compiler resource files" ));
95
100
96
- static llvm::cl::opt<std::string>
97
- SDKPath (" sdk" , llvm::cl::desc(" The path to the SDK for use with the clang "
101
+ llvm::cl::opt<std::string>
102
+ SDKPath = llvm::cl::opt<std::string> (" sdk" , llvm::cl::desc(" The path to the SDK for use with the clang "
98
103
" importer." ),
99
- llvm::cl::init(" " ));
104
+ llvm::cl::init (" " ));
100
105
101
- static llvm::cl::opt<std::string> Triple (" target" ,
102
- llvm::cl::desc (" target triple" ));
106
+ llvm::cl::opt<std::string>
107
+ Triple = llvm::cl::opt<std::string>(" target" ,
108
+ llvm::cl::desc (" target triple" ));
103
109
104
- static llvm::cl::opt<bool >
105
- EmitSortedSIL (" emit-sorted-sil" , llvm::cl::Hidden, llvm::cl::init(false ),
110
+ llvm::cl::opt<bool >
111
+ EmitSortedSIL = llvm::cl::opt< bool > (" emit-sorted-sil" , llvm::cl::Hidden, llvm::cl::init(false ),
106
112
llvm::cl::desc (" Sort Functions, VTables, Globals, "
107
113
" WitnessTables by name to ease diffing." ));
108
114
109
- static llvm::cl::opt<bool >
110
- DisableASTDump (" sil-disable-ast-dump" , llvm::cl::Hidden,
111
- llvm::cl::init (false ),
112
- llvm::cl::desc(" Do not dump AST." ));
113
-
114
- static llvm::cl::opt<bool > EnableOSSAModules (
115
- " enable-ossa-modules" ,
116
- llvm::cl::desc (" Do we always serialize SIL in OSSA form? If "
117
- " this is disabled we do not serialize in OSSA "
118
- " form when optimizing." ));
119
-
120
- static llvm::cl::opt<llvm::cl::boolOrDefault> EnableObjCInterop (
121
- " enable-objc-interop" ,
122
- llvm::cl::desc (" Whether the Objective-C interop should be enabled. "
123
- " The value is `true` by default on Darwin platforms." ));
124
-
125
- // This function isn't referenced outside its translation unit, but it
126
- // can't use the "static" keyword because its address is used for
127
- // getMainExecutable (since some platforms don't support taking the
128
- // address of main, and some platforms can't implement getMainExecutable
129
- // without being given the address of a function in the main executable).
130
- void anchorForGetMainExecutable () {}
131
-
132
- static void getFunctionNames (std::vector<std::string> &Names) {
133
- std::copy (CommandLineFunctionNames.begin (), CommandLineFunctionNames.end (),
115
+ llvm::cl::opt<bool >
116
+ DisableASTDump = llvm::cl::opt<bool >(" sil-disable-ast-dump" , llvm::cl::Hidden,
117
+ llvm::cl::init (false ),
118
+ llvm::cl::desc(" Do not dump AST." ));
119
+
120
+ llvm::cl::opt<bool >
121
+ EnableOSSAModules = llvm::cl::opt<bool >(
122
+ " enable-ossa-modules" ,
123
+ llvm::cl::desc (" Do we always serialize SIL in OSSA form? If "
124
+ " this is disabled we do not serialize in OSSA "
125
+ " form when optimizing." ));
126
+
127
+ llvm::cl::opt<llvm::cl::boolOrDefault>
128
+ EnableObjCInterop = llvm::cl::opt<llvm::cl::boolOrDefault>(
129
+ " enable-objc-interop" ,
130
+ llvm::cl::desc (" Whether the Objective-C interop should be enabled. "
131
+ " The value is `true` by default on Darwin platforms." ));
132
+ };
133
+
134
+ static void getFunctionNames (std::vector<std::string> &Names,
135
+ const SILFuncExtractorOptions &options) {
136
+ std::copy (options.CommandLineFunctionNames .begin (), options.CommandLineFunctionNames .end (),
134
137
std::back_inserter (Names));
135
138
136
- if (!FunctionNameFile.empty ()) {
139
+ if (!options. FunctionNameFile .empty ()) {
137
140
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
138
- llvm::MemoryBuffer::getFileOrSTDIN (FunctionNameFile);
141
+ llvm::MemoryBuffer::getFileOrSTDIN (options. FunctionNameFile );
139
142
if (!FileBufOrErr) {
140
143
fprintf (stderr, " Error! Failed to open file: %s\n " ,
141
- InputFilename.c_str ());
144
+ options. InputFilename .c_str ());
142
145
exit (-1 );
143
146
}
144
147
StringRef Buffer = FileBufOrErr.get ()->getBuffer ();
@@ -168,7 +171,8 @@ static bool stringInSortedArray(
168
171
}
169
172
170
173
void removeUnwantedFunctions (SILModule *M, ArrayRef<std::string> MangledNames,
171
- ArrayRef<std::string> DemangledNames) {
174
+ ArrayRef<std::string> DemangledNames,
175
+ const SILFuncExtractorOptions &options) {
172
176
assert ((!MangledNames.empty () || !DemangledNames.empty ()) &&
173
177
" Expected names of function we want to retain!" );
174
178
assert (M && " Expected a SIL module to extract from." );
@@ -191,7 +195,7 @@ void removeUnwantedFunctions(SILModule *M, ArrayRef<std::string> MangledNames,
191
195
return str1.substr (0 , str1.find (' ' )) <
192
196
str2.substr (0 , str2.find (' ' ));
193
197
});
194
- if ((FoundMangledName || FoundDemangledName) ^ InvertMatch) {
198
+ if ((FoundMangledName || FoundDemangledName) ^ options. InvertMatch ) {
195
199
LLVM_DEBUG (llvm::dbgs () << " Not removing!\n " );
196
200
continue ;
197
201
}
@@ -225,57 +229,57 @@ void removeUnwantedFunctions(SILModule *M, ArrayRef<std::string> MangledNames,
225
229
performSILDeadFunctionElimination (M);
226
230
}
227
231
228
- int main (int argc, char **argv) {
229
- PROGRAM_START (argc, argv);
232
+ int sil_func_extractor_main (ArrayRef<const char *> argv, void *MainAddr) {
230
233
INITIALIZE_LLVM ();
231
234
232
- llvm::cl::ParseCommandLineOptions (argc, argv, " Swift SIL Extractor\n " );
235
+ SILFuncExtractorOptions options;
236
+
237
+ llvm::cl::ParseCommandLineOptions (argv.size (), argv.data (), " Swift SIL Extractor\n " );
233
238
234
239
CompilerInvocation Invocation;
235
240
236
- Invocation.setMainExecutablePath (llvm::sys::fs::getMainExecutable (
237
- argv[0 ], reinterpret_cast <void *>(&anchorForGetMainExecutable)));
241
+ Invocation.setMainExecutablePath (llvm::sys::fs::getMainExecutable (argv[0 ], MainAddr));
238
242
239
243
// Give the context the list of search paths to use for modules.
240
- Invocation.setImportSearchPaths (ImportPaths);
244
+ Invocation.setImportSearchPaths (options. ImportPaths );
241
245
// Set the SDK path and target if given.
242
- if (SDKPath.getNumOccurrences () == 0 ) {
246
+ if (options. SDKPath .getNumOccurrences () == 0 ) {
243
247
const char *SDKROOT = getenv (" SDKROOT" );
244
248
if (SDKROOT)
245
- SDKPath = SDKROOT;
249
+ options. SDKPath = SDKROOT;
246
250
}
247
- if (!SDKPath.empty ())
248
- Invocation.setSDKPath (SDKPath);
249
- if (!Triple.empty ())
250
- Invocation.setTargetTriple (Triple);
251
- if (!ResourceDir.empty ())
252
- Invocation.setRuntimeResourcePath (ResourceDir);
253
- Invocation.getClangImporterOptions ().ModuleCachePath = ModuleCachePath;
251
+ if (!options. SDKPath .empty ())
252
+ Invocation.setSDKPath (options. SDKPath );
253
+ if (!options. Triple .empty ())
254
+ Invocation.setTargetTriple (options. Triple );
255
+ if (!options. ResourceDir .empty ())
256
+ Invocation.setRuntimeResourcePath (options. ResourceDir );
257
+ Invocation.getClangImporterOptions ().ModuleCachePath = options. ModuleCachePath ;
254
258
Invocation.setParseStdlib ();
255
259
Invocation.getLangOptions ().DisableAvailabilityChecking = true ;
256
260
Invocation.getLangOptions ().EnableAccessControl = false ;
257
261
Invocation.getLangOptions ().EnableObjCAttrRequiresFoundation = false ;
258
262
259
- if (EnableObjCInterop == llvm::cl::BOU_UNSET) {
263
+ if (options. EnableObjCInterop == llvm::cl::BOU_UNSET) {
260
264
Invocation.getLangOptions ().EnableObjCInterop =
261
265
Invocation.getLangOptions ().Target .isOSDarwin ();
262
266
} else {
263
267
Invocation.getLangOptions ().EnableObjCInterop =
264
- EnableObjCInterop == llvm::cl::BOU_TRUE;
268
+ options. EnableObjCInterop == llvm::cl::BOU_TRUE;
265
269
}
266
270
267
271
SILOptions &Opts = Invocation.getSILOptions ();
268
- Opts.EmitVerboseSIL = EmitVerboseSIL;
269
- Opts.EmitSortedSIL = EmitSortedSIL;
270
- Opts.EnableOSSAModules = EnableOSSAModules;
272
+ Opts.EmitVerboseSIL = options. EmitVerboseSIL ;
273
+ Opts.EmitSortedSIL = options. EmitSortedSIL ;
274
+ Opts.EnableOSSAModules = options. EnableOSSAModules ;
271
275
272
276
serialization::ExtendedValidationInfo extendedInfo;
273
277
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
274
- Invocation.setUpInputForSILTool (InputFilename, ModuleName,
278
+ Invocation.setUpInputForSILTool (options. InputFilename , options. ModuleName ,
275
279
/* alwaysSetModuleToMain*/ true ,
276
280
/* bePrimary*/ false , extendedInfo);
277
281
if (!FileBufOrErr) {
278
- fprintf (stderr, " Error! Failed to open file: %s\n " , InputFilename.c_str ());
282
+ fprintf (stderr, " Error! Failed to open file: %s\n " , options. InputFilename .c_str ());
279
283
exit (-1 );
280
284
}
281
285
@@ -297,13 +301,13 @@ int main(int argc, char **argv) {
297
301
auto SILMod = performASTLowering (CI.getMainModule (), CI.getSILTypes (),
298
302
CI.getSILOptions ());
299
303
300
- if (CommandLineFunctionNames.empty () && FunctionNameFile.empty ())
304
+ if (options. CommandLineFunctionNames .empty () && options. FunctionNameFile .empty ())
301
305
return CI.getASTContext ().hadError ();
302
306
303
307
// For efficient usage, we separate our names into two separate sorted
304
308
// lists, one of managled names, and one of unmangled names.
305
309
std::vector<std::string> Names;
306
- getFunctionNames (Names);
310
+ getFunctionNames (Names, options );
307
311
308
312
// First partition our function names into mangled/demangled arrays.
309
313
auto FirstDemangledName = std::partition (
@@ -339,14 +343,14 @@ int main(int argc, char **argv) {
339
343
llvm::errs () << " " << str << ' \n ' ;
340
344
}));
341
345
342
- removeUnwantedFunctions (SILMod.get (), MangledNames, DemangledNames);
346
+ removeUnwantedFunctions (SILMod.get (), MangledNames, DemangledNames, options );
343
347
344
- if (EmitSIB) {
348
+ if (options. EmitSIB ) {
345
349
llvm::SmallString<128 > OutputFile;
346
- if (OutputFilename.size ()) {
347
- OutputFile = OutputFilename;
348
- } else if (ModuleName.size ()) {
349
- OutputFile = ModuleName;
350
+ if (options. OutputFilename .size ()) {
351
+ OutputFile = options. OutputFilename ;
352
+ } else if (options. ModuleName .size ()) {
353
+ OutputFile = options. ModuleName ;
350
354
llvm::sys::path::replace_extension (
351
355
OutputFile, file_types::getExtension (file_types::TY_SIB));
352
356
} else {
@@ -365,14 +369,14 @@ int main(int argc, char **argv) {
365
369
serialize (CI.getMainModule (), serializationOpts, symbolGraphOpts, SILMod.get ());
366
370
} else {
367
371
const StringRef OutputFile =
368
- OutputFilename.size () ? StringRef (OutputFilename) : " -" ;
372
+ options. OutputFilename .size () ? StringRef (options. OutputFilename ) : " -" ;
369
373
370
374
auto SILOpts = SILOptions ();
371
- SILOpts.EmitVerboseSIL = EmitVerboseSIL;
372
- SILOpts.EmitSortedSIL = EmitSortedSIL;
375
+ SILOpts.EmitVerboseSIL = options. EmitVerboseSIL ;
376
+ SILOpts.EmitSortedSIL = options. EmitSortedSIL ;
373
377
374
378
if (OutputFile == " -" ) {
375
- SILMod->print (llvm::outs (), CI.getMainModule (), SILOpts, !DisableASTDump);
379
+ SILMod->print (llvm::outs (), CI.getMainModule (), SILOpts, !options. DisableASTDump );
376
380
} else {
377
381
std::error_code EC;
378
382
llvm::raw_fd_ostream OS (OutputFile, EC, llvm::sys::fs::OF_None);
@@ -381,7 +385,8 @@ int main(int argc, char **argv) {
381
385
<< ' \n ' ;
382
386
return 1 ;
383
387
}
384
- SILMod->print (OS, CI.getMainModule (), SILOpts, !DisableASTDump);
388
+ SILMod->print (OS, CI.getMainModule (), SILOpts, !options. DisableASTDump );
385
389
}
386
390
}
391
+ return 0 ;
387
392
}
0 commit comments