14ba319b5SDimitry Andric //===- CompilerInvocation.cpp ---------------------------------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky
1044290647SDimitry Andric #include "clang/Frontend/CompilerInvocation.h"
110623d748SDimitry Andric #include "TestModuleFileExtension.h"
12ea942507SDimitry Andric #include "clang/Basic/Builtins.h"
134ba319b5SDimitry Andric #include "clang/Basic/CharInfo.h"
14*b5893f02SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
154ba319b5SDimitry Andric #include "clang/Basic/CommentOptions.h"
164ba319b5SDimitry Andric #include "clang/Basic/DebugInfoOptions.h"
174ba319b5SDimitry Andric #include "clang/Basic/Diagnostic.h"
184ba319b5SDimitry Andric #include "clang/Basic/DiagnosticOptions.h"
194ba319b5SDimitry Andric #include "clang/Basic/FileSystemOptions.h"
204ba319b5SDimitry Andric #include "clang/Basic/LLVM.h"
214ba319b5SDimitry Andric #include "clang/Basic/LangOptions.h"
224ba319b5SDimitry Andric #include "clang/Basic/ObjCRuntime.h"
234ba319b5SDimitry Andric #include "clang/Basic/Sanitizers.h"
244ba319b5SDimitry Andric #include "clang/Basic/SourceLocation.h"
254ba319b5SDimitry Andric #include "clang/Basic/TargetOptions.h"
26139f7f9bSDimitry Andric #include "clang/Basic/Version.h"
274ba319b5SDimitry Andric #include "clang/Basic/Visibility.h"
284ba319b5SDimitry Andric #include "clang/Basic/XRayInstr.h"
2939d628a0SDimitry Andric #include "clang/Config/config.h"
30f22ef01cSRoman Divacky #include "clang/Driver/DriverDiagnostic.h"
31139f7f9bSDimitry Andric #include "clang/Driver/Options.h"
324ba319b5SDimitry Andric #include "clang/Frontend/CommandLineSourceLoc.h"
334ba319b5SDimitry Andric #include "clang/Frontend/DependencyOutputOptions.h"
3459d1ed5bSDimitry Andric #include "clang/Frontend/FrontendDiagnostic.h"
354ba319b5SDimitry Andric #include "clang/Frontend/FrontendOptions.h"
36*b5893f02SDimitry Andric #include "clang/Frontend/FrontendPluginRegistry.h"
37f22ef01cSRoman Divacky #include "clang/Frontend/LangStandard.h"
384ba319b5SDimitry Andric #include "clang/Frontend/MigratorOptions.h"
394ba319b5SDimitry Andric #include "clang/Frontend/PreprocessorOutputOptions.h"
40f785676fSDimitry Andric #include "clang/Frontend/Utils.h"
41139f7f9bSDimitry Andric #include "clang/Lex/HeaderSearchOptions.h"
4244290647SDimitry Andric #include "clang/Lex/PreprocessorOptions.h"
434ba319b5SDimitry Andric #include "clang/Sema/CodeCompleteOptions.h"
440623d748SDimitry Andric #include "clang/Serialization/ModuleFileExtension.h"
454ba319b5SDimitry Andric #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
464ba319b5SDimitry Andric #include "llvm/ADT/APInt.h"
474ba319b5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
484ba319b5SDimitry Andric #include "llvm/ADT/CachedHashString.h"
493861d79fSDimitry Andric #include "llvm/ADT/Hashing.h"
504ba319b5SDimitry Andric #include "llvm/ADT/None.h"
514ba319b5SDimitry Andric #include "llvm/ADT/Optional.h"
524ba319b5SDimitry Andric #include "llvm/ADT/SmallString.h"
5339d628a0SDimitry Andric #include "llvm/ADT/SmallVector.h"
544ba319b5SDimitry Andric #include "llvm/ADT/StringRef.h"
55f22ef01cSRoman Divacky #include "llvm/ADT/StringSwitch.h"
56e580952dSDimitry Andric #include "llvm/ADT/Triple.h"
574ba319b5SDimitry Andric #include "llvm/ADT/Twine.h"
58*b5893f02SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
590623d748SDimitry Andric #include "llvm/Linker/Linker.h"
604ba319b5SDimitry Andric #include "llvm/MC/MCTargetOptions.h"
61f785676fSDimitry Andric #include "llvm/Option/Arg.h"
62f785676fSDimitry Andric #include "llvm/Option/ArgList.h"
634ba319b5SDimitry Andric #include "llvm/Option/OptSpecifier.h"
64f785676fSDimitry Andric #include "llvm/Option/OptTable.h"
65f785676fSDimitry Andric #include "llvm/Option/Option.h"
66e7145dcbSDimitry Andric #include "llvm/ProfileData/InstrProfReader.h"
6759d1ed5bSDimitry Andric #include "llvm/Support/CodeGen.h"
684ba319b5SDimitry Andric #include "llvm/Support/Compiler.h"
694ba319b5SDimitry Andric #include "llvm/Support/Error.h"
70f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
714ba319b5SDimitry Andric #include "llvm/Support/ErrorOr.h"
72f785676fSDimitry Andric #include "llvm/Support/FileSystem.h"
732754fe60SDimitry Andric #include "llvm/Support/Host.h"
744ba319b5SDimitry Andric #include "llvm/Support/MathExtras.h"
754ba319b5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
762754fe60SDimitry Andric #include "llvm/Support/Path.h"
77f785676fSDimitry Andric #include "llvm/Support/Process.h"
784ba319b5SDimitry Andric #include "llvm/Support/Regex.h"
794ba319b5SDimitry Andric #include "llvm/Support/VersionTuple.h"
80*b5893f02SDimitry Andric #include "llvm/Support/VirtualFileSystem.h"
814ba319b5SDimitry Andric #include "llvm/Support/raw_ostream.h"
820623d748SDimitry Andric #include "llvm/Target/TargetOptions.h"
834ba319b5SDimitry Andric #include <algorithm>
8459d1ed5bSDimitry Andric #include <atomic>
854ba319b5SDimitry Andric #include <cassert>
864ba319b5SDimitry Andric #include <cstddef>
874ba319b5SDimitry Andric #include <cstring>
8859d1ed5bSDimitry Andric #include <memory>
894ba319b5SDimitry Andric #include <string>
904ba319b5SDimitry Andric #include <tuple>
914ba319b5SDimitry Andric #include <utility>
924ba319b5SDimitry Andric #include <vector>
934ba319b5SDimitry Andric
94f22ef01cSRoman Divacky using namespace clang;
954ba319b5SDimitry Andric using namespace driver;
964ba319b5SDimitry Andric using namespace options;
974ba319b5SDimitry Andric using namespace llvm::opt;
98f22ef01cSRoman Divacky
99dff0c46cSDimitry Andric //===----------------------------------------------------------------------===//
100dff0c46cSDimitry Andric // Initialization.
101dff0c46cSDimitry Andric //===----------------------------------------------------------------------===//
102dff0c46cSDimitry Andric
CompilerInvocationBase()103dff0c46cSDimitry Andric CompilerInvocationBase::CompilerInvocationBase()
1043861d79fSDimitry Andric : LangOpts(new LangOptions()), TargetOpts(new TargetOptions()),
1053861d79fSDimitry Andric DiagnosticOpts(new DiagnosticOptions()),
1063861d79fSDimitry Andric HeaderSearchOpts(new HeaderSearchOptions()),
1073861d79fSDimitry Andric PreprocessorOpts(new PreprocessorOptions()) {}
108dff0c46cSDimitry Andric
CompilerInvocationBase(const CompilerInvocationBase & X)109dff0c46cSDimitry Andric CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X)
11095ec533aSDimitry Andric : LangOpts(new LangOptions(*X.getLangOpts())),
1113861d79fSDimitry Andric TargetOpts(new TargetOptions(X.getTargetOpts())),
1123861d79fSDimitry Andric DiagnosticOpts(new DiagnosticOptions(X.getDiagnosticOpts())),
1133861d79fSDimitry Andric HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())),
1143861d79fSDimitry Andric PreprocessorOpts(new PreprocessorOptions(X.getPreprocessorOpts())) {}
115dff0c46cSDimitry Andric
1164ba319b5SDimitry Andric CompilerInvocationBase::~CompilerInvocationBase() = default;
11759d1ed5bSDimitry Andric
118dff0c46cSDimitry Andric //===----------------------------------------------------------------------===//
1193861d79fSDimitry Andric // Deserialization (from args)
120f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
121f22ef01cSRoman Divacky
getOptimizationLevel(ArgList & Args,InputKind IK,DiagnosticsEngine & Diags)1222754fe60SDimitry Andric static unsigned getOptimizationLevel(ArgList &Args, InputKind IK,
1236122f3e6SDimitry Andric DiagnosticsEngine &Diags) {
124*b5893f02SDimitry Andric unsigned DefaultOpt = llvm::CodeGenOpt::None;
125f37b6182SDimitry Andric if (IK.getLanguage() == InputKind::OpenCL && !Args.hasArg(OPT_cl_opt_disable))
126*b5893f02SDimitry Andric DefaultOpt = llvm::CodeGenOpt::Default;
1277ae0e2c9SDimitry Andric
1287ae0e2c9SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
1297ae0e2c9SDimitry Andric if (A->getOption().matches(options::OPT_O0))
130*b5893f02SDimitry Andric return llvm::CodeGenOpt::None;
1317ae0e2c9SDimitry Andric
132284c1978SDimitry Andric if (A->getOption().matches(options::OPT_Ofast))
133*b5893f02SDimitry Andric return llvm::CodeGenOpt::Aggressive;
134284c1978SDimitry Andric
1357ae0e2c9SDimitry Andric assert(A->getOption().matches(options::OPT_O));
1367ae0e2c9SDimitry Andric
137139f7f9bSDimitry Andric StringRef S(A->getValue());
1387ae0e2c9SDimitry Andric if (S == "s" || S == "z" || S.empty())
139*b5893f02SDimitry Andric return llvm::CodeGenOpt::Default;
1407ae0e2c9SDimitry Andric
14144290647SDimitry Andric if (S == "g")
142*b5893f02SDimitry Andric return llvm::CodeGenOpt::Less;
14344290647SDimitry Andric
144f785676fSDimitry Andric return getLastArgIntValue(Args, OPT_O, DefaultOpt, Diags);
1457ae0e2c9SDimitry Andric }
1467ae0e2c9SDimitry Andric
1477ae0e2c9SDimitry Andric return DefaultOpt;
1487ae0e2c9SDimitry Andric }
1497ae0e2c9SDimitry Andric
getOptimizationLevelSize(ArgList & Args)150284c1978SDimitry Andric static unsigned getOptimizationLevelSize(ArgList &Args) {
1517ae0e2c9SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
1527ae0e2c9SDimitry Andric if (A->getOption().matches(options::OPT_O)) {
1533861d79fSDimitry Andric switch (A->getValue()[0]) {
1547ae0e2c9SDimitry Andric default:
1557ae0e2c9SDimitry Andric return 0;
1567ae0e2c9SDimitry Andric case 's':
1577ae0e2c9SDimitry Andric return 1;
1587ae0e2c9SDimitry Andric case 'z':
1597ae0e2c9SDimitry Andric return 2;
1607ae0e2c9SDimitry Andric }
1617ae0e2c9SDimitry Andric }
1627ae0e2c9SDimitry Andric }
1637ae0e2c9SDimitry Andric return 0;
1647ae0e2c9SDimitry Andric }
1657ae0e2c9SDimitry Andric
addDiagnosticArgs(ArgList & Args,OptSpecifier Group,OptSpecifier GroupWithValue,std::vector<std::string> & Diagnostics)16659d1ed5bSDimitry Andric static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
16759d1ed5bSDimitry Andric OptSpecifier GroupWithValue,
16859d1ed5bSDimitry Andric std::vector<std::string> &Diagnostics) {
1694ba319b5SDimitry Andric for (auto *A : Args.filtered(Group)) {
1707ae0e2c9SDimitry Andric if (A->getOption().getKind() == Option::FlagClass) {
17159d1ed5bSDimitry Andric // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
17259d1ed5bSDimitry Andric // its name (minus the "W" or "R" at the beginning) to the warning list.
17359d1ed5bSDimitry Andric Diagnostics.push_back(A->getOption().getName().drop_front(1));
17459d1ed5bSDimitry Andric } else if (A->getOption().matches(GroupWithValue)) {
17559d1ed5bSDimitry Andric // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic group.
17659d1ed5bSDimitry Andric Diagnostics.push_back(A->getOption().getName().drop_front(1).rtrim("=-"));
1777ae0e2c9SDimitry Andric } else {
17859d1ed5bSDimitry Andric // Otherwise, add its value (for OPT_W_Joined and similar).
1794ba319b5SDimitry Andric for (const auto *Arg : A->getValues())
18097bc6c73SDimitry Andric Diagnostics.emplace_back(Arg);
1817ae0e2c9SDimitry Andric }
1827ae0e2c9SDimitry Andric }
1832754fe60SDimitry Andric }
1842754fe60SDimitry Andric
185*b5893f02SDimitry Andric // Parse the Static Analyzer configuration. If \p Diags is set to nullptr,
186*b5893f02SDimitry Andric // it won't verify the input.
187*b5893f02SDimitry Andric static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts,
188*b5893f02SDimitry Andric DiagnosticsEngine *Diags);
189*b5893f02SDimitry Andric
getAllNoBuiltinFuncValues(ArgList & Args,std::vector<std::string> & Funcs)190ea942507SDimitry Andric static void getAllNoBuiltinFuncValues(ArgList &Args,
191ea942507SDimitry Andric std::vector<std::string> &Funcs) {
192ea942507SDimitry Andric SmallVector<const char *, 8> Values;
193ea942507SDimitry Andric for (const auto &Arg : Args) {
194ea942507SDimitry Andric const Option &O = Arg->getOption();
195ea942507SDimitry Andric if (O.matches(options::OPT_fno_builtin_)) {
196ea942507SDimitry Andric const char *FuncName = Arg->getValue();
197ea942507SDimitry Andric if (Builtin::Context::isBuiltinFunc(FuncName))
198ea942507SDimitry Andric Values.push_back(FuncName);
199ea942507SDimitry Andric }
200ea942507SDimitry Andric }
201ea942507SDimitry Andric Funcs.insert(Funcs.end(), Values.begin(), Values.end());
202ea942507SDimitry Andric }
203ea942507SDimitry Andric
ParseAnalyzerArgs(AnalyzerOptions & Opts,ArgList & Args,DiagnosticsEngine & Diags)204dff0c46cSDimitry Andric static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
2056122f3e6SDimitry Andric DiagnosticsEngine &Diags) {
206dff0c46cSDimitry Andric bool Success = true;
207f22ef01cSRoman Divacky if (Arg *A = Args.getLastArg(OPT_analyzer_store)) {
2083861d79fSDimitry Andric StringRef Name = A->getValue();
209f22ef01cSRoman Divacky AnalysisStores Value = llvm::StringSwitch<AnalysisStores>(Name)
210f22ef01cSRoman Divacky #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) \
211f22ef01cSRoman Divacky .Case(CMDFLAG, NAME##Model)
2123861d79fSDimitry Andric #include "clang/StaticAnalyzer/Core/Analyses.def"
213f22ef01cSRoman Divacky .Default(NumStores);
214dff0c46cSDimitry Andric if (Value == NumStores) {
215f22ef01cSRoman Divacky Diags.Report(diag::err_drv_invalid_value)
216ffd1746dSEd Schouten << A->getAsString(Args) << Name;
217dff0c46cSDimitry Andric Success = false;
218dff0c46cSDimitry Andric } else {
219f22ef01cSRoman Divacky Opts.AnalysisStoreOpt = Value;
220f22ef01cSRoman Divacky }
221dff0c46cSDimitry Andric }
222f22ef01cSRoman Divacky
223f22ef01cSRoman Divacky if (Arg *A = Args.getLastArg(OPT_analyzer_constraints)) {
2243861d79fSDimitry Andric StringRef Name = A->getValue();
225f22ef01cSRoman Divacky AnalysisConstraints Value = llvm::StringSwitch<AnalysisConstraints>(Name)
226f22ef01cSRoman Divacky #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
227f22ef01cSRoman Divacky .Case(CMDFLAG, NAME##Model)
2283861d79fSDimitry Andric #include "clang/StaticAnalyzer/Core/Analyses.def"
229f22ef01cSRoman Divacky .Default(NumConstraints);
230dff0c46cSDimitry Andric if (Value == NumConstraints) {
231f22ef01cSRoman Divacky Diags.Report(diag::err_drv_invalid_value)
232ffd1746dSEd Schouten << A->getAsString(Args) << Name;
233dff0c46cSDimitry Andric Success = false;
234dff0c46cSDimitry Andric } else {
235f22ef01cSRoman Divacky Opts.AnalysisConstraintsOpt = Value;
236f22ef01cSRoman Divacky }
237dff0c46cSDimitry Andric }
238f22ef01cSRoman Divacky
239f22ef01cSRoman Divacky if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {
2403861d79fSDimitry Andric StringRef Name = A->getValue();
241f22ef01cSRoman Divacky AnalysisDiagClients Value = llvm::StringSwitch<AnalysisDiagClients>(Name)
242f785676fSDimitry Andric #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
243f22ef01cSRoman Divacky .Case(CMDFLAG, PD_##NAME)
2443861d79fSDimitry Andric #include "clang/StaticAnalyzer/Core/Analyses.def"
245f22ef01cSRoman Divacky .Default(NUM_ANALYSIS_DIAG_CLIENTS);
246dff0c46cSDimitry Andric if (Value == NUM_ANALYSIS_DIAG_CLIENTS) {
247f22ef01cSRoman Divacky Diags.Report(diag::err_drv_invalid_value)
248ffd1746dSEd Schouten << A->getAsString(Args) << Name;
249dff0c46cSDimitry Andric Success = false;
250dff0c46cSDimitry Andric } else {
251f22ef01cSRoman Divacky Opts.AnalysisDiagOpt = Value;
252f22ef01cSRoman Divacky }
253dff0c46cSDimitry Andric }
254f22ef01cSRoman Divacky
2556122f3e6SDimitry Andric if (Arg *A = Args.getLastArg(OPT_analyzer_purge)) {
2563861d79fSDimitry Andric StringRef Name = A->getValue();
2576122f3e6SDimitry Andric AnalysisPurgeMode Value = llvm::StringSwitch<AnalysisPurgeMode>(Name)
2586122f3e6SDimitry Andric #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
2596122f3e6SDimitry Andric .Case(CMDFLAG, NAME)
2603861d79fSDimitry Andric #include "clang/StaticAnalyzer/Core/Analyses.def"
2616122f3e6SDimitry Andric .Default(NumPurgeModes);
262dff0c46cSDimitry Andric if (Value == NumPurgeModes) {
2636122f3e6SDimitry Andric Diags.Report(diag::err_drv_invalid_value)
2646122f3e6SDimitry Andric << A->getAsString(Args) << Name;
265dff0c46cSDimitry Andric Success = false;
266dff0c46cSDimitry Andric } else {
2676122f3e6SDimitry Andric Opts.AnalysisPurgeOpt = Value;
2686122f3e6SDimitry Andric }
269dff0c46cSDimitry Andric }
270dff0c46cSDimitry Andric
271dff0c46cSDimitry Andric if (Arg *A = Args.getLastArg(OPT_analyzer_inlining_mode)) {
2723861d79fSDimitry Andric StringRef Name = A->getValue();
273dff0c46cSDimitry Andric AnalysisInliningMode Value = llvm::StringSwitch<AnalysisInliningMode>(Name)
274dff0c46cSDimitry Andric #define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
275dff0c46cSDimitry Andric .Case(CMDFLAG, NAME)
2763861d79fSDimitry Andric #include "clang/StaticAnalyzer/Core/Analyses.def"
277dff0c46cSDimitry Andric .Default(NumInliningModes);
278dff0c46cSDimitry Andric if (Value == NumInliningModes) {
279dff0c46cSDimitry Andric Diags.Report(diag::err_drv_invalid_value)
280dff0c46cSDimitry Andric << A->getAsString(Args) << Name;
281dff0c46cSDimitry Andric Success = false;
282dff0c46cSDimitry Andric } else {
283dff0c46cSDimitry Andric Opts.InliningMode = Value;
284dff0c46cSDimitry Andric }
285dff0c46cSDimitry Andric }
2866122f3e6SDimitry Andric
287dd6029ffSDimitry Andric Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help);
288*b5893f02SDimitry Andric Opts.ShowConfigOptionsList = Args.hasArg(OPT_analyzer_config_help);
28944290647SDimitry Andric Opts.ShowEnabledCheckerList = Args.hasArg(OPT_analyzer_list_enabled_checkers);
290*b5893f02SDimitry Andric Opts.ShouldEmitErrorsOnInvalidConfigValue =
291*b5893f02SDimitry Andric /* negated */!llvm::StringSwitch<bool>(
292*b5893f02SDimitry Andric Args.getLastArgValue(OPT_analyzer_config_compatibility_mode))
293*b5893f02SDimitry Andric .Case("true", true)
294*b5893f02SDimitry Andric .Case("false", false)
295*b5893f02SDimitry Andric .Default(false);
29639d628a0SDimitry Andric Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks);
29739d628a0SDimitry Andric
2983861d79fSDimitry Andric Opts.visualizeExplodedGraphWithGraphViz =
2993861d79fSDimitry Andric Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
300*b5893f02SDimitry Andric Opts.DumpExplodedGraphTo = Args.getLastArgValue(OPT_analyzer_dump_egraph);
301dff0c46cSDimitry Andric Opts.NoRetryExhausted = Args.hasArg(OPT_analyzer_disable_retry_exhausted);
302f22ef01cSRoman Divacky Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers);
303f22ef01cSRoman Divacky Opts.AnalyzerDisplayProgress = Args.hasArg(OPT_analyzer_display_progress);
304f22ef01cSRoman Divacky Opts.AnalyzeNestedBlocks =
305f22ef01cSRoman Divacky Args.hasArg(OPT_analyzer_opt_analyze_nested_blocks);
306f22ef01cSRoman Divacky Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function);
307e580952dSDimitry Andric Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG);
308f22ef01cSRoman Divacky Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
309f785676fSDimitry Andric Opts.maxBlockVisitOnPath =
310f785676fSDimitry Andric getLastArgIntValue(Args, OPT_analyzer_max_loop, 4, Diags);
311dff0c46cSDimitry Andric Opts.PrintStats = Args.hasArg(OPT_analyzer_stats);
312dff0c46cSDimitry Andric Opts.InlineMaxStackDepth =
313f785676fSDimitry Andric getLastArgIntValue(Args, OPT_analyzer_inline_max_stack_depth,
314dff0c46cSDimitry Andric Opts.InlineMaxStackDepth, Diags);
3152754fe60SDimitry Andric
3162754fe60SDimitry Andric Opts.CheckersControlList.clear();
31797bc6c73SDimitry Andric for (const Arg *A :
31897bc6c73SDimitry Andric Args.filtered(OPT_analyzer_checker, OPT_analyzer_disable_checker)) {
3192754fe60SDimitry Andric A->claim();
3202754fe60SDimitry Andric bool enable = (A->getOption().getID() == OPT_analyzer_checker);
321dd6029ffSDimitry Andric // We can have a list of comma separated checker names, e.g:
322dd6029ffSDimitry Andric // '-analyzer-checker=cocoa,unix'
3233861d79fSDimitry Andric StringRef checkerList = A->getValue();
3246122f3e6SDimitry Andric SmallVector<StringRef, 4> checkers;
325dd6029ffSDimitry Andric checkerList.split(checkers, ",");
3264ba319b5SDimitry Andric for (auto checker : checkers)
32797bc6c73SDimitry Andric Opts.CheckersControlList.emplace_back(checker, enable);
3282754fe60SDimitry Andric }
329dff0c46cSDimitry Andric
3303861d79fSDimitry Andric // Go through the analyzer configuration options.
3314ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_analyzer_config)) {
332*b5893f02SDimitry Andric
3333861d79fSDimitry Andric // We can have a list of comma separated config names, e.g:
3343861d79fSDimitry Andric // '-analyzer-config key1=val1,key2=val2'
3353861d79fSDimitry Andric StringRef configList = A->getValue();
3363861d79fSDimitry Andric SmallVector<StringRef, 4> configVals;
3373861d79fSDimitry Andric configList.split(configVals, ",");
3384ba319b5SDimitry Andric for (const auto &configVal : configVals) {
3393861d79fSDimitry Andric StringRef key, val;
3404ba319b5SDimitry Andric std::tie(key, val) = configVal.split("=");
3413861d79fSDimitry Andric if (val.empty()) {
3423861d79fSDimitry Andric Diags.Report(SourceLocation(),
3434ba319b5SDimitry Andric diag::err_analyzer_config_no_value) << configVal;
3443861d79fSDimitry Andric Success = false;
3453861d79fSDimitry Andric break;
3463861d79fSDimitry Andric }
3473861d79fSDimitry Andric if (val.find('=') != StringRef::npos) {
3483861d79fSDimitry Andric Diags.Report(SourceLocation(),
3493861d79fSDimitry Andric diag::err_analyzer_config_multiple_values)
3504ba319b5SDimitry Andric << configVal;
3513861d79fSDimitry Andric Success = false;
3523861d79fSDimitry Andric break;
3533861d79fSDimitry Andric }
354*b5893f02SDimitry Andric
355*b5893f02SDimitry Andric // TODO: Check checker options too, possibly in CheckerRegistry.
356*b5893f02SDimitry Andric // Leave unknown non-checker configs unclaimed.
357*b5893f02SDimitry Andric if (!key.contains(":") && Opts.isUnknownAnalyzerConfig(key)) {
358*b5893f02SDimitry Andric if (Opts.ShouldEmitErrorsOnInvalidConfigValue)
359*b5893f02SDimitry Andric Diags.Report(diag::err_analyzer_config_unknown) << key;
360*b5893f02SDimitry Andric continue;
361*b5893f02SDimitry Andric }
362*b5893f02SDimitry Andric
363*b5893f02SDimitry Andric A->claim();
3643861d79fSDimitry Andric Opts.Config[key] = val;
3653861d79fSDimitry Andric }
3663861d79fSDimitry Andric }
3673861d79fSDimitry Andric
368*b5893f02SDimitry Andric if (Opts.ShouldEmitErrorsOnInvalidConfigValue)
369*b5893f02SDimitry Andric parseAnalyzerConfigs(Opts, &Diags);
370*b5893f02SDimitry Andric else
371*b5893f02SDimitry Andric parseAnalyzerConfigs(Opts, nullptr);
372*b5893f02SDimitry Andric
3734ba319b5SDimitry Andric llvm::raw_string_ostream os(Opts.FullCompilerInvocation);
3744ba319b5SDimitry Andric for (unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) {
3754ba319b5SDimitry Andric if (i != 0)
3764ba319b5SDimitry Andric os << " ";
3774ba319b5SDimitry Andric os << Args.getArgString(i);
3784ba319b5SDimitry Andric }
3794ba319b5SDimitry Andric os.flush();
3804ba319b5SDimitry Andric
381dff0c46cSDimitry Andric return Success;
382f22ef01cSRoman Divacky }
383f22ef01cSRoman Divacky
getStringOption(AnalyzerOptions::ConfigTable & Config,StringRef OptionName,StringRef DefaultVal)384*b5893f02SDimitry Andric static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config,
385*b5893f02SDimitry Andric StringRef OptionName, StringRef DefaultVal) {
386*b5893f02SDimitry Andric return Config.insert({OptionName, DefaultVal}).first->second;
387*b5893f02SDimitry Andric }
388*b5893f02SDimitry Andric
initOption(AnalyzerOptions::ConfigTable & Config,DiagnosticsEngine * Diags,StringRef & OptionField,StringRef Name,StringRef DefaultVal)389*b5893f02SDimitry Andric static void initOption(AnalyzerOptions::ConfigTable &Config,
390*b5893f02SDimitry Andric DiagnosticsEngine *Diags,
391*b5893f02SDimitry Andric StringRef &OptionField, StringRef Name,
392*b5893f02SDimitry Andric StringRef DefaultVal) {
393*b5893f02SDimitry Andric // String options may be known to invalid (e.g. if the expected string is a
394*b5893f02SDimitry Andric // file name, but the file does not exist), those will have to be checked in
395*b5893f02SDimitry Andric // parseConfigs.
396*b5893f02SDimitry Andric OptionField = getStringOption(Config, Name, DefaultVal);
397*b5893f02SDimitry Andric }
398*b5893f02SDimitry Andric
initOption(AnalyzerOptions::ConfigTable & Config,DiagnosticsEngine * Diags,bool & OptionField,StringRef Name,bool DefaultVal)399*b5893f02SDimitry Andric static void initOption(AnalyzerOptions::ConfigTable &Config,
400*b5893f02SDimitry Andric DiagnosticsEngine *Diags,
401*b5893f02SDimitry Andric bool &OptionField, StringRef Name, bool DefaultVal) {
402*b5893f02SDimitry Andric auto PossiblyInvalidVal = llvm::StringSwitch<Optional<bool>>(
403*b5893f02SDimitry Andric getStringOption(Config, Name, (DefaultVal ? "true" : "false")))
404*b5893f02SDimitry Andric .Case("true", true)
405*b5893f02SDimitry Andric .Case("false", false)
406*b5893f02SDimitry Andric .Default(None);
407*b5893f02SDimitry Andric
408*b5893f02SDimitry Andric if (!PossiblyInvalidVal) {
409*b5893f02SDimitry Andric if (Diags)
410*b5893f02SDimitry Andric Diags->Report(diag::err_analyzer_config_invalid_input)
411*b5893f02SDimitry Andric << Name << "a boolean";
412*b5893f02SDimitry Andric else
413*b5893f02SDimitry Andric OptionField = DefaultVal;
414*b5893f02SDimitry Andric } else
415*b5893f02SDimitry Andric OptionField = PossiblyInvalidVal.getValue();
416*b5893f02SDimitry Andric }
417*b5893f02SDimitry Andric
initOption(AnalyzerOptions::ConfigTable & Config,DiagnosticsEngine * Diags,unsigned & OptionField,StringRef Name,unsigned DefaultVal)418*b5893f02SDimitry Andric static void initOption(AnalyzerOptions::ConfigTable &Config,
419*b5893f02SDimitry Andric DiagnosticsEngine *Diags,
420*b5893f02SDimitry Andric unsigned &OptionField, StringRef Name,
421*b5893f02SDimitry Andric unsigned DefaultVal) {
422*b5893f02SDimitry Andric
423*b5893f02SDimitry Andric OptionField = DefaultVal;
424*b5893f02SDimitry Andric bool HasFailed = getStringOption(Config, Name, std::to_string(DefaultVal))
425*b5893f02SDimitry Andric .getAsInteger(10, OptionField);
426*b5893f02SDimitry Andric if (Diags && HasFailed)
427*b5893f02SDimitry Andric Diags->Report(diag::err_analyzer_config_invalid_input)
428*b5893f02SDimitry Andric << Name << "an unsigned";
429*b5893f02SDimitry Andric }
430*b5893f02SDimitry Andric
parseAnalyzerConfigs(AnalyzerOptions & AnOpts,DiagnosticsEngine * Diags)431*b5893f02SDimitry Andric static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts,
432*b5893f02SDimitry Andric DiagnosticsEngine *Diags) {
433*b5893f02SDimitry Andric // TODO: There's no need to store the entire configtable, it'd be plenty
434*b5893f02SDimitry Andric // enough tostore checker options.
435*b5893f02SDimitry Andric
436*b5893f02SDimitry Andric #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
437*b5893f02SDimitry Andric initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, DEFAULT_VAL);
438*b5893f02SDimitry Andric
439*b5893f02SDimitry Andric #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
440*b5893f02SDimitry Andric SHALLOW_VAL, DEEP_VAL) \
441*b5893f02SDimitry Andric switch (AnOpts.getUserMode()) { \
442*b5893f02SDimitry Andric case UMK_Shallow: \
443*b5893f02SDimitry Andric initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, SHALLOW_VAL); \
444*b5893f02SDimitry Andric break; \
445*b5893f02SDimitry Andric case UMK_Deep: \
446*b5893f02SDimitry Andric initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, DEEP_VAL); \
447*b5893f02SDimitry Andric break; \
448*b5893f02SDimitry Andric } \
449*b5893f02SDimitry Andric
450*b5893f02SDimitry Andric #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
451*b5893f02SDimitry Andric #undef ANALYZER_OPTION
452*b5893f02SDimitry Andric #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
453*b5893f02SDimitry Andric
454*b5893f02SDimitry Andric // At this point, AnalyzerOptions is configured. Let's validate some options.
455*b5893f02SDimitry Andric
456*b5893f02SDimitry Andric if (!Diags)
457*b5893f02SDimitry Andric return;
458*b5893f02SDimitry Andric
459*b5893f02SDimitry Andric if (!AnOpts.CTUDir.empty() && !llvm::sys::fs::is_directory(AnOpts.CTUDir))
460*b5893f02SDimitry Andric Diags->Report(diag::err_analyzer_config_invalid_input) << "ctu-dir"
461*b5893f02SDimitry Andric << "a filename";
462*b5893f02SDimitry Andric
463*b5893f02SDimitry Andric if (!AnOpts.ModelPath.empty() &&
464*b5893f02SDimitry Andric !llvm::sys::fs::is_directory(AnOpts.ModelPath))
465*b5893f02SDimitry Andric Diags->Report(diag::err_analyzer_config_invalid_input) << "model-path"
466*b5893f02SDimitry Andric << "a filename";
467*b5893f02SDimitry Andric }
468*b5893f02SDimitry Andric
ParseMigratorArgs(MigratorOptions & Opts,ArgList & Args)469dff0c46cSDimitry Andric static bool ParseMigratorArgs(MigratorOptions &Opts, ArgList &Args) {
470dff0c46cSDimitry Andric Opts.NoNSAllocReallocError = Args.hasArg(OPT_migrator_no_nsalloc_error);
471dff0c46cSDimitry Andric Opts.NoFinalizeRemoval = Args.hasArg(OPT_migrator_no_finalize_removal);
472dff0c46cSDimitry Andric return true;
473dff0c46cSDimitry Andric }
474dff0c46cSDimitry Andric
ParseCommentArgs(CommentOptions & Opts,ArgList & Args)475139f7f9bSDimitry Andric static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) {
476139f7f9bSDimitry Andric Opts.BlockCommandNames = Args.getAllArgValues(OPT_fcomment_block_commands);
477284c1978SDimitry Andric Opts.ParseAllComments = Args.hasArg(OPT_fparse_all_comments);
478139f7f9bSDimitry Andric }
479139f7f9bSDimitry Andric
getCodeModel(ArgList & Args,DiagnosticsEngine & Diags)48059d1ed5bSDimitry Andric static StringRef getCodeModel(ArgList &Args, DiagnosticsEngine &Diags) {
48159d1ed5bSDimitry Andric if (Arg *A = Args.getLastArg(OPT_mcode_model)) {
48259d1ed5bSDimitry Andric StringRef Value = A->getValue();
48359d1ed5bSDimitry Andric if (Value == "small" || Value == "kernel" || Value == "medium" ||
484*b5893f02SDimitry Andric Value == "large" || Value == "tiny")
48559d1ed5bSDimitry Andric return Value;
48659d1ed5bSDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value;
48759d1ed5bSDimitry Andric }
48859d1ed5bSDimitry Andric return "default";
48959d1ed5bSDimitry Andric }
49059d1ed5bSDimitry Andric
getRelocModel(ArgList & Args,DiagnosticsEngine & Diags)4914ba319b5SDimitry Andric static llvm::Reloc::Model getRelocModel(ArgList &Args,
4924ba319b5SDimitry Andric DiagnosticsEngine &Diags) {
49320e90f04SDimitry Andric if (Arg *A = Args.getLastArg(OPT_mrelocation_model)) {
49420e90f04SDimitry Andric StringRef Value = A->getValue();
4954ba319b5SDimitry Andric auto RM = llvm::StringSwitch<llvm::Optional<llvm::Reloc::Model>>(Value)
4964ba319b5SDimitry Andric .Case("static", llvm::Reloc::Static)
4974ba319b5SDimitry Andric .Case("pic", llvm::Reloc::PIC_)
4984ba319b5SDimitry Andric .Case("ropi", llvm::Reloc::ROPI)
4994ba319b5SDimitry Andric .Case("rwpi", llvm::Reloc::RWPI)
5004ba319b5SDimitry Andric .Case("ropi-rwpi", llvm::Reloc::ROPI_RWPI)
5014ba319b5SDimitry Andric .Case("dynamic-no-pic", llvm::Reloc::DynamicNoPIC)
5024ba319b5SDimitry Andric .Default(None);
5034ba319b5SDimitry Andric if (RM.hasValue())
5044ba319b5SDimitry Andric return *RM;
50520e90f04SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value;
50620e90f04SDimitry Andric }
5074ba319b5SDimitry Andric return llvm::Reloc::PIC_;
50820e90f04SDimitry Andric }
50920e90f04SDimitry Andric
5104ba319b5SDimitry Andric /// Create a new Regex instance out of the string value in \p RpassArg.
51159d1ed5bSDimitry Andric /// It returns a pointer to the newly generated Regex instance.
51259d1ed5bSDimitry Andric static std::shared_ptr<llvm::Regex>
GenerateOptimizationRemarkRegex(DiagnosticsEngine & Diags,ArgList & Args,Arg * RpassArg)51359d1ed5bSDimitry Andric GenerateOptimizationRemarkRegex(DiagnosticsEngine &Diags, ArgList &Args,
51459d1ed5bSDimitry Andric Arg *RpassArg) {
51559d1ed5bSDimitry Andric StringRef Val = RpassArg->getValue();
51659d1ed5bSDimitry Andric std::string RegexError;
51759d1ed5bSDimitry Andric std::shared_ptr<llvm::Regex> Pattern = std::make_shared<llvm::Regex>(Val);
51859d1ed5bSDimitry Andric if (!Pattern->isValid(RegexError)) {
51959d1ed5bSDimitry Andric Diags.Report(diag::err_drv_optimization_remark_pattern)
52059d1ed5bSDimitry Andric << RegexError << RpassArg->getAsString(Args);
52159d1ed5bSDimitry Andric Pattern.reset();
52259d1ed5bSDimitry Andric }
52359d1ed5bSDimitry Andric return Pattern;
52459d1ed5bSDimitry Andric }
52559d1ed5bSDimitry Andric
parseDiagnosticLevelMask(StringRef FlagName,const std::vector<std::string> & Levels,DiagnosticsEngine * Diags,DiagnosticLevelMask & M)5268f0fd8f6SDimitry Andric static bool parseDiagnosticLevelMask(StringRef FlagName,
5278f0fd8f6SDimitry Andric const std::vector<std::string> &Levels,
5288f0fd8f6SDimitry Andric DiagnosticsEngine *Diags,
5298f0fd8f6SDimitry Andric DiagnosticLevelMask &M) {
5308f0fd8f6SDimitry Andric bool Success = true;
5318f0fd8f6SDimitry Andric for (const auto &Level : Levels) {
5328f0fd8f6SDimitry Andric DiagnosticLevelMask const PM =
5338f0fd8f6SDimitry Andric llvm::StringSwitch<DiagnosticLevelMask>(Level)
5348f0fd8f6SDimitry Andric .Case("note", DiagnosticLevelMask::Note)
5358f0fd8f6SDimitry Andric .Case("remark", DiagnosticLevelMask::Remark)
5368f0fd8f6SDimitry Andric .Case("warning", DiagnosticLevelMask::Warning)
5378f0fd8f6SDimitry Andric .Case("error", DiagnosticLevelMask::Error)
5388f0fd8f6SDimitry Andric .Default(DiagnosticLevelMask::None);
5398f0fd8f6SDimitry Andric if (PM == DiagnosticLevelMask::None) {
5408f0fd8f6SDimitry Andric Success = false;
5418f0fd8f6SDimitry Andric if (Diags)
5428f0fd8f6SDimitry Andric Diags->Report(diag::err_drv_invalid_value) << FlagName << Level;
5438f0fd8f6SDimitry Andric }
5448f0fd8f6SDimitry Andric M = M | PM;
5458f0fd8f6SDimitry Andric }
5468f0fd8f6SDimitry Andric return Success;
5478f0fd8f6SDimitry Andric }
5488f0fd8f6SDimitry Andric
parseSanitizerKinds(StringRef FlagName,const std::vector<std::string> & Sanitizers,DiagnosticsEngine & Diags,SanitizerSet & S)54939d628a0SDimitry Andric static void parseSanitizerKinds(StringRef FlagName,
55039d628a0SDimitry Andric const std::vector<std::string> &Sanitizers,
55139d628a0SDimitry Andric DiagnosticsEngine &Diags, SanitizerSet &S) {
55239d628a0SDimitry Andric for (const auto &Sanitizer : Sanitizers) {
55333956c43SDimitry Andric SanitizerMask K = parseSanitizerValue(Sanitizer, /*AllowGroups=*/false);
55433956c43SDimitry Andric if (K == 0)
55539d628a0SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
55639d628a0SDimitry Andric else
55739d628a0SDimitry Andric S.set(K, true);
55839d628a0SDimitry Andric }
55939d628a0SDimitry Andric }
56039d628a0SDimitry Andric
parseXRayInstrumentationBundle(StringRef FlagName,StringRef Bundle,ArgList & Args,DiagnosticsEngine & D,XRayInstrSet & S)5614ba319b5SDimitry Andric static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle,
5624ba319b5SDimitry Andric ArgList &Args, DiagnosticsEngine &D,
5634ba319b5SDimitry Andric XRayInstrSet &S) {
5644ba319b5SDimitry Andric llvm::SmallVector<StringRef, 2> BundleParts;
5654ba319b5SDimitry Andric llvm::SplitString(Bundle, BundleParts, ",");
5664ba319b5SDimitry Andric for (const auto B : BundleParts) {
5674ba319b5SDimitry Andric auto Mask = parseXRayInstrValue(B);
5684ba319b5SDimitry Andric if (Mask == XRayInstrKind::None)
5694ba319b5SDimitry Andric if (B != "none")
5704ba319b5SDimitry Andric D.Report(diag::err_drv_invalid_value) << FlagName << Bundle;
5714ba319b5SDimitry Andric else
5724ba319b5SDimitry Andric S.Mask = Mask;
5734ba319b5SDimitry Andric else if (Mask == XRayInstrKind::All)
5744ba319b5SDimitry Andric S.Mask = Mask;
5754ba319b5SDimitry Andric else
5764ba319b5SDimitry Andric S.set(Mask, true);
5774ba319b5SDimitry Andric }
5784ba319b5SDimitry Andric }
5794ba319b5SDimitry Andric
580e7145dcbSDimitry Andric // Set the profile kind for fprofile-instrument.
setPGOInstrumentor(CodeGenOptions & Opts,ArgList & Args,DiagnosticsEngine & Diags)581e7145dcbSDimitry Andric static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args,
582e7145dcbSDimitry Andric DiagnosticsEngine &Diags) {
583e7145dcbSDimitry Andric Arg *A = Args.getLastArg(OPT_fprofile_instrument_EQ);
584e7145dcbSDimitry Andric if (A == nullptr)
585e7145dcbSDimitry Andric return;
586e7145dcbSDimitry Andric StringRef S = A->getValue();
587e7145dcbSDimitry Andric unsigned I = llvm::StringSwitch<unsigned>(S)
588e7145dcbSDimitry Andric .Case("none", CodeGenOptions::ProfileNone)
589e7145dcbSDimitry Andric .Case("clang", CodeGenOptions::ProfileClangInstr)
590e7145dcbSDimitry Andric .Case("llvm", CodeGenOptions::ProfileIRInstr)
591e7145dcbSDimitry Andric .Default(~0U);
592e7145dcbSDimitry Andric if (I == ~0U) {
593e7145dcbSDimitry Andric Diags.Report(diag::err_drv_invalid_pgo_instrumentor) << A->getAsString(Args)
594e7145dcbSDimitry Andric << S;
595e7145dcbSDimitry Andric return;
596e7145dcbSDimitry Andric }
5974ba319b5SDimitry Andric auto Instrumentor = static_cast<CodeGenOptions::ProfileInstrKind>(I);
598e7145dcbSDimitry Andric Opts.setProfileInstr(Instrumentor);
599e7145dcbSDimitry Andric }
600e7145dcbSDimitry Andric
601e7145dcbSDimitry Andric // Set the profile kind using fprofile-instrument-use-path.
setPGOUseInstrumentor(CodeGenOptions & Opts,const Twine & ProfileName)602e7145dcbSDimitry Andric static void setPGOUseInstrumentor(CodeGenOptions &Opts,
603e7145dcbSDimitry Andric const Twine &ProfileName) {
604e7145dcbSDimitry Andric auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName);
605e7145dcbSDimitry Andric // In error, return silently and let Clang PGOUse report the error message.
606e7145dcbSDimitry Andric if (auto E = ReaderOrErr.takeError()) {
607e7145dcbSDimitry Andric llvm::consumeError(std::move(E));
608e7145dcbSDimitry Andric Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
609e7145dcbSDimitry Andric return;
610e7145dcbSDimitry Andric }
611e7145dcbSDimitry Andric std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader =
612e7145dcbSDimitry Andric std::move(ReaderOrErr.get());
613e7145dcbSDimitry Andric if (PGOReader->isIRLevelProfile())
614e7145dcbSDimitry Andric Opts.setProfileUse(CodeGenOptions::ProfileIRInstr);
615e7145dcbSDimitry Andric else
616e7145dcbSDimitry Andric Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
617e7145dcbSDimitry Andric }
618e7145dcbSDimitry Andric
ParseCodeGenArgs(CodeGenOptions & Opts,ArgList & Args,InputKind IK,DiagnosticsEngine & Diags,const TargetOptions & TargetOpts,const FrontendOptions & FrontendOpts)619dff0c46cSDimitry Andric static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
620f9688ceeSEd Maste DiagnosticsEngine &Diags,
6214ba319b5SDimitry Andric const TargetOptions &TargetOpts,
6224ba319b5SDimitry Andric const FrontendOptions &FrontendOpts) {
623dff0c46cSDimitry Andric bool Success = true;
6240623d748SDimitry Andric llvm::Triple Triple = llvm::Triple(TargetOpts.Triple);
6252754fe60SDimitry Andric
62639d628a0SDimitry Andric unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
627f785676fSDimitry Andric // TODO: This could be done in Driver
628f785676fSDimitry Andric unsigned MaxOptLevel = 3;
62939d628a0SDimitry Andric if (OptimizationLevel > MaxOptLevel) {
63039d628a0SDimitry Andric // If the optimization level is not supported, fall back on the default
63139d628a0SDimitry Andric // optimization
632f785676fSDimitry Andric Diags.Report(diag::warn_drv_optimization_value)
633f785676fSDimitry Andric << Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
63439d628a0SDimitry Andric OptimizationLevel = MaxOptLevel;
635f22ef01cSRoman Divacky }
63639d628a0SDimitry Andric Opts.OptimizationLevel = OptimizationLevel;
637f22ef01cSRoman Divacky
63844290647SDimitry Andric // At O0 we want to fully disable inlining outside of cases marked with
63944290647SDimitry Andric // 'alwaysinline' that are required for correctness.
64044290647SDimitry Andric Opts.setInlining((Opts.OptimizationLevel == 0)
64144290647SDimitry Andric ? CodeGenOptions::OnlyAlwaysInlining
64244290647SDimitry Andric : CodeGenOptions::NormalInlining);
64344290647SDimitry Andric // Explicit inlining flags can disable some or all inlining even at
64444290647SDimitry Andric // optimization levels above zero.
64544290647SDimitry Andric if (Arg *InlineArg = Args.getLastArg(
64644290647SDimitry Andric options::OPT_finline_functions, options::OPT_finline_hint_functions,
64744290647SDimitry Andric options::OPT_fno_inline_functions, options::OPT_fno_inline)) {
64844290647SDimitry Andric if (Opts.OptimizationLevel > 0) {
649e7145dcbSDimitry Andric const Option &InlineOpt = InlineArg->getOption();
650e7145dcbSDimitry Andric if (InlineOpt.matches(options::OPT_finline_functions))
651e7145dcbSDimitry Andric Opts.setInlining(CodeGenOptions::NormalInlining);
652e7145dcbSDimitry Andric else if (InlineOpt.matches(options::OPT_finline_hint_functions))
653e7145dcbSDimitry Andric Opts.setInlining(CodeGenOptions::OnlyHintInlining);
654e7145dcbSDimitry Andric else
655e7145dcbSDimitry Andric Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
656e7145dcbSDimitry Andric }
65744290647SDimitry Andric }
65844290647SDimitry Andric
65944290647SDimitry Andric Opts.ExperimentalNewPassManager = Args.hasFlag(
66044290647SDimitry Andric OPT_fexperimental_new_pass_manager, OPT_fno_experimental_new_pass_manager,
6614ba319b5SDimitry Andric /* Default */ ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER);
662f22ef01cSRoman Divacky
663a580b014SDimitry Andric Opts.DebugPassManager =
664a580b014SDimitry Andric Args.hasFlag(OPT_fdebug_pass_manager, OPT_fno_debug_pass_manager,
665a580b014SDimitry Andric /* Default */ false);
666a580b014SDimitry Andric
66733956c43SDimitry Andric if (Arg *A = Args.getLastArg(OPT_fveclib)) {
66833956c43SDimitry Andric StringRef Name = A->getValue();
66933956c43SDimitry Andric if (Name == "Accelerate")
67033956c43SDimitry Andric Opts.setVecLib(CodeGenOptions::Accelerate);
67144290647SDimitry Andric else if (Name == "SVML")
67244290647SDimitry Andric Opts.setVecLib(CodeGenOptions::SVML);
67333956c43SDimitry Andric else if (Name == "none")
67433956c43SDimitry Andric Opts.setVecLib(CodeGenOptions::NoLibrary);
67533956c43SDimitry Andric else
67633956c43SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
67733956c43SDimitry Andric }
67833956c43SDimitry Andric
6790623d748SDimitry Andric if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {
680ea942507SDimitry Andric unsigned Val =
681ea942507SDimitry Andric llvm::StringSwitch<unsigned>(A->getValue())
682e7145dcbSDimitry Andric .Case("line-tables-only", codegenoptions::DebugLineTablesOnly)
683*b5893f02SDimitry Andric .Case("line-directives-only", codegenoptions::DebugDirectivesOnly)
684e7145dcbSDimitry Andric .Case("limited", codegenoptions::LimitedDebugInfo)
685e7145dcbSDimitry Andric .Case("standalone", codegenoptions::FullDebugInfo)
686ea942507SDimitry Andric .Default(~0U);
687ea942507SDimitry Andric if (Val == ~0U)
688ea942507SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
689ea942507SDimitry Andric << A->getValue();
690ea942507SDimitry Andric else
691e7145dcbSDimitry Andric Opts.setDebugInfo(static_cast<codegenoptions::DebugInfoKind>(Val));
6927ae0e2c9SDimitry Andric }
6930623d748SDimitry Andric if (Arg *A = Args.getLastArg(OPT_debugger_tuning_EQ)) {
694ea942507SDimitry Andric unsigned Val = llvm::StringSwitch<unsigned>(A->getValue())
695e7145dcbSDimitry Andric .Case("gdb", unsigned(llvm::DebuggerKind::GDB))
696e7145dcbSDimitry Andric .Case("lldb", unsigned(llvm::DebuggerKind::LLDB))
697e7145dcbSDimitry Andric .Case("sce", unsigned(llvm::DebuggerKind::SCE))
698ea942507SDimitry Andric .Default(~0U);
699ea942507SDimitry Andric if (Val == ~0U)
700ea942507SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
701ea942507SDimitry Andric << A->getValue();
702ea942507SDimitry Andric else
703e7145dcbSDimitry Andric Opts.setDebuggerTuning(static_cast<llvm::DebuggerKind>(Val));
7040623d748SDimitry Andric }
7050623d748SDimitry Andric Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 0, Diags);
7063861d79fSDimitry Andric Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info);
7070623d748SDimitry Andric Opts.EmitCodeView = Args.hasArg(OPT_gcodeview);
708*b5893f02SDimitry Andric Opts.CodeViewGHash = Args.hasArg(OPT_gcodeview_ghash);
70920e90f04SDimitry Andric Opts.MacroDebugInfo = Args.hasArg(OPT_debug_info_macro);
710e7145dcbSDimitry Andric Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables);
711e7145dcbSDimitry Andric Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std);
712139f7f9bSDimitry Andric Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
71344290647SDimitry Andric Opts.SplitDwarfInlining = !Args.hasArg(OPT_fno_split_dwarf_inlining);
714*b5893f02SDimitry Andric
715*b5893f02SDimitry Andric if (Arg *A =
716*b5893f02SDimitry Andric Args.getLastArg(OPT_enable_split_dwarf, OPT_enable_split_dwarf_EQ)) {
717*b5893f02SDimitry Andric if (A->getOption().matches(options::OPT_enable_split_dwarf)) {
718*b5893f02SDimitry Andric Opts.setSplitDwarfMode(CodeGenOptions::SplitFileFission);
719*b5893f02SDimitry Andric } else {
720*b5893f02SDimitry Andric StringRef Name = A->getValue();
721*b5893f02SDimitry Andric if (Name == "single")
722*b5893f02SDimitry Andric Opts.setSplitDwarfMode(CodeGenOptions::SingleFileFission);
723*b5893f02SDimitry Andric else if (Name == "split")
724*b5893f02SDimitry Andric Opts.setSplitDwarfMode(CodeGenOptions::SplitFileFission);
725*b5893f02SDimitry Andric else
726*b5893f02SDimitry Andric Diags.Report(diag::err_drv_invalid_value)
727*b5893f02SDimitry Andric << A->getAsString(Args) << Name;
728*b5893f02SDimitry Andric }
729*b5893f02SDimitry Andric }
730*b5893f02SDimitry Andric
7310623d748SDimitry Andric Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs);
7329a199699SDimitry Andric Opts.DebugExplicitImport = Args.hasArg(OPT_dwarf_explicit_import);
7339a199699SDimitry Andric Opts.DebugFwdTemplateParams = Args.hasArg(OPT_debug_forward_template_params);
7344ba319b5SDimitry Andric Opts.EmbedSource = Args.hasArg(OPT_gembed_source);
7350623d748SDimitry Andric
7360623d748SDimitry Andric for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ))
7370623d748SDimitry Andric Opts.DebugPrefixMap.insert(StringRef(Arg).split('='));
7387ae0e2c9SDimitry Andric
73933956c43SDimitry Andric if (const Arg *A =
74033956c43SDimitry Andric Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists))
74133956c43SDimitry Andric Opts.EmitLLVMUseLists = A->getOption().getID() == OPT_emit_llvm_uselists;
74233956c43SDimitry Andric
7430623d748SDimitry Andric Opts.DisableLLVMPasses = Args.hasArg(OPT_disable_llvm_passes);
74424e2fe98SDimitry Andric Opts.DisableLifetimeMarkers = Args.hasArg(OPT_disable_lifetimemarkers);
745302affcbSDimitry Andric Opts.DisableO0ImplyOptNone = Args.hasArg(OPT_disable_O0_optnone);
746f22ef01cSRoman Divacky Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone);
747*b5893f02SDimitry Andric Opts.IndirectTlsSegRefs = Args.hasArg(OPT_mno_tls_direct_seg_refs);
7483b0f4066SDimitry Andric Opts.ForbidGuardVariables = Args.hasArg(OPT_fforbid_guard_variables);
74917a519f9SDimitry Andric Opts.UseRegisterSizedBitfieldAccess = Args.hasArg(
75017a519f9SDimitry Andric OPT_fuse_register_sized_bitfield_access);
7512754fe60SDimitry Andric Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing);
752f785676fSDimitry Andric Opts.StructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa);
7539a199699SDimitry Andric Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&
7549a199699SDimitry Andric Args.hasArg(OPT_new_struct_path_tbaa);
7559a199699SDimitry Andric Opts.FineGrainedBitfieldAccesses =
7569a199699SDimitry Andric Args.hasFlag(OPT_ffine_grained_bitfield_accesses,
7579a199699SDimitry Andric OPT_fno_fine_grained_bitfield_accesses, false);
758f22ef01cSRoman Divacky Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags);
759*b5893f02SDimitry Andric Opts.RecordCommandLine = Args.getLastArgValue(OPT_record_command_line);
7606ccc06f6SDimitry Andric Opts.MergeAllConstants = Args.hasArg(OPT_fmerge_all_constants);
761f22ef01cSRoman Divacky Opts.NoCommon = Args.hasArg(OPT_fno_common);
762f22ef01cSRoman Divacky Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float);
763284c1978SDimitry Andric Opts.OptimizeSize = getOptimizationLevelSize(Args);
764ffd1746dSEd Schouten Opts.SimplifyLibCalls = !(Args.hasArg(OPT_fno_builtin) ||
765ffd1746dSEd Schouten Args.hasArg(OPT_ffreestanding));
766ea942507SDimitry Andric if (Opts.SimplifyLibCalls)
767ea942507SDimitry Andric getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs);
768f785676fSDimitry Andric Opts.UnrollLoops =
769f785676fSDimitry Andric Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
770e7145dcbSDimitry Andric (Opts.OptimizationLevel > 1));
771f785676fSDimitry Andric Opts.RerollLoops = Args.hasArg(OPT_freroll_loops);
772f22ef01cSRoman Divacky
77359d1ed5bSDimitry Andric Opts.DisableIntegratedAS = Args.hasArg(OPT_fno_integrated_as);
774284c1978SDimitry Andric Opts.Autolink = !Args.hasArg(OPT_fno_autolink);
775f785676fSDimitry Andric Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ);
77620e90f04SDimitry Andric Opts.DebugInfoForProfiling = Args.hasFlag(
77720e90f04SDimitry Andric OPT_fdebug_info_for_profiling, OPT_fno_debug_info_for_profiling, false);
778*b5893f02SDimitry Andric Opts.DebugNameTable = static_cast<unsigned>(
779*b5893f02SDimitry Andric Args.hasArg(OPT_ggnu_pubnames)
780*b5893f02SDimitry Andric ? llvm::DICompileUnit::DebugNameTableKind::GNU
781*b5893f02SDimitry Andric : Args.hasArg(OPT_gpubnames)
782*b5893f02SDimitry Andric ? llvm::DICompileUnit::DebugNameTableKind::Default
783*b5893f02SDimitry Andric : llvm::DICompileUnit::DebugNameTableKind::None);
784*b5893f02SDimitry Andric Opts.DebugRangesBaseAddress = Args.hasArg(OPT_fdebug_ranges_base_address);
785e7145dcbSDimitry Andric
786e7145dcbSDimitry Andric setPGOInstrumentor(Opts, Args, Diags);
787e7145dcbSDimitry Andric Opts.InstrProfileOutput =
788e7145dcbSDimitry Andric Args.getLastArgValue(OPT_fprofile_instrument_path_EQ);
789e7145dcbSDimitry Andric Opts.ProfileInstrumentUsePath =
790e7145dcbSDimitry Andric Args.getLastArgValue(OPT_fprofile_instrument_use_path_EQ);
791e7145dcbSDimitry Andric if (!Opts.ProfileInstrumentUsePath.empty())
792e7145dcbSDimitry Andric setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath);
793*b5893f02SDimitry Andric Opts.ProfileRemappingFile =
794*b5893f02SDimitry Andric Args.getLastArgValue(OPT_fprofile_remapping_file_EQ);
795*b5893f02SDimitry Andric if (!Opts.ProfileRemappingFile.empty() && !Opts.ExperimentalNewPassManager) {
796*b5893f02SDimitry Andric Diags.Report(diag::err_drv_argument_only_allowed_with)
797*b5893f02SDimitry Andric << Args.getLastArg(OPT_fprofile_remapping_file_EQ)->getAsString(Args)
798*b5893f02SDimitry Andric << "-fexperimental-new-pass-manager";
799*b5893f02SDimitry Andric }
800e7145dcbSDimitry Andric
8010623d748SDimitry Andric Opts.CoverageMapping =
8020623d748SDimitry Andric Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false);
80339d628a0SDimitry Andric Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);
804f22ef01cSRoman Divacky Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
80544290647SDimitry Andric Opts.PreserveAsmComments = !Args.hasArg(OPT_fno_preserve_as_comments);
806e7145dcbSDimitry Andric Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
80717a519f9SDimitry Andric Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);
808f22ef01cSRoman Divacky Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
8094ba319b5SDimitry Andric Opts.RegisterGlobalDtorsWithAtExit =
8104ba319b5SDimitry Andric Args.hasArg(OPT_fregister_global_dtors_with_atexit);
811f22ef01cSRoman Divacky Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
812*b5893f02SDimitry Andric Opts.CodeModel = TargetOpts.CodeModel;
813f22ef01cSRoman Divacky Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass);
8140623d748SDimitry Andric Opts.DisableFPElim =
8150623d748SDimitry Andric (Args.hasArg(OPT_mdisable_fp_elim) || Args.hasArg(OPT_pg));
816f785676fSDimitry Andric Opts.DisableFree = Args.hasArg(OPT_disable_free);
817e7145dcbSDimitry Andric Opts.DiscardValueNames = Args.hasArg(OPT_discard_value_names);
818dff0c46cSDimitry Andric Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls);
8194ba319b5SDimitry Andric Opts.NoEscapingBlockTailCalls =
8204ba319b5SDimitry Andric Args.hasArg(OPT_fno_escaping_block_tail_calls);
821f22ef01cSRoman Divacky Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi);
82220e90f04SDimitry Andric Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable) ||
82320e90f04SDimitry Andric Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
82420e90f04SDimitry Andric Args.hasArg(OPT_cl_fast_relaxed_math);
825f22ef01cSRoman Divacky Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision);
826dff0c46cSDimitry Andric Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) ||
827dff0c46cSDimitry Andric Args.hasArg(OPT_cl_finite_math_only) ||
828dff0c46cSDimitry Andric Args.hasArg(OPT_cl_fast_relaxed_math));
829dff0c46cSDimitry Andric Opts.NoNaNsFPMath = (Args.hasArg(OPT_menable_no_nans) ||
83039d628a0SDimitry Andric Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
831dff0c46cSDimitry Andric Args.hasArg(OPT_cl_finite_math_only) ||
832dff0c46cSDimitry Andric Args.hasArg(OPT_cl_fast_relaxed_math));
833e7145dcbSDimitry Andric Opts.NoSignedZeros = (Args.hasArg(OPT_fno_signed_zeros) ||
83420e90f04SDimitry Andric Args.hasArg(OPT_cl_no_signed_zeros) ||
83520e90f04SDimitry Andric Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
83620e90f04SDimitry Andric Args.hasArg(OPT_cl_fast_relaxed_math));
8379a199699SDimitry Andric Opts.Reassociate = Args.hasArg(OPT_mreassociate);
8384ba319b5SDimitry Andric Opts.FlushDenorm = Args.hasArg(OPT_cl_denorms_are_zero) ||
8394ba319b5SDimitry Andric (Args.hasArg(OPT_fcuda_is_device) &&
8404ba319b5SDimitry Andric Args.hasArg(OPT_fcuda_flush_denormals_to_zero));
84144290647SDimitry Andric Opts.CorrectlyRoundedDivSqrt =
84244290647SDimitry Andric Args.hasArg(OPT_cl_fp32_correctly_rounded_divide_sqrt);
8434ba319b5SDimitry Andric Opts.UniformWGSize =
8444ba319b5SDimitry Andric Args.hasArg(OPT_cl_uniform_work_group_size);
8459a199699SDimitry Andric Opts.Reciprocals = Args.getAllArgValues(OPT_mrecip_EQ);
84633956c43SDimitry Andric Opts.ReciprocalMath = Args.hasArg(OPT_freciprocal_math);
84744290647SDimitry Andric Opts.NoTrappingMath = Args.hasArg(OPT_fno_trapping_math);
8484ba319b5SDimitry Andric Opts.StrictFloatCastOverflow =
8494ba319b5SDimitry Andric !Args.hasArg(OPT_fno_strict_float_cast_overflow);
8504ba319b5SDimitry Andric
851f22ef01cSRoman Divacky Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss);
852f785676fSDimitry Andric Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags);
85317a519f9SDimitry Andric Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack);
85439d628a0SDimitry Andric Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
855139f7f9bSDimitry Andric Opts.EnableSegmentedStacks = Args.hasArg(OPT_split_stacks);
856f22ef01cSRoman Divacky Opts.RelaxAll = Args.hasArg(OPT_mrelax_all);
8570623d748SDimitry Andric Opts.IncrementalLinkerCompatible =
8580623d748SDimitry Andric Args.hasArg(OPT_mincremental_linker_compatible);
85944290647SDimitry Andric Opts.PIECopyRelocations =
86044290647SDimitry Andric Args.hasArg(OPT_mpie_copy_relocations);
8619a199699SDimitry Andric Opts.NoPLT = Args.hasArg(OPT_fno_plt);
862ffd1746dSEd Schouten Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer);
8633b0f4066SDimitry Andric Opts.SaveTempLabels = Args.hasArg(OPT_msave_temp_labels);
864dff0c46cSDimitry Andric Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm);
865f22ef01cSRoman Divacky Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
866dff0c46cSDimitry Andric Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
8678e0f8b8cSDimitry Andric Opts.StrictReturn = !Args.hasArg(OPT_fno_strict_return);
8680623d748SDimitry Andric Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers);
8694ba319b5SDimitry Andric Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables);
870dff0c46cSDimitry Andric Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
871dff0c46cSDimitry Andric Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
8722754fe60SDimitry Andric Args.hasArg(OPT_cl_fast_relaxed_math);
873f22ef01cSRoman Divacky Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
87420e90f04SDimitry Andric Opts.RelocationModel = getRelocModel(Args, Diags);
87539d628a0SDimitry Andric Opts.ThreadModel = Args.getLastArgValue(OPT_mthread_model, "posix");
87639d628a0SDimitry Andric if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single")
87739d628a0SDimitry Andric Diags.Report(diag::err_drv_invalid_value)
87839d628a0SDimitry Andric << Args.getLastArg(OPT_mthread_model)->getAsString(Args)
87939d628a0SDimitry Andric << Opts.ThreadModel;
880dff0c46cSDimitry Andric Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ);
8817ae0e2c9SDimitry Andric Opts.UseInitArray = Args.hasArg(OPT_fuse_init_array);
882f22ef01cSRoman Divacky
883f785676fSDimitry Andric Opts.FunctionSections = Args.hasFlag(OPT_ffunction_sections,
884f785676fSDimitry Andric OPT_fno_function_sections, false);
885f785676fSDimitry Andric Opts.DataSections = Args.hasFlag(OPT_fdata_sections,
886f785676fSDimitry Andric OPT_fno_data_sections, false);
8874ba319b5SDimitry Andric Opts.StackSizeSection =
8884ba319b5SDimitry Andric Args.hasFlag(OPT_fstack_size_section, OPT_fno_stack_size_section, false);
88933956c43SDimitry Andric Opts.UniqueSectionNames = Args.hasFlag(OPT_funique_section_names,
89033956c43SDimitry Andric OPT_fno_unique_section_names, true);
89133956c43SDimitry Andric
89239d628a0SDimitry Andric Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions);
893f785676fSDimitry Andric
894e7145dcbSDimitry Andric Opts.NoUseJumpTables = Args.hasArg(OPT_fno_jump_tables);
895e7145dcbSDimitry Andric
8964ba319b5SDimitry Andric Opts.NullPointerIsValid = Args.hasArg(OPT_fno_delete_null_pointer_checks);
8974ba319b5SDimitry Andric
8989a199699SDimitry Andric Opts.ProfileSampleAccurate = Args.hasArg(OPT_fprofile_sample_accurate);
8999a199699SDimitry Andric
9000623d748SDimitry Andric Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ);
9014ba319b5SDimitry Andric Opts.PrepareForThinLTO = false;
90224d58133SDimitry Andric if (Arg *A = Args.getLastArg(OPT_flto_EQ)) {
90324d58133SDimitry Andric StringRef S = A->getValue();
90424d58133SDimitry Andric if (S == "thin")
9054ba319b5SDimitry Andric Opts.PrepareForThinLTO = true;
90624d58133SDimitry Andric else if (S != "full")
90724d58133SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
90824d58133SDimitry Andric }
90920e90f04SDimitry Andric Opts.LTOUnit = Args.hasFlag(OPT_flto_unit, OPT_fno_lto_unit, false);
910*b5893f02SDimitry Andric Opts.EnableSplitLTOUnit = Args.hasArg(OPT_fsplit_lto_unit);
9110623d748SDimitry Andric if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
912f37b6182SDimitry Andric if (IK.getLanguage() != InputKind::LLVM_IR)
9130623d748SDimitry Andric Diags.Report(diag::err_drv_argument_only_allowed_with)
9140623d748SDimitry Andric << A->getAsString(Args) << "-x ir";
9150623d748SDimitry Andric Opts.ThinLTOIndexFile = Args.getLastArgValue(OPT_fthinlto_index_EQ);
9160623d748SDimitry Andric }
9174ba319b5SDimitry Andric if (Arg *A = Args.getLastArg(OPT_save_temps_EQ))
9184ba319b5SDimitry Andric Opts.SaveTempsFilePrefix =
9194ba319b5SDimitry Andric llvm::StringSwitch<std::string>(A->getValue())
9204ba319b5SDimitry Andric .Case("obj", FrontendOpts.OutputFile)
9214ba319b5SDimitry Andric .Default(llvm::sys::path::filename(FrontendOpts.OutputFile).str());
9224ba319b5SDimitry Andric
92320e90f04SDimitry Andric Opts.ThinLinkBitcodeFile = Args.getLastArgValue(OPT_fthin_link_bitcode_EQ);
924875ed548SDimitry Andric
92533956c43SDimitry Andric Opts.MSVolatile = Args.hasArg(OPT_fms_volatile);
92633956c43SDimitry Andric
927f785676fSDimitry Andric Opts.VectorizeLoop = Args.hasArg(OPT_vectorize_loops);
928f785676fSDimitry Andric Opts.VectorizeSLP = Args.hasArg(OPT_vectorize_slp);
929f22ef01cSRoman Divacky
9309a199699SDimitry Andric Opts.PreferVectorWidth = Args.getLastArgValue(OPT_mprefer_vector_width_EQ);
9319a199699SDimitry Andric
932f22ef01cSRoman Divacky Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name);
933f22ef01cSRoman Divacky Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
934139f7f9bSDimitry Andric
9354ba319b5SDimitry Andric Opts.ControlFlowGuard = Args.hasArg(OPT_cfguard);
9364ba319b5SDimitry Andric
937139f7f9bSDimitry Andric Opts.DisableGCov = Args.hasArg(OPT_test_coverage);
938139f7f9bSDimitry Andric Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data);
939139f7f9bSDimitry Andric Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes);
940139f7f9bSDimitry Andric if (Opts.EmitGcovArcs || Opts.EmitGcovNotes) {
94144290647SDimitry Andric Opts.CoverageDataFile = Args.getLastArgValue(OPT_coverage_data_file);
94244290647SDimitry Andric Opts.CoverageNotesFile = Args.getLastArgValue(OPT_coverage_notes_file);
943139f7f9bSDimitry Andric Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
944139f7f9bSDimitry Andric Opts.CoverageNoFunctionNamesInData =
945139f7f9bSDimitry Andric Args.hasArg(OPT_coverage_no_function_names_in_data);
946*b5893f02SDimitry Andric Opts.ProfileFilterFiles =
947*b5893f02SDimitry Andric Args.getLastArgValue(OPT_fprofile_filter_files_EQ);
948*b5893f02SDimitry Andric Opts.ProfileExcludeFiles =
949*b5893f02SDimitry Andric Args.getLastArgValue(OPT_fprofile_exclude_files_EQ);
95033956c43SDimitry Andric Opts.CoverageExitBlockBeforeBody =
95133956c43SDimitry Andric Args.hasArg(OPT_coverage_exit_block_before_body);
952139f7f9bSDimitry Andric if (Args.hasArg(OPT_coverage_version_EQ)) {
953139f7f9bSDimitry Andric StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);
954139f7f9bSDimitry Andric if (CoverageVersion.size() != 4) {
955139f7f9bSDimitry Andric Diags.Report(diag::err_drv_invalid_value)
956139f7f9bSDimitry Andric << Args.getLastArg(OPT_coverage_version_EQ)->getAsString(Args)
957139f7f9bSDimitry Andric << CoverageVersion;
958139f7f9bSDimitry Andric } else {
959139f7f9bSDimitry Andric memcpy(Opts.CoverageVersion, CoverageVersion.data(), 4);
960139f7f9bSDimitry Andric }
961139f7f9bSDimitry Andric }
962139f7f9bSDimitry Andric }
963e7145dcbSDimitry Andric // Handle -fembed-bitcode option.
964e7145dcbSDimitry Andric if (Arg *A = Args.getLastArg(OPT_fembed_bitcode_EQ)) {
965e7145dcbSDimitry Andric StringRef Name = A->getValue();
966e7145dcbSDimitry Andric unsigned Model = llvm::StringSwitch<unsigned>(Name)
967e7145dcbSDimitry Andric .Case("off", CodeGenOptions::Embed_Off)
968e7145dcbSDimitry Andric .Case("all", CodeGenOptions::Embed_All)
969e7145dcbSDimitry Andric .Case("bitcode", CodeGenOptions::Embed_Bitcode)
970e7145dcbSDimitry Andric .Case("marker", CodeGenOptions::Embed_Marker)
971e7145dcbSDimitry Andric .Default(~0U);
972e7145dcbSDimitry Andric if (Model == ~0U) {
973e7145dcbSDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
974e7145dcbSDimitry Andric Success = false;
975e7145dcbSDimitry Andric } else
976e7145dcbSDimitry Andric Opts.setEmbedBitcode(
977e7145dcbSDimitry Andric static_cast<CodeGenOptions::EmbedBitcodeKind>(Model));
978e7145dcbSDimitry Andric }
979e7145dcbSDimitry Andric // FIXME: For backend options that are not yet recorded as function
980e7145dcbSDimitry Andric // attributes in the IR, keep track of them so we can embed them in a
981e7145dcbSDimitry Andric // separate data section and use them when building the bitcode.
982e7145dcbSDimitry Andric if (Opts.getEmbedBitcode() == CodeGenOptions::Embed_All) {
983e7145dcbSDimitry Andric for (const auto &A : Args) {
984e7145dcbSDimitry Andric // Do not encode output and input.
985e7145dcbSDimitry Andric if (A->getOption().getID() == options::OPT_o ||
986e7145dcbSDimitry Andric A->getOption().getID() == options::OPT_INPUT ||
987e7145dcbSDimitry Andric A->getOption().getID() == options::OPT_x ||
988e7145dcbSDimitry Andric A->getOption().getID() == options::OPT_fembed_bitcode ||
989e7145dcbSDimitry Andric (A->getOption().getGroup().isValid() &&
990e7145dcbSDimitry Andric A->getOption().getGroup().getID() == options::OPT_W_Group))
991e7145dcbSDimitry Andric continue;
992e7145dcbSDimitry Andric ArgStringList ASL;
993e7145dcbSDimitry Andric A->render(Args, ASL);
994e7145dcbSDimitry Andric for (const auto &arg : ASL) {
995e7145dcbSDimitry Andric StringRef ArgStr(arg);
996e7145dcbSDimitry Andric Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end());
997*b5893f02SDimitry Andric // using \00 to separate each commandline options.
998e7145dcbSDimitry Andric Opts.CmdArgs.push_back('\0');
999e7145dcbSDimitry Andric }
1000e7145dcbSDimitry Andric }
1001e7145dcbSDimitry Andric }
1002f22ef01cSRoman Divacky
100320e90f04SDimitry Andric Opts.PreserveVec3Type = Args.hasArg(OPT_fpreserve_vec3_type);
1004ffd1746dSEd Schouten Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions);
10059a199699SDimitry Andric Opts.InstrumentFunctionsAfterInlining =
10069a199699SDimitry Andric Args.hasArg(OPT_finstrument_functions_after_inlining);
10079a199699SDimitry Andric Opts.InstrumentFunctionEntryBare =
10089a199699SDimitry Andric Args.hasArg(OPT_finstrument_function_entry_bare);
10094ba319b5SDimitry Andric
10104ba319b5SDimitry Andric Opts.XRayInstrumentFunctions =
10114ba319b5SDimitry Andric Args.hasArg(OPT_fxray_instrument);
10129a199699SDimitry Andric Opts.XRayAlwaysEmitCustomEvents =
10139a199699SDimitry Andric Args.hasArg(OPT_fxray_always_emit_customevents);
10144ba319b5SDimitry Andric Opts.XRayAlwaysEmitTypedEvents =
10154ba319b5SDimitry Andric Args.hasArg(OPT_fxray_always_emit_typedevents);
1016e7145dcbSDimitry Andric Opts.XRayInstructionThreshold =
101720e90f04SDimitry Andric getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
10184ba319b5SDimitry Andric
10194ba319b5SDimitry Andric auto XRayInstrBundles =
10204ba319b5SDimitry Andric Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
10214ba319b5SDimitry Andric if (XRayInstrBundles.empty())
10224ba319b5SDimitry Andric Opts.XRayInstrumentationBundle.Mask = XRayInstrKind::All;
10234ba319b5SDimitry Andric else
10244ba319b5SDimitry Andric for (const auto &A : XRayInstrBundles)
10254ba319b5SDimitry Andric parseXRayInstrumentationBundle("-fxray-instrumentation-bundle=", A, Args,
10264ba319b5SDimitry Andric Diags, Opts.XRayInstrumentationBundle);
10274ba319b5SDimitry Andric
10282754fe60SDimitry Andric Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
102920e90f04SDimitry Andric Opts.CallFEntry = Args.hasArg(OPT_mfentry);
10307ae0e2c9SDimitry Andric Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);
1031edd7eaddSDimitry Andric
10324ba319b5SDimitry Andric if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
10334ba319b5SDimitry Andric StringRef Name = A->getValue();
10344ba319b5SDimitry Andric if (Name == "full") {
10354ba319b5SDimitry Andric Opts.CFProtectionReturn = 1;
10364ba319b5SDimitry Andric Opts.CFProtectionBranch = 1;
10374ba319b5SDimitry Andric } else if (Name == "return")
10384ba319b5SDimitry Andric Opts.CFProtectionReturn = 1;
10394ba319b5SDimitry Andric else if (Name == "branch")
10404ba319b5SDimitry Andric Opts.CFProtectionBranch = 1;
10414ba319b5SDimitry Andric else if (Name != "none") {
10424ba319b5SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
10434ba319b5SDimitry Andric Success = false;
10444ba319b5SDimitry Andric }
10454ba319b5SDimitry Andric }
10464ba319b5SDimitry Andric
1047edd7eaddSDimitry Andric if (const Arg *A = Args.getLastArg(OPT_compress_debug_sections,
1048edd7eaddSDimitry Andric OPT_compress_debug_sections_EQ)) {
1049edd7eaddSDimitry Andric if (A->getOption().getID() == OPT_compress_debug_sections) {
1050edd7eaddSDimitry Andric // TODO: be more clever about the compression type auto-detection
1051db17bf38SDimitry Andric Opts.setCompressDebugSections(llvm::DebugCompressionType::GNU);
1052edd7eaddSDimitry Andric } else {
1053edd7eaddSDimitry Andric auto DCT = llvm::StringSwitch<llvm::DebugCompressionType>(A->getValue())
1054edd7eaddSDimitry Andric .Case("none", llvm::DebugCompressionType::None)
1055edd7eaddSDimitry Andric .Case("zlib", llvm::DebugCompressionType::Z)
1056edd7eaddSDimitry Andric .Case("zlib-gnu", llvm::DebugCompressionType::GNU)
1057edd7eaddSDimitry Andric .Default(llvm::DebugCompressionType::None);
1058edd7eaddSDimitry Andric Opts.setCompressDebugSections(DCT);
1059edd7eaddSDimitry Andric }
1060edd7eaddSDimitry Andric }
1061edd7eaddSDimitry Andric
1062e7145dcbSDimitry Andric Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations);
1063dff0c46cSDimitry Andric Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
10644ba319b5SDimitry Andric for (auto *A :
1065*b5893f02SDimitry Andric Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) {
106620e90f04SDimitry Andric CodeGenOptions::BitcodeFileToLink F;
106720e90f04SDimitry Andric F.Filename = A->getValue();
1068*b5893f02SDimitry Andric if (A->getOption().matches(OPT_mlink_builtin_bitcode)) {
106920e90f04SDimitry Andric F.LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded;
107020e90f04SDimitry Andric // When linking CUDA bitcode, propagate function attributes so that
107120e90f04SDimitry Andric // e.g. libdevice gets fast-math attrs if we're building with fast-math.
107220e90f04SDimitry Andric F.PropagateAttrs = true;
107320e90f04SDimitry Andric F.Internalize = true;
107420e90f04SDimitry Andric }
107520e90f04SDimitry Andric Opts.LinkBitcodeFiles.push_back(F);
10760623d748SDimitry Andric }
107733956c43SDimitry Andric Opts.SanitizeCoverageType =
107833956c43SDimitry Andric getLastArgIntValue(Args, OPT_fsanitize_coverage_type, 0, Diags);
107933956c43SDimitry Andric Opts.SanitizeCoverageIndirectCalls =
108033956c43SDimitry Andric Args.hasArg(OPT_fsanitize_coverage_indirect_calls);
108133956c43SDimitry Andric Opts.SanitizeCoverageTraceBB = Args.hasArg(OPT_fsanitize_coverage_trace_bb);
108233956c43SDimitry Andric Opts.SanitizeCoverageTraceCmp = Args.hasArg(OPT_fsanitize_coverage_trace_cmp);
108344290647SDimitry Andric Opts.SanitizeCoverageTraceDiv = Args.hasArg(OPT_fsanitize_coverage_trace_div);
108444290647SDimitry Andric Opts.SanitizeCoverageTraceGep = Args.hasArg(OPT_fsanitize_coverage_trace_gep);
108533956c43SDimitry Andric Opts.SanitizeCoverage8bitCounters =
108633956c43SDimitry Andric Args.hasArg(OPT_fsanitize_coverage_8bit_counters);
1087e7145dcbSDimitry Andric Opts.SanitizeCoverageTracePC = Args.hasArg(OPT_fsanitize_coverage_trace_pc);
108844290647SDimitry Andric Opts.SanitizeCoverageTracePCGuard =
108944290647SDimitry Andric Args.hasArg(OPT_fsanitize_coverage_trace_pc_guard);
10900f5676f4SDimitry Andric Opts.SanitizeCoverageNoPrune = Args.hasArg(OPT_fsanitize_coverage_no_prune);
10916d97bb29SDimitry Andric Opts.SanitizeCoverageInline8bitCounters =
10926d97bb29SDimitry Andric Args.hasArg(OPT_fsanitize_coverage_inline_8bit_counters);
10939a199699SDimitry Andric Opts.SanitizeCoveragePCTable = Args.hasArg(OPT_fsanitize_coverage_pc_table);
10949a199699SDimitry Andric Opts.SanitizeCoverageStackDepth =
10959a199699SDimitry Andric Args.hasArg(OPT_fsanitize_coverage_stack_depth);
1096139f7f9bSDimitry Andric Opts.SanitizeMemoryTrackOrigins =
109759d1ed5bSDimitry Andric getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
1098875ed548SDimitry Andric Opts.SanitizeMemoryUseAfterDtor =
10999a199699SDimitry Andric Args.hasFlag(OPT_fsanitize_memory_use_after_dtor,
11009a199699SDimitry Andric OPT_fno_sanitize_memory_use_after_dtor,
11019a199699SDimitry Andric false);
11029a199699SDimitry Andric Opts.SanitizeMinimalRuntime = Args.hasArg(OPT_fsanitize_minimal_runtime);
11030623d748SDimitry Andric Opts.SanitizeCfiCrossDso = Args.hasArg(OPT_fsanitize_cfi_cross_dso);
11049a199699SDimitry Andric Opts.SanitizeCfiICallGeneralizePointers =
11059a199699SDimitry Andric Args.hasArg(OPT_fsanitize_cfi_icall_generalize_pointers);
1106e7145dcbSDimitry Andric Opts.SanitizeStats = Args.hasArg(OPT_fsanitize_stats);
11074ba319b5SDimitry Andric if (Arg *A = Args.getLastArg(
1108*b5893f02SDimitry Andric OPT_fsanitize_address_poison_custom_array_cookie,
1109*b5893f02SDimitry Andric OPT_fno_sanitize_address_poison_custom_array_cookie)) {
1110*b5893f02SDimitry Andric Opts.SanitizeAddressPoisonCustomArrayCookie =
11114ba319b5SDimitry Andric A->getOption().getID() ==
1112*b5893f02SDimitry Andric OPT_fsanitize_address_poison_custom_array_cookie;
11134ba319b5SDimitry Andric }
111444290647SDimitry Andric if (Arg *A = Args.getLastArg(OPT_fsanitize_address_use_after_scope,
111544290647SDimitry Andric OPT_fno_sanitize_address_use_after_scope)) {
1116e7145dcbSDimitry Andric Opts.SanitizeAddressUseAfterScope =
111744290647SDimitry Andric A->getOption().getID() == OPT_fsanitize_address_use_after_scope;
111844290647SDimitry Andric }
11195517e702SDimitry Andric Opts.SanitizeAddressGlobalsDeadStripping =
11205517e702SDimitry Andric Args.hasArg(OPT_fsanitize_address_globals_dead_stripping);
1121*b5893f02SDimitry Andric if (Arg *A = Args.getLastArg(OPT_fsanitize_address_use_odr_indicator,
1122*b5893f02SDimitry Andric OPT_fno_sanitize_address_use_odr_indicator)) {
1123*b5893f02SDimitry Andric Opts.SanitizeAddressUseOdrIndicator =
1124*b5893f02SDimitry Andric A->getOption().getID() == OPT_fsanitize_address_use_odr_indicator;
1125*b5893f02SDimitry Andric }
11263861d79fSDimitry Andric Opts.SSPBufferSize =
1127f785676fSDimitry Andric getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags);
1128dff0c46cSDimitry Andric Opts.StackRealignment = Args.hasArg(OPT_mstackrealign);
1129dff0c46cSDimitry Andric if (Arg *A = Args.getLastArg(OPT_mstack_alignment)) {
11303861d79fSDimitry Andric StringRef Val = A->getValue();
11313861d79fSDimitry Andric unsigned StackAlignment = Opts.StackAlignment;
11323861d79fSDimitry Andric Val.getAsInteger(10, StackAlignment);
11333861d79fSDimitry Andric Opts.StackAlignment = StackAlignment;
1134dff0c46cSDimitry Andric }
1135ffd1746dSEd Schouten
113633956c43SDimitry Andric if (Arg *A = Args.getLastArg(OPT_mstack_probe_size)) {
113733956c43SDimitry Andric StringRef Val = A->getValue();
113833956c43SDimitry Andric unsigned StackProbeSize = Opts.StackProbeSize;
113933956c43SDimitry Andric Val.getAsInteger(0, StackProbeSize);
114033956c43SDimitry Andric Opts.StackProbeSize = StackProbeSize;
114133956c43SDimitry Andric }
114233956c43SDimitry Andric
11434ba319b5SDimitry Andric Opts.NoStackArgProbe = Args.hasArg(OPT_mno_stack_arg_probe);
11444ba319b5SDimitry Andric
1145f22ef01cSRoman Divacky if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) {
11463861d79fSDimitry Andric StringRef Name = A->getValue();
1147f22ef01cSRoman Divacky unsigned Method = llvm::StringSwitch<unsigned>(Name)
1148f22ef01cSRoman Divacky .Case("legacy", CodeGenOptions::Legacy)
1149f22ef01cSRoman Divacky .Case("non-legacy", CodeGenOptions::NonLegacy)
1150f22ef01cSRoman Divacky .Case("mixed", CodeGenOptions::Mixed)
1151f22ef01cSRoman Divacky .Default(~0U);
1152dff0c46cSDimitry Andric if (Method == ~0U) {
1153f22ef01cSRoman Divacky Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
1154dff0c46cSDimitry Andric Success = false;
1155dff0c46cSDimitry Andric } else {
11563861d79fSDimitry Andric Opts.setObjCDispatchMethod(
11573861d79fSDimitry Andric static_cast<CodeGenOptions::ObjCDispatchMethodKind>(Method));
1158f22ef01cSRoman Divacky }
1159f22ef01cSRoman Divacky }
1160f22ef01cSRoman Divacky
1161*b5893f02SDimitry Andric
1162*b5893f02SDimitry Andric if (Args.hasArg(OPT_fno_objc_convert_messages_to_runtime_calls))
1163*b5893f02SDimitry Andric Opts.ObjCConvertMessagesToRuntimeCalls = 0;
1164*b5893f02SDimitry Andric
11654ba319b5SDimitry Andric if (Args.getLastArg(OPT_femulated_tls) ||
11664ba319b5SDimitry Andric Args.getLastArg(OPT_fno_emulated_tls)) {
11674ba319b5SDimitry Andric Opts.ExplicitEmulatedTLS = true;
11680623d748SDimitry Andric Opts.EmulatedTLS =
11690623d748SDimitry Andric Args.hasFlag(OPT_femulated_tls, OPT_fno_emulated_tls, false);
11704ba319b5SDimitry Andric }
11710623d748SDimitry Andric
11727ae0e2c9SDimitry Andric if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
11733861d79fSDimitry Andric StringRef Name = A->getValue();
11747ae0e2c9SDimitry Andric unsigned Model = llvm::StringSwitch<unsigned>(Name)
11757ae0e2c9SDimitry Andric .Case("global-dynamic", CodeGenOptions::GeneralDynamicTLSModel)
11767ae0e2c9SDimitry Andric .Case("local-dynamic", CodeGenOptions::LocalDynamicTLSModel)
11777ae0e2c9SDimitry Andric .Case("initial-exec", CodeGenOptions::InitialExecTLSModel)
11787ae0e2c9SDimitry Andric .Case("local-exec", CodeGenOptions::LocalExecTLSModel)
11797ae0e2c9SDimitry Andric .Default(~0U);
11807ae0e2c9SDimitry Andric if (Model == ~0U) {
11817ae0e2c9SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
11827ae0e2c9SDimitry Andric Success = false;
11837ae0e2c9SDimitry Andric } else {
11843861d79fSDimitry Andric Opts.setDefaultTLSModel(static_cast<CodeGenOptions::TLSModel>(Model));
11857ae0e2c9SDimitry Andric }
11867ae0e2c9SDimitry Andric }
11877ae0e2c9SDimitry Andric
118844290647SDimitry Andric if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
118944290647SDimitry Andric StringRef Val = A->getValue();
119044290647SDimitry Andric if (Val == "ieee")
119144290647SDimitry Andric Opts.FPDenormalMode = "ieee";
119244290647SDimitry Andric else if (Val == "preserve-sign")
119344290647SDimitry Andric Opts.FPDenormalMode = "preserve-sign";
119444290647SDimitry Andric else if (Val == "positive-zero")
119544290647SDimitry Andric Opts.FPDenormalMode = "positive-zero";
119644290647SDimitry Andric else
119744290647SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
119844290647SDimitry Andric }
119944290647SDimitry Andric
1200f785676fSDimitry Andric if (Arg *A = Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return)) {
1201f785676fSDimitry Andric if (A->getOption().matches(OPT_fpcc_struct_return)) {
1202f785676fSDimitry Andric Opts.setStructReturnConvention(CodeGenOptions::SRCK_OnStack);
1203f785676fSDimitry Andric } else {
1204f785676fSDimitry Andric assert(A->getOption().matches(OPT_freg_struct_return));
1205f785676fSDimitry Andric Opts.setStructReturnConvention(CodeGenOptions::SRCK_InRegs);
1206f785676fSDimitry Andric }
1207f785676fSDimitry Andric }
1208f785676fSDimitry Andric
1209f785676fSDimitry Andric Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib);
1210e7145dcbSDimitry Andric Opts.LinkerOptions = Args.getAllArgValues(OPT_linker_option);
121159d1ed5bSDimitry Andric bool NeedLocTracking = false;
121259d1ed5bSDimitry Andric
121344290647SDimitry Andric Opts.OptRecordFile = Args.getLastArgValue(OPT_opt_record_file);
121444290647SDimitry Andric if (!Opts.OptRecordFile.empty())
121544290647SDimitry Andric NeedLocTracking = true;
121644290647SDimitry Andric
121759d1ed5bSDimitry Andric if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) {
121859d1ed5bSDimitry Andric Opts.OptimizationRemarkPattern =
121959d1ed5bSDimitry Andric GenerateOptimizationRemarkRegex(Diags, Args, A);
122059d1ed5bSDimitry Andric NeedLocTracking = true;
122159d1ed5bSDimitry Andric }
122259d1ed5bSDimitry Andric
122359d1ed5bSDimitry Andric if (Arg *A = Args.getLastArg(OPT_Rpass_missed_EQ)) {
122459d1ed5bSDimitry Andric Opts.OptimizationRemarkMissedPattern =
122559d1ed5bSDimitry Andric GenerateOptimizationRemarkRegex(Diags, Args, A);
122659d1ed5bSDimitry Andric NeedLocTracking = true;
122759d1ed5bSDimitry Andric }
122859d1ed5bSDimitry Andric
122959d1ed5bSDimitry Andric if (Arg *A = Args.getLastArg(OPT_Rpass_analysis_EQ)) {
123059d1ed5bSDimitry Andric Opts.OptimizationRemarkAnalysisPattern =
123159d1ed5bSDimitry Andric GenerateOptimizationRemarkRegex(Diags, Args, A);
123259d1ed5bSDimitry Andric NeedLocTracking = true;
123359d1ed5bSDimitry Andric }
123459d1ed5bSDimitry Andric
123544290647SDimitry Andric Opts.DiagnosticsWithHotness =
123644290647SDimitry Andric Args.hasArg(options::OPT_fdiagnostics_show_hotness);
1237edd7eaddSDimitry Andric bool UsingSampleProfile = !Opts.SampleProfileFile.empty();
1238a580b014SDimitry Andric bool UsingProfile = UsingSampleProfile ||
1239a580b014SDimitry Andric (Opts.getProfileUse() != CodeGenOptions::ProfileNone);
1240edd7eaddSDimitry Andric
12414ba319b5SDimitry Andric if (Opts.DiagnosticsWithHotness && !UsingProfile &&
12424ba319b5SDimitry Andric // An IR file will contain PGO as metadata
12434ba319b5SDimitry Andric IK.getLanguage() != InputKind::LLVM_IR)
1244a580b014SDimitry Andric Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
1245a580b014SDimitry Andric << "-fdiagnostics-show-hotness";
1246a580b014SDimitry Andric
1247a580b014SDimitry Andric Opts.DiagnosticsHotnessThreshold = getLastArgUInt64Value(
1248a580b014SDimitry Andric Args, options::OPT_fdiagnostics_hotness_threshold_EQ, 0);
1249a580b014SDimitry Andric if (Opts.DiagnosticsHotnessThreshold > 0 && !UsingProfile)
1250a580b014SDimitry Andric Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
1251a580b014SDimitry Andric << "-fdiagnostics-hotness-threshold=";
125244290647SDimitry Andric
125339d628a0SDimitry Andric // If the user requested to use a sample profile for PGO, then the
125439d628a0SDimitry Andric // backend will need to track source location information so the profile
125539d628a0SDimitry Andric // can be incorporated into the IR.
1256edd7eaddSDimitry Andric if (UsingSampleProfile)
125739d628a0SDimitry Andric NeedLocTracking = true;
125839d628a0SDimitry Andric
125939d628a0SDimitry Andric // If the user requested a flag that requires source locations available in
126039d628a0SDimitry Andric // the backend, make sure that the backend tracks source location information.
1261e7145dcbSDimitry Andric if (NeedLocTracking && Opts.getDebugInfo() == codegenoptions::NoDebugInfo)
1262e7145dcbSDimitry Andric Opts.setDebugInfo(codegenoptions::LocTrackingOnly);
1263f785676fSDimitry Andric
126439d628a0SDimitry Andric Opts.RewriteMapFiles = Args.getAllArgValues(OPT_frewrite_map_file);
126539d628a0SDimitry Andric
126639d628a0SDimitry Andric // Parse -fsanitize-recover= arguments.
126739d628a0SDimitry Andric // FIXME: Report unrecoverable sanitizers incorrectly specified here.
126839d628a0SDimitry Andric parseSanitizerKinds("-fsanitize-recover=",
126939d628a0SDimitry Andric Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags,
127039d628a0SDimitry Andric Opts.SanitizeRecover);
12718f0fd8f6SDimitry Andric parseSanitizerKinds("-fsanitize-trap=",
12728f0fd8f6SDimitry Andric Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
12738f0fd8f6SDimitry Andric Opts.SanitizeTrap);
127439d628a0SDimitry Andric
12754ba319b5SDimitry Andric Opts.CudaGpuBinaryFileName =
12764ba319b5SDimitry Andric Args.getLastArgValue(OPT_fcuda_include_gpubinary);
127733956c43SDimitry Andric
1278e7145dcbSDimitry Andric Opts.Backchain = Args.hasArg(OPT_mbackchain);
1279e7145dcbSDimitry Andric
1280e7145dcbSDimitry Andric Opts.EmitCheckPathComponentsToStrip = getLastArgIntValue(
1281e7145dcbSDimitry Andric Args, OPT_fsanitize_undefined_strip_path_components_EQ, 0, Diags);
1282e7145dcbSDimitry Andric
12834ba319b5SDimitry Andric Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
12844ba319b5SDimitry Andric
12854ba319b5SDimitry Andric Opts.Addrsig = Args.hasArg(OPT_faddrsig);
12864ba319b5SDimitry Andric
1287*b5893f02SDimitry Andric if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) {
1288*b5893f02SDimitry Andric StringRef SignScope = A->getValue();
1289*b5893f02SDimitry Andric
1290*b5893f02SDimitry Andric if (SignScope.equals_lower("none"))
1291*b5893f02SDimitry Andric Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::None);
1292*b5893f02SDimitry Andric else if (SignScope.equals_lower("all"))
1293*b5893f02SDimitry Andric Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::All);
1294*b5893f02SDimitry Andric else if (SignScope.equals_lower("non-leaf"))
1295*b5893f02SDimitry Andric Opts.setSignReturnAddress(
1296*b5893f02SDimitry Andric CodeGenOptions::SignReturnAddressScope::NonLeaf);
1297*b5893f02SDimitry Andric else
1298*b5893f02SDimitry Andric Diags.Report(diag::err_drv_invalid_value)
1299*b5893f02SDimitry Andric << A->getAsString(Args) << SignScope;
1300*b5893f02SDimitry Andric
1301*b5893f02SDimitry Andric if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) {
1302*b5893f02SDimitry Andric StringRef SignKey = A->getValue();
1303*b5893f02SDimitry Andric if (!SignScope.empty() && !SignKey.empty()) {
1304*b5893f02SDimitry Andric if (SignKey.equals_lower("a_key"))
1305*b5893f02SDimitry Andric Opts.setSignReturnAddressKey(
1306*b5893f02SDimitry Andric CodeGenOptions::SignReturnAddressKeyValue::AKey);
1307*b5893f02SDimitry Andric else if (SignKey.equals_lower("b_key"))
1308*b5893f02SDimitry Andric Opts.setSignReturnAddressKey(
1309*b5893f02SDimitry Andric CodeGenOptions::SignReturnAddressKeyValue::BKey);
1310*b5893f02SDimitry Andric else
1311*b5893f02SDimitry Andric Diags.Report(diag::err_drv_invalid_value)
1312*b5893f02SDimitry Andric << A->getAsString(Args) << SignKey;
1313*b5893f02SDimitry Andric }
1314*b5893f02SDimitry Andric }
1315*b5893f02SDimitry Andric }
1316*b5893f02SDimitry Andric
1317*b5893f02SDimitry Andric Opts.BranchTargetEnforcement = Args.hasArg(OPT_mbranch_target_enforce);
1318*b5893f02SDimitry Andric
1319*b5893f02SDimitry Andric Opts.KeepStaticConsts = Args.hasArg(OPT_fkeep_static_consts);
1320*b5893f02SDimitry Andric
1321*b5893f02SDimitry Andric Opts.SpeculativeLoadHardening = Args.hasArg(OPT_mspeculative_load_hardening);
1322*b5893f02SDimitry Andric
1323*b5893f02SDimitry Andric Opts.DefaultFunctionAttrs = Args.getAllArgValues(OPT_default_function_attr);
1324*b5893f02SDimitry Andric
1325dff0c46cSDimitry Andric return Success;
1326dff0c46cSDimitry Andric }
1327dff0c46cSDimitry Andric
ParseDependencyOutputArgs(DependencyOutputOptions & Opts,ArgList & Args)1328f22ef01cSRoman Divacky static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
1329f22ef01cSRoman Divacky ArgList &Args) {
1330f22ef01cSRoman Divacky Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file);
1331f22ef01cSRoman Divacky Opts.Targets = Args.getAllArgValues(OPT_MT);
1332f22ef01cSRoman Divacky Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
133359d1ed5bSDimitry Andric Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps);
1334f22ef01cSRoman Divacky Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
13352754fe60SDimitry Andric Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
13362754fe60SDimitry Andric Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);
133717a519f9SDimitry Andric Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG);
13384ba319b5SDimitry Andric if (Args.hasArg(OPT_show_includes)) {
13394ba319b5SDimitry Andric // Writing both /showIncludes and preprocessor output to stdout
13404ba319b5SDimitry Andric // would produce interleaved output, so use stderr for /showIncludes.
13414ba319b5SDimitry Andric // This behaves the same as cl.exe, when /E, /EP or /P are passed.
13424ba319b5SDimitry Andric if (Args.hasArg(options::OPT_E) || Args.hasArg(options::OPT_P))
13434ba319b5SDimitry Andric Opts.ShowIncludesDest = ShowIncludesDestination::Stderr;
13444ba319b5SDimitry Andric else
13454ba319b5SDimitry Andric Opts.ShowIncludesDest = ShowIncludesDestination::Stdout;
13464ba319b5SDimitry Andric } else {
13474ba319b5SDimitry Andric Opts.ShowIncludesDest = ShowIncludesDestination::None;
13484ba319b5SDimitry Andric }
1349dff0c46cSDimitry Andric Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot);
135059d1ed5bSDimitry Andric Opts.ModuleDependencyOutputDir =
135159d1ed5bSDimitry Andric Args.getLastArgValue(OPT_module_dependency_dir);
135233956c43SDimitry Andric if (Args.hasArg(OPT_MV))
135333956c43SDimitry Andric Opts.OutputFormat = DependencyOutputFormat::NMake;
13540623d748SDimitry Andric // Add sanitizer blacklists as extra dependencies.
13550623d748SDimitry Andric // They won't be discovered by the regular preprocessor, so
13560623d748SDimitry Andric // we let make / ninja to know about this implicit dependency.
13570623d748SDimitry Andric Opts.ExtraDeps = Args.getAllArgValues(OPT_fdepfile_entry);
13589a199699SDimitry Andric // Only the -fmodule-file=<file> form.
13594ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_fmodule_file)) {
13609a199699SDimitry Andric StringRef Val = A->getValue();
13619a199699SDimitry Andric if (Val.find('=') == StringRef::npos)
13629a199699SDimitry Andric Opts.ExtraDeps.push_back(Val);
13639a199699SDimitry Andric }
1364f22ef01cSRoman Divacky }
1365f22ef01cSRoman Divacky
parseShowColorsArgs(const ArgList & Args,bool DefaultColor)1366e7145dcbSDimitry Andric static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) {
1367e7145dcbSDimitry Andric // Color diagnostics default to auto ("on" if terminal supports) in the driver
1368e7145dcbSDimitry Andric // but default to off in cc1, needing an explicit OPT_fdiagnostics_color.
1369e7145dcbSDimitry Andric // Support both clang's -f[no-]color-diagnostics and gcc's
1370e7145dcbSDimitry Andric // -f[no-]diagnostics-colors[=never|always|auto].
1371e7145dcbSDimitry Andric enum {
1372e7145dcbSDimitry Andric Colors_On,
1373e7145dcbSDimitry Andric Colors_Off,
1374e7145dcbSDimitry Andric Colors_Auto
1375e7145dcbSDimitry Andric } ShowColors = DefaultColor ? Colors_Auto : Colors_Off;
13764ba319b5SDimitry Andric for (auto *A : Args) {
1377e7145dcbSDimitry Andric const Option &O = A->getOption();
1378e7145dcbSDimitry Andric if (O.matches(options::OPT_fcolor_diagnostics) ||
1379e7145dcbSDimitry Andric O.matches(options::OPT_fdiagnostics_color)) {
1380e7145dcbSDimitry Andric ShowColors = Colors_On;
1381e7145dcbSDimitry Andric } else if (O.matches(options::OPT_fno_color_diagnostics) ||
1382e7145dcbSDimitry Andric O.matches(options::OPT_fno_diagnostics_color)) {
1383e7145dcbSDimitry Andric ShowColors = Colors_Off;
138444290647SDimitry Andric } else if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
1385e7145dcbSDimitry Andric StringRef Value(A->getValue());
1386e7145dcbSDimitry Andric if (Value == "always")
1387e7145dcbSDimitry Andric ShowColors = Colors_On;
1388e7145dcbSDimitry Andric else if (Value == "never")
1389e7145dcbSDimitry Andric ShowColors = Colors_Off;
1390e7145dcbSDimitry Andric else if (Value == "auto")
1391e7145dcbSDimitry Andric ShowColors = Colors_Auto;
1392e7145dcbSDimitry Andric }
1393e7145dcbSDimitry Andric }
139444290647SDimitry Andric return ShowColors == Colors_On ||
139544290647SDimitry Andric (ShowColors == Colors_Auto &&
139644290647SDimitry Andric llvm::sys::Process::StandardErrHasColors());
1397e7145dcbSDimitry Andric }
1398e7145dcbSDimitry Andric
checkVerifyPrefixes(const std::vector<std::string> & VerifyPrefixes,DiagnosticsEngine * Diags)13999a199699SDimitry Andric static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes,
14009a199699SDimitry Andric DiagnosticsEngine *Diags) {
14019a199699SDimitry Andric bool Success = true;
14029a199699SDimitry Andric for (const auto &Prefix : VerifyPrefixes) {
14039a199699SDimitry Andric // Every prefix must start with a letter and contain only alphanumeric
14049a199699SDimitry Andric // characters, hyphens, and underscores.
14059a199699SDimitry Andric auto BadChar = std::find_if(Prefix.begin(), Prefix.end(),
14069a199699SDimitry Andric [](char C){return !isAlphanumeric(C)
14079a199699SDimitry Andric && C != '-' && C != '_';});
14089a199699SDimitry Andric if (BadChar != Prefix.end() || !isLetter(Prefix[0])) {
14099a199699SDimitry Andric Success = false;
14109a199699SDimitry Andric if (Diags) {
14119a199699SDimitry Andric Diags->Report(diag::err_drv_invalid_value) << "-verify=" << Prefix;
14129a199699SDimitry Andric Diags->Report(diag::note_drv_verify_prefix_spelling);
14139a199699SDimitry Andric }
14149a199699SDimitry Andric }
14159a199699SDimitry Andric }
14169a199699SDimitry Andric return Success;
14179a199699SDimitry Andric }
14189a199699SDimitry Andric
ParseDiagnosticArgs(DiagnosticOptions & Opts,ArgList & Args,DiagnosticsEngine * Diags,bool DefaultDiagColor,bool DefaultShowOpt)1419dff0c46cSDimitry Andric bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
1420e7145dcbSDimitry Andric DiagnosticsEngine *Diags,
142144290647SDimitry Andric bool DefaultDiagColor, bool DefaultShowOpt) {
1422dff0c46cSDimitry Andric bool Success = true;
1423dff0c46cSDimitry Andric
14243b0f4066SDimitry Andric Opts.DiagnosticLogFile = Args.getLastArgValue(OPT_diagnostic_log_file);
142539d628a0SDimitry Andric if (Arg *A =
142639d628a0SDimitry Andric Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags))
142739d628a0SDimitry Andric Opts.DiagnosticSerializationFile = A->getValue();
1428f22ef01cSRoman Divacky Opts.IgnoreWarnings = Args.hasArg(OPT_w);
1429f22ef01cSRoman Divacky Opts.NoRewriteMacros = Args.hasArg(OPT_Wno_rewrite_macros);
1430f22ef01cSRoman Divacky Opts.Pedantic = Args.hasArg(OPT_pedantic);
1431f22ef01cSRoman Divacky Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors);
1432f22ef01cSRoman Divacky Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics);
1433e7145dcbSDimitry Andric Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor);
1434bd5abe19SDimitry Andric Opts.ShowColumn = Args.hasFlag(OPT_fshow_column,
1435bd5abe19SDimitry Andric OPT_fno_show_column,
1436bd5abe19SDimitry Andric /*Default=*/true);
1437f22ef01cSRoman Divacky Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info);
1438f22ef01cSRoman Divacky Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location);
143944290647SDimitry Andric Opts.AbsolutePath = Args.hasArg(OPT_fdiagnostics_absolute_paths);
144044290647SDimitry Andric Opts.ShowOptionNames =
144144290647SDimitry Andric Args.hasFlag(OPT_fdiagnostics_show_option,
144244290647SDimitry Andric OPT_fno_diagnostics_show_option, DefaultShowOpt);
1443f22ef01cSRoman Divacky
1444f785676fSDimitry Andric llvm::sys::Process::UseANSIEscapeCodes(Args.hasArg(OPT_fansi_escape_codes));
1445f785676fSDimitry Andric
14463b0f4066SDimitry Andric // Default behavior is to not to show note include stacks.
14473b0f4066SDimitry Andric Opts.ShowNoteIncludeStack = false;
14483b0f4066SDimitry Andric if (Arg *A = Args.getLastArg(OPT_fdiagnostics_show_note_include_stack,
14493b0f4066SDimitry Andric OPT_fno_diagnostics_show_note_include_stack))
14503b0f4066SDimitry Andric if (A->getOption().matches(OPT_fdiagnostics_show_note_include_stack))
14513b0f4066SDimitry Andric Opts.ShowNoteIncludeStack = true;
14523b0f4066SDimitry Andric
14536122f3e6SDimitry Andric StringRef ShowOverloads =
1454ffd1746dSEd Schouten Args.getLastArgValue(OPT_fshow_overloads_EQ, "all");
1455ffd1746dSEd Schouten if (ShowOverloads == "best")
14563861d79fSDimitry Andric Opts.setShowOverloads(Ovl_Best);
1457ffd1746dSEd Schouten else if (ShowOverloads == "all")
14583861d79fSDimitry Andric Opts.setShowOverloads(Ovl_All);
1459dff0c46cSDimitry Andric else {
1460dff0c46cSDimitry Andric Success = false;
1461dff0c46cSDimitry Andric if (Diags)
1462dff0c46cSDimitry Andric Diags->Report(diag::err_drv_invalid_value)
1463ffd1746dSEd Schouten << Args.getLastArg(OPT_fshow_overloads_EQ)->getAsString(Args)
1464ffd1746dSEd Schouten << ShowOverloads;
1465dff0c46cSDimitry Andric }
1466ffd1746dSEd Schouten
14676122f3e6SDimitry Andric StringRef ShowCategory =
1468f22ef01cSRoman Divacky Args.getLastArgValue(OPT_fdiagnostics_show_category, "none");
1469f22ef01cSRoman Divacky if (ShowCategory == "none")
1470f22ef01cSRoman Divacky Opts.ShowCategories = 0;
1471f22ef01cSRoman Divacky else if (ShowCategory == "id")
1472f22ef01cSRoman Divacky Opts.ShowCategories = 1;
1473f22ef01cSRoman Divacky else if (ShowCategory == "name")
1474f22ef01cSRoman Divacky Opts.ShowCategories = 2;
1475dff0c46cSDimitry Andric else {
1476dff0c46cSDimitry Andric Success = false;
1477dff0c46cSDimitry Andric if (Diags)
1478dff0c46cSDimitry Andric Diags->Report(diag::err_drv_invalid_value)
1479f22ef01cSRoman Divacky << Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args)
1480f22ef01cSRoman Divacky << ShowCategory;
1481dff0c46cSDimitry Andric }
1482f22ef01cSRoman Divacky
14836122f3e6SDimitry Andric StringRef Format =
1484bd5abe19SDimitry Andric Args.getLastArgValue(OPT_fdiagnostics_format, "clang");
1485bd5abe19SDimitry Andric if (Format == "clang")
14863861d79fSDimitry Andric Opts.setFormat(DiagnosticOptions::Clang);
1487bd5abe19SDimitry Andric else if (Format == "msvc")
148833956c43SDimitry Andric Opts.setFormat(DiagnosticOptions::MSVC);
1489f785676fSDimitry Andric else if (Format == "msvc-fallback") {
149033956c43SDimitry Andric Opts.setFormat(DiagnosticOptions::MSVC);
1491f785676fSDimitry Andric Opts.CLFallbackMode = true;
1492f785676fSDimitry Andric } else if (Format == "vi")
14933861d79fSDimitry Andric Opts.setFormat(DiagnosticOptions::Vi);
1494dff0c46cSDimitry Andric else {
1495dff0c46cSDimitry Andric Success = false;
1496dff0c46cSDimitry Andric if (Diags)
1497dff0c46cSDimitry Andric Diags->Report(diag::err_drv_invalid_value)
1498bd5abe19SDimitry Andric << Args.getLastArg(OPT_fdiagnostics_format)->getAsString(Args)
1499bd5abe19SDimitry Andric << Format;
1500dff0c46cSDimitry Andric }
1501bd5abe19SDimitry Andric
1502f22ef01cSRoman Divacky Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
1503e580952dSDimitry Andric Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits);
1504139f7f9bSDimitry Andric Opts.ShowPresumedLoc = !Args.hasArg(OPT_fno_diagnostics_use_presumed_location);
15059a199699SDimitry Andric Opts.VerifyDiagnostics = Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ);
15069a199699SDimitry Andric Opts.VerifyPrefixes = Args.getAllArgValues(OPT_verify_EQ);
15079a199699SDimitry Andric if (Args.hasArg(OPT_verify))
15089a199699SDimitry Andric Opts.VerifyPrefixes.push_back("expected");
15099a199699SDimitry Andric // Keep VerifyPrefixes in its original order for the sake of diagnostics, and
15109a199699SDimitry Andric // then sort it to prepare for fast lookup using std::binary_search.
15119a199699SDimitry Andric if (!checkVerifyPrefixes(Opts.VerifyPrefixes, Diags)) {
15129a199699SDimitry Andric Opts.VerifyDiagnostics = false;
15139a199699SDimitry Andric Success = false;
15149a199699SDimitry Andric }
15159a199699SDimitry Andric else
1516*b5893f02SDimitry Andric llvm::sort(Opts.VerifyPrefixes);
15178f0fd8f6SDimitry Andric DiagnosticLevelMask DiagMask = DiagnosticLevelMask::None;
15188f0fd8f6SDimitry Andric Success &= parseDiagnosticLevelMask("-verify-ignore-unexpected=",
15198f0fd8f6SDimitry Andric Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ),
15208f0fd8f6SDimitry Andric Diags, DiagMask);
15218f0fd8f6SDimitry Andric if (Args.hasArg(OPT_verify_ignore_unexpected))
15228f0fd8f6SDimitry Andric DiagMask = DiagnosticLevelMask::All;
15238f0fd8f6SDimitry Andric Opts.setVerifyIgnoreUnexpected(DiagMask);
15247ae0e2c9SDimitry Andric Opts.ElideType = !Args.hasArg(OPT_fno_elide_type);
15257ae0e2c9SDimitry Andric Opts.ShowTemplateTree = Args.hasArg(OPT_fdiagnostics_show_template_tree);
1526f785676fSDimitry Andric Opts.ErrorLimit = getLastArgIntValue(Args, OPT_ferror_limit, 0, Diags);
1527f785676fSDimitry Andric Opts.MacroBacktraceLimit =
1528f785676fSDimitry Andric getLastArgIntValue(Args, OPT_fmacro_backtrace_limit,
1529f22ef01cSRoman Divacky DiagnosticOptions::DefaultMacroBacktraceLimit, Diags);
1530f785676fSDimitry Andric Opts.TemplateBacktraceLimit = getLastArgIntValue(
1531f785676fSDimitry Andric Args, OPT_ftemplate_backtrace_limit,
1532f785676fSDimitry Andric DiagnosticOptions::DefaultTemplateBacktraceLimit, Diags);
1533f785676fSDimitry Andric Opts.ConstexprBacktraceLimit = getLastArgIntValue(
1534f785676fSDimitry Andric Args, OPT_fconstexpr_backtrace_limit,
1535f785676fSDimitry Andric DiagnosticOptions::DefaultConstexprBacktraceLimit, Diags);
153639d628a0SDimitry Andric Opts.SpellCheckingLimit = getLastArgIntValue(
153739d628a0SDimitry Andric Args, OPT_fspell_checking_limit,
153839d628a0SDimitry Andric DiagnosticOptions::DefaultSpellCheckingLimit, Diags);
1539302affcbSDimitry Andric Opts.SnippetLineLimit = getLastArgIntValue(
1540302affcbSDimitry Andric Args, OPT_fcaret_diagnostics_max_lines,
1541302affcbSDimitry Andric DiagnosticOptions::DefaultSnippetLineLimit, Diags);
1542f785676fSDimitry Andric Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop,
1543f22ef01cSRoman Divacky DiagnosticOptions::DefaultTabStop, Diags);
1544f22ef01cSRoman Divacky if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
1545f22ef01cSRoman Divacky Opts.TabStop = DiagnosticOptions::DefaultTabStop;
1546dff0c46cSDimitry Andric if (Diags)
1547dff0c46cSDimitry Andric Diags->Report(diag::warn_ignoring_ftabstop_value)
1548dff0c46cSDimitry Andric << Opts.TabStop << DiagnosticOptions::DefaultTabStop;
1549f22ef01cSRoman Divacky }
1550f785676fSDimitry Andric Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags);
155159d1ed5bSDimitry Andric addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings);
155259d1ed5bSDimitry Andric addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks);
1553dff0c46cSDimitry Andric
1554dff0c46cSDimitry Andric return Success;
1555f22ef01cSRoman Divacky }
1556f22ef01cSRoman Divacky
ParseFileSystemArgs(FileSystemOptions & Opts,ArgList & Args)15572754fe60SDimitry Andric static void ParseFileSystemArgs(FileSystemOptions &Opts, ArgList &Args) {
15582754fe60SDimitry Andric Opts.WorkingDir = Args.getLastArgValue(OPT_working_directory);
15592754fe60SDimitry Andric }
15602754fe60SDimitry Andric
15610623d748SDimitry Andric /// Parse the argument to the -ftest-module-file-extension
15620623d748SDimitry Andric /// command-line argument.
15630623d748SDimitry Andric ///
15640623d748SDimitry Andric /// \returns true on error, false on success.
parseTestModuleFileExtensionArg(StringRef Arg,std::string & BlockName,unsigned & MajorVersion,unsigned & MinorVersion,bool & Hashed,std::string & UserInfo)15650623d748SDimitry Andric static bool parseTestModuleFileExtensionArg(StringRef Arg,
15660623d748SDimitry Andric std::string &BlockName,
15670623d748SDimitry Andric unsigned &MajorVersion,
15680623d748SDimitry Andric unsigned &MinorVersion,
15690623d748SDimitry Andric bool &Hashed,
15700623d748SDimitry Andric std::string &UserInfo) {
15710623d748SDimitry Andric SmallVector<StringRef, 5> Args;
15720623d748SDimitry Andric Arg.split(Args, ':', 5);
15730623d748SDimitry Andric if (Args.size() < 5)
15740623d748SDimitry Andric return true;
15750623d748SDimitry Andric
15760623d748SDimitry Andric BlockName = Args[0];
15770623d748SDimitry Andric if (Args[1].getAsInteger(10, MajorVersion)) return true;
15780623d748SDimitry Andric if (Args[2].getAsInteger(10, MinorVersion)) return true;
15790623d748SDimitry Andric if (Args[3].getAsInteger(2, Hashed)) return true;
15800623d748SDimitry Andric if (Args.size() > 4)
15810623d748SDimitry Andric UserInfo = Args[4];
15820623d748SDimitry Andric return false;
15830623d748SDimitry Andric }
15840623d748SDimitry Andric
ParseFrontendArgs(FrontendOptions & Opts,ArgList & Args,DiagnosticsEngine & Diags,bool & IsHeaderFile)1585ffd1746dSEd Schouten static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
158644290647SDimitry Andric DiagnosticsEngine &Diags,
158744290647SDimitry Andric bool &IsHeaderFile) {
1588f22ef01cSRoman Divacky Opts.ProgramAction = frontend::ParseSyntaxOnly;
1589f22ef01cSRoman Divacky if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
1590f22ef01cSRoman Divacky switch (A->getOption().getID()) {
1591f22ef01cSRoman Divacky default:
15926122f3e6SDimitry Andric llvm_unreachable("Invalid option in group!");
15937ae0e2c9SDimitry Andric case OPT_ast_list:
15947ae0e2c9SDimitry Andric Opts.ProgramAction = frontend::ASTDeclList; break;
1595f22ef01cSRoman Divacky case OPT_ast_dump:
159620e90f04SDimitry Andric case OPT_ast_dump_all:
159739d628a0SDimitry Andric case OPT_ast_dump_lookups:
1598f22ef01cSRoman Divacky Opts.ProgramAction = frontend::ASTDump; break;
1599f22ef01cSRoman Divacky case OPT_ast_print:
1600f22ef01cSRoman Divacky Opts.ProgramAction = frontend::ASTPrint; break;
1601f22ef01cSRoman Divacky case OPT_ast_view:
1602f22ef01cSRoman Divacky Opts.ProgramAction = frontend::ASTView; break;
16034ba319b5SDimitry Andric case OPT_compiler_options_dump:
16044ba319b5SDimitry Andric Opts.ProgramAction = frontend::DumpCompilerOptions; break;
1605f22ef01cSRoman Divacky case OPT_dump_raw_tokens:
1606f22ef01cSRoman Divacky Opts.ProgramAction = frontend::DumpRawTokens; break;
1607f22ef01cSRoman Divacky case OPT_dump_tokens:
1608f22ef01cSRoman Divacky Opts.ProgramAction = frontend::DumpTokens; break;
1609f22ef01cSRoman Divacky case OPT_S:
1610f22ef01cSRoman Divacky Opts.ProgramAction = frontend::EmitAssembly; break;
1611f22ef01cSRoman Divacky case OPT_emit_llvm_bc:
1612f22ef01cSRoman Divacky Opts.ProgramAction = frontend::EmitBC; break;
1613f22ef01cSRoman Divacky case OPT_emit_html:
1614f22ef01cSRoman Divacky Opts.ProgramAction = frontend::EmitHTML; break;
1615f22ef01cSRoman Divacky case OPT_emit_llvm:
1616f22ef01cSRoman Divacky Opts.ProgramAction = frontend::EmitLLVM; break;
1617f22ef01cSRoman Divacky case OPT_emit_llvm_only:
1618f22ef01cSRoman Divacky Opts.ProgramAction = frontend::EmitLLVMOnly; break;
1619f22ef01cSRoman Divacky case OPT_emit_codegen_only:
1620f22ef01cSRoman Divacky Opts.ProgramAction = frontend::EmitCodeGenOnly; break;
1621f22ef01cSRoman Divacky case OPT_emit_obj:
1622f22ef01cSRoman Divacky Opts.ProgramAction = frontend::EmitObj; break;
1623f22ef01cSRoman Divacky case OPT_fixit_EQ:
16243861d79fSDimitry Andric Opts.FixItSuffix = A->getValue();
1625*b5893f02SDimitry Andric LLVM_FALLTHROUGH;
1626f22ef01cSRoman Divacky case OPT_fixit:
1627f22ef01cSRoman Divacky Opts.ProgramAction = frontend::FixIt; break;
16286122f3e6SDimitry Andric case OPT_emit_module:
16296122f3e6SDimitry Andric Opts.ProgramAction = frontend::GenerateModule; break;
163044290647SDimitry Andric case OPT_emit_module_interface:
163144290647SDimitry Andric Opts.ProgramAction = frontend::GenerateModuleInterface; break;
1632*b5893f02SDimitry Andric case OPT_emit_header_module:
1633*b5893f02SDimitry Andric Opts.ProgramAction = frontend::GenerateHeaderModule; break;
1634f22ef01cSRoman Divacky case OPT_emit_pch:
1635f22ef01cSRoman Divacky Opts.ProgramAction = frontend::GeneratePCH; break;
1636f22ef01cSRoman Divacky case OPT_init_only:
1637f22ef01cSRoman Divacky Opts.ProgramAction = frontend::InitOnly; break;
1638f22ef01cSRoman Divacky case OPT_fsyntax_only:
1639f22ef01cSRoman Divacky Opts.ProgramAction = frontend::ParseSyntaxOnly; break;
1640139f7f9bSDimitry Andric case OPT_module_file_info:
1641139f7f9bSDimitry Andric Opts.ProgramAction = frontend::ModuleFileInfo; break;
164259d1ed5bSDimitry Andric case OPT_verify_pch:
164359d1ed5bSDimitry Andric Opts.ProgramAction = frontend::VerifyPCH; break;
1644e580952dSDimitry Andric case OPT_print_preamble:
1645e580952dSDimitry Andric Opts.ProgramAction = frontend::PrintPreamble; break;
1646f22ef01cSRoman Divacky case OPT_E:
1647f22ef01cSRoman Divacky Opts.ProgramAction = frontend::PrintPreprocessedInput; break;
16484ba319b5SDimitry Andric case OPT_templight_dump:
16494ba319b5SDimitry Andric Opts.ProgramAction = frontend::TemplightDump; break;
1650f22ef01cSRoman Divacky case OPT_rewrite_macros:
1651f22ef01cSRoman Divacky Opts.ProgramAction = frontend::RewriteMacros; break;
1652f22ef01cSRoman Divacky case OPT_rewrite_objc:
1653f22ef01cSRoman Divacky Opts.ProgramAction = frontend::RewriteObjC; break;
1654f22ef01cSRoman Divacky case OPT_rewrite_test:
1655f22ef01cSRoman Divacky Opts.ProgramAction = frontend::RewriteTest; break;
1656f22ef01cSRoman Divacky case OPT_analyze:
1657f22ef01cSRoman Divacky Opts.ProgramAction = frontend::RunAnalysis; break;
1658dff0c46cSDimitry Andric case OPT_migrate:
1659dff0c46cSDimitry Andric Opts.ProgramAction = frontend::MigrateSource; break;
1660f22ef01cSRoman Divacky case OPT_Eonly:
1661f22ef01cSRoman Divacky Opts.ProgramAction = frontend::RunPreprocessorOnly; break;
1662f22ef01cSRoman Divacky }
1663f22ef01cSRoman Divacky }
1664ffd1746dSEd Schouten
1665f22ef01cSRoman Divacky if (const Arg* A = Args.getLastArg(OPT_plugin)) {
166697bc6c73SDimitry Andric Opts.Plugins.emplace_back(A->getValue(0));
1667f22ef01cSRoman Divacky Opts.ProgramAction = frontend::PluginAction;
16683861d79fSDimitry Andric Opts.ActionName = A->getValue();
1669f22ef01cSRoman Divacky }
16702754fe60SDimitry Andric Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin);
16714ba319b5SDimitry Andric for (const auto *AA : Args.filtered(OPT_plugin_arg))
1672e7145dcbSDimitry Andric Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
16732754fe60SDimitry Andric
16740623d748SDimitry Andric for (const std::string &Arg :
16750623d748SDimitry Andric Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) {
16760623d748SDimitry Andric std::string BlockName;
16770623d748SDimitry Andric unsigned MajorVersion;
16780623d748SDimitry Andric unsigned MinorVersion;
16790623d748SDimitry Andric bool Hashed;
16800623d748SDimitry Andric std::string UserInfo;
16810623d748SDimitry Andric if (parseTestModuleFileExtensionArg(Arg, BlockName, MajorVersion,
16820623d748SDimitry Andric MinorVersion, Hashed, UserInfo)) {
16830623d748SDimitry Andric Diags.Report(diag::err_test_module_file_extension_format) << Arg;
16840623d748SDimitry Andric
16850623d748SDimitry Andric continue;
16860623d748SDimitry Andric }
16870623d748SDimitry Andric
16880623d748SDimitry Andric // Add the testing module file extension.
16890623d748SDimitry Andric Opts.ModuleFileExtensions.push_back(
169095ec533aSDimitry Andric std::make_shared<TestModuleFileExtension>(
169195ec533aSDimitry Andric BlockName, MajorVersion, MinorVersion, Hashed, UserInfo));
16920623d748SDimitry Andric }
16930623d748SDimitry Andric
1694f22ef01cSRoman Divacky if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
1695f22ef01cSRoman Divacky Opts.CodeCompletionAt =
16963861d79fSDimitry Andric ParsedSourceLocation::FromString(A->getValue());
1697f22ef01cSRoman Divacky if (Opts.CodeCompletionAt.FileName.empty())
1698f22ef01cSRoman Divacky Diags.Report(diag::err_drv_invalid_value)
16993861d79fSDimitry Andric << A->getAsString(Args) << A->getValue();
1700f22ef01cSRoman Divacky }
1701f22ef01cSRoman Divacky Opts.DisableFree = Args.hasArg(OPT_disable_free);
1702f22ef01cSRoman Divacky
1703f22ef01cSRoman Divacky Opts.OutputFile = Args.getLastArgValue(OPT_o);
1704f22ef01cSRoman Divacky Opts.Plugins = Args.getAllArgValues(OPT_load);
1705f22ef01cSRoman Divacky Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch);
1706f22ef01cSRoman Divacky Opts.ShowHelp = Args.hasArg(OPT_help);
1707f22ef01cSRoman Divacky Opts.ShowStats = Args.hasArg(OPT_print_stats);
1708f22ef01cSRoman Divacky Opts.ShowTimers = Args.hasArg(OPT_ftime_report);
1709f22ef01cSRoman Divacky Opts.ShowVersion = Args.hasArg(OPT_version);
1710f22ef01cSRoman Divacky Opts.ASTMergeFiles = Args.getAllArgValues(OPT_ast_merge);
1711f22ef01cSRoman Divacky Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
1712e580952dSDimitry Andric Opts.FixWhatYouCan = Args.hasArg(OPT_fix_what_you_can);
1713dff0c46cSDimitry Andric Opts.FixOnlyWarnings = Args.hasArg(OPT_fix_only_warnings);
1714dff0c46cSDimitry Andric Opts.FixAndRecompile = Args.hasArg(OPT_fixit_recompile);
1715dff0c46cSDimitry Andric Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp);
171639d628a0SDimitry Andric Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump);
171720e90f04SDimitry Andric Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all);
17187ae0e2c9SDimitry Andric Opts.ASTDumpFilter = Args.getLastArgValue(OPT_ast_dump_filter);
1719f785676fSDimitry Andric Opts.ASTDumpLookups = Args.hasArg(OPT_ast_dump_lookups);
1720139f7f9bSDimitry Andric Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index);
1721139f7f9bSDimitry Andric Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex;
172239d628a0SDimitry Andric Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file);
17239a199699SDimitry Andric // Only the -fmodule-file=<file> form.
17244ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_fmodule_file)) {
17259a199699SDimitry Andric StringRef Val = A->getValue();
17269a199699SDimitry Andric if (Val.find('=') == StringRef::npos)
17279a199699SDimitry Andric Opts.ModuleFiles.push_back(Val);
17289a199699SDimitry Andric }
17290623d748SDimitry Andric Opts.ModulesEmbedFiles = Args.getAllArgValues(OPT_fmodules_embed_file_EQ);
17300623d748SDimitry Andric Opts.ModulesEmbedAllFiles = Args.hasArg(OPT_fmodules_embed_all_files);
1731e7145dcbSDimitry Andric Opts.IncludeTimestamps = !Args.hasArg(OPT_fno_pch_timestamp);
17327ae0e2c9SDimitry Andric
17337ae0e2c9SDimitry Andric Opts.CodeCompleteOpts.IncludeMacros
17347ae0e2c9SDimitry Andric = Args.hasArg(OPT_code_completion_macros);
17357ae0e2c9SDimitry Andric Opts.CodeCompleteOpts.IncludeCodePatterns
17367ae0e2c9SDimitry Andric = Args.hasArg(OPT_code_completion_patterns);
17377ae0e2c9SDimitry Andric Opts.CodeCompleteOpts.IncludeGlobals
17387ae0e2c9SDimitry Andric = !Args.hasArg(OPT_no_code_completion_globals);
17399a199699SDimitry Andric Opts.CodeCompleteOpts.IncludeNamespaceLevelDecls
17409a199699SDimitry Andric = !Args.hasArg(OPT_no_code_completion_ns_level_decls);
17417ae0e2c9SDimitry Andric Opts.CodeCompleteOpts.IncludeBriefComments
17427ae0e2c9SDimitry Andric = Args.hasArg(OPT_code_completion_brief_comments);
17434ba319b5SDimitry Andric Opts.CodeCompleteOpts.IncludeFixIts
17444ba319b5SDimitry Andric = Args.hasArg(OPT_code_completion_with_fixits);
17457ae0e2c9SDimitry Andric
1746dff0c46cSDimitry Andric Opts.OverrideRecordLayoutsFile
1747dff0c46cSDimitry Andric = Args.getLastArgValue(OPT_foverride_record_layout_EQ);
1748*b5893f02SDimitry Andric Opts.AuxTriple = Args.getLastArgValue(OPT_aux_triple);
174944290647SDimitry Andric Opts.StatsFile = Args.getLastArgValue(OPT_stats_file);
17500623d748SDimitry Andric
175117a519f9SDimitry Andric if (const Arg *A = Args.getLastArg(OPT_arcmt_check,
175217a519f9SDimitry Andric OPT_arcmt_modify,
175317a519f9SDimitry Andric OPT_arcmt_migrate)) {
175417a519f9SDimitry Andric switch (A->getOption().getID()) {
175517a519f9SDimitry Andric default:
175617a519f9SDimitry Andric llvm_unreachable("missed a case");
175717a519f9SDimitry Andric case OPT_arcmt_check:
175817a519f9SDimitry Andric Opts.ARCMTAction = FrontendOptions::ARCMT_Check;
175917a519f9SDimitry Andric break;
176017a519f9SDimitry Andric case OPT_arcmt_modify:
176117a519f9SDimitry Andric Opts.ARCMTAction = FrontendOptions::ARCMT_Modify;
176217a519f9SDimitry Andric break;
176317a519f9SDimitry Andric case OPT_arcmt_migrate:
176417a519f9SDimitry Andric Opts.ARCMTAction = FrontendOptions::ARCMT_Migrate;
176517a519f9SDimitry Andric break;
176617a519f9SDimitry Andric }
176717a519f9SDimitry Andric }
1768dff0c46cSDimitry Andric Opts.MTMigrateDir = Args.getLastArgValue(OPT_mt_migrate_directory);
17696122f3e6SDimitry Andric Opts.ARCMTMigrateReportOut
17706122f3e6SDimitry Andric = Args.getLastArgValue(OPT_arcmt_migrate_report_output);
17716122f3e6SDimitry Andric Opts.ARCMTMigrateEmitARCErrors
17726122f3e6SDimitry Andric = Args.hasArg(OPT_arcmt_migrate_emit_arc_errors);
177317a519f9SDimitry Andric
1774dff0c46cSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_literals))
1775dff0c46cSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Literals;
1776dff0c46cSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_subscripting))
1777dff0c46cSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Subscripting;
177839d628a0SDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_property_dot_syntax))
177939d628a0SDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_PropertyDotSyntax;
1780f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_property))
1781f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Property;
1782f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_readonly_property))
1783f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReadonlyProperty;
1784f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_readwrite_property))
1785f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReadwriteProperty;
1786f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_annotation))
1787f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Annotation;
1788f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_returns_innerpointer_property))
1789f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReturnsInnerPointerProperty;
1790f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_instancetype))
1791f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Instancetype;
1792f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_nsmacros))
1793f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsMacros;
1794f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_protocol_conformance))
1795f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ProtocolConformance;
1796f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_atomic_property))
1797f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_AtomicProperty;
1798f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_ns_nonatomic_iosonly))
1799f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty;
180059d1ed5bSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_designated_init))
180159d1ed5bSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_DesignatedInitializer;
1802f785676fSDimitry Andric if (Args.hasArg(OPT_objcmt_migrate_all))
1803f785676fSDimitry Andric Opts.ObjCMTAction |= FrontendOptions::ObjCMT_MigrateDecls;
1804f785676fSDimitry Andric
180559d1ed5bSDimitry Andric Opts.ObjCMTWhiteListPath = Args.getLastArgValue(OPT_objcmt_whitelist_dir_path);
1806dff0c46cSDimitry Andric
1807dff0c46cSDimitry Andric if (Opts.ARCMTAction != FrontendOptions::ARCMT_None &&
1808dff0c46cSDimitry Andric Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) {
1809dff0c46cSDimitry Andric Diags.Report(diag::err_drv_argument_not_allowed_with)
1810dff0c46cSDimitry Andric << "ARC migration" << "ObjC migration";
1811dff0c46cSDimitry Andric }
1812dff0c46cSDimitry Andric
1813f37b6182SDimitry Andric InputKind DashX(InputKind::Unknown);
1814f22ef01cSRoman Divacky if (const Arg *A = Args.getLastArg(OPT_x)) {
1815f37b6182SDimitry Andric StringRef XValue = A->getValue();
1816f37b6182SDimitry Andric
1817f37b6182SDimitry Andric // Parse suffixes: '<lang>(-header|[-module-map][-cpp-output])'.
1818f37b6182SDimitry Andric // FIXME: Supporting '<lang>-header-cpp-output' would be useful.
1819f37b6182SDimitry Andric bool Preprocessed = XValue.consume_back("-cpp-output");
1820f37b6182SDimitry Andric bool ModuleMap = XValue.consume_back("-module-map");
1821f37b6182SDimitry Andric IsHeaderFile =
1822f37b6182SDimitry Andric !Preprocessed && !ModuleMap && XValue.consume_back("-header");
1823f37b6182SDimitry Andric
1824f37b6182SDimitry Andric // Principal languages.
1825f37b6182SDimitry Andric DashX = llvm::StringSwitch<InputKind>(XValue)
1826f37b6182SDimitry Andric .Case("c", InputKind::C)
1827f37b6182SDimitry Andric .Case("cl", InputKind::OpenCL)
1828f37b6182SDimitry Andric .Case("cuda", InputKind::CUDA)
18294ba319b5SDimitry Andric .Case("hip", InputKind::HIP)
1830f37b6182SDimitry Andric .Case("c++", InputKind::CXX)
1831f37b6182SDimitry Andric .Case("objective-c", InputKind::ObjC)
1832f37b6182SDimitry Andric .Case("objective-c++", InputKind::ObjCXX)
1833f37b6182SDimitry Andric .Case("renderscript", InputKind::RenderScript)
1834f37b6182SDimitry Andric .Default(InputKind::Unknown);
1835f37b6182SDimitry Andric
1836f37b6182SDimitry Andric // "objc[++]-cpp-output" is an acceptable synonym for
1837f37b6182SDimitry Andric // "objective-c[++]-cpp-output".
1838f37b6182SDimitry Andric if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && !ModuleMap)
1839f37b6182SDimitry Andric DashX = llvm::StringSwitch<InputKind>(XValue)
1840f37b6182SDimitry Andric .Case("objc", InputKind::ObjC)
1841f37b6182SDimitry Andric .Case("objc++", InputKind::ObjCXX)
1842f37b6182SDimitry Andric .Default(InputKind::Unknown);
1843f37b6182SDimitry Andric
1844f37b6182SDimitry Andric // Some special cases cannot be combined with suffixes.
1845f37b6182SDimitry Andric if (DashX.isUnknown() && !Preprocessed && !ModuleMap && !IsHeaderFile)
1846f37b6182SDimitry Andric DashX = llvm::StringSwitch<InputKind>(XValue)
1847f37b6182SDimitry Andric .Case("cpp-output", InputKind(InputKind::C).getPreprocessed())
1848f37b6182SDimitry Andric .Case("assembler-with-cpp", InputKind::Asm)
1849f37b6182SDimitry Andric .Cases("ast", "pcm",
1850f37b6182SDimitry Andric InputKind(InputKind::Unknown, InputKind::Precompiled))
1851f37b6182SDimitry Andric .Case("ir", InputKind::LLVM_IR)
1852f37b6182SDimitry Andric .Default(InputKind::Unknown);
1853f37b6182SDimitry Andric
1854f37b6182SDimitry Andric if (DashX.isUnknown())
1855f22ef01cSRoman Divacky Diags.Report(diag::err_drv_invalid_value)
18563861d79fSDimitry Andric << A->getAsString(Args) << A->getValue();
1857f37b6182SDimitry Andric
1858f37b6182SDimitry Andric if (Preprocessed)
1859f37b6182SDimitry Andric DashX = DashX.getPreprocessed();
1860f37b6182SDimitry Andric if (ModuleMap)
1861f37b6182SDimitry Andric DashX = DashX.withFormat(InputKind::ModuleMap);
1862f22ef01cSRoman Divacky }
1863f22ef01cSRoman Divacky
1864f22ef01cSRoman Divacky // '-' is the default input if none is given.
1865f22ef01cSRoman Divacky std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
1866f22ef01cSRoman Divacky Opts.Inputs.clear();
1867f22ef01cSRoman Divacky if (Inputs.empty())
1868f22ef01cSRoman Divacky Inputs.push_back("-");
1869f22ef01cSRoman Divacky for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
1870ffd1746dSEd Schouten InputKind IK = DashX;
1871f37b6182SDimitry Andric if (IK.isUnknown()) {
1872f22ef01cSRoman Divacky IK = FrontendOptions::getInputKindForExtension(
18736122f3e6SDimitry Andric StringRef(Inputs[i]).rsplit('.').second);
1874f37b6182SDimitry Andric // FIXME: Warn on this?
1875f37b6182SDimitry Andric if (IK.isUnknown())
1876f37b6182SDimitry Andric IK = InputKind::C;
1877f22ef01cSRoman Divacky // FIXME: Remove this hack.
1878f22ef01cSRoman Divacky if (i == 0)
1879f22ef01cSRoman Divacky DashX = IK;
1880f22ef01cSRoman Divacky }
1881f37b6182SDimitry Andric
1882f37b6182SDimitry Andric // The -emit-module action implicitly takes a module map.
1883f37b6182SDimitry Andric if (Opts.ProgramAction == frontend::GenerateModule &&
1884f37b6182SDimitry Andric IK.getFormat() == InputKind::Source)
1885f37b6182SDimitry Andric IK = IK.withFormat(InputKind::ModuleMap);
1886f37b6182SDimitry Andric
188797bc6c73SDimitry Andric Opts.Inputs.emplace_back(std::move(Inputs[i]), IK);
1888f22ef01cSRoman Divacky }
1889f22ef01cSRoman Divacky
1890f22ef01cSRoman Divacky return DashX;
1891f22ef01cSRoman Divacky }
1892f22ef01cSRoman Divacky
GetResourcesPath(const char * Argv0,void * MainAddr)1893f22ef01cSRoman Divacky std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
1894f22ef01cSRoman Divacky void *MainAddr) {
189539d628a0SDimitry Andric std::string ClangExecutable =
189639d628a0SDimitry Andric llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
189739d628a0SDimitry Andric StringRef Dir = llvm::sys::path::parent_path(ClangExecutable);
1898f22ef01cSRoman Divacky
189939d628a0SDimitry Andric // Compute the path to the resource directory.
190039d628a0SDimitry Andric StringRef ClangResourceDir(CLANG_RESOURCE_DIR);
190139d628a0SDimitry Andric SmallString<128> P(Dir);
19020623d748SDimitry Andric if (ClangResourceDir != "")
190339d628a0SDimitry Andric llvm::sys::path::append(P, ClangResourceDir);
19040623d748SDimitry Andric else
19050623d748SDimitry Andric llvm::sys::path::append(P, "..", Twine("lib") + CLANG_LIBDIR_SUFFIX,
19060623d748SDimitry Andric "clang", CLANG_VERSION_STRING);
1907f22ef01cSRoman Divacky
1908f22ef01cSRoman Divacky return P.str();
1909f22ef01cSRoman Divacky }
1910f22ef01cSRoman Divacky
ParseHeaderSearchArgs(HeaderSearchOptions & Opts,ArgList & Args,const std::string & WorkingDir)191120e90f04SDimitry Andric static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
191220e90f04SDimitry Andric const std::string &WorkingDir) {
1913f22ef01cSRoman Divacky Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/");
1914f22ef01cSRoman Divacky Opts.Verbose = Args.hasArg(OPT_v);
1915f22ef01cSRoman Divacky Opts.UseBuiltinIncludes = !Args.hasArg(OPT_nobuiltininc);
19166122f3e6SDimitry Andric Opts.UseStandardSystemIncludes = !Args.hasArg(OPT_nostdsysteminc);
1917f22ef01cSRoman Divacky Opts.UseStandardCXXIncludes = !Args.hasArg(OPT_nostdincxx);
191817a519f9SDimitry Andric if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ))
19193861d79fSDimitry Andric Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);
1920f22ef01cSRoman Divacky Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir);
192120e90f04SDimitry Andric
192220e90f04SDimitry Andric // Canonicalize -fmodules-cache-path before storing it.
192320e90f04SDimitry Andric SmallString<128> P(Args.getLastArgValue(OPT_fmodules_cache_path));
192420e90f04SDimitry Andric if (!(P.empty() || llvm::sys::path::is_absolute(P))) {
192520e90f04SDimitry Andric if (WorkingDir.empty())
192620e90f04SDimitry Andric llvm::sys::fs::make_absolute(P);
192720e90f04SDimitry Andric else
192820e90f04SDimitry Andric llvm::sys::fs::make_absolute(WorkingDir, P);
192920e90f04SDimitry Andric }
193020e90f04SDimitry Andric llvm::sys::path::remove_dots(P);
193120e90f04SDimitry Andric Opts.ModuleCachePath = P.str();
193220e90f04SDimitry Andric
193359d1ed5bSDimitry Andric Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path);
19349a199699SDimitry Andric // Only the -fmodule-file=<name>=<file> form.
19354ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_fmodule_file)) {
19369a199699SDimitry Andric StringRef Val = A->getValue();
19379a199699SDimitry Andric if (Val.find('=') != StringRef::npos)
19389a199699SDimitry Andric Opts.PrebuiltModuleFiles.insert(Val.split('='));
19399a199699SDimitry Andric }
19404ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_fprebuilt_module_path))
194144290647SDimitry Andric Opts.AddPrebuiltModulePath(A->getValue());
19426122f3e6SDimitry Andric Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
194320e90f04SDimitry Andric Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content);
194444290647SDimitry Andric Opts.ModulesValidateDiagnosticOptions =
194544290647SDimitry Andric !Args.hasArg(OPT_fmodules_disable_diagnostic_validation);
19468f0fd8f6SDimitry Andric Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);
194739d628a0SDimitry Andric Opts.ModuleMapFileHomeIsCwd = Args.hasArg(OPT_fmodule_map_file_home_is_cwd);
1948f785676fSDimitry Andric Opts.ModuleCachePruneInterval =
1949f785676fSDimitry Andric getLastArgIntValue(Args, OPT_fmodules_prune_interval, 7 * 24 * 60 * 60);
1950f785676fSDimitry Andric Opts.ModuleCachePruneAfter =
1951f785676fSDimitry Andric getLastArgIntValue(Args, OPT_fmodules_prune_after, 31 * 24 * 60 * 60);
195259d1ed5bSDimitry Andric Opts.ModulesValidateOncePerBuildSession =
195359d1ed5bSDimitry Andric Args.hasArg(OPT_fmodules_validate_once_per_build_session);
195459d1ed5bSDimitry Andric Opts.BuildSessionTimestamp =
195559d1ed5bSDimitry Andric getLastArgUInt64Value(Args, OPT_fbuild_session_timestamp, 0);
195659d1ed5bSDimitry Andric Opts.ModulesValidateSystemHeaders =
195759d1ed5bSDimitry Andric Args.hasArg(OPT_fmodules_validate_system_headers);
1958b6c25e0eSDimitry Andric if (const Arg *A = Args.getLastArg(OPT_fmodule_format_EQ))
1959b6c25e0eSDimitry Andric Opts.ModuleFormat = A->getValue();
196059d1ed5bSDimitry Andric
19614ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) {
196297bc6c73SDimitry Andric StringRef MacroDef = A->getValue();
196344290647SDimitry Andric Opts.ModulesIgnoreMacros.insert(
196444290647SDimitry Andric llvm::CachedHashString(MacroDef.split('=').first));
1965139f7f9bSDimitry Andric }
1966f22ef01cSRoman Divacky
19676122f3e6SDimitry Andric // Add -I..., -F..., and -index-header-map options in order.
19686122f3e6SDimitry Andric bool IsIndexHeaderMap = false;
1969e7145dcbSDimitry Andric bool IsSysrootSpecified =
1970e7145dcbSDimitry Andric Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);
19714ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) {
197297bc6c73SDimitry Andric if (A->getOption().matches(OPT_index_header_map)) {
19736122f3e6SDimitry Andric // -index-header-map applies to the next -I or -F.
19746122f3e6SDimitry Andric IsIndexHeaderMap = true;
19756122f3e6SDimitry Andric continue;
19766122f3e6SDimitry Andric }
19776122f3e6SDimitry Andric
197897bc6c73SDimitry Andric frontend::IncludeDirGroup Group =
197997bc6c73SDimitry Andric IsIndexHeaderMap ? frontend::IndexHeaderMap : frontend::Angled;
19806122f3e6SDimitry Andric
1981e7145dcbSDimitry Andric bool IsFramework = A->getOption().matches(OPT_F);
1982e7145dcbSDimitry Andric std::string Path = A->getValue();
1983e7145dcbSDimitry Andric
1984e7145dcbSDimitry Andric if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') {
1985e7145dcbSDimitry Andric SmallString<32> Buffer;
1986e7145dcbSDimitry Andric llvm::sys::path::append(Buffer, Opts.Sysroot,
1987e7145dcbSDimitry Andric llvm::StringRef(A->getValue()).substr(1));
1988e7145dcbSDimitry Andric Path = Buffer.str();
1989e7145dcbSDimitry Andric }
1990e7145dcbSDimitry Andric
199144290647SDimitry Andric Opts.AddPath(Path, Group, IsFramework,
1992e7145dcbSDimitry Andric /*IgnoreSysroot*/ true);
19936122f3e6SDimitry Andric IsIndexHeaderMap = false;
19946122f3e6SDimitry Andric }
1995f22ef01cSRoman Divacky
1996139f7f9bSDimitry Andric // Add -iprefix/-iwithprefix/-iwithprefixbefore options.
19976122f3e6SDimitry Andric StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
19984ba319b5SDimitry Andric for (const auto *A :
199997bc6c73SDimitry Andric Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {
2000ffd1746dSEd Schouten if (A->getOption().matches(OPT_iprefix))
20013861d79fSDimitry Andric Prefix = A->getValue();
2002ffd1746dSEd Schouten else if (A->getOption().matches(OPT_iwithprefix))
200397bc6c73SDimitry Andric Opts.AddPath(Prefix.str() + A->getValue(), frontend::After, false, true);
2004f22ef01cSRoman Divacky else
200597bc6c73SDimitry Andric Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true);
2006f22ef01cSRoman Divacky }
2007f22ef01cSRoman Divacky
20084ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_idirafter))
200997bc6c73SDimitry Andric Opts.AddPath(A->getValue(), frontend::After, false, true);
20104ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_iquote))
201197bc6c73SDimitry Andric Opts.AddPath(A->getValue(), frontend::Quoted, false, true);
20124ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot))
201397bc6c73SDimitry Andric Opts.AddPath(A->getValue(), frontend::System, false,
201497bc6c73SDimitry Andric !A->getOption().matches(OPT_iwithsysroot));
20154ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_iframework))
201697bc6c73SDimitry Andric Opts.AddPath(A->getValue(), frontend::System, true, true);
20174ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot))
201820e90f04SDimitry Andric Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true,
201920e90f04SDimitry Andric /*IgnoreSysRoot=*/false);
2020f22ef01cSRoman Divacky
20216122f3e6SDimitry Andric // Add the paths for the various language specific isystem flags.
20224ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_c_isystem))
202397bc6c73SDimitry Andric Opts.AddPath(A->getValue(), frontend::CSystem, false, true);
20244ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_cxx_isystem))
202597bc6c73SDimitry Andric Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true);
20264ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_objc_isystem))
202797bc6c73SDimitry Andric Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true);
20284ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_objcxx_isystem))
202997bc6c73SDimitry Andric Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true);
2030f8254f43SDimitry Andric
2031f8254f43SDimitry Andric // Add the internal paths from a driver that detects standard include paths.
20324ba319b5SDimitry Andric for (const auto *A :
203397bc6c73SDimitry Andric Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
2034139f7f9bSDimitry Andric frontend::IncludeDirGroup Group = frontend::System;
203597bc6c73SDimitry Andric if (A->getOption().matches(OPT_internal_externc_isystem))
2036139f7f9bSDimitry Andric Group = frontend::ExternCSystem;
203797bc6c73SDimitry Andric Opts.AddPath(A->getValue(), Group, false, true);
2038139f7f9bSDimitry Andric }
20397ae0e2c9SDimitry Andric
20407ae0e2c9SDimitry Andric // Add the path prefixes which are implicitly treated as being system headers.
20414ba319b5SDimitry Andric for (const auto *A :
204297bc6c73SDimitry Andric Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
204359d1ed5bSDimitry Andric Opts.AddSystemHeaderPrefix(
204497bc6c73SDimitry Andric A->getValue(), A->getOption().matches(OPT_system_header_prefix));
204559d1ed5bSDimitry Andric
20464ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_ivfsoverlay))
204797bc6c73SDimitry Andric Opts.AddVFSOverlayFile(A->getValue());
2048f22ef01cSRoman Divacky }
2049f22ef01cSRoman Divacky
setLangDefaults(LangOptions & Opts,InputKind IK,const llvm::Triple & T,PreprocessorOptions & PPOpts,LangStandard::Kind LangStd)20502754fe60SDimitry Andric void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
2051e7145dcbSDimitry Andric const llvm::Triple &T,
2052e7145dcbSDimitry Andric PreprocessorOptions &PPOpts,
20532754fe60SDimitry Andric LangStandard::Kind LangStd) {
20543b0f4066SDimitry Andric // Set some properties which depend solely on the input kind; it would be nice
2055f22ef01cSRoman Divacky // to move these to the language standard, and have the driver resolve the
2056f22ef01cSRoman Divacky // input kind + language standard.
2057f37b6182SDimitry Andric //
2058f37b6182SDimitry Andric // FIXME: Perhaps a better model would be for a single source file to have
2059f37b6182SDimitry Andric // multiple language standards (C / C++ std, ObjC std, OpenCL std, OpenMP std)
2060f37b6182SDimitry Andric // simultaneously active?
2061f37b6182SDimitry Andric if (IK.getLanguage() == InputKind::Asm) {
2062f22ef01cSRoman Divacky Opts.AsmPreprocessor = 1;
2063f37b6182SDimitry Andric } else if (IK.isObjectiveC()) {
2064*b5893f02SDimitry Andric Opts.ObjC = 1;
2065f22ef01cSRoman Divacky }
2066f22ef01cSRoman Divacky
2067f22ef01cSRoman Divacky if (LangStd == LangStandard::lang_unspecified) {
2068f22ef01cSRoman Divacky // Based on the base language, pick one.
2069f37b6182SDimitry Andric switch (IK.getLanguage()) {
2070f37b6182SDimitry Andric case InputKind::Unknown:
2071f37b6182SDimitry Andric case InputKind::LLVM_IR:
20726122f3e6SDimitry Andric llvm_unreachable("Invalid input kind!");
2073f37b6182SDimitry Andric case InputKind::OpenCL:
2074f37b6182SDimitry Andric LangStd = LangStandard::lang_opencl10;
2075f22ef01cSRoman Divacky break;
2076f37b6182SDimitry Andric case InputKind::CUDA:
20772754fe60SDimitry Andric LangStd = LangStandard::lang_cuda;
20782754fe60SDimitry Andric break;
2079f37b6182SDimitry Andric case InputKind::Asm:
2080f37b6182SDimitry Andric case InputKind::C:
20814ba319b5SDimitry Andric #if defined(CLANG_DEFAULT_STD_C)
20824ba319b5SDimitry Andric LangStd = CLANG_DEFAULT_STD_C;
20834ba319b5SDimitry Andric #else
2084e7145dcbSDimitry Andric // The PS4 uses C99 as the default C standard.
2085e7145dcbSDimitry Andric if (T.isPS4())
2086e7145dcbSDimitry Andric LangStd = LangStandard::lang_gnu99;
2087e7145dcbSDimitry Andric else
208839d628a0SDimitry Andric LangStd = LangStandard::lang_gnu11;
20894ba319b5SDimitry Andric #endif
2090f22ef01cSRoman Divacky break;
2091f37b6182SDimitry Andric case InputKind::ObjC:
20924ba319b5SDimitry Andric #if defined(CLANG_DEFAULT_STD_C)
20934ba319b5SDimitry Andric LangStd = CLANG_DEFAULT_STD_C;
20944ba319b5SDimitry Andric #else
209544290647SDimitry Andric LangStd = LangStandard::lang_gnu11;
20964ba319b5SDimitry Andric #endif
209744290647SDimitry Andric break;
2098f37b6182SDimitry Andric case InputKind::CXX:
2099f37b6182SDimitry Andric case InputKind::ObjCXX:
21004ba319b5SDimitry Andric #if defined(CLANG_DEFAULT_STD_CXX)
21014ba319b5SDimitry Andric LangStd = CLANG_DEFAULT_STD_CXX;
21024ba319b5SDimitry Andric #else
21039a199699SDimitry Andric LangStd = LangStandard::lang_gnucxx14;
21044ba319b5SDimitry Andric #endif
2105f22ef01cSRoman Divacky break;
2106f37b6182SDimitry Andric case InputKind::RenderScript:
2107e7145dcbSDimitry Andric LangStd = LangStandard::lang_c99;
2108e7145dcbSDimitry Andric break;
21094ba319b5SDimitry Andric case InputKind::HIP:
21104ba319b5SDimitry Andric LangStd = LangStandard::lang_hip;
21114ba319b5SDimitry Andric break;
2112f22ef01cSRoman Divacky }
2113f22ef01cSRoman Divacky }
2114f22ef01cSRoman Divacky
2115f22ef01cSRoman Divacky const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
21163861d79fSDimitry Andric Opts.LineComment = Std.hasLineComments();
2117f22ef01cSRoman Divacky Opts.C99 = Std.isC99();
2118dff0c46cSDimitry Andric Opts.C11 = Std.isC11();
21199a199699SDimitry Andric Opts.C17 = Std.isC17();
2120f22ef01cSRoman Divacky Opts.CPlusPlus = Std.isCPlusPlus();
2121139f7f9bSDimitry Andric Opts.CPlusPlus11 = Std.isCPlusPlus11();
212239d628a0SDimitry Andric Opts.CPlusPlus14 = Std.isCPlusPlus14();
21239a199699SDimitry Andric Opts.CPlusPlus17 = Std.isCPlusPlus17();
2124b40b48b8SDimitry Andric Opts.CPlusPlus2a = Std.isCPlusPlus2a();
2125f22ef01cSRoman Divacky Opts.Digraphs = Std.hasDigraphs();
2126f22ef01cSRoman Divacky Opts.GNUMode = Std.isGNUMode();
2127f37b6182SDimitry Andric Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus;
2128f22ef01cSRoman Divacky Opts.HexFloats = Std.hasHexFloats();
2129f22ef01cSRoman Divacky Opts.ImplicitInt = Std.hasImplicitInt();
2130f22ef01cSRoman Divacky
21317ae0e2c9SDimitry Andric // Set OpenCL Version.
2132f37b6182SDimitry Andric Opts.OpenCL = Std.isOpenCL();
2133f37b6182SDimitry Andric if (LangStd == LangStandard::lang_opencl10)
21347ae0e2c9SDimitry Andric Opts.OpenCLVersion = 100;
213559d1ed5bSDimitry Andric else if (LangStd == LangStandard::lang_opencl11)
21367ae0e2c9SDimitry Andric Opts.OpenCLVersion = 110;
213759d1ed5bSDimitry Andric else if (LangStd == LangStandard::lang_opencl12)
21387ae0e2c9SDimitry Andric Opts.OpenCLVersion = 120;
213939d628a0SDimitry Andric else if (LangStd == LangStandard::lang_opencl20)
214039d628a0SDimitry Andric Opts.OpenCLVersion = 200;
21414ba319b5SDimitry Andric else if (LangStd == LangStandard::lang_openclcpp)
21424ba319b5SDimitry Andric Opts.OpenCLCPlusPlusVersion = 100;
21437ae0e2c9SDimitry Andric
21447ae0e2c9SDimitry Andric // OpenCL has some additional defaults.
21457ae0e2c9SDimitry Andric if (Opts.OpenCL) {
21466122f3e6SDimitry Andric Opts.AltiVec = 0;
2147b6c25e0eSDimitry Andric Opts.ZVector = 0;
21486122f3e6SDimitry Andric Opts.LaxVectorConversions = 0;
214920e90f04SDimitry Andric Opts.setDefaultFPContractMode(LangOptions::FPC_On);
2150139f7f9bSDimitry Andric Opts.NativeHalfType = 1;
2151e7145dcbSDimitry Andric Opts.NativeHalfArgsAndReturns = 1;
21524ba319b5SDimitry Andric Opts.OpenCLCPlusPlus = Opts.CPlusPlus;
2153e7145dcbSDimitry Andric // Include default header file for OpenCL.
2154e7145dcbSDimitry Andric if (Opts.IncludeDefaultHeader) {
2155e7145dcbSDimitry Andric PPOpts.Includes.push_back("opencl-c.h");
2156e7145dcbSDimitry Andric }
2157f22ef01cSRoman Divacky }
2158f22ef01cSRoman Divacky
21594ba319b5SDimitry Andric Opts.HIP = IK.getLanguage() == InputKind::HIP;
21604ba319b5SDimitry Andric Opts.CUDA = IK.getLanguage() == InputKind::CUDA || Opts.HIP;
216120e90f04SDimitry Andric if (Opts.CUDA)
216220e90f04SDimitry Andric // Set default FP_CONTRACT to FAST.
216320e90f04SDimitry Andric Opts.setDefaultFPContractMode(LangOptions::FPC_Fast);
21642754fe60SDimitry Andric
2165f37b6182SDimitry Andric Opts.RenderScript = IK.getLanguage() == InputKind::RenderScript;
2166e7145dcbSDimitry Andric if (Opts.RenderScript) {
2167e7145dcbSDimitry Andric Opts.NativeHalfType = 1;
2168e7145dcbSDimitry Andric Opts.NativeHalfArgsAndReturns = 1;
2169e7145dcbSDimitry Andric }
2170e7145dcbSDimitry Andric
2171f22ef01cSRoman Divacky // OpenCL and C++ both have bool, true, false keywords.
2172f22ef01cSRoman Divacky Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
2173f22ef01cSRoman Divacky
217459d1ed5bSDimitry Andric // OpenCL has half keyword
217559d1ed5bSDimitry Andric Opts.Half = Opts.OpenCL;
217659d1ed5bSDimitry Andric
21773861d79fSDimitry Andric // C++ has wchar_t keyword.
21783861d79fSDimitry Andric Opts.WChar = Opts.CPlusPlus;
21793861d79fSDimitry Andric
21802754fe60SDimitry Andric Opts.GNUKeywords = Opts.GNUMode;
21812754fe60SDimitry Andric Opts.CXXOperatorNames = Opts.CPlusPlus;
21822754fe60SDimitry Andric
21839a199699SDimitry Andric Opts.AlignedAllocation = Opts.CPlusPlus17;
218444290647SDimitry Andric
21852754fe60SDimitry Andric Opts.DollarIdents = !Opts.AsmPreprocessor;
21862754fe60SDimitry Andric }
21872754fe60SDimitry Andric
2188139f7f9bSDimitry Andric /// Attempt to parse a visibility value out of the given argument.
parseVisibility(Arg * arg,ArgList & args,DiagnosticsEngine & diags)2189139f7f9bSDimitry Andric static Visibility parseVisibility(Arg *arg, ArgList &args,
2190139f7f9bSDimitry Andric DiagnosticsEngine &diags) {
2191139f7f9bSDimitry Andric StringRef value = arg->getValue();
2192139f7f9bSDimitry Andric if (value == "default") {
2193139f7f9bSDimitry Andric return DefaultVisibility;
21940623d748SDimitry Andric } else if (value == "hidden" || value == "internal") {
2195139f7f9bSDimitry Andric return HiddenVisibility;
2196139f7f9bSDimitry Andric } else if (value == "protected") {
2197139f7f9bSDimitry Andric // FIXME: diagnose if target does not support protected visibility
2198139f7f9bSDimitry Andric return ProtectedVisibility;
2199139f7f9bSDimitry Andric }
2200139f7f9bSDimitry Andric
2201139f7f9bSDimitry Andric diags.Report(diag::err_drv_invalid_value)
2202139f7f9bSDimitry Andric << arg->getAsString(args) << value;
2203139f7f9bSDimitry Andric return DefaultVisibility;
2204139f7f9bSDimitry Andric }
2205139f7f9bSDimitry Andric
220620e90f04SDimitry Andric /// Check if input file kind and language standard are compatible.
IsInputCompatibleWithStandard(InputKind IK,const LangStandard & S)220720e90f04SDimitry Andric static bool IsInputCompatibleWithStandard(InputKind IK,
220820e90f04SDimitry Andric const LangStandard &S) {
2209f37b6182SDimitry Andric switch (IK.getLanguage()) {
2210f37b6182SDimitry Andric case InputKind::Unknown:
2211f37b6182SDimitry Andric case InputKind::LLVM_IR:
2212f37b6182SDimitry Andric llvm_unreachable("should not parse language flags for this input");
2213f37b6182SDimitry Andric
2214f37b6182SDimitry Andric case InputKind::C:
2215f37b6182SDimitry Andric case InputKind::ObjC:
2216f37b6182SDimitry Andric case InputKind::RenderScript:
2217f37b6182SDimitry Andric return S.getLanguage() == InputKind::C;
2218f37b6182SDimitry Andric
2219f37b6182SDimitry Andric case InputKind::OpenCL:
2220f37b6182SDimitry Andric return S.getLanguage() == InputKind::OpenCL;
2221f37b6182SDimitry Andric
2222f37b6182SDimitry Andric case InputKind::CXX:
2223f37b6182SDimitry Andric case InputKind::ObjCXX:
2224f37b6182SDimitry Andric return S.getLanguage() == InputKind::CXX;
2225f37b6182SDimitry Andric
2226f37b6182SDimitry Andric case InputKind::CUDA:
2227f37b6182SDimitry Andric // FIXME: What -std= values should be permitted for CUDA compilations?
2228f37b6182SDimitry Andric return S.getLanguage() == InputKind::CUDA ||
2229f37b6182SDimitry Andric S.getLanguage() == InputKind::CXX;
2230f37b6182SDimitry Andric
22314ba319b5SDimitry Andric case InputKind::HIP:
22324ba319b5SDimitry Andric return S.getLanguage() == InputKind::CXX ||
22334ba319b5SDimitry Andric S.getLanguage() == InputKind::HIP;
22344ba319b5SDimitry Andric
2235f37b6182SDimitry Andric case InputKind::Asm:
2236f37b6182SDimitry Andric // Accept (and ignore) all -std= values.
2237f37b6182SDimitry Andric // FIXME: The -std= value is not ignored; it affects the tokenization
2238f37b6182SDimitry Andric // and preprocessing rules if we're preprocessing this asm input.
223920e90f04SDimitry Andric return true;
224020e90f04SDimitry Andric }
2241f37b6182SDimitry Andric
2242f37b6182SDimitry Andric llvm_unreachable("unexpected input language");
224320e90f04SDimitry Andric }
224420e90f04SDimitry Andric
224520e90f04SDimitry Andric /// Get language name for given input kind.
GetInputKindName(InputKind IK)224620e90f04SDimitry Andric static const StringRef GetInputKindName(InputKind IK) {
2247f37b6182SDimitry Andric switch (IK.getLanguage()) {
2248f37b6182SDimitry Andric case InputKind::C:
2249f37b6182SDimitry Andric return "C";
2250f37b6182SDimitry Andric case InputKind::ObjC:
2251f37b6182SDimitry Andric return "Objective-C";
2252f37b6182SDimitry Andric case InputKind::CXX:
2253f37b6182SDimitry Andric return "C++";
2254f37b6182SDimitry Andric case InputKind::ObjCXX:
2255f37b6182SDimitry Andric return "Objective-C++";
2256f37b6182SDimitry Andric case InputKind::OpenCL:
225720e90f04SDimitry Andric return "OpenCL";
2258f37b6182SDimitry Andric case InputKind::CUDA:
225920e90f04SDimitry Andric return "CUDA";
2260f37b6182SDimitry Andric case InputKind::RenderScript:
2261f37b6182SDimitry Andric return "RenderScript";
22624ba319b5SDimitry Andric case InputKind::HIP:
22634ba319b5SDimitry Andric return "HIP";
2264f37b6182SDimitry Andric
2265f37b6182SDimitry Andric case InputKind::Asm:
2266f37b6182SDimitry Andric return "Asm";
2267f37b6182SDimitry Andric case InputKind::LLVM_IR:
2268f37b6182SDimitry Andric return "LLVM IR";
2269f37b6182SDimitry Andric
2270f37b6182SDimitry Andric case InputKind::Unknown:
2271f37b6182SDimitry Andric break;
227220e90f04SDimitry Andric }
2273f37b6182SDimitry Andric llvm_unreachable("unknown input language");
227420e90f04SDimitry Andric }
227520e90f04SDimitry Andric
ParseLangArgs(LangOptions & Opts,ArgList & Args,InputKind IK,const TargetOptions & TargetOpts,PreprocessorOptions & PPOpts,DiagnosticsEngine & Diags)22762754fe60SDimitry Andric static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
2277e7145dcbSDimitry Andric const TargetOptions &TargetOpts,
2278e7145dcbSDimitry Andric PreprocessorOptions &PPOpts,
22796122f3e6SDimitry Andric DiagnosticsEngine &Diags) {
22802754fe60SDimitry Andric // FIXME: Cleanup per-file based stuff.
22812754fe60SDimitry Andric LangStandard::Kind LangStd = LangStandard::lang_unspecified;
22822754fe60SDimitry Andric if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
22833861d79fSDimitry Andric LangStd = llvm::StringSwitch<LangStandard::Kind>(A->getValue())
2284f37b6182SDimitry Andric #define LANGSTANDARD(id, name, lang, desc, features) \
22852754fe60SDimitry Andric .Case(name, LangStandard::lang_##id)
2286e7145dcbSDimitry Andric #define LANGSTANDARD_ALIAS(id, alias) \
2287e7145dcbSDimitry Andric .Case(alias, LangStandard::lang_##id)
22882754fe60SDimitry Andric #include "clang/Frontend/LangStandards.def"
22892754fe60SDimitry Andric .Default(LangStandard::lang_unspecified);
229020e90f04SDimitry Andric if (LangStd == LangStandard::lang_unspecified) {
22912754fe60SDimitry Andric Diags.Report(diag::err_drv_invalid_value)
22923861d79fSDimitry Andric << A->getAsString(Args) << A->getValue();
229320e90f04SDimitry Andric // Report supported standards with short description.
229420e90f04SDimitry Andric for (unsigned KindValue = 0;
229520e90f04SDimitry Andric KindValue != LangStandard::lang_unspecified;
229620e90f04SDimitry Andric ++KindValue) {
229720e90f04SDimitry Andric const LangStandard &Std = LangStandard::getLangStandardForKind(
229820e90f04SDimitry Andric static_cast<LangStandard::Kind>(KindValue));
229920e90f04SDimitry Andric if (IsInputCompatibleWithStandard(IK, Std)) {
2300f37b6182SDimitry Andric auto Diag = Diags.Report(diag::note_drv_use_standard);
2301f37b6182SDimitry Andric Diag << Std.getName() << Std.getDescription();
2302f37b6182SDimitry Andric unsigned NumAliases = 0;
2303f37b6182SDimitry Andric #define LANGSTANDARD(id, name, lang, desc, features)
2304f37b6182SDimitry Andric #define LANGSTANDARD_ALIAS(id, alias) \
2305f37b6182SDimitry Andric if (KindValue == LangStandard::lang_##id) ++NumAliases;
2306f37b6182SDimitry Andric #define LANGSTANDARD_ALIAS_DEPR(id, alias)
2307f37b6182SDimitry Andric #include "clang/Frontend/LangStandards.def"
2308f37b6182SDimitry Andric Diag << NumAliases;
2309f37b6182SDimitry Andric #define LANGSTANDARD(id, name, lang, desc, features)
2310f37b6182SDimitry Andric #define LANGSTANDARD_ALIAS(id, alias) \
2311f37b6182SDimitry Andric if (KindValue == LangStandard::lang_##id) Diag << alias;
2312f37b6182SDimitry Andric #define LANGSTANDARD_ALIAS_DEPR(id, alias)
2313f37b6182SDimitry Andric #include "clang/Frontend/LangStandards.def"
231420e90f04SDimitry Andric }
231520e90f04SDimitry Andric }
231620e90f04SDimitry Andric } else {
231759d1ed5bSDimitry Andric // Valid standard, check to make sure language and standard are
231859d1ed5bSDimitry Andric // compatible.
2319bd5abe19SDimitry Andric const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
232020e90f04SDimitry Andric if (!IsInputCompatibleWithStandard(IK, Std)) {
2321bd5abe19SDimitry Andric Diags.Report(diag::err_drv_argument_not_allowed_with)
232220e90f04SDimitry Andric << A->getAsString(Args) << GetInputKindName(IK);
2323bd5abe19SDimitry Andric }
2324bd5abe19SDimitry Andric }
23252754fe60SDimitry Andric }
23262754fe60SDimitry Andric
2327*b5893f02SDimitry Andric if (Args.hasArg(OPT_fno_dllexport_inlines))
2328*b5893f02SDimitry Andric Opts.DllExportInlines = false;
2329*b5893f02SDimitry Andric
23304ba319b5SDimitry Andric if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
23314ba319b5SDimitry Andric StringRef Name = A->getValue();
23324ba319b5SDimitry Andric if (Name == "full" || Name == "branch") {
23334ba319b5SDimitry Andric Opts.CFProtectionBranch = 1;
23344ba319b5SDimitry Andric }
23354ba319b5SDimitry Andric }
23367ae0e2c9SDimitry Andric // -cl-std only applies for OpenCL language standards.
23377ae0e2c9SDimitry Andric // Override the -std option in this case.
23382754fe60SDimitry Andric if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
23397ae0e2c9SDimitry Andric LangStandard::Kind OpenCLLangStd
23403861d79fSDimitry Andric = llvm::StringSwitch<LangStandard::Kind>(A->getValue())
2341f37b6182SDimitry Andric .Cases("cl", "CL", LangStandard::lang_opencl10)
2342e7145dcbSDimitry Andric .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)
2343e7145dcbSDimitry Andric .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)
2344e7145dcbSDimitry Andric .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)
23454ba319b5SDimitry Andric .Case("c++", LangStandard::lang_openclcpp)
23467ae0e2c9SDimitry Andric .Default(LangStandard::lang_unspecified);
23477ae0e2c9SDimitry Andric
23487ae0e2c9SDimitry Andric if (OpenCLLangStd == LangStandard::lang_unspecified) {
23492754fe60SDimitry Andric Diags.Report(diag::err_drv_invalid_value)
23503861d79fSDimitry Andric << A->getAsString(Args) << A->getValue();
23512754fe60SDimitry Andric }
23527ae0e2c9SDimitry Andric else
23537ae0e2c9SDimitry Andric LangStd = OpenCLLangStd;
23542754fe60SDimitry Andric }
23552754fe60SDimitry Andric
2356e7145dcbSDimitry Andric Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
2357e7145dcbSDimitry Andric
2358e7145dcbSDimitry Andric llvm::Triple T(TargetOpts.Triple);
2359e7145dcbSDimitry Andric CompilerInvocation::setLangDefaults(Opts, IK, T, PPOpts, LangStd);
2360e7145dcbSDimitry Andric
2361e7145dcbSDimitry Andric // -cl-strict-aliasing needs to emit diagnostic in the case where CL > 1.0.
2362e7145dcbSDimitry Andric // This option should be deprecated for CL > 1.0 because
2363e7145dcbSDimitry Andric // this option was added for compatibility with OpenCL 1.0.
2364e7145dcbSDimitry Andric if (Args.getLastArg(OPT_cl_strict_aliasing)
2365e7145dcbSDimitry Andric && Opts.OpenCLVersion > 100) {
2366e7145dcbSDimitry Andric Diags.Report(diag::warn_option_invalid_ocl_version)
23674ba319b5SDimitry Andric << Opts.getOpenCLVersionTuple().getAsString()
23684ba319b5SDimitry Andric << Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args);
2369e7145dcbSDimitry Andric }
23702754fe60SDimitry Andric
2371f22ef01cSRoman Divacky // We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
2372f22ef01cSRoman Divacky // keywords. This behavior is provided by GCC's poorly named '-fasm' flag,
2373f22ef01cSRoman Divacky // while a subset (the non-C++ GNU keywords) is provided by GCC's
2374f22ef01cSRoman Divacky // '-fgnu-keywords'. Clang conflates the two for simplicity under the single
2375f22ef01cSRoman Divacky // name, as it doesn't seem a useful distinction.
2376f22ef01cSRoman Divacky Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords,
23772754fe60SDimitry Andric Opts.GNUKeywords);
2378f22ef01cSRoman Divacky
23794ba319b5SDimitry Andric Opts.Digraphs = Args.hasFlag(OPT_fdigraphs, OPT_fno_digraphs, Opts.Digraphs);
23804ba319b5SDimitry Andric
23812754fe60SDimitry Andric if (Args.hasArg(OPT_fno_operator_names))
23822754fe60SDimitry Andric Opts.CXXOperatorNames = 0;
2383f22ef01cSRoman Divacky
238439d628a0SDimitry Andric if (Args.hasArg(OPT_fcuda_is_device))
238539d628a0SDimitry Andric Opts.CUDAIsDevice = 1;
238639d628a0SDimitry Andric
2387e7145dcbSDimitry Andric if (Args.hasArg(OPT_fcuda_allow_variadic_functions))
2388e7145dcbSDimitry Andric Opts.CUDAAllowVariadicFunctions = 1;
238933956c43SDimitry Andric
2390e7145dcbSDimitry Andric if (Args.hasArg(OPT_fno_cuda_host_device_constexpr))
2391e7145dcbSDimitry Andric Opts.CUDAHostDeviceConstexpr = 0;
239233956c43SDimitry Andric
2393e7145dcbSDimitry Andric if (Opts.CUDAIsDevice && Args.hasArg(OPT_fcuda_approx_transcendentals))
2394e7145dcbSDimitry Andric Opts.CUDADeviceApproxTranscendentals = 1;
23950623d748SDimitry Andric
2396*b5893f02SDimitry Andric Opts.GPURelocatableDeviceCode = Args.hasArg(OPT_fgpu_rdc);
23974ba319b5SDimitry Andric
2398*b5893f02SDimitry Andric if (Opts.ObjC) {
23997ae0e2c9SDimitry Andric if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
24003861d79fSDimitry Andric StringRef value = arg->getValue();
24017ae0e2c9SDimitry Andric if (Opts.ObjCRuntime.tryParse(value))
24027ae0e2c9SDimitry Andric Diags.Report(diag::err_drv_unknown_objc_runtime) << value;
24037ae0e2c9SDimitry Andric }
24047ae0e2c9SDimitry Andric
2405f22ef01cSRoman Divacky if (Args.hasArg(OPT_fobjc_gc_only))
24066122f3e6SDimitry Andric Opts.setGC(LangOptions::GCOnly);
2407f22ef01cSRoman Divacky else if (Args.hasArg(OPT_fobjc_gc))
24086122f3e6SDimitry Andric Opts.setGC(LangOptions::HybridGC);
240917a519f9SDimitry Andric else if (Args.hasArg(OPT_fobjc_arc)) {
241017a519f9SDimitry Andric Opts.ObjCAutoRefCount = 1;
24113861d79fSDimitry Andric if (!Opts.ObjCRuntime.allowsARC())
24123861d79fSDimitry Andric Diags.Report(diag::err_arc_unsupported_on_runtime);
24130623d748SDimitry Andric }
2414f22ef01cSRoman Divacky
24150623d748SDimitry Andric // ObjCWeakRuntime tracks whether the runtime supports __weak, not
24160623d748SDimitry Andric // whether the feature is actually enabled. This is predominantly
24170623d748SDimitry Andric // determined by -fobjc-runtime, but we allow it to be overridden
24180623d748SDimitry Andric // from the command line for testing purposes.
241917a519f9SDimitry Andric if (Args.hasArg(OPT_fobjc_runtime_has_weak))
24200623d748SDimitry Andric Opts.ObjCWeakRuntime = 1;
24213861d79fSDimitry Andric else
24220623d748SDimitry Andric Opts.ObjCWeakRuntime = Opts.ObjCRuntime.allowsWeak();
24230623d748SDimitry Andric
24240623d748SDimitry Andric // ObjCWeak determines whether __weak is actually enabled.
24250623d748SDimitry Andric // Note that we allow -fno-objc-weak to disable this even in ARC mode.
24260623d748SDimitry Andric if (auto weakArg = Args.getLastArg(OPT_fobjc_weak, OPT_fno_objc_weak)) {
24270623d748SDimitry Andric if (!weakArg->getOption().matches(OPT_fobjc_weak)) {
24280623d748SDimitry Andric assert(!Opts.ObjCWeak);
24290623d748SDimitry Andric } else if (Opts.getGC() != LangOptions::NonGC) {
24300623d748SDimitry Andric Diags.Report(diag::err_objc_weak_with_gc);
24310623d748SDimitry Andric } else if (!Opts.ObjCWeakRuntime) {
24320623d748SDimitry Andric Diags.Report(diag::err_objc_weak_unsupported);
24330623d748SDimitry Andric } else {
24340623d748SDimitry Andric Opts.ObjCWeak = 1;
24350623d748SDimitry Andric }
24360623d748SDimitry Andric } else if (Opts.ObjCAutoRefCount) {
24370623d748SDimitry Andric Opts.ObjCWeak = Opts.ObjCWeakRuntime;
24383861d79fSDimitry Andric }
243917a519f9SDimitry Andric
244017a519f9SDimitry Andric if (Args.hasArg(OPT_fno_objc_infer_related_result_type))
244117a519f9SDimitry Andric Opts.ObjCInferRelatedResultType = 0;
2442f785676fSDimitry Andric
2443f785676fSDimitry Andric if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime))
2444f785676fSDimitry Andric Opts.ObjCSubscriptingLegacyRuntime =
2445f785676fSDimitry Andric (Opts.ObjCRuntime.getKind() == ObjCRuntime::FragileMacOSX);
244617a519f9SDimitry Andric }
244717a519f9SDimitry Andric
244833956c43SDimitry Andric if (Args.hasArg(OPT_fgnu89_inline)) {
244933956c43SDimitry Andric if (Opts.CPlusPlus)
245020e90f04SDimitry Andric Diags.Report(diag::err_drv_argument_not_allowed_with)
245120e90f04SDimitry Andric << "-fgnu89-inline" << GetInputKindName(IK);
245233956c43SDimitry Andric else
245317a519f9SDimitry Andric Opts.GNUInline = 1;
245433956c43SDimitry Andric }
2455bd5abe19SDimitry Andric
24562754fe60SDimitry Andric if (Args.hasArg(OPT_fapple_kext)) {
24572754fe60SDimitry Andric if (!Opts.CPlusPlus)
24582754fe60SDimitry Andric Diags.Report(diag::warn_c_kext);
24592754fe60SDimitry Andric else
24602754fe60SDimitry Andric Opts.AppleKext = 1;
24612754fe60SDimitry Andric }
24622754fe60SDimitry Andric
2463f22ef01cSRoman Divacky if (Args.hasArg(OPT_print_ivar_layout))
2464f22ef01cSRoman Divacky Opts.ObjCGCBitmapPrint = 1;
2465*b5893f02SDimitry Andric
2466f22ef01cSRoman Divacky if (Args.hasArg(OPT_fno_constant_cfstrings))
2467f22ef01cSRoman Divacky Opts.NoConstantCFStrings = 1;
2468*b5893f02SDimitry Andric if (const auto *A = Args.getLastArg(OPT_fcf_runtime_abi_EQ))
2469*b5893f02SDimitry Andric Opts.CFRuntime =
2470*b5893f02SDimitry Andric llvm::StringSwitch<LangOptions::CoreFoundationABI>(A->getValue())
2471*b5893f02SDimitry Andric .Cases("unspecified", "standalone", "objc",
2472*b5893f02SDimitry Andric LangOptions::CoreFoundationABI::ObjectiveC)
2473*b5893f02SDimitry Andric .Cases("swift", "swift-5.0",
2474*b5893f02SDimitry Andric LangOptions::CoreFoundationABI::Swift5_0)
2475*b5893f02SDimitry Andric .Case("swift-4.2", LangOptions::CoreFoundationABI::Swift4_2)
2476*b5893f02SDimitry Andric .Case("swift-4.1", LangOptions::CoreFoundationABI::Swift4_1)
2477*b5893f02SDimitry Andric .Default(LangOptions::CoreFoundationABI::ObjectiveC);
2478f22ef01cSRoman Divacky
2479b6c25e0eSDimitry Andric if (Args.hasArg(OPT_fzvector))
2480b6c25e0eSDimitry Andric Opts.ZVector = 1;
2481b6c25e0eSDimitry Andric
2482f22ef01cSRoman Divacky if (Args.hasArg(OPT_pthread))
2483f22ef01cSRoman Divacky Opts.POSIXThreads = 1;
2484f22ef01cSRoman Divacky
2485139f7f9bSDimitry Andric // The value-visibility mode defaults to "default".
2486139f7f9bSDimitry Andric if (Arg *visOpt = Args.getLastArg(OPT_fvisibility)) {
2487139f7f9bSDimitry Andric Opts.setValueVisibilityMode(parseVisibility(visOpt, Args, Diags));
2488139f7f9bSDimitry Andric } else {
2489139f7f9bSDimitry Andric Opts.setValueVisibilityMode(DefaultVisibility);
2490139f7f9bSDimitry Andric }
24913b0f4066SDimitry Andric
2492139f7f9bSDimitry Andric // The type-visibility mode defaults to the value-visibility mode.
2493139f7f9bSDimitry Andric if (Arg *typeVisOpt = Args.getLastArg(OPT_ftype_visibility)) {
2494139f7f9bSDimitry Andric Opts.setTypeVisibilityMode(parseVisibility(typeVisOpt, Args, Diags));
2495139f7f9bSDimitry Andric } else {
2496139f7f9bSDimitry Andric Opts.setTypeVisibilityMode(Opts.getValueVisibilityMode());
24977ae0e2c9SDimitry Andric }
24987ae0e2c9SDimitry Andric
2499ffd1746dSEd Schouten if (Args.hasArg(OPT_fvisibility_inlines_hidden))
2500ffd1746dSEd Schouten Opts.InlineVisibilityHidden = 1;
2501ffd1746dSEd Schouten
2502*b5893f02SDimitry Andric if (Args.hasArg(OPT_fvisibility_global_new_delete_hidden))
2503*b5893f02SDimitry Andric Opts.GlobalAllocationFunctionVisibilityHidden = 1;
2504*b5893f02SDimitry Andric
25052754fe60SDimitry Andric if (Args.hasArg(OPT_ftrapv)) {
2506ffd1746dSEd Schouten Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping);
25072754fe60SDimitry Andric // Set the handler, if one is specified.
25082754fe60SDimitry Andric Opts.OverflowHandler =
25092754fe60SDimitry Andric Args.getLastArgValue(OPT_ftrapv_handler);
25102754fe60SDimitry Andric }
2511ffd1746dSEd Schouten else if (Args.hasArg(OPT_fwrapv))
2512ffd1746dSEd Schouten Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
2513f22ef01cSRoman Divacky
251439d628a0SDimitry Andric Opts.MSVCCompat = Args.hasArg(OPT_fms_compatibility);
251539d628a0SDimitry Andric Opts.MicrosoftExt = Opts.MSVCCompat || Args.hasArg(OPT_fms_extensions);
251639d628a0SDimitry Andric Opts.AsmBlocks = Args.hasArg(OPT_fasm_blocks) || Opts.MicrosoftExt;
251733956c43SDimitry Andric Opts.MSCompatibilityVersion = 0;
251833956c43SDimitry Andric if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
251933956c43SDimitry Andric VersionTuple VT;
252033956c43SDimitry Andric if (VT.tryParse(A->getValue()))
252133956c43SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
252233956c43SDimitry Andric << A->getValue();
252333956c43SDimitry Andric Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 +
252433956c43SDimitry Andric VT.getMinor().getValueOr(0) * 100000 +
252533956c43SDimitry Andric VT.getSubminor().getValueOr(0);
252633956c43SDimitry Andric }
252739d628a0SDimitry Andric
2528*b5893f02SDimitry Andric // Mimicking gcc's behavior, trigraphs are only enabled if -trigraphs
252939d628a0SDimitry Andric // is specified, or -std is set to a conforming mode.
253039d628a0SDimitry Andric // Trigraphs are disabled by default in c++1z onwards.
25319a199699SDimitry Andric Opts.Trigraphs = !Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17;
253239d628a0SDimitry Andric Opts.Trigraphs =
253339d628a0SDimitry Andric Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);
2534f22ef01cSRoman Divacky
2535f22ef01cSRoman Divacky Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
2536f22ef01cSRoman Divacky OPT_fno_dollars_in_identifiers,
25372754fe60SDimitry Andric Opts.DollarIdents);
2538f22ef01cSRoman Divacky Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
253959d1ed5bSDimitry Andric Opts.VtorDispMode = getLastArgIntValue(Args, OPT_vtordisp_mode_EQ, 1, Diags);
2540e580952dSDimitry Andric Opts.Borland = Args.hasArg(OPT_fborland_extensions);
2541f22ef01cSRoman Divacky Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
25423b0f4066SDimitry Andric Opts.ConstStrings = Args.hasFlag(OPT_fconst_strings, OPT_fno_const_strings,
25433b0f4066SDimitry Andric Opts.ConstStrings);
2544f22ef01cSRoman Divacky if (Args.hasArg(OPT_fno_lax_vector_conversions))
2545f22ef01cSRoman Divacky Opts.LaxVectorConversions = 0;
2546f22ef01cSRoman Divacky if (Args.hasArg(OPT_fno_threadsafe_statics))
2547f22ef01cSRoman Divacky Opts.ThreadsafeStatics = 0;
2548f22ef01cSRoman Divacky Opts.Exceptions = Args.hasArg(OPT_fexceptions);
2549dd6029ffSDimitry Andric Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions);
2550dd6029ffSDimitry Andric Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
25519a199699SDimitry Andric
25524ba319b5SDimitry Andric // -ffixed-point
25534ba319b5SDimitry Andric Opts.FixedPoint =
25544ba319b5SDimitry Andric Args.hasFlag(OPT_ffixed_point, OPT_fno_fixed_point, /*Default=*/false) &&
25554ba319b5SDimitry Andric !Opts.CPlusPlus;
25564ba319b5SDimitry Andric Opts.PaddingOnUnsignedFixedPoint =
25574ba319b5SDimitry Andric Args.hasFlag(OPT_fpadding_on_unsigned_fixed_point,
25584ba319b5SDimitry Andric OPT_fno_padding_on_unsigned_fixed_point,
25594ba319b5SDimitry Andric /*Default=*/false) &&
25604ba319b5SDimitry Andric Opts.FixedPoint;
25614ba319b5SDimitry Andric
25629a199699SDimitry Andric // Handle exception personalities
25639a199699SDimitry Andric Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions,
25649a199699SDimitry Andric options::OPT_fseh_exceptions,
25659a199699SDimitry Andric options::OPT_fdwarf_exceptions);
25669a199699SDimitry Andric if (A) {
25679a199699SDimitry Andric const Option &Opt = A->getOption();
25684ba319b5SDimitry Andric llvm::Triple T(TargetOpts.Triple);
25694ba319b5SDimitry Andric if (T.isWindowsMSVCEnvironment())
25704ba319b5SDimitry Andric Diags.Report(diag::err_fe_invalid_exception_model)
25714ba319b5SDimitry Andric << Opt.getName() << T.str();
25724ba319b5SDimitry Andric
25739a199699SDimitry Andric Opts.SjLjExceptions = Opt.matches(options::OPT_fsjlj_exceptions);
25749a199699SDimitry Andric Opts.SEHExceptions = Opt.matches(options::OPT_fseh_exceptions);
25759a199699SDimitry Andric Opts.DWARFExceptions = Opt.matches(options::OPT_fdwarf_exceptions);
25769a199699SDimitry Andric }
25779a199699SDimitry Andric
2578e7145dcbSDimitry Andric Opts.ExternCNoUnwind = Args.hasArg(OPT_fexternc_nounwind);
25793b0f4066SDimitry Andric Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp);
2580dd6029ffSDimitry Andric
2581e7145dcbSDimitry Andric Opts.RTTI = Opts.CPlusPlus && !Args.hasArg(OPT_fno_rtti);
258259d1ed5bSDimitry Andric Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data);
2583e7145dcbSDimitry Andric Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
25844ba319b5SDimitry Andric && Opts.OpenCLVersion == 200);
25856122f3e6SDimitry Andric Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional);
258644290647SDimitry Andric Opts.CoroutinesTS = Args.hasArg(OPT_fcoroutines_ts);
25879a199699SDimitry Andric
25889a199699SDimitry Andric // Enable [[]] attributes in C++11 by default.
25899a199699SDimitry Andric Opts.DoubleSquareBracketAttributes =
25909a199699SDimitry Andric Args.hasFlag(OPT_fdouble_square_bracket_attributes,
25919a199699SDimitry Andric OPT_fno_double_square_bracket_attributes, Opts.CPlusPlus11);
25929a199699SDimitry Andric
259344290647SDimitry Andric Opts.ModulesTS = Args.hasArg(OPT_fmodules_ts);
259444290647SDimitry Andric Opts.Modules = Args.hasArg(OPT_fmodules) || Opts.ModulesTS;
259559d1ed5bSDimitry Andric Opts.ModulesStrictDeclUse = Args.hasArg(OPT_fmodules_strict_decluse);
259659d1ed5bSDimitry Andric Opts.ModulesDeclUse =
259759d1ed5bSDimitry Andric Args.hasArg(OPT_fmodules_decluse) || Opts.ModulesStrictDeclUse;
259833956c43SDimitry Andric Opts.ModulesLocalVisibility =
259944290647SDimitry Andric Args.hasArg(OPT_fmodules_local_submodule_visibility) || Opts.ModulesTS;
260020e90f04SDimitry Andric Opts.ModulesCodegen = Args.hasArg(OPT_fmodules_codegen);
260120e90f04SDimitry Andric Opts.ModulesDebugInfo = Args.hasArg(OPT_fmodules_debuginfo);
260259d1ed5bSDimitry Andric Opts.ModulesSearchAll = Opts.Modules &&
260359d1ed5bSDimitry Andric !Args.hasArg(OPT_fno_modules_search_all) &&
260459d1ed5bSDimitry Andric Args.hasArg(OPT_fmodules_search_all);
260559d1ed5bSDimitry Andric Opts.ModulesErrorRecovery = !Args.hasArg(OPT_fno_modules_error_recovery);
260633956c43SDimitry Andric Opts.ImplicitModules = !Args.hasArg(OPT_fno_implicit_modules);
2607f785676fSDimitry Andric Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char);
26083861d79fSDimitry Andric Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar);
2609*b5893f02SDimitry Andric Opts.Char8 = Args.hasFlag(OPT_fchar8__t, OPT_fno_char8__t, Opts.CPlusPlus2a);
26109a199699SDimitry Andric if (const Arg *A = Args.getLastArg(OPT_fwchar_type_EQ)) {
26119a199699SDimitry Andric Opts.WCharSize = llvm::StringSwitch<unsigned>(A->getValue())
26129a199699SDimitry Andric .Case("char", 1)
26139a199699SDimitry Andric .Case("short", 2)
26149a199699SDimitry Andric .Case("int", 4)
26159a199699SDimitry Andric .Default(0);
26169a199699SDimitry Andric if (Opts.WCharSize == 0)
26179a199699SDimitry Andric Diags.Report(diag::err_fe_invalid_wchar_type) << A->getValue();
26189a199699SDimitry Andric }
26199a199699SDimitry Andric Opts.WCharIsSigned = Args.hasFlag(OPT_fsigned_wchar, OPT_fno_signed_wchar, true);
26202754fe60SDimitry Andric Opts.ShortEnums = Args.hasArg(OPT_fshort_enums);
2621f22ef01cSRoman Divacky Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
2622f22ef01cSRoman Divacky Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
2623ea942507SDimitry Andric if (!Opts.NoBuiltin)
2624ea942507SDimitry Andric getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs);
2625f785676fSDimitry Andric Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin);
262644290647SDimitry Andric Opts.RelaxedTemplateTemplateArgs =
262744290647SDimitry Andric Args.hasArg(OPT_frelaxed_template_template_args);
262833956c43SDimitry Andric Opts.SizedDeallocation = Args.hasArg(OPT_fsized_deallocation);
262944290647SDimitry Andric Opts.AlignedAllocation =
263044290647SDimitry Andric Args.hasFlag(OPT_faligned_allocation, OPT_fno_aligned_allocation,
263144290647SDimitry Andric Opts.AlignedAllocation);
2632a580b014SDimitry Andric Opts.AlignedAllocationUnavailable =
2633a580b014SDimitry Andric Opts.AlignedAllocation && Args.hasArg(OPT_aligned_alloc_unavailable);
263444290647SDimitry Andric Opts.NewAlignOverride =
263544290647SDimitry Andric getLastArgIntValue(Args, OPT_fnew_alignment_EQ, 0, Diags);
263644290647SDimitry Andric if (Opts.NewAlignOverride && !llvm::isPowerOf2_32(Opts.NewAlignOverride)) {
263744290647SDimitry Andric Arg *A = Args.getLastArg(OPT_fnew_alignment_EQ);
263844290647SDimitry Andric Diags.Report(diag::err_fe_invalid_alignment) << A->getAsString(Args)
263944290647SDimitry Andric << A->getValue();
264044290647SDimitry Andric Opts.NewAlignOverride = 0;
264144290647SDimitry Andric }
264233956c43SDimitry Andric Opts.ConceptsTS = Args.hasArg(OPT_fconcepts_ts);
2643f22ef01cSRoman Divacky Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
2644f22ef01cSRoman Divacky Opts.AccessControl = !Args.hasArg(OPT_fno_access_control);
2645f22ef01cSRoman Divacky Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
2646f785676fSDimitry Andric Opts.MathErrno = !Opts.OpenCL && Args.hasArg(OPT_fmath_errno);
2647f785676fSDimitry Andric Opts.InstantiationDepth =
264844290647SDimitry Andric getLastArgIntValue(Args, OPT_ftemplate_depth, 1024, Diags);
2649f785676fSDimitry Andric Opts.ArrowDepth =
2650f785676fSDimitry Andric getLastArgIntValue(Args, OPT_foperator_arrow_depth, 256, Diags);
2651f785676fSDimitry Andric Opts.ConstexprCallDepth =
2652f785676fSDimitry Andric getLastArgIntValue(Args, OPT_fconstexpr_depth, 512, Diags);
2653f785676fSDimitry Andric Opts.ConstexprStepLimit =
2654f785676fSDimitry Andric getLastArgIntValue(Args, OPT_fconstexpr_steps, 1048576, Diags);
2655f785676fSDimitry Andric Opts.BracketDepth = getLastArgIntValue(Args, OPT_fbracket_depth, 256, Diags);
26563b0f4066SDimitry Andric Opts.DelayedTemplateParsing = Args.hasArg(OPT_fdelayed_template_parsing);
2657f785676fSDimitry Andric Opts.NumLargeByValueCopy =
2658f785676fSDimitry Andric getLastArgIntValue(Args, OPT_Wlarge_by_value_copy_EQ, 0, Diags);
26592754fe60SDimitry Andric Opts.MSBitfields = Args.hasArg(OPT_mms_bitfields);
2660f22ef01cSRoman Divacky Opts.ObjCConstantStringClass =
2661f22ef01cSRoman Divacky Args.getLastArgValue(OPT_fconstant_string_class);
26622754fe60SDimitry Andric Opts.ObjCDefaultSynthProperties =
2663f785676fSDimitry Andric !Args.hasArg(OPT_disable_objc_default_synthesize_properties);
26643861d79fSDimitry Andric Opts.EncodeExtendedBlockSig =
26653861d79fSDimitry Andric Args.hasArg(OPT_fencode_extended_block_signature);
2666f22ef01cSRoman Divacky Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
2667f785676fSDimitry Andric Opts.PackStruct = getLastArgIntValue(Args, OPT_fpack_struct_EQ, 0, Diags);
266839d628a0SDimitry Andric Opts.MaxTypeAlign = getLastArgIntValue(Args, OPT_fmax_type_align_EQ, 0, Diags);
2669e7145dcbSDimitry Andric Opts.AlignDouble = Args.hasArg(OPT_malign_double);
2670f785676fSDimitry Andric Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
2671e7145dcbSDimitry Andric Opts.PIE = Args.hasArg(OPT_pic_is_pie);
2672f22ef01cSRoman Divacky Opts.Static = Args.hasArg(OPT_static_define);
2673dff0c46cSDimitry Andric Opts.DumpRecordLayoutsSimple = Args.hasArg(OPT_fdump_record_layouts_simple);
2674dff0c46cSDimitry Andric Opts.DumpRecordLayouts = Opts.DumpRecordLayoutsSimple
2675dff0c46cSDimitry Andric || Args.hasArg(OPT_fdump_record_layouts);
2676f22ef01cSRoman Divacky Opts.DumpVTableLayouts = Args.hasArg(OPT_fdump_vtable_layouts);
2677ffd1746dSEd Schouten Opts.SpellChecking = !Args.hasArg(OPT_fno_spell_checking);
2678f22ef01cSRoman Divacky Opts.NoBitFieldTypeAlign = Args.hasArg(OPT_fno_bitfield_type_align);
26792754fe60SDimitry Andric Opts.SinglePrecisionConstants = Args.hasArg(OPT_cl_single_precision_constant);
26802754fe60SDimitry Andric Opts.FastRelaxedMath = Args.hasArg(OPT_cl_fast_relaxed_math);
2681dff0c46cSDimitry Andric Opts.HexagonQdsp6Compat = Args.hasArg(OPT_mqdsp6_compat);
26823b0f4066SDimitry Andric Opts.FakeAddressSpaceMap = Args.hasArg(OPT_ffake_address_space_map);
26833b0f4066SDimitry Andric Opts.ParseUnknownAnytype = Args.hasArg(OPT_funknown_anytype);
268417a519f9SDimitry Andric Opts.DebuggerSupport = Args.hasArg(OPT_fdebugger_support);
2685dff0c46cSDimitry Andric Opts.DebuggerCastResultToId = Args.hasArg(OPT_fdebugger_cast_result_to_id);
2686dff0c46cSDimitry Andric Opts.DebuggerObjCLiteral = Args.hasArg(OPT_fdebugger_objc_literal);
2687dff0c46cSDimitry Andric Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack);
26884ba319b5SDimitry Andric Opts.ModuleName = Args.getLastArgValue(OPT_fmodule_name_EQ);
26894ba319b5SDimitry Andric Opts.CurrentModule = Opts.ModuleName;
269033956c43SDimitry Andric Opts.AppExt = Args.hasArg(OPT_fapplication_extension);
269133956c43SDimitry Andric Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature);
2692*b5893f02SDimitry Andric llvm::sort(Opts.ModuleFeatures);
269333956c43SDimitry Andric Opts.NativeHalfType |= Args.hasArg(OPT_fnative_half_type);
2694e7145dcbSDimitry Andric Opts.NativeHalfArgsAndReturns |= Args.hasArg(OPT_fnative_half_arguments_and_returns);
2695e7145dcbSDimitry Andric // Enable HalfArgsAndReturns if present in Args or if NativeHalfArgsAndReturns
2696e7145dcbSDimitry Andric // is enabled.
2697e7145dcbSDimitry Andric Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns)
2698e7145dcbSDimitry Andric | Opts.NativeHalfArgsAndReturns;
269933956c43SDimitry Andric Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
270039d628a0SDimitry Andric
27010623d748SDimitry Andric // __declspec is enabled by default for the PS4 by the driver, and also
27020623d748SDimitry Andric // enabled for Microsoft Extensions or Borland Extensions, here.
27030623d748SDimitry Andric //
27040623d748SDimitry Andric // FIXME: __declspec is also currently enabled for CUDA, but isn't really a
270544290647SDimitry Andric // CUDA extension. However, it is required for supporting
270644290647SDimitry Andric // __clang_cuda_builtin_vars.h, which uses __declspec(property). Once that has
270744290647SDimitry Andric // been rewritten in terms of something more generic, remove the Opts.CUDA
270844290647SDimitry Andric // term here.
27090623d748SDimitry Andric Opts.DeclSpecKeyword =
27100623d748SDimitry Andric Args.hasFlag(OPT_fdeclspec, OPT_fno_declspec,
27110623d748SDimitry Andric (Opts.MicrosoftExt || Opts.Borland || Opts.CUDA));
27120623d748SDimitry Andric
2713f785676fSDimitry Andric if (Arg *A = Args.getLastArg(OPT_faddress_space_map_mangling_EQ)) {
2714f785676fSDimitry Andric switch (llvm::StringSwitch<unsigned>(A->getValue())
2715f785676fSDimitry Andric .Case("target", LangOptions::ASMM_Target)
2716f785676fSDimitry Andric .Case("no", LangOptions::ASMM_Off)
2717f785676fSDimitry Andric .Case("yes", LangOptions::ASMM_On)
2718f785676fSDimitry Andric .Default(255)) {
2719f785676fSDimitry Andric default:
2720f785676fSDimitry Andric Diags.Report(diag::err_drv_invalid_value)
2721f785676fSDimitry Andric << "-faddress-space-map-mangling=" << A->getValue();
2722f785676fSDimitry Andric break;
2723f785676fSDimitry Andric case LangOptions::ASMM_Target:
2724f785676fSDimitry Andric Opts.setAddressSpaceMapMangling(LangOptions::ASMM_Target);
2725f785676fSDimitry Andric break;
2726f785676fSDimitry Andric case LangOptions::ASMM_On:
2727f785676fSDimitry Andric Opts.setAddressSpaceMapMangling(LangOptions::ASMM_On);
2728f785676fSDimitry Andric break;
2729f785676fSDimitry Andric case LangOptions::ASMM_Off:
2730f785676fSDimitry Andric Opts.setAddressSpaceMapMangling(LangOptions::ASMM_Off);
2731f785676fSDimitry Andric break;
2732f785676fSDimitry Andric }
2733f785676fSDimitry Andric }
2734f785676fSDimitry Andric
273559d1ed5bSDimitry Andric if (Arg *A = Args.getLastArg(OPT_fms_memptr_rep_EQ)) {
273659d1ed5bSDimitry Andric LangOptions::PragmaMSPointersToMembersKind InheritanceModel =
273759d1ed5bSDimitry Andric llvm::StringSwitch<LangOptions::PragmaMSPointersToMembersKind>(
273859d1ed5bSDimitry Andric A->getValue())
273959d1ed5bSDimitry Andric .Case("single",
274059d1ed5bSDimitry Andric LangOptions::PPTMK_FullGeneralitySingleInheritance)
274159d1ed5bSDimitry Andric .Case("multiple",
274259d1ed5bSDimitry Andric LangOptions::PPTMK_FullGeneralityMultipleInheritance)
274359d1ed5bSDimitry Andric .Case("virtual",
274459d1ed5bSDimitry Andric LangOptions::PPTMK_FullGeneralityVirtualInheritance)
274559d1ed5bSDimitry Andric .Default(LangOptions::PPTMK_BestCase);
274659d1ed5bSDimitry Andric if (InheritanceModel == LangOptions::PPTMK_BestCase)
274759d1ed5bSDimitry Andric Diags.Report(diag::err_drv_invalid_value)
274859d1ed5bSDimitry Andric << "-fms-memptr-rep=" << A->getValue();
274959d1ed5bSDimitry Andric
275059d1ed5bSDimitry Andric Opts.setMSPointerToMemberRepresentationMethod(InheritanceModel);
275159d1ed5bSDimitry Andric }
275259d1ed5bSDimitry Andric
2753e7145dcbSDimitry Andric // Check for MS default calling conventions being specified.
2754e7145dcbSDimitry Andric if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {
2755e7145dcbSDimitry Andric LangOptions::DefaultCallingConvention DefaultCC =
27569a199699SDimitry Andric llvm::StringSwitch<LangOptions::DefaultCallingConvention>(A->getValue())
2757e7145dcbSDimitry Andric .Case("cdecl", LangOptions::DCC_CDecl)
2758e7145dcbSDimitry Andric .Case("fastcall", LangOptions::DCC_FastCall)
2759e7145dcbSDimitry Andric .Case("stdcall", LangOptions::DCC_StdCall)
2760e7145dcbSDimitry Andric .Case("vectorcall", LangOptions::DCC_VectorCall)
27619a199699SDimitry Andric .Case("regcall", LangOptions::DCC_RegCall)
2762e7145dcbSDimitry Andric .Default(LangOptions::DCC_None);
2763e7145dcbSDimitry Andric if (DefaultCC == LangOptions::DCC_None)
2764e7145dcbSDimitry Andric Diags.Report(diag::err_drv_invalid_value)
2765e7145dcbSDimitry Andric << "-fdefault-calling-conv=" << A->getValue();
2766e7145dcbSDimitry Andric
2767e7145dcbSDimitry Andric llvm::Triple T(TargetOpts.Triple);
2768e7145dcbSDimitry Andric llvm::Triple::ArchType Arch = T.getArch();
2769e7145dcbSDimitry Andric bool emitError = (DefaultCC == LangOptions::DCC_FastCall ||
2770e7145dcbSDimitry Andric DefaultCC == LangOptions::DCC_StdCall) &&
2771e7145dcbSDimitry Andric Arch != llvm::Triple::x86;
27729a199699SDimitry Andric emitError |= (DefaultCC == LangOptions::DCC_VectorCall ||
27739a199699SDimitry Andric DefaultCC == LangOptions::DCC_RegCall) &&
2774e7145dcbSDimitry Andric !(Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64);
2775e7145dcbSDimitry Andric if (emitError)
2776e7145dcbSDimitry Andric Diags.Report(diag::err_drv_argument_not_allowed_with)
2777e7145dcbSDimitry Andric << A->getSpelling() << T.getTriple();
2778e7145dcbSDimitry Andric else
2779e7145dcbSDimitry Andric Opts.setDefaultCallingConv(DefaultCC);
2780e7145dcbSDimitry Andric }
2781e7145dcbSDimitry Andric
2782e7145dcbSDimitry Andric // -mrtd option
2783e7145dcbSDimitry Andric if (Arg *A = Args.getLastArg(OPT_mrtd)) {
2784e7145dcbSDimitry Andric if (Opts.getDefaultCallingConv() != LangOptions::DCC_None)
2785e7145dcbSDimitry Andric Diags.Report(diag::err_drv_argument_not_allowed_with)
2786e7145dcbSDimitry Andric << A->getSpelling() << "-fdefault-calling-conv";
2787e7145dcbSDimitry Andric else {
2788e7145dcbSDimitry Andric llvm::Triple T(TargetOpts.Triple);
2789e7145dcbSDimitry Andric if (T.getArch() != llvm::Triple::x86)
2790e7145dcbSDimitry Andric Diags.Report(diag::err_drv_argument_not_allowed_with)
2791e7145dcbSDimitry Andric << A->getSpelling() << T.getTriple();
2792e7145dcbSDimitry Andric else
2793e7145dcbSDimitry Andric Opts.setDefaultCallingConv(LangOptions::DCC_StdCall);
2794e7145dcbSDimitry Andric }
2795e7145dcbSDimitry Andric }
2796e7145dcbSDimitry Andric
279733956c43SDimitry Andric // Check if -fopenmp is specified.
2798e7145dcbSDimitry Andric Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 1 : 0;
279930785c0eSDimitry Andric // Check if -fopenmp-simd is specified.
28004ba319b5SDimitry Andric bool IsSimdSpecified =
28014ba319b5SDimitry Andric Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
280230785c0eSDimitry Andric /*Default=*/false);
28034ba319b5SDimitry Andric Opts.OpenMPSimd = !Opts.OpenMP && IsSimdSpecified;
2804875ed548SDimitry Andric Opts.OpenMPUseTLS =
2805875ed548SDimitry Andric Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
2806ea942507SDimitry Andric Opts.OpenMPIsDevice =
2807ea942507SDimitry Andric Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_device);
28084ba319b5SDimitry Andric bool IsTargetSpecified =
28094ba319b5SDimitry Andric Opts.OpenMPIsDevice || Args.hasArg(options::OPT_fopenmp_targets_EQ);
2810ea942507SDimitry Andric
281130785c0eSDimitry Andric if (Opts.OpenMP || Opts.OpenMPSimd) {
28124ba319b5SDimitry Andric if (int Version = getLastArgIntValue(
28134ba319b5SDimitry Andric Args, OPT_fopenmp_version_EQ,
28144ba319b5SDimitry Andric (IsSimdSpecified || IsTargetSpecified) ? 45 : Opts.OpenMP, Diags))
2815e7145dcbSDimitry Andric Opts.OpenMP = Version;
28164ba319b5SDimitry Andric else if (IsSimdSpecified || IsTargetSpecified)
281730785c0eSDimitry Andric Opts.OpenMP = 45;
2818e7145dcbSDimitry Andric // Provide diagnostic when a given target is not expected to be an OpenMP
2819e7145dcbSDimitry Andric // device or host.
2820e7145dcbSDimitry Andric if (!Opts.OpenMPIsDevice) {
2821e7145dcbSDimitry Andric switch (T.getArch()) {
2822e7145dcbSDimitry Andric default:
2823e7145dcbSDimitry Andric break;
2824e7145dcbSDimitry Andric // Add unsupported host targets here:
2825e7145dcbSDimitry Andric case llvm::Triple::nvptx:
2826e7145dcbSDimitry Andric case llvm::Triple::nvptx64:
28274ba319b5SDimitry Andric Diags.Report(diag::err_drv_omp_host_target_not_supported)
2828e7145dcbSDimitry Andric << TargetOpts.Triple;
2829e7145dcbSDimitry Andric break;
2830e7145dcbSDimitry Andric }
2831e7145dcbSDimitry Andric }
2832e7145dcbSDimitry Andric }
2833e7145dcbSDimitry Andric
28349a199699SDimitry Andric // Set the flag to prevent the implementation from emitting device exception
28359a199699SDimitry Andric // handling code for those requiring so.
28364ba319b5SDimitry Andric Opts.OpenMPHostCXXExceptions = Opts.Exceptions && Opts.CXXExceptions;
28374ba319b5SDimitry Andric if ((Opts.OpenMPIsDevice && T.isNVPTX()) || Opts.OpenCLCPlusPlus) {
28389a199699SDimitry Andric Opts.Exceptions = 0;
28399a199699SDimitry Andric Opts.CXXExceptions = 0;
28409a199699SDimitry Andric }
2841*b5893f02SDimitry Andric if (Opts.OpenMPIsDevice && T.isNVPTX()) {
2842*b5893f02SDimitry Andric Opts.OpenMPCUDANumSMs =
2843*b5893f02SDimitry Andric getLastArgIntValue(Args, options::OPT_fopenmp_cuda_number_of_sm_EQ,
2844*b5893f02SDimitry Andric Opts.OpenMPCUDANumSMs, Diags);
2845*b5893f02SDimitry Andric Opts.OpenMPCUDABlocksPerSM =
2846*b5893f02SDimitry Andric getLastArgIntValue(Args, options::OPT_fopenmp_cuda_blocks_per_sm_EQ,
2847*b5893f02SDimitry Andric Opts.OpenMPCUDABlocksPerSM, Diags);
2848*b5893f02SDimitry Andric }
2849*b5893f02SDimitry Andric
2850*b5893f02SDimitry Andric // Prevent auto-widening the representation of loop counters during an
2851*b5893f02SDimitry Andric // OpenMP collapse clause.
2852*b5893f02SDimitry Andric Opts.OpenMPOptimisticCollapse =
2853*b5893f02SDimitry Andric Args.hasArg(options::OPT_fopenmp_optimistic_collapse) ? 1 : 0;
28549a199699SDimitry Andric
2855ea942507SDimitry Andric // Get the OpenMP target triples if any.
2856e7145dcbSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) {
2857ea942507SDimitry Andric
2858ea942507SDimitry Andric for (unsigned i = 0; i < A->getNumValues(); ++i) {
2859ea942507SDimitry Andric llvm::Triple TT(A->getValue(i));
2860ea942507SDimitry Andric
28619a199699SDimitry Andric if (TT.getArch() == llvm::Triple::UnknownArch ||
28629a199699SDimitry Andric !(TT.getArch() == llvm::Triple::ppc ||
28639a199699SDimitry Andric TT.getArch() == llvm::Triple::ppc64 ||
28649a199699SDimitry Andric TT.getArch() == llvm::Triple::ppc64le ||
28659a199699SDimitry Andric TT.getArch() == llvm::Triple::nvptx ||
28669a199699SDimitry Andric TT.getArch() == llvm::Triple::nvptx64 ||
28679a199699SDimitry Andric TT.getArch() == llvm::Triple::x86 ||
28689a199699SDimitry Andric TT.getArch() == llvm::Triple::x86_64))
28694ba319b5SDimitry Andric Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i);
2870ea942507SDimitry Andric else
2871ea942507SDimitry Andric Opts.OMPTargetTriples.push_back(TT);
2872ea942507SDimitry Andric }
2873ea942507SDimitry Andric }
2874ea942507SDimitry Andric
2875ea942507SDimitry Andric // Get OpenMP host file path if any and report if a non existent file is
2876ea942507SDimitry Andric // found
2877e7145dcbSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_fopenmp_host_ir_file_path)) {
2878ea942507SDimitry Andric Opts.OMPHostIRFile = A->getValue();
2879ea942507SDimitry Andric if (!llvm::sys::fs::exists(Opts.OMPHostIRFile))
28804ba319b5SDimitry Andric Diags.Report(diag::err_drv_omp_host_ir_file_not_found)
2881ea942507SDimitry Andric << Opts.OMPHostIRFile;
2882ea942507SDimitry Andric }
2883139f7f9bSDimitry Andric
2884*b5893f02SDimitry Andric // Set CUDA mode for OpenMP target NVPTX if specified in options
28854ba319b5SDimitry Andric Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && T.isNVPTX() &&
28864ba319b5SDimitry Andric Args.hasArg(options::OPT_fopenmp_cuda_mode);
28874ba319b5SDimitry Andric
2888*b5893f02SDimitry Andric // Set CUDA mode for OpenMP target NVPTX if specified in options
2889*b5893f02SDimitry Andric Opts.OpenMPCUDAForceFullRuntime =
2890*b5893f02SDimitry Andric Opts.OpenMPIsDevice && T.isNVPTX() &&
2891*b5893f02SDimitry Andric Args.hasArg(options::OPT_fopenmp_cuda_force_full_runtime);
2892*b5893f02SDimitry Andric
28933b0f4066SDimitry Andric // Record whether the __DEPRECATED define was requested.
28943b0f4066SDimitry Andric Opts.Deprecated = Args.hasFlag(OPT_fdeprecated_macro,
28953b0f4066SDimitry Andric OPT_fno_deprecated_macro,
28963b0f4066SDimitry Andric Opts.Deprecated);
2897f22ef01cSRoman Divacky
2898f22ef01cSRoman Divacky // FIXME: Eliminate this dependency.
28997ae0e2c9SDimitry Andric unsigned Opt = getOptimizationLevel(Args, IK, Diags),
2900284c1978SDimitry Andric OptSize = getOptimizationLevelSize(Args);
2901f22ef01cSRoman Divacky Opts.Optimize = Opt != 0;
29027ae0e2c9SDimitry Andric Opts.OptimizeSize = OptSize != 0;
2903f22ef01cSRoman Divacky
2904f22ef01cSRoman Divacky // This is the __NO_INLINE__ define, which just depends on things like the
2905f22ef01cSRoman Divacky // optimization level and -fno-inline, not actually whether the backend has
2906f22ef01cSRoman Divacky // inlining enabled.
290744290647SDimitry Andric Opts.NoInlineDefine = !Opts.Optimize;
290844290647SDimitry Andric if (Arg *InlineArg = Args.getLastArg(
290944290647SDimitry Andric options::OPT_finline_functions, options::OPT_finline_hint_functions,
291044290647SDimitry Andric options::OPT_fno_inline_functions, options::OPT_fno_inline))
291144290647SDimitry Andric if (InlineArg->getOption().matches(options::OPT_fno_inline))
291244290647SDimitry Andric Opts.NoInlineDefine = true;
2913dff0c46cSDimitry Andric
291439d628a0SDimitry Andric Opts.FastMath = Args.hasArg(OPT_ffast_math) ||
291539d628a0SDimitry Andric Args.hasArg(OPT_cl_fast_relaxed_math);
291639d628a0SDimitry Andric Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only) ||
291739d628a0SDimitry Andric Args.hasArg(OPT_cl_finite_math_only) ||
291839d628a0SDimitry Andric Args.hasArg(OPT_cl_fast_relaxed_math);
29190623d748SDimitry Andric Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
29200623d748SDimitry Andric Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
29210623d748SDimitry Andric Args.hasArg(OPT_cl_fast_relaxed_math);
2922f22ef01cSRoman Divacky
292320e90f04SDimitry Andric if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
292420e90f04SDimitry Andric StringRef Val = A->getValue();
292520e90f04SDimitry Andric if (Val == "fast")
292620e90f04SDimitry Andric Opts.setDefaultFPContractMode(LangOptions::FPC_Fast);
292720e90f04SDimitry Andric else if (Val == "on")
292820e90f04SDimitry Andric Opts.setDefaultFPContractMode(LangOptions::FPC_On);
292920e90f04SDimitry Andric else if (Val == "off")
293020e90f04SDimitry Andric Opts.setDefaultFPContractMode(LangOptions::FPC_Off);
293120e90f04SDimitry Andric else
293220e90f04SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
293320e90f04SDimitry Andric }
293420e90f04SDimitry Andric
29353861d79fSDimitry Andric Opts.RetainCommentsFromSystemHeaders =
29363861d79fSDimitry Andric Args.hasArg(OPT_fretain_comments_from_system_headers);
29373861d79fSDimitry Andric
2938f785676fSDimitry Andric unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
2939f22ef01cSRoman Divacky switch (SSP) {
2940f22ef01cSRoman Divacky default:
2941f22ef01cSRoman Divacky Diags.Report(diag::err_drv_invalid_value)
2942f22ef01cSRoman Divacky << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
2943f22ef01cSRoman Divacky break;
29446122f3e6SDimitry Andric case 0: Opts.setStackProtector(LangOptions::SSPOff); break;
29456122f3e6SDimitry Andric case 1: Opts.setStackProtector(LangOptions::SSPOn); break;
294659d1ed5bSDimitry Andric case 2: Opts.setStackProtector(LangOptions::SSPStrong); break;
294759d1ed5bSDimitry Andric case 3: Opts.setStackProtector(LangOptions::SSPReq); break;
2948f22ef01cSRoman Divacky }
29493861d79fSDimitry Andric
2950*b5893f02SDimitry Andric if (Arg *A = Args.getLastArg(OPT_ftrivial_auto_var_init)) {
2951*b5893f02SDimitry Andric StringRef Val = A->getValue();
2952*b5893f02SDimitry Andric if (Val == "uninitialized")
2953*b5893f02SDimitry Andric Opts.setTrivialAutoVarInit(
2954*b5893f02SDimitry Andric LangOptions::TrivialAutoVarInitKind::Uninitialized);
2955*b5893f02SDimitry Andric else if (Val == "zero")
2956*b5893f02SDimitry Andric Opts.setTrivialAutoVarInit(LangOptions::TrivialAutoVarInitKind::Zero);
2957*b5893f02SDimitry Andric else if (Val == "pattern")
2958*b5893f02SDimitry Andric Opts.setTrivialAutoVarInit(LangOptions::TrivialAutoVarInitKind::Pattern);
2959*b5893f02SDimitry Andric else
2960*b5893f02SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2961*b5893f02SDimitry Andric }
2962*b5893f02SDimitry Andric
29633861d79fSDimitry Andric // Parse -fsanitize= arguments.
296439d628a0SDimitry Andric parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
296539d628a0SDimitry Andric Diags, Opts.Sanitize);
296639d628a0SDimitry Andric // -fsanitize-address-field-padding=N has to be a LangOpt, parse it here.
296739d628a0SDimitry Andric Opts.SanitizeAddressFieldPadding =
296839d628a0SDimitry Andric getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags);
296933956c43SDimitry Andric Opts.SanitizerBlacklistFiles = Args.getAllArgValues(OPT_fsanitize_blacklist);
297020e90f04SDimitry Andric
297120e90f04SDimitry Andric // -fxray-instrument
297220e90f04SDimitry Andric Opts.XRayInstrument =
297320e90f04SDimitry Andric Args.hasFlag(OPT_fxray_instrument, OPT_fnoxray_instrument, false);
297420e90f04SDimitry Andric
29759a199699SDimitry Andric // -fxray-always-emit-customevents
29769a199699SDimitry Andric Opts.XRayAlwaysEmitCustomEvents =
29779a199699SDimitry Andric Args.hasFlag(OPT_fxray_always_emit_customevents,
29789a199699SDimitry Andric OPT_fnoxray_always_emit_customevents, false);
29799a199699SDimitry Andric
29804ba319b5SDimitry Andric // -fxray-always-emit-typedevents
29814ba319b5SDimitry Andric Opts.XRayAlwaysEmitTypedEvents =
29824ba319b5SDimitry Andric Args.hasFlag(OPT_fxray_always_emit_typedevents,
29834ba319b5SDimitry Andric OPT_fnoxray_always_emit_customevents, false);
29844ba319b5SDimitry Andric
298520e90f04SDimitry Andric // -fxray-{always,never}-instrument= filenames.
298620e90f04SDimitry Andric Opts.XRayAlwaysInstrumentFiles =
298720e90f04SDimitry Andric Args.getAllArgValues(OPT_fxray_always_instrument);
298820e90f04SDimitry Andric Opts.XRayNeverInstrumentFiles =
298920e90f04SDimitry Andric Args.getAllArgValues(OPT_fxray_never_instrument);
29904ba319b5SDimitry Andric Opts.XRayAttrListFiles = Args.getAllArgValues(OPT_fxray_attr_list);
29914ba319b5SDimitry Andric
29924ba319b5SDimitry Andric // -fforce-emit-vtables
29934ba319b5SDimitry Andric Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables);
29946bc11b14SDimitry Andric
29956bc11b14SDimitry Andric // -fallow-editor-placeholders
29966bc11b14SDimitry Andric Opts.AllowEditorPlaceholders = Args.hasArg(OPT_fallow_editor_placeholders);
29974ba319b5SDimitry Andric
2998*b5893f02SDimitry Andric Opts.RegisterStaticDestructors = !Args.hasArg(OPT_fno_cxx_static_destructors);
2999*b5893f02SDimitry Andric
30004ba319b5SDimitry Andric if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
30014ba319b5SDimitry Andric Opts.setClangABICompat(LangOptions::ClangABI::Latest);
30024ba319b5SDimitry Andric
30034ba319b5SDimitry Andric StringRef Ver = A->getValue();
30044ba319b5SDimitry Andric std::pair<StringRef, StringRef> VerParts = Ver.split('.');
30054ba319b5SDimitry Andric unsigned Major, Minor = 0;
30064ba319b5SDimitry Andric
30074ba319b5SDimitry Andric // Check the version number is valid: either 3.x (0 <= x <= 9) or
30084ba319b5SDimitry Andric // y or y.0 (4 <= y <= current version).
30094ba319b5SDimitry Andric if (!VerParts.first.startswith("0") &&
30104ba319b5SDimitry Andric !VerParts.first.getAsInteger(10, Major) &&
30114ba319b5SDimitry Andric 3 <= Major && Major <= CLANG_VERSION_MAJOR &&
30124ba319b5SDimitry Andric (Major == 3 ? VerParts.second.size() == 1 &&
30134ba319b5SDimitry Andric !VerParts.second.getAsInteger(10, Minor)
30144ba319b5SDimitry Andric : VerParts.first.size() == Ver.size() ||
30154ba319b5SDimitry Andric VerParts.second == "0")) {
30164ba319b5SDimitry Andric // Got a valid version number.
30174ba319b5SDimitry Andric if (Major == 3 && Minor <= 8)
30184ba319b5SDimitry Andric Opts.setClangABICompat(LangOptions::ClangABI::Ver3_8);
30194ba319b5SDimitry Andric else if (Major <= 4)
30204ba319b5SDimitry Andric Opts.setClangABICompat(LangOptions::ClangABI::Ver4);
30214ba319b5SDimitry Andric else if (Major <= 6)
30224ba319b5SDimitry Andric Opts.setClangABICompat(LangOptions::ClangABI::Ver6);
3023*b5893f02SDimitry Andric else if (Major <= 7)
3024*b5893f02SDimitry Andric Opts.setClangABICompat(LangOptions::ClangABI::Ver7);
30254ba319b5SDimitry Andric } else if (Ver != "latest") {
30264ba319b5SDimitry Andric Diags.Report(diag::err_drv_invalid_value)
30274ba319b5SDimitry Andric << A->getAsString(Args) << A->getValue();
30284ba319b5SDimitry Andric }
30294ba319b5SDimitry Andric }
30304ba319b5SDimitry Andric
30314ba319b5SDimitry Andric Opts.CompleteMemberPointers = Args.hasArg(OPT_fcomplete_member_pointers);
30324ba319b5SDimitry Andric Opts.BuildingPCHWithObjectFile = Args.hasArg(OPT_building_pch_with_obj);
3033f22ef01cSRoman Divacky }
3034f22ef01cSRoman Divacky
isStrictlyPreprocessorAction(frontend::ActionKind Action)3035edd7eaddSDimitry Andric static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
3036edd7eaddSDimitry Andric switch (Action) {
3037edd7eaddSDimitry Andric case frontend::ASTDeclList:
3038edd7eaddSDimitry Andric case frontend::ASTDump:
3039edd7eaddSDimitry Andric case frontend::ASTPrint:
3040edd7eaddSDimitry Andric case frontend::ASTView:
3041edd7eaddSDimitry Andric case frontend::EmitAssembly:
3042edd7eaddSDimitry Andric case frontend::EmitBC:
3043edd7eaddSDimitry Andric case frontend::EmitHTML:
3044edd7eaddSDimitry Andric case frontend::EmitLLVM:
3045edd7eaddSDimitry Andric case frontend::EmitLLVMOnly:
3046edd7eaddSDimitry Andric case frontend::EmitCodeGenOnly:
3047edd7eaddSDimitry Andric case frontend::EmitObj:
3048edd7eaddSDimitry Andric case frontend::FixIt:
3049edd7eaddSDimitry Andric case frontend::GenerateModule:
3050edd7eaddSDimitry Andric case frontend::GenerateModuleInterface:
3051*b5893f02SDimitry Andric case frontend::GenerateHeaderModule:
3052edd7eaddSDimitry Andric case frontend::GeneratePCH:
3053edd7eaddSDimitry Andric case frontend::ParseSyntaxOnly:
3054edd7eaddSDimitry Andric case frontend::ModuleFileInfo:
3055edd7eaddSDimitry Andric case frontend::VerifyPCH:
3056edd7eaddSDimitry Andric case frontend::PluginAction:
3057edd7eaddSDimitry Andric case frontend::RewriteObjC:
3058edd7eaddSDimitry Andric case frontend::RewriteTest:
3059edd7eaddSDimitry Andric case frontend::RunAnalysis:
30604ba319b5SDimitry Andric case frontend::TemplightDump:
3061edd7eaddSDimitry Andric case frontend::MigrateSource:
3062edd7eaddSDimitry Andric return false;
3063edd7eaddSDimitry Andric
30644ba319b5SDimitry Andric case frontend::DumpCompilerOptions:
3065edd7eaddSDimitry Andric case frontend::DumpRawTokens:
3066edd7eaddSDimitry Andric case frontend::DumpTokens:
3067edd7eaddSDimitry Andric case frontend::InitOnly:
3068edd7eaddSDimitry Andric case frontend::PrintPreamble:
3069edd7eaddSDimitry Andric case frontend::PrintPreprocessedInput:
3070edd7eaddSDimitry Andric case frontend::RewriteMacros:
3071edd7eaddSDimitry Andric case frontend::RunPreprocessorOnly:
3072edd7eaddSDimitry Andric return true;
3073edd7eaddSDimitry Andric }
3074edd7eaddSDimitry Andric llvm_unreachable("invalid frontend action");
3075edd7eaddSDimitry Andric }
3076edd7eaddSDimitry Andric
ParsePreprocessorArgs(PreprocessorOptions & Opts,ArgList & Args,DiagnosticsEngine & Diags,frontend::ActionKind Action)3077f22ef01cSRoman Divacky static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
3078edd7eaddSDimitry Andric DiagnosticsEngine &Diags,
3079edd7eaddSDimitry Andric frontend::ActionKind Action) {
3080f22ef01cSRoman Divacky Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch);
3081*b5893f02SDimitry Andric Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) ||
3082*b5893f02SDimitry Andric Args.hasArg(OPT_pch_through_hdrstop_use);
3083*b5893f02SDimitry Andric Opts.PCHWithHdrStopCreate = Args.hasArg(OPT_pch_through_hdrstop_create);
30844ba319b5SDimitry Andric Opts.PCHThroughHeader = Args.getLastArgValue(OPT_pch_through_header_EQ);
3085f22ef01cSRoman Divacky Opts.UsePredefines = !Args.hasArg(OPT_undef);
3086f22ef01cSRoman Divacky Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
3087e580952dSDimitry Andric Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
308820e90f04SDimitry Andric Opts.AllowPCHWithCompilerErrors = Args.hasArg(OPT_fallow_pch_with_errors);
3089e580952dSDimitry Andric
30902754fe60SDimitry Andric Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
30914ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
30923861d79fSDimitry Andric Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
30932754fe60SDimitry Andric
3094e580952dSDimitry Andric if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
30953861d79fSDimitry Andric StringRef Value(A->getValue());
3096e580952dSDimitry Andric size_t Comma = Value.find(',');
3097e580952dSDimitry Andric unsigned Bytes = 0;
3098e580952dSDimitry Andric unsigned EndOfLine = 0;
3099e580952dSDimitry Andric
31006122f3e6SDimitry Andric if (Comma == StringRef::npos ||
3101e580952dSDimitry Andric Value.substr(0, Comma).getAsInteger(10, Bytes) ||
3102e580952dSDimitry Andric Value.substr(Comma + 1).getAsInteger(10, EndOfLine))
3103e580952dSDimitry Andric Diags.Report(diag::err_drv_preamble_format);
3104e580952dSDimitry Andric else {
3105e580952dSDimitry Andric Opts.PrecompiledPreambleBytes.first = Bytes;
3106e580952dSDimitry Andric Opts.PrecompiledPreambleBytes.second = (EndOfLine != 0);
3107e580952dSDimitry Andric }
3108e580952dSDimitry Andric }
3109e580952dSDimitry Andric
31104ba319b5SDimitry Andric // Add the __CET__ macro if a CFProtection option is set.
31114ba319b5SDimitry Andric if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
31124ba319b5SDimitry Andric StringRef Name = A->getValue();
31134ba319b5SDimitry Andric if (Name == "branch")
31144ba319b5SDimitry Andric Opts.addMacroDef("__CET__=1");
31154ba319b5SDimitry Andric else if (Name == "return")
31164ba319b5SDimitry Andric Opts.addMacroDef("__CET__=2");
31174ba319b5SDimitry Andric else if (Name == "full")
31184ba319b5SDimitry Andric Opts.addMacroDef("__CET__=3");
31194ba319b5SDimitry Andric }
31204ba319b5SDimitry Andric
3121f22ef01cSRoman Divacky // Add macros from the command line.
31224ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_D, OPT_U)) {
312397bc6c73SDimitry Andric if (A->getOption().matches(OPT_D))
312497bc6c73SDimitry Andric Opts.addMacroDef(A->getValue());
3125f22ef01cSRoman Divacky else
312697bc6c73SDimitry Andric Opts.addMacroUndef(A->getValue());
3127f22ef01cSRoman Divacky }
3128f22ef01cSRoman Divacky
3129f22ef01cSRoman Divacky Opts.MacroIncludes = Args.getAllArgValues(OPT_imacros);
3130f22ef01cSRoman Divacky
3131f22ef01cSRoman Divacky // Add the ordered list of -includes.
31324ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_include))
313397bc6c73SDimitry Andric Opts.Includes.emplace_back(A->getValue());
3134f22ef01cSRoman Divacky
31354ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_chain_include))
313697bc6c73SDimitry Andric Opts.ChainedIncludes.emplace_back(A->getValue());
31373b0f4066SDimitry Andric
31384ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_remap_file)) {
313997bc6c73SDimitry Andric std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';');
3140f22ef01cSRoman Divacky
3141f22ef01cSRoman Divacky if (Split.second.empty()) {
3142ffd1746dSEd Schouten Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
3143f22ef01cSRoman Divacky continue;
3144f22ef01cSRoman Divacky }
3145f22ef01cSRoman Divacky
3146f22ef01cSRoman Divacky Opts.addRemappedFile(Split.first, Split.second);
3147f22ef01cSRoman Divacky }
314817a519f9SDimitry Andric
314917a519f9SDimitry Andric if (Arg *A = Args.getLastArg(OPT_fobjc_arc_cxxlib_EQ)) {
31503861d79fSDimitry Andric StringRef Name = A->getValue();
315117a519f9SDimitry Andric unsigned Library = llvm::StringSwitch<unsigned>(Name)
315217a519f9SDimitry Andric .Case("libc++", ARCXX_libcxx)
315317a519f9SDimitry Andric .Case("libstdc++", ARCXX_libstdcxx)
315417a519f9SDimitry Andric .Case("none", ARCXX_nolib)
315517a519f9SDimitry Andric .Default(~0U);
315617a519f9SDimitry Andric if (Library == ~0U)
315717a519f9SDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
315817a519f9SDimitry Andric else
315917a519f9SDimitry Andric Opts.ObjCXXARCStandardLibrary = (ObjCXXARCStandardLibraryKind)Library;
316017a519f9SDimitry Andric }
3161edd7eaddSDimitry Andric
3162edd7eaddSDimitry Andric // Always avoid lexing editor placeholders when we're just running the
3163edd7eaddSDimitry Andric // preprocessor as we never want to emit the
3164edd7eaddSDimitry Andric // "editor placeholder in source file" error in PP only mode.
3165edd7eaddSDimitry Andric if (isStrictlyPreprocessorAction(Action))
3166edd7eaddSDimitry Andric Opts.LexEditorPlaceholders = false;
3167f22ef01cSRoman Divacky }
3168f22ef01cSRoman Divacky
ParsePreprocessorOutputArgs(PreprocessorOutputOptions & Opts,ArgList & Args,frontend::ActionKind Action)3169f22ef01cSRoman Divacky static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
3170139f7f9bSDimitry Andric ArgList &Args,
3171139f7f9bSDimitry Andric frontend::ActionKind Action) {
3172edd7eaddSDimitry Andric if (isStrictlyPreprocessorAction(Action))
3173f22ef01cSRoman Divacky Opts.ShowCPP = !Args.hasArg(OPT_dM);
3174edd7eaddSDimitry Andric else
3175edd7eaddSDimitry Andric Opts.ShowCPP = 0;
3176139f7f9bSDimitry Andric
3177f22ef01cSRoman Divacky Opts.ShowComments = Args.hasArg(OPT_C);
3178e580952dSDimitry Andric Opts.ShowLineMarkers = !Args.hasArg(OPT_P);
3179f22ef01cSRoman Divacky Opts.ShowMacroComments = Args.hasArg(OPT_CC);
3180e580952dSDimitry Andric Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
318144290647SDimitry Andric Opts.ShowIncludeDirectives = Args.hasArg(OPT_dI);
31827ae0e2c9SDimitry Andric Opts.RewriteIncludes = Args.hasArg(OPT_frewrite_includes);
3183db17bf38SDimitry Andric Opts.RewriteImports = Args.hasArg(OPT_frewrite_imports);
318433956c43SDimitry Andric Opts.UseLineDirectives = Args.hasArg(OPT_fuse_line_directives);
3185f22ef01cSRoman Divacky }
3186f22ef01cSRoman Divacky
ParseTargetArgs(TargetOptions & Opts,ArgList & Args,DiagnosticsEngine & Diags)3187e7145dcbSDimitry Andric static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
3188e7145dcbSDimitry Andric DiagnosticsEngine &Diags) {
3189*b5893f02SDimitry Andric Opts.CodeModel = getCodeModel(Args, Diags);
3190f22ef01cSRoman Divacky Opts.ABI = Args.getLastArgValue(OPT_target_abi);
3191e7145dcbSDimitry Andric if (Arg *A = Args.getLastArg(OPT_meabi)) {
3192e7145dcbSDimitry Andric StringRef Value = A->getValue();
3193e7145dcbSDimitry Andric llvm::EABI EABIVersion = llvm::StringSwitch<llvm::EABI>(Value)
3194e7145dcbSDimitry Andric .Case("default", llvm::EABI::Default)
3195e7145dcbSDimitry Andric .Case("4", llvm::EABI::EABI4)
3196e7145dcbSDimitry Andric .Case("5", llvm::EABI::EABI5)
3197e7145dcbSDimitry Andric .Case("gnu", llvm::EABI::GNU)
3198e7145dcbSDimitry Andric .Default(llvm::EABI::Unknown);
3199e7145dcbSDimitry Andric if (EABIVersion == llvm::EABI::Unknown)
3200e7145dcbSDimitry Andric Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
3201e7145dcbSDimitry Andric << Value;
3202e7145dcbSDimitry Andric else
3203a580b014SDimitry Andric Opts.EABIVersion = EABIVersion;
3204e7145dcbSDimitry Andric }
3205f22ef01cSRoman Divacky Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
3206f785676fSDimitry Andric Opts.FPMath = Args.getLastArgValue(OPT_mfpmath);
32073861d79fSDimitry Andric Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature);
3208e580952dSDimitry Andric Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version);
32094ba319b5SDimitry Andric Opts.Triple = Args.getLastArgValue(OPT_triple);
3210dff0c46cSDimitry Andric // Use the default target triple if unspecified.
3211f22ef01cSRoman Divacky if (Opts.Triple.empty())
3212dff0c46cSDimitry Andric Opts.Triple = llvm::sys::getDefaultTargetTriple();
32134ba319b5SDimitry Andric Opts.Triple = llvm::Triple::normalize(Opts.Triple);
321444290647SDimitry Andric Opts.OpenCLExtensionsAsWritten = Args.getAllArgValues(OPT_cl_ext_EQ);
32154ba319b5SDimitry Andric Opts.ForceEnableInt128 = Args.hasArg(OPT_fforce_enable_int128);
32164ba319b5SDimitry Andric Opts.NVPTXUseShortPointers = Args.hasFlag(
32174ba319b5SDimitry Andric options::OPT_fcuda_short_ptr, options::OPT_fno_cuda_short_ptr, false);
3218*b5893f02SDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version_EQ)) {
3219*b5893f02SDimitry Andric llvm::VersionTuple Version;
3220*b5893f02SDimitry Andric if (Version.tryParse(A->getValue()))
3221*b5893f02SDimitry Andric Diags.Report(diag::err_drv_invalid_value)
3222*b5893f02SDimitry Andric << A->getAsString(Args) << A->getValue();
3223*b5893f02SDimitry Andric else
3224*b5893f02SDimitry Andric Opts.SDKVersion = Version;
3225*b5893f02SDimitry Andric }
3226f22ef01cSRoman Divacky }
3227f22ef01cSRoman Divacky
CreateFromArgs(CompilerInvocation & Res,const char * const * ArgBegin,const char * const * ArgEnd,DiagnosticsEngine & Diags)3228dff0c46cSDimitry Andric bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
32292754fe60SDimitry Andric const char *const *ArgBegin,
32302754fe60SDimitry Andric const char *const *ArgEnd,
32316122f3e6SDimitry Andric DiagnosticsEngine &Diags) {
3232dff0c46cSDimitry Andric bool Success = true;
3233dff0c46cSDimitry Andric
3234f22ef01cSRoman Divacky // Parse the arguments.
323520e90f04SDimitry Andric std::unique_ptr<OptTable> Opts = createDriverOptTable();
3236f785676fSDimitry Andric const unsigned IncludedFlagsBitmask = options::CC1Option;
3237f22ef01cSRoman Divacky unsigned MissingArgIndex, MissingArgCount;
32383dac3a9bSDimitry Andric InputArgList Args =
32393dac3a9bSDimitry Andric Opts->ParseArgs(llvm::makeArrayRef(ArgBegin, ArgEnd), MissingArgIndex,
32403dac3a9bSDimitry Andric MissingArgCount, IncludedFlagsBitmask);
3241e7145dcbSDimitry Andric LangOptions &LangOpts = *Res.getLangOpts();
3242f22ef01cSRoman Divacky
3243f22ef01cSRoman Divacky // Check for missing argument error.
3244dff0c46cSDimitry Andric if (MissingArgCount) {
3245f22ef01cSRoman Divacky Diags.Report(diag::err_drv_missing_argument)
32463dac3a9bSDimitry Andric << Args.getArgString(MissingArgIndex) << MissingArgCount;
3247dff0c46cSDimitry Andric Success = false;
3248dff0c46cSDimitry Andric }
3249f22ef01cSRoman Divacky
3250f22ef01cSRoman Divacky // Issue errors on unknown arguments.
32514ba319b5SDimitry Andric for (const auto *A : Args.filtered(OPT_UNKNOWN)) {
32524ba319b5SDimitry Andric auto ArgString = A->getAsString(Args);
32534ba319b5SDimitry Andric std::string Nearest;
32544ba319b5SDimitry Andric if (Opts->findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1)
32554ba319b5SDimitry Andric Diags.Report(diag::err_drv_unknown_argument) << ArgString;
32564ba319b5SDimitry Andric else
32574ba319b5SDimitry Andric Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
32584ba319b5SDimitry Andric << ArgString << Nearest;
3259dff0c46cSDimitry Andric Success = false;
3260dff0c46cSDimitry Andric }
3261f22ef01cSRoman Divacky
32623dac3a9bSDimitry Andric Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags);
32633dac3a9bSDimitry Andric Success &= ParseMigratorArgs(Res.getMigratorOpts(), Args);
32643dac3a9bSDimitry Andric ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args);
326544290647SDimitry Andric Success &=
326644290647SDimitry Andric ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags,
326744290647SDimitry Andric false /*DefaultDiagColor*/, false /*DefaultShowOpt*/);
3268e7145dcbSDimitry Andric ParseCommentArgs(LangOpts.CommentOpts, Args);
32693dac3a9bSDimitry Andric ParseFileSystemArgs(Res.getFileSystemOpts(), Args);
32702754fe60SDimitry Andric // FIXME: We shouldn't have to pass the DashX option around here
327144290647SDimitry Andric InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), Args, Diags,
327244290647SDimitry Andric LangOpts.IsHeaderFile);
3273e7145dcbSDimitry Andric ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
32743dac3a9bSDimitry Andric Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags,
32754ba319b5SDimitry Andric Res.getTargetOpts(), Res.getFrontendOpts());
327620e90f04SDimitry Andric ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args,
327720e90f04SDimitry Andric Res.getFileSystemOpts().WorkingDir);
3278*b5893f02SDimitry Andric llvm::Triple T(Res.getTargetOpts().Triple);
3279f37b6182SDimitry Andric if (DashX.getFormat() == InputKind::Precompiled ||
3280f37b6182SDimitry Andric DashX.getLanguage() == InputKind::LLVM_IR) {
32810623d748SDimitry Andric // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
32820623d748SDimitry Andric // PassManager in BackendUtil.cpp. They need to be initializd no matter
32830623d748SDimitry Andric // what the input type is.
32840623d748SDimitry Andric if (Args.hasArg(OPT_fobjc_arc))
3285e7145dcbSDimitry Andric LangOpts.ObjCAutoRefCount = 1;
3286e7145dcbSDimitry Andric // PIClevel and PIELevel are needed during code generation and this should be
3287e7145dcbSDimitry Andric // set regardless of the input type.
3288e7145dcbSDimitry Andric LangOpts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
3289e7145dcbSDimitry Andric LangOpts.PIE = Args.hasArg(OPT_pic_is_pie);
32900623d748SDimitry Andric parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
3291e7145dcbSDimitry Andric Diags, LangOpts.Sanitize);
32920623d748SDimitry Andric } else {
3293*b5893f02SDimitry Andric // Other LangOpts are only initialized when the input is not AST or LLVM IR.
3294f37b6182SDimitry Andric // FIXME: Should we really be calling this for an InputKind::Asm input?
3295e7145dcbSDimitry Andric ParseLangArgs(LangOpts, Args, DashX, Res.getTargetOpts(),
3296e7145dcbSDimitry Andric Res.getPreprocessorOpts(), Diags);
3297dd6029ffSDimitry Andric if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
3298e7145dcbSDimitry Andric LangOpts.ObjCExceptions = 1;
3299*b5893f02SDimitry Andric if (T.isOSDarwin() && DashX.isPreprocessed()) {
3300*b5893f02SDimitry Andric // Supress the darwin-specific 'stdlibcxx-not-found' diagnostic for
3301*b5893f02SDimitry Andric // preprocessed input as we don't expect it to be used with -std=libc++
3302*b5893f02SDimitry Andric // anyway.
3303*b5893f02SDimitry Andric Res.getDiagnosticOpts().Warnings.push_back("no-stdlibcxx-not-found");
3304*b5893f02SDimitry Andric }
3305dd6029ffSDimitry Andric }
3306e7145dcbSDimitry Andric
33074ba319b5SDimitry Andric LangOpts.FunctionAlignment =
33084ba319b5SDimitry Andric getLastArgIntValue(Args, OPT_function_alignment, 0, Diags);
33094ba319b5SDimitry Andric
3310e7145dcbSDimitry Andric if (LangOpts.CUDA) {
3311e7145dcbSDimitry Andric // During CUDA device-side compilation, the aux triple is the
3312e7145dcbSDimitry Andric // triple used for host compilation.
3313e7145dcbSDimitry Andric if (LangOpts.CUDAIsDevice)
3314e7145dcbSDimitry Andric Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
3315e7145dcbSDimitry Andric }
3316e7145dcbSDimitry Andric
3317a580b014SDimitry Andric // Set the triple of the host for OpenMP device compile.
3318a580b014SDimitry Andric if (LangOpts.OpenMPIsDevice)
3319a580b014SDimitry Andric Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
3320a580b014SDimitry Andric
3321e7145dcbSDimitry Andric // FIXME: Override value name discarding when asan or msan is used because the
3322e7145dcbSDimitry Andric // backend passes depend on the name of the alloca in order to print out
3323e7145dcbSDimitry Andric // names.
3324e7145dcbSDimitry Andric Res.getCodeGenOpts().DiscardValueNames &=
3325e7145dcbSDimitry Andric !LangOpts.Sanitize.has(SanitizerKind::Address) &&
3326*b5893f02SDimitry Andric !LangOpts.Sanitize.has(SanitizerKind::KernelAddress) &&
3327*b5893f02SDimitry Andric !LangOpts.Sanitize.has(SanitizerKind::Memory) &&
3328*b5893f02SDimitry Andric !LangOpts.Sanitize.has(SanitizerKind::KernelMemory);
3329e7145dcbSDimitry Andric
33304ba319b5SDimitry Andric ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, Diags,
3331edd7eaddSDimitry Andric Res.getFrontendOpts().ProgramAction);
33323dac3a9bSDimitry Andric ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), Args,
3333139f7f9bSDimitry Andric Res.getFrontendOpts().ProgramAction);
333444290647SDimitry Andric
333544290647SDimitry Andric // Turn on -Wspir-compat for SPIR target.
333644290647SDimitry Andric auto Arch = T.getArch();
333744290647SDimitry Andric if (Arch == llvm::Triple::spir || Arch == llvm::Triple::spir64) {
333844290647SDimitry Andric Res.getDiagnosticOpts().Warnings.push_back("spir-compat");
333944290647SDimitry Andric }
33409a199699SDimitry Andric
33419a199699SDimitry Andric // If sanitizer is enabled, disable OPT_ffine_grained_bitfield_accesses.
33429a199699SDimitry Andric if (Res.getCodeGenOpts().FineGrainedBitfieldAccesses &&
33439a199699SDimitry Andric !Res.getLangOpts()->Sanitize.empty()) {
33449a199699SDimitry Andric Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false;
33459a199699SDimitry Andric Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);
33469a199699SDimitry Andric }
3347dff0c46cSDimitry Andric return Success;
3348f22ef01cSRoman Divacky }
33496122f3e6SDimitry Andric
getModuleHash() const33506122f3e6SDimitry Andric std::string CompilerInvocation::getModuleHash() const {
3351139f7f9bSDimitry Andric // Note: For QoI reasons, the things we use as a hash here should all be
3352139f7f9bSDimitry Andric // dumped via the -module-info flag.
33533861d79fSDimitry Andric using llvm::hash_code;
33543861d79fSDimitry Andric using llvm::hash_value;
33553861d79fSDimitry Andric using llvm::hash_combine;
33566122f3e6SDimitry Andric
33576122f3e6SDimitry Andric // Start the signature with the compiler version.
33583861d79fSDimitry Andric // FIXME: We'd rather use something more cryptographically sound than
33593861d79fSDimitry Andric // CityHash, but this will do for now.
33603861d79fSDimitry Andric hash_code code = hash_value(getClangFullRepositoryVersion());
33616122f3e6SDimitry Andric
33626122f3e6SDimitry Andric // Extend the signature with the language options
33636122f3e6SDimitry Andric #define LANGOPT(Name, Bits, Default, Description) \
33643861d79fSDimitry Andric code = hash_combine(code, LangOpts->Name);
33656122f3e6SDimitry Andric #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
33663861d79fSDimitry Andric code = hash_combine(code, static_cast<unsigned>(LangOpts->get##Name()));
33676122f3e6SDimitry Andric #define BENIGN_LANGOPT(Name, Bits, Default, Description)
33686122f3e6SDimitry Andric #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
33696122f3e6SDimitry Andric #include "clang/Basic/LangOptions.def"
33706122f3e6SDimitry Andric
33713dac3a9bSDimitry Andric for (StringRef Feature : LangOpts->ModuleFeatures)
33723dac3a9bSDimitry Andric code = hash_combine(code, Feature);
33733dac3a9bSDimitry Andric
33743861d79fSDimitry Andric // Extend the signature with the target options.
33753861d79fSDimitry Andric code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU,
337659d1ed5bSDimitry Andric TargetOpts->ABI);
33774ba319b5SDimitry Andric for (const auto &FeatureAsWritten : TargetOpts->FeaturesAsWritten)
33784ba319b5SDimitry Andric code = hash_combine(code, FeatureAsWritten);
33796122f3e6SDimitry Andric
33806122f3e6SDimitry Andric // Extend the signature with preprocessor options.
33813861d79fSDimitry Andric const PreprocessorOptions &ppOpts = getPreprocessorOpts();
3382139f7f9bSDimitry Andric const HeaderSearchOptions &hsOpts = getHeaderSearchOpts();
33833861d79fSDimitry Andric code = hash_combine(code, ppOpts.UsePredefines, ppOpts.DetailedRecord);
33846122f3e6SDimitry Andric
33854ba319b5SDimitry Andric for (const auto &I : getPreprocessorOpts().Macros) {
3386139f7f9bSDimitry Andric // If we're supposed to ignore this macro for the purposes of modules,
3387139f7f9bSDimitry Andric // don't put it into the hash.
3388139f7f9bSDimitry Andric if (!hsOpts.ModulesIgnoreMacros.empty()) {
3389139f7f9bSDimitry Andric // Check whether we're ignoring this macro.
33904ba319b5SDimitry Andric StringRef MacroDef = I.first;
339144290647SDimitry Andric if (hsOpts.ModulesIgnoreMacros.count(
339244290647SDimitry Andric llvm::CachedHashString(MacroDef.split('=').first)))
3393139f7f9bSDimitry Andric continue;
3394139f7f9bSDimitry Andric }
3395139f7f9bSDimitry Andric
33964ba319b5SDimitry Andric code = hash_combine(code, I.first, I.second);
33976122f3e6SDimitry Andric }
33986122f3e6SDimitry Andric
3399444ed5c5SDimitry Andric // Extend the signature with the sysroot and other header search options.
3400444ed5c5SDimitry Andric code = hash_combine(code, hsOpts.Sysroot,
3401444ed5c5SDimitry Andric hsOpts.ModuleFormat,
3402444ed5c5SDimitry Andric hsOpts.UseDebugInfo,
3403444ed5c5SDimitry Andric hsOpts.UseBuiltinIncludes,
34043861d79fSDimitry Andric hsOpts.UseStandardSystemIncludes,
34053861d79fSDimitry Andric hsOpts.UseStandardCXXIncludes,
340644290647SDimitry Andric hsOpts.UseLibcxx,
340744290647SDimitry Andric hsOpts.ModulesValidateDiagnosticOptions);
340859d1ed5bSDimitry Andric code = hash_combine(code, hsOpts.ResourceDir);
340959d1ed5bSDimitry Andric
341059d1ed5bSDimitry Andric // Extend the signature with the user build path.
341159d1ed5bSDimitry Andric code = hash_combine(code, hsOpts.ModuleUserBuildPath);
34126122f3e6SDimitry Andric
34130623d748SDimitry Andric // Extend the signature with the module file extensions.
34140623d748SDimitry Andric const FrontendOptions &frontendOpts = getFrontendOpts();
3415e7145dcbSDimitry Andric for (const auto &ext : frontendOpts.ModuleFileExtensions) {
34160623d748SDimitry Andric code = ext->hashExtension(code);
34170623d748SDimitry Andric }
34180623d748SDimitry Andric
3419*b5893f02SDimitry Andric // When compiling with -gmodules, also hash -fdebug-prefix-map as it
3420*b5893f02SDimitry Andric // affects the debug info in the PCM.
3421*b5893f02SDimitry Andric if (getCodeGenOpts().DebugTypeExtRefs)
3422*b5893f02SDimitry Andric for (const auto &KeyValue : getCodeGenOpts().DebugPrefixMap)
3423*b5893f02SDimitry Andric code = hash_combine(code, KeyValue.first, KeyValue.second);
3424*b5893f02SDimitry Andric
34256d97bb29SDimitry Andric // Extend the signature with the enabled sanitizers, if at least one is
34266d97bb29SDimitry Andric // enabled. Sanitizers which cannot affect AST generation aren't hashed.
34276d97bb29SDimitry Andric SanitizerSet SanHash = LangOpts->Sanitize;
34286d97bb29SDimitry Andric SanHash.clear(getPPTransparentSanitizers());
34296d97bb29SDimitry Andric if (!SanHash.empty())
34306d97bb29SDimitry Andric code = hash_combine(code, SanHash.Mask);
34316d97bb29SDimitry Andric
34323861d79fSDimitry Andric return llvm::APInt(64, code).toString(36, /*Signed=*/false);
34336122f3e6SDimitry Andric }
3434f785676fSDimitry Andric
343559d1ed5bSDimitry Andric template<typename IntTy>
getLastArgIntValueImpl(const ArgList & Args,OptSpecifier Id,IntTy Default,DiagnosticsEngine * Diags)343659d1ed5bSDimitry Andric static IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id,
343759d1ed5bSDimitry Andric IntTy Default,
3438f785676fSDimitry Andric DiagnosticsEngine *Diags) {
343959d1ed5bSDimitry Andric IntTy Res = Default;
3440f785676fSDimitry Andric if (Arg *A = Args.getLastArg(Id)) {
3441f785676fSDimitry Andric if (StringRef(A->getValue()).getAsInteger(10, Res)) {
3442f785676fSDimitry Andric if (Diags)
3443f785676fSDimitry Andric Diags->Report(diag::err_drv_invalid_int_value) << A->getAsString(Args)
3444f785676fSDimitry Andric << A->getValue();
3445f785676fSDimitry Andric }
3446f785676fSDimitry Andric }
3447f785676fSDimitry Andric return Res;
3448f785676fSDimitry Andric }
344959d1ed5bSDimitry Andric
34504ba319b5SDimitry Andric namespace clang {
345159d1ed5bSDimitry Andric
345259d1ed5bSDimitry Andric // Declared in clang/Frontend/Utils.h.
getLastArgIntValue(const ArgList & Args,OptSpecifier Id,int Default,DiagnosticsEngine * Diags)345359d1ed5bSDimitry Andric int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
345459d1ed5bSDimitry Andric DiagnosticsEngine *Diags) {
345559d1ed5bSDimitry Andric return getLastArgIntValueImpl<int>(Args, Id, Default, Diags);
3456f785676fSDimitry Andric }
345759d1ed5bSDimitry Andric
getLastArgUInt64Value(const ArgList & Args,OptSpecifier Id,uint64_t Default,DiagnosticsEngine * Diags)345859d1ed5bSDimitry Andric uint64_t getLastArgUInt64Value(const ArgList &Args, OptSpecifier Id,
345959d1ed5bSDimitry Andric uint64_t Default,
346059d1ed5bSDimitry Andric DiagnosticsEngine *Diags) {
346159d1ed5bSDimitry Andric return getLastArgIntValueImpl<uint64_t>(Args, Id, Default, Diags);
346259d1ed5bSDimitry Andric }
346359d1ed5bSDimitry Andric
3464*b5893f02SDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem>
createVFSFromCompilerInvocation(const CompilerInvocation & CI,DiagnosticsEngine & Diags)346559d1ed5bSDimitry Andric createVFSFromCompilerInvocation(const CompilerInvocation &CI,
346659d1ed5bSDimitry Andric DiagnosticsEngine &Diags) {
3467*b5893f02SDimitry Andric return createVFSFromCompilerInvocation(CI, Diags,
3468*b5893f02SDimitry Andric llvm::vfs::getRealFileSystem());
3469302affcbSDimitry Andric }
347059d1ed5bSDimitry Andric
createVFSFromCompilerInvocation(const CompilerInvocation & CI,DiagnosticsEngine & Diags,IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS)3471*b5893f02SDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation(
3472*b5893f02SDimitry Andric const CompilerInvocation &CI, DiagnosticsEngine &Diags,
3473*b5893f02SDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) {
3474302affcbSDimitry Andric if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty())
3475302affcbSDimitry Andric return BaseFS;
3476302affcbSDimitry Andric
3477*b5893f02SDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> Result = BaseFS;
347859d1ed5bSDimitry Andric // earlier vfs files are on the bottom
34794ba319b5SDimitry Andric for (const auto &File : CI.getHeaderSearchOpts().VFSOverlayFiles) {
348059d1ed5bSDimitry Andric llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
3481*b5893f02SDimitry Andric Result->getBufferForFile(File);
348259d1ed5bSDimitry Andric if (!Buffer) {
348359d1ed5bSDimitry Andric Diags.Report(diag::err_missing_vfs_overlay_file) << File;
34844ba319b5SDimitry Andric continue;
348559d1ed5bSDimitry Andric }
348659d1ed5bSDimitry Andric
3487*b5893f02SDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = llvm::vfs::getVFSFromYAML(
3488*b5893f02SDimitry Andric std::move(Buffer.get()), /*DiagHandler*/ nullptr, File,
3489*b5893f02SDimitry Andric /*DiagContext*/ nullptr, Result);
3490*b5893f02SDimitry Andric if (!FS) {
34914ba319b5SDimitry Andric Diags.Report(diag::err_invalid_vfs_overlay) << File;
3492*b5893f02SDimitry Andric continue;
349359d1ed5bSDimitry Andric }
3494*b5893f02SDimitry Andric
3495*b5893f02SDimitry Andric Result = FS;
3496*b5893f02SDimitry Andric }
3497*b5893f02SDimitry Andric return Result;
349859d1ed5bSDimitry Andric }
34994ba319b5SDimitry Andric
35004ba319b5SDimitry Andric } // namespace clang
3501