1 //===--- CompilerInvocation.cpp -------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/Frontend/CompilerInvocation.h"
11 #include "llvm/ADT/StringExtras.h"
12 #include "llvm/Support/ErrorHandling.h"
13 using namespace clang;
15 void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
16 const llvm::SmallVectorImpl<llvm::StringRef> &Args) {
19 static const char *getAnalysisName(Analyses Kind) {
22 llvm::llvm_unreachable("Unknown analysis store!");
23 #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\
24 case NAME: return CMDFLAG;
25 #include "clang/Frontend/Analyses.def"
29 static const char *getAnalysisStoreName(AnalysisStores Kind) {
32 llvm::llvm_unreachable("Unknown analysis store!");
33 #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) \
34 case NAME##Model: return CMDFLAG;
35 #include "clang/Frontend/Analyses.def"
39 static const char *getAnalysisConstraintName(AnalysisConstraints Kind) {
42 llvm::llvm_unreachable("Unknown analysis constraints!");
43 #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
44 case NAME##Model: return CMDFLAG;
45 #include "clang/Frontend/Analyses.def"
49 static const char *getAnalysisDiagClientName(AnalysisDiagClients Kind) {
52 llvm::llvm_unreachable("Unknown analysis client!");
53 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREATE) \
54 case PD_##NAME: return CMDFLAG;
55 #include "clang/Frontend/Analyses.def"
59 static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts,
60 std::vector<std::string> &Res) {
61 for (unsigned i = 0, e = Opts.AnalysisList.size(); i != e; ++i)
62 Res.push_back(getAnalysisName(Opts.AnalysisList[i]));
63 if (Opts.AnalysisStoreOpt != BasicStoreModel) {
64 Res.push_back("-analyzer-store");
65 Res.push_back(getAnalysisStoreName(Opts.AnalysisStoreOpt));
67 if (Opts.AnalysisConstraintsOpt != RangeConstraintsModel) {
68 Res.push_back("-analyzer-constraints");
69 Res.push_back(getAnalysisConstraintName(Opts.AnalysisConstraintsOpt));
71 if (Opts.AnalysisDiagOpt != PD_HTML) {
72 Res.push_back("-analyzer-output");
73 Res.push_back(getAnalysisDiagClientName(Opts.AnalysisDiagOpt));
75 if (!Opts.AnalyzeSpecificFunction.empty()) {
76 Res.push_back("-analyze-function");
77 Res.push_back(Opts.AnalyzeSpecificFunction);
80 Res.push_back("-analyzer-opt-analyze-headers");
81 if (Opts.AnalyzerDisplayProgress)
82 Res.push_back("-analyzer-display-progress");
83 if (Opts.EagerlyAssume)
84 Res.push_back("-analyzer-eagerly-assume");
86 Res.push_back("-analyzer-no-purge-dead");
88 Res.push_back("-trim-egraph");
89 if (Opts.VisualizeEGDot)
90 Res.push_back("-analyzer-viz-egraph-graphviz");
91 if (Opts.VisualizeEGDot)
92 Res.push_back("-analyzer-viz-egraph-ubigraph");
93 if (Opts.EnableExperimentalChecks)
94 Res.push_back("-analyzer-experimental-checks");
95 if (Opts.EnableExperimentalInternalChecks)
96 Res.push_back("-analyzer-experimental-internal-checls");
99 static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
100 std::vector<std::string> &Res) {
103 if (Opts.DisableLLVMOpts)
104 Res.push_back("-disable-llvm-optzns");
105 if (Opts.DisableRedZone)
106 Res.push_back("-disable-red-zone");
107 if (!Opts.MergeAllConstants)
108 Res.push_back("-fno-merge-all-constants");
109 // NoCommon is only derived.
110 if (Opts.NoImplicitFloat)
111 Res.push_back("-no-implicit-float");
112 if (Opts.OptimizeSize) {
113 assert(Opts.OptimizationLevel == 2 && "Invalid options!");
114 Res.push_back("-Os");
115 } else if (Opts.OptimizationLevel == 0)
116 Res.push_back("-O" + Opts.OptimizationLevel);
117 // SimplifyLibCalls is only derived.
118 // TimePasses is only derived.
119 // UnitAtATime is unused.
120 // UnrollLoops is only derived.
121 // VerifyModule is only derived.
122 // Inlining is only derived.
125 static void DependencyOutputOptsToArgs(const DependencyOutputOptions &Opts,
126 std::vector<std::string> &Res) {
127 if (Opts.IncludeSystemHeaders)
128 Res.push_back("-sys-header-deps");
129 if (Opts.UsePhonyTargets)
130 Res.push_back("-MP");
131 if (!Opts.OutputFile.empty()) {
132 Res.push_back("-dependency-file");
133 Res.push_back(Opts.OutputFile);
135 for (unsigned i = 0, e = Opts.Targets.size(); i != e; ++i) {
136 Res.push_back("-MT");
137 Res.push_back(Opts.Targets[i]);
141 static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts,
142 std::vector<std::string> &Res) {
143 if (Opts.IgnoreWarnings)
145 if (Opts.NoRewriteMacros)
146 Res.push_back("-Wno-rewrite-macros");
148 Res.push_back("-pedantic");
149 if (Opts.PedanticErrors)
150 Res.push_back("-pedantic-errors");
151 if (!Opts.ShowColumn)
152 Res.push_back("-fno-show-column");
153 if (!Opts.ShowLocation)
154 Res.push_back("-fno-show-source-location");
155 if (!Opts.ShowCarets)
156 Res.push_back("-fno-caret-diagnostics");
157 if (!Opts.ShowFixits)
158 Res.push_back("-fno-diagnostics-fixit-info");
159 if (Opts.ShowSourceRanges)
160 Res.push_back("-fdiagnostics-print-source-range-info");
162 Res.push_back("-fcolor-diagnostics");
163 if (Opts.VerifyDiagnostics)
164 Res.push_back("-verify");
165 if (Opts.ShowOptionNames)
166 Res.push_back("-fdiagnostics-show-option");
167 if (Opts.MessageLength) {
168 Res.push_back("-fmessage-length");
169 Res.push_back(llvm::utostr(Opts.MessageLength));
171 if (!Opts.DumpBuildInformation.empty()) {
172 Res.push_back("-dump-build-information");
173 Res.push_back(Opts.DumpBuildInformation);
175 for (unsigned i = 0, e = Opts.Warnings.size(); i != e; ++i)
176 Res.push_back("-W" + Opts.Warnings[i]);
179 static const char *getInputKindName(FrontendOptions::InputKind Kind) {
181 case FrontendOptions::IK_None: break;
182 case FrontendOptions::IK_AST: return "ast";
183 case FrontendOptions::IK_Asm: return "assembler-with-cpp";
184 case FrontendOptions::IK_C: return "c";
185 case FrontendOptions::IK_CXX: return "c++";
186 case FrontendOptions::IK_ObjC: return "objective-c";
187 case FrontendOptions::IK_ObjCXX: return "objective-c++";
188 case FrontendOptions::IK_OpenCL: return "cl";
189 case FrontendOptions::IK_PreprocessedC: return "cpp-output";
190 case FrontendOptions::IK_PreprocessedCXX: return "c++-cpp-output";
191 case FrontendOptions::IK_PreprocessedObjC: return "objective-c-cpp-output";
192 case FrontendOptions::IK_PreprocessedObjCXX: return "objective-c++-cpp-output";
195 llvm::llvm_unreachable("Unexpected language kind!");
199 static const char *getActionName(frontend::ActionKind Kind) {
201 case frontend::PluginAction:
202 case frontend::InheritanceView:
203 llvm::llvm_unreachable("Invalid kind!");
205 case frontend::ASTDump: return "-ast-dump";
206 case frontend::ASTPrint: return "-ast-print";
207 case frontend::ASTPrintXML: return "-ast-print-xml";
208 case frontend::ASTView: return "-ast-view";
209 case frontend::DumpRawTokens: return "-dump-raw-tokens";
210 case frontend::DumpRecordLayouts: return "-dump-record-layouts";
211 case frontend::DumpTokens: return "-dump-tokens";
212 case frontend::EmitAssembly: return "-S";
213 case frontend::EmitBC: return "-emit-llvm-bc";
214 case frontend::EmitHTML: return "-emit-html";
215 case frontend::EmitLLVM: return "-emit-llvm";
216 case frontend::EmitLLVMOnly: return "-emit-llvm-only";
217 case frontend::FixIt: return "-fixit";
218 case frontend::GeneratePCH: return "-emit-pch";
219 case frontend::GeneratePTH: return "-emit-pth";
220 case frontend::ParseNoop: return "-parse-noop";
221 case frontend::ParsePrintCallbacks: return "-parse-print-callbacks";
222 case frontend::ParseSyntaxOnly: return "-fsyntax-only";
223 case frontend::PrintDeclContext: return "-print-decl-contexts";
224 case frontend::PrintPreprocessedInput: return "-E";
225 case frontend::RewriteBlocks: return "-rewrite-blocks";
226 case frontend::RewriteMacros: return "-rewrite-macros";
227 case frontend::RewriteObjC: return "-rewrite-objc";
228 case frontend::RewriteTest: return "-rewrite-test";
229 case frontend::RunAnalysis: return "-analyze";
230 case frontend::RunPreprocessorOnly: return "-Eonly";
233 llvm::llvm_unreachable("Unexpected language kind!");
237 static void FrontendOptsToArgs(const FrontendOptions &Opts,
238 std::vector<std::string> &Res) {
239 if (!Opts.DebugCodeCompletionPrinter)
240 Res.push_back("-no-code-completion-debug-printer");
241 if (Opts.DisableFree)
242 Res.push_back("-disable-free");
243 if (Opts.EmptyInputOnly)
244 Res.push_back("-empty-input-only");
245 if (Opts.RelocatablePCH)
246 Res.push_back("-relocatable-pch");
247 if (Opts.ShowMacrosInCodeCompletion)
248 Res.push_back("-code-completion-macros");
250 Res.push_back("-stats");
252 Res.push_back("-ftime-report");
254 bool NeedLang = false;
255 for (unsigned i = 0, e = Opts.Inputs.size(); i != e; ++i)
256 if (FrontendOptions::getInputKindForExtension(Opts.Inputs[i].second) !=
257 Opts.Inputs[i].first)
261 Res.push_back(getInputKindName(Opts.Inputs[0].first));
263 for (unsigned i = 0, e = Opts.Inputs.size(); i != e; ++i) {
264 assert((!NeedLang || Opts.Inputs[i].first == Opts.Inputs[0].first) &&
265 "Unable to represent this input vector!");
266 Res.push_back(Opts.Inputs[i].second);
269 if (!Opts.OutputFile.empty()) {
271 Res.push_back(Opts.OutputFile);
273 if (!Opts.ViewClassInheritance.empty()) {
274 Res.push_back("-cxx-inheritance-view");
275 Res.push_back(Opts.ViewClassInheritance);
277 for (unsigned i = 0, e = Opts.FixItLocations.size(); i != e; ++i) {
278 Res.push_back("-fixit-at");
279 Res.push_back(Opts.FixItLocations[i].FileName + ":" +
280 llvm::utostr(Opts.FixItLocations[i].Line) + ":" +
281 llvm::utostr(Opts.FixItLocations[i].Column));
283 if (!Opts.CodeCompletionAt.FileName.empty()) {
284 Res.push_back("-code-completion-at");
285 Res.push_back(Opts.CodeCompletionAt.FileName + ":" +
286 llvm::utostr(Opts.CodeCompletionAt.Line) + ":" +
287 llvm::utostr(Opts.CodeCompletionAt.Column));
289 if (Opts.ProgramAction != frontend::InheritanceView &&
290 Opts.ProgramAction != frontend::PluginAction)
291 Res.push_back(getActionName(Opts.ProgramAction));
292 if (!Opts.ActionName.empty()) {
293 Res.push_back("-plugin");
294 Res.push_back(Opts.ActionName);
298 static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
299 std::vector<std::string> &Res) {
300 if (Opts.Sysroot != "/") {
301 Res.push_back("-isysroot");
302 Res.push_back(Opts.Sysroot);
305 /// User specified include entries.
306 for (unsigned i = 0, e = Opts.UserEntries.size(); i != e; ++i) {
307 const HeaderSearchOptions::Entry &E = Opts.UserEntries[i];
308 if (E.IsFramework && (E.Group != frontend::Angled || E.IsUserSupplied))
309 llvm::llvm_report_error("Invalid option set!");
310 if (E.IsUserSupplied) {
311 if (E.Group == frontend::After) {
312 Res.push_back("-idirafter");
313 } else if (E.Group == frontend::Quoted) {
314 Res.push_back("-iquoted");
315 } else if (E.Group == frontend::System) {
316 Res.push_back("-isystem");
318 assert(E.Group == frontend::Angled && "Invalid group!");
319 Res.push_back(E.IsFramework ? "-F" : "-I");
322 if (E.Group != frontend::Angled && E.Group != frontend::System)
323 llvm::llvm_report_error("Invalid option set!");
324 Res.push_back(E.Group == frontend::Angled ? "-iwithprefixbefore" :
327 Res.push_back(E.Path);
330 if (!Opts.EnvIncPath.empty()) {
331 // FIXME: Provide an option for this, and move env detection to driver.
332 llvm::llvm_report_error("Not yet implemented!");
334 if (!Opts.CEnvIncPath.empty()) {
335 // FIXME: Provide an option for this, and move env detection to driver.
336 llvm::llvm_report_error("Not yet implemented!");
338 if (!Opts.ObjCEnvIncPath.empty()) {
339 // FIXME: Provide an option for this, and move env detection to driver.
340 llvm::llvm_report_error("Not yet implemented!");
342 if (!Opts.CXXEnvIncPath.empty()) {
343 // FIXME: Provide an option for this, and move env detection to driver.
344 llvm::llvm_report_error("Not yet implemented!");
346 if (!Opts.ObjCXXEnvIncPath.empty()) {
347 // FIXME: Provide an option for this, and move env detection to driver.
348 llvm::llvm_report_error("Not yet implemented!");
350 if (!Opts.BuiltinIncludePath.empty()) {
351 // FIXME: Provide an option for this, and move to driver.
353 if (!Opts.UseStandardIncludes)
354 Res.push_back("-nostdinc");
359 static void LangOptsToArgs(const LangOptions &Opts,
360 std::vector<std::string> &Res) {
361 LangOptions DefaultLangOpts;
363 // FIXME: Need to set -std to get all the implicit options.
365 // FIXME: We want to only pass options relative to the defaults, which
366 // requires constructing a target. :(
368 // It would be better to push the all target specific choices into the driver,
369 // so that everything below that was more uniform.
372 Res.push_back("-trigraphs");
373 // Implicit based on the input kind:
374 // AsmPreprocessor, CPlusPlus, ObjC1, ObjC2, OpenCL
375 // Implicit based on the input language standard:
376 // BCPLComment, C99, CPlusPlus0x, Digraphs, GNUInline, ImplicitInt, GNUMode
377 if (Opts.DollarIdents)
378 Res.push_back("-fdollars-in-identifiers");
380 Res.push_back("-fms-extensions=1");
381 if (Opts.ObjCNonFragileABI)
382 Res.push_back("-fobjc-nonfragile-abi");
383 // NoInline is implicit.
384 if (!Opts.CXXOperatorNames)
385 Res.push_back("-fno-operator-names");
386 if (Opts.PascalStrings)
387 Res.push_back("-fpascal-strings");
388 if (Opts.WritableStrings)
389 Res.push_back("-fwritable-strings");
390 if (!Opts.LaxVectorConversions)
391 Res.push_back("-fno-lax-vector-conversions");
393 Res.push_back("-faltivec");
394 Res.push_back("-fexceptions");
395 Res.push_back(Opts.Exceptions ? "1" : "0");
397 Res.push_back("-fno-rtti");
398 if (!Opts.NeXTRuntime)
399 Res.push_back("-fgnu-runtime");
400 if (Opts.Freestanding)
401 Res.push_back("-ffreestanding");
403 Res.push_back("-fno-builtin");
404 if (Opts.ThreadsafeStatics)
405 llvm::llvm_report_error("FIXME: Not yet implemented!");
406 if (Opts.POSIXThreads)
407 Res.push_back("-pthread");
409 Res.push_back("-fblocks=1");
410 if (Opts.EmitAllDecls)
411 Res.push_back("-femit-all-decls");
413 Res.push_back("-fno-math-errno");
414 if (Opts.OverflowChecking)
415 Res.push_back("-ftrapv");
416 if (Opts.HeinousExtensions)
417 Res.push_back("-fheinous-gnu-extensions");
418 // Optimize is implicit.
419 // OptimizeSize is implicit.
421 Res.push_back("-static-define");
423 Res.push_back("-pic-level");
424 Res.push_back(llvm::utostr(Opts.PICLevel));
426 if (Opts.ObjCGCBitmapPrint)
427 Res.push_back("-print-ivar-layout");
428 Res.push_back("-faccess-control");
429 Res.push_back(Opts.AccessControl ? "1" : "0");
430 Res.push_back("-fsigned-char");
431 Res.push_back(Opts.CharIsSigned ? "1" : "0");
432 Res.push_back("-fshort-wchar");
433 Res.push_back(Opts.ShortWChar ? "1" : "0");
434 if (!Opts.ElideConstructors)
435 Res.push_back("-fno-elide-constructors");
436 if (Opts.getGCMode() != LangOptions::NonGC) {
437 if (Opts.getGCMode() == LangOptions::HybridGC) {
438 Res.push_back("-fobjc-gc");
440 assert(Opts.getGCMode() == LangOptions::GCOnly && "Invalid GC mode!");
441 Res.push_back("-fobjc-gc-only");
444 if (Opts.getVisibilityMode() != LangOptions::Default) {
445 Res.push_back("-fvisibility");
446 if (Opts.getVisibilityMode() == LangOptions::Hidden) {
447 Res.push_back("default");
449 assert(Opts.getVisibilityMode() == LangOptions::Protected &&
450 "Invalid visibility!");
451 Res.push_back("protected");
454 if (Opts.getStackProtectorMode() != 0) {
455 Res.push_back("-stack-protector");
456 Res.push_back(llvm::utostr(Opts.getStackProtectorMode()));
458 if (Opts.getMainFileName()) {
459 Res.push_back("-main-file-name");
460 Res.push_back(Opts.getMainFileName());
462 if (Opts.InstantiationDepth != DefaultLangOpts.InstantiationDepth) {
463 Res.push_back("-ftemplate-depth");
464 Res.push_back(llvm::utostr(Opts.InstantiationDepth));
466 if (Opts.ObjCConstantStringClass) {
467 Res.push_back("-fconstant-string-class");
468 Res.push_back(Opts.ObjCConstantStringClass);
472 static void PreprocessorOptsToArgs(const PreprocessorOptions &Opts,
473 std::vector<std::string> &Res) {
474 for (unsigned i = 0, e = Opts.Macros.size(); i != e; ++i)
475 Res.push_back((Opts.Macros[i].second ? "-U" : "-D") + Opts.Macros[i].first);
476 for (unsigned i = 0, e = Opts.Includes.size(); i != e; ++i) {
477 Res.push_back("-include");
478 Res.push_back(Opts.Includes[i]);
480 for (unsigned i = 0, e = Opts.MacroIncludes.size(); i != e; ++i) {
481 Res.push_back("-imacros");
482 Res.push_back(Opts.Includes[i]);
484 if (!Opts.UsePredefines)
485 Res.push_back("-undef");
486 if (!Opts.ImplicitPCHInclude.empty()) {
487 Res.push_back("-implicit-pch-include");
488 Res.push_back(Opts.ImplicitPCHInclude);
490 if (!Opts.ImplicitPTHInclude.empty()) {
491 Res.push_back("-implicit-pth-include");
492 Res.push_back(Opts.ImplicitPTHInclude);
494 if (!Opts.TokenCache.empty()) {
495 Res.push_back("-token-cache");
496 Res.push_back(Opts.TokenCache);
500 static void PreprocessorOutputOptsToArgs(const PreprocessorOutputOptions &Opts,
501 std::vector<std::string> &Res) {
502 if (!Opts.ShowCPP && !Opts.ShowMacros)
503 llvm::llvm_report_error("Invalid option combination!");
505 if (Opts.ShowCPP && Opts.ShowMacros)
506 Res.push_back("-dD");
507 else if (!Opts.ShowCPP && Opts.ShowMacros)
508 Res.push_back("-dM");
510 if (!Opts.ShowLineMarkers)
512 if (Opts.ShowComments)
514 if (Opts.ShowMacroComments)
515 Res.push_back("-CC");
518 static void TargetOptsToArgs(const TargetOptions &Opts,
519 std::vector<std::string> &Res) {
520 Res.push_back("-triple");
521 Res.push_back(Opts.Triple);
522 if (!Opts.CPU.empty()) {
523 Res.push_back("-target-cpu");
524 Res.push_back(Opts.CPU);
526 if (!Opts.ABI.empty()) {
527 Res.push_back("-target-abi");
528 Res.push_back(Opts.ABI);
530 for (unsigned i = 0, e = Opts.Features.size(); i != e; ++i) {
531 Res.push_back("-target-feature");
532 Res.push_back(Opts.Features[i]);
536 void CompilerInvocation::toArgs(std::vector<std::string> &Res) {
537 AnalyzerOptsToArgs(getAnalyzerOpts(), Res);
538 CodeGenOptsToArgs(getCodeGenOpts(), Res);
539 DependencyOutputOptsToArgs(getDependencyOutputOpts(), Res);
540 DiagnosticOptsToArgs(getDiagnosticOpts(), Res);
541 FrontendOptsToArgs(getFrontendOpts(), Res);
542 HeaderSearchOptsToArgs(getHeaderSearchOpts(), Res);
543 LangOptsToArgs(getLangOpts(), Res);
544 PreprocessorOptsToArgs(getPreprocessorOpts(), Res);
545 PreprocessorOutputOptsToArgs(getPreprocessorOutputOpts(), Res);
546 TargetOptsToArgs(getTargetOpts(), Res);