Skip to content

Instantly share code, notes, and snippets.

@yamaguchi1024
Created June 26, 2017 00:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yamaguchi1024/7a4d7dd0018d8d23fe9aabc45caf3df0 to your computer and use it in GitHub Desktop.
Save yamaguchi1024/7a4d7dd0018d8d23fe9aabc45caf3df0 to your computer and use it in GitHub Desktop.
I suggest to implement the value completion which flags are handled in clang Driver.
Some flags pass the value string directly to further process, which is too hard to chase and few people would use those flag.
Eg. "clang foo.a -Wa,--foobar -o foo" will execute "as --foobar -o foo", and Driver has no information about --foobar.
I've researched flags which take a value as an argument.
As you can see, there are some flags which includes .def files, and I think it's reasonable to merge its information to Options.td using tablegen.
Many of "No fixed value" flags were passing value "foobar" as string to further process or using it as a string.
* -analyze-function <value>
it doesn't take fixed value
* -analyzer-checker <value>
// We can have a list of comma separated checker names, e.g:
// '-analyzer-checker=cocoa,unix'
This is one example in CompilerInvocation.cpp, but it doesn't seem checking the value.
* -analyzer-config <value>
// We can have a list of comma separated config names, e.g:
// '-analyzer-config key1=val1,key2=val2'
This is one example in CompilerInvocation.cpp, either.
* -analyzer-constraints <value>
clang/StaticAnalyzer/Core/Analyses.def
* -analyzer-disable-checker <value>
Same as -analyzer-checker. It doesn't take fixed value.
* -analyzer-inline-max-stack-depth <value>
It takes integer (4 by default)
* -analyzer-inlining-mode <value>
clang/StaticAnalyzer/Core/Analyses.def
* -analyzer-max-loop <value>
It takes integer.
* -analyzer-output <value>
clang/StaticAnalyzer/Core/Analyses.def
* -analyzer-purge <value>
clang/StaticAnalyzer/Core/Analyses.def
* -analyzer-store <value>
clang/StaticAnalyzer/Core/Analyses.def
* -arcmt-migrate-report-output <value>
Seems it doesn't take fixed value.
* -aux-triple <value>
for CUDA, I think...
* -backend-option <value>
Seems it doesn't take fixed value.
* -cl-ext=<value>
Support for OpenCL extensions.
Seems it doesn't take fixed value?
* cl-std <value>
ok
// -cl-std only applies for OpenCL language standards.
// Override the -std option in this case.
if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
LangStandard::Kind OpenCLLangStd
= llvm::StringSwitch<LangStandard::Kind>(A->getValue())
.Cases("cl", "CL", LangStandard::lang_opencl10)
.Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)
.Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)
.Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)
.Default(LangStandard::lang_unspecified);
if (OpenCLLangStd == LangStandard::lang_unspecified) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
}
else
LangStd = OpenCLLangStd;
}
* -coverage-data-file <value>
No fixed value.
* -coverage-notes-file <value>
No fixed value.
* -coverage-version=<value>
4bytes string.
if (Args.hasArg(OPT_coverage_version_EQ)) {
StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);
if (CoverageVersion.size() != 4) {
Diags.Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_coverage_version_EQ)->getAsString(Args)
<< CoverageVersion;
} else {
memcpy(Opts.CoverageVersion, CoverageVersion.data(), 4);
}
}
* -dependency-dot <value>
No fixed value.
* -dependency-file <value>
No fixed value.
* --dependent-lib=<value>
No fixed value.
* -diagnostic-log-file <value>
No fixed value.
* -dwarf-debug-flags <value>
No fixed value.
* -D <macro>=<value>
No fixed value.
* -error-on-deserialized-decl <value>
No fixed value.
* -fbracket-depth <value>
* -fconstexpr-depth <value>
* -fconstexpr-steps <value>
No fixed value.
* -fcuda-include-gpubinary <value>
No fixed value.
* -fdebug-compilation-dir <value>
No fixed value.
* -fdebug-prefix-map=<value>
No fixed value.
* -fdefault-calling-conv=<value>
ok
// Check for MS default calling conventions being specified.
if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {
LangOptions::DefaultCallingConvention DefaultCC =
llvm::StringSwitch<LangOptions::DefaultCallingConvention>(
A->getValue())
.Case("cdecl", LangOptions::DCC_CDecl)
.Case("fastcall", LangOptions::DCC_FastCall)
.Case("stdcall", LangOptions::DCC_StdCall)
.Case("vectorcall", LangOptions::DCC_VectorCall)
.Default(LangOptions::DCC_None);
if (DefaultCC == LangOptions::DCC_None)
Diags.Report(diag::err_drv_invalid_value)
<< "-fdefault-calling-conv=" << A->getValue();
llvm::Triple T(TargetOpts.Triple);
llvm::Triple::ArchType Arch = T.getArch();
bool emitError = (DefaultCC == LangOptions::DCC_FastCall ||
DefaultCC == LangOptions::DCC_StdCall) &&
Arch != llvm::Triple::x86;
emitError |= DefaultCC == LangOptions::DCC_VectorCall &&
!(Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64);
if (emitError)
Diags.Report(diag::err_drv_argument_not_allowed_with)
<< A->getSpelling() << T.getTriple();
else
Opts.setDefaultCallingConv(DefaultCC);
}
* -fdiagnostics-format <value>
ok
StringRef Format =
Args.getLastArgValue(OPT_fdiagnostics_format, "clang");
if (Format == "clang")
Opts.setFormat(DiagnosticOptions::Clang);
else if (Format == "msvc")
Opts.setFormat(DiagnosticOptions::MSVC);
else if (Format == "msvc-fallback") {
Opts.setFormat(DiagnosticOptions::MSVC);
Opts.CLFallbackMode = true;
} else if (Format == "vi")
Opts.setFormat(DiagnosticOptions::Vi);
else {
Success = false;
if (Diags)
Diags->Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fdiagnostics_format)->getAsString(Args)
<< Format;
}
* -fdiagnostics-show-category <value>
ok
StringRef ShowCategory =
Args.getLastArgValue(OPT_fdiagnostics_show_category, "none");
if (ShowCategory == "none")
Opts.ShowCategories = 0;
else if (ShowCategory == "id")
Opts.ShowCategories = 1;
else if (ShowCategory == "name")
Opts.ShowCategories = 2;
else {
Success = false;
if (Diags)
Diags->Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args)
<< ShowCategory;
}
* -ffp-contract=<value>
ok
if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
StringRef Val = A->getValue();
if (Val == "fast")
Opts.setDefaultFPContractMode(LangOptions::FPC_Fast);
else if (Val == "on")
Opts.setDefaultFPContractMode(LangOptions::FPC_On);
else if (Val == "off")
Opts.setDefaultFPContractMode(LangOptions::FPC_Off);
else
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
}
* -find-pch-source=<value>
No fixed value.
* -fixit=<value>
No fixed value.
* -flto-jobs=<value>
It takes integer
* -flto=<value>
ok
Set LTO mode to either 'full' or 'thin'
Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ);
const Arg *A = Args.getLastArg(OPT_flto, OPT_flto_EQ);
Opts.EmitSummaryIndex = A && A->containsValue("thin");
Opts.LTOUnit = Args.hasFlag(OPT_flto_unit, OPT_fno_lto_unit, false);
if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
if (IK.getLanguage() != InputKind::LLVM_IR)
Diags.Report(diag::err_drv_argument_only_allowed_with)
<< A->getAsString(Args) << "-x ir";
Opts.ThinLTOIndexFile = Args.getLastArgValue(OPT_fthinlto_index_EQ);
}
* -fmax-type-align=<value>
No fixed value.
* -fmodule-format=<value>
Select the container format for clang modules and PCH. Supported options are 'raw' and 'obj'.
* -fmodules-embed-all-files<value>
It takes file which exists.
* -fmodules-ignore-macro=<value>
No fixed value.
* -fms-compatibility-version=<value>
No fixed value.
* -fno-builtin-<value>
No fixed value.
* -fsanitize-coverage=<value>
* -fno-sanitize-coverage=<value>
ok
int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
A->getOption().matches(options::OPT_fno_sanitize_coverage));
int Features = 0;
for (int i = 0, n = A->getNumValues(); i != n; ++i) {
const char *Value = A->getValue(i);
int F = llvm::StringSwitch<int>(Value)
.Case("func", CoverageFunc)
.Case("bb", CoverageBB)
.Case("edge", CoverageEdge)
.Case("indirect-calls", CoverageIndirCall)
.Case("trace-bb", CoverageTraceBB)
.Case("trace-cmp", CoverageTraceCmp)
.Case("trace-div", CoverageTraceDiv)
.Case("trace-gep", CoverageTraceGep)
.Case("8bit-counters", Coverage8bitCounters)
.Case("trace-pc", CoverageTracePC)
.Case("trace-pc-guard", CoverageTracePCGuard)
.Case("no-prune", CoverageNoPrune)
.Case("inline-8bit-counters", CoverageInline8bitCounters)
.Default(0);
if (F == 0)
D.Diag(clang::diag::err_drv_unsupported_option_argument)
<< A->getOption().getName() << Value;
Features |= F;
}
return Features;
}
* -fno-sanitize-recover=<value>
} else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) {
DeprecatedReplacement = "-fno-sanitize-recover=undefined,integer' or "
"'-fno-sanitize-recover=all";
* -fno-sanitize-trap=<value>
No fixed value.
* -fobjc-arc-cxxlib=<value>
if (Arg *A = Args.getLastArg(OPT_fobjc_arc_cxxlib_EQ)) {
ok
StringRef Name = A->getValue();
unsigned Library = llvm::StringSwitch<unsigned>(Name)
.Case("libc++", ARCXX_libcxx)
.Case("libstdc++", ARCXX_libstdcxx)
.Case("none", ARCXX_nolib)
.Default(~0U);
if (Library == ~0U)
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
else
Opts.ObjCXXARCStandardLibrary = (ObjCXXARCStandardLibraryKind)Library;
}
* -fobjc-dispatch-method=<value>
ok
if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) {
StringRef Name = A->getValue();
unsigned Method = llvm::StringSwitch<unsigned>(Name)
.Case("legacy", CodeGenOptions::Legacy)
.Case("non-legacy", CodeGenOptions::NonLegacy)
.Case("mixed", CodeGenOptions::Mixed)
.Default(~0U);
if (Method == ~0U) {
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
Success = false;
} else {
Opts.setObjCDispatchMethod(
static_cast<CodeGenOptions::ObjCDispatchMethodKind>(Method));
}
}
* -fobjc-runtime=<value>
No fixed value.
* -fopenmp-host-ir-file-path <value>
No fixed value.
* -fopenmp-targets=<value>
No fixed value.
* -foperator-arrow-depth <value>
No fixed value.
* -foverride-record-layout=<value>
No fixed value.
* -fpack-struct=<value> Specify the default maximum struct packing alignment
Seems it take integer.
* -fprofile-instrument-path=<value>
No fixed value.
* -fprofile-instrument-use-path=<value>
No fixed value.
* -fprofile-instrument=<value>
ok
static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
Arg *A = Args.getLastArg(OPT_fprofile_instrument_EQ);
if (A == nullptr)
return;
StringRef S = A->getValue();
unsigned I = llvm::StringSwitch<unsigned>(S)
.Case("none", CodeGenOptions::ProfileNone)
.Case("clang", CodeGenOptions::ProfileClangInstr)
.Case("llvm", CodeGenOptions::ProfileIRInstr)
.Default(~0U);
* -fprofile-sample-use=<value>
No fixed value.
* -fsanitize-address-field-padding=<value>
Seems it take integer.
* -fsanitize-blacklist=<value>
No fixed value.
* -fsanitize-coverage-type=<value>
Seems it take integer.
* -fsanitize-memory-track-origins=<value>
Seems it take integer.
* -fsanitize-recover=<value>
No fixed value.
* -fsanitize-trap=<value> Enable trapping for specified sanitizers
No fixed value.
* -fshort-enums
No fixed value.
* -fshow-overloads=<value>
ok
ok
StringRef ShowOverloads =
Args.getLastArgValue(OPT_fshow_overloads_EQ, "all");
if (ShowOverloads == "best")
Opts.setShowOverloads(Ovl_Best);
else if (ShowOverloads == "all")
Opts.setShowOverloads(Ovl_All);
else {
Success = false;
if (Diags)
Diags->Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fshow_overloads_EQ)->getAsString(Args)
<< ShowOverloads;
}
* -fstrict-enums Enable optimizations based on the strict definition of an enum's value range
No fixed value.
* -ftemplate-depth <value>
Seems it take integer.
* -ftest-module-file-extension=<value>
No fixed value.
* -fthin-link-bitcode=<value>
No fixed value.
* -fthinlto-index=<value> Perform ThinLTO importing using provided function summary index
No fixed value.
* -ftrap-function=<value> Issue call to specified function rather than a trap instruction
No fixed value.
* -ftype-visibility <value>
No fixed value.
* -fveclib=<value> Use the given vector functions library
ok
if (Arg *A = Args.getLastArg(OPT_fveclib)) {
StringRef Name = A->getValue();
if (Name == "Accelerate")
Opts.setVecLib(CodeGenOptions::Accelerate);
else if (Name == "SVML")
Opts.setVecLib(CodeGenOptions::SVML);
else if (Name == "none")
Opts.setVecLib(CodeGenOptions::NoLibrary);
else
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
}
* -fvisibility <value> Default type and symbol visibility
ok
// -fvisibility= and -fvisibility-ms-compat are of a piece.
if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
options::OPT_fvisibility_ms_compat)) {
if (A->getOption().matches(options::OPT_fvisibility_EQ)) {
CmdArgs.push_back("-fvisibility");
CmdArgs.push_back(A->getValue());
} else {
assert(A->getOption().matches(options::OPT_fvisibility_ms_compat));
CmdArgs.push_back("-fvisibility");
CmdArgs.push_back("hidden");
CmdArgs.push_back("-ftype-visibility");
CmdArgs.push_back("default");
}
}
* -fxray-always-instrument= <value>
Expect filenames.
* -fxray-instruction-threshold= <value>
No fixed value.
* -fxray-never-instrument= <value>
Expect filenames.
* -F <value> Add directory to framework include search path
Expect path.
* -header-include-file <value>
No fixed value.
* -idirafter <value> Add directory to AFTER include search path
no fixed value.
* -iframework <value> Add directory to SYSTEM framework search path
no fixed value.
* -ivfsoverlay <value> Overlay the virtual filesystem described by file over the real file system
no fixed value.
* --linker-option=<value> Add linker option
no fixed value.
* -main-file-name <value> Main file name to use for debug info
no fixed value.
* -mcode-model <value> The code model to use
ok
static StringRef getCodeModel(ArgList &Args, DiagnosticsEngine &Diags) {
if (Arg *A = Args.getLastArg(OPT_mcode_model)) {
StringRef Value = A->getValue();
if (Value == "small" || Value == "kernel" || Value == "medium" ||
Value == "large")
return Value;
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value;
}
return "default";
}
* -mdebug-pass <value> Enable additional debug output
no fixed value.
* -meabi <value> Set EABI type, e.g. 4, 5 or gnu (default depends on triple)
ok
Opts.ABI = Args.getLastArgValue(OPT_target_abi);
if (Arg *A = Args.getLastArg(OPT_meabi)) {
StringRef Value = A->getValue();
llvm::EABI EABIVersion = llvm::StringSwitch<llvm::EABI>(Value)
.Case("default", llvm::EABI::Default)
.Case("4", llvm::EABI::EABI4)
.Case("5", llvm::EABI::EABI5)
.Case("gnu", llvm::EABI::GNU)
.Default(llvm::EABI::Unknown);
if (EABIVersion == llvm::EABI::Unknown)
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
<< Value;
else
Opts.EABIVersion = Value;
}
* -mfloat-abi <value> The float ABI to use
ok
hard or soft.
switch (arm::getARMFloatABI(getToolChain(), Args)) {
case arm::FloatABI::Invalid: llvm_unreachable("must have an ABI!");
case arm::FloatABI::Soft:
CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=soft"));
break;
case arm::FloatABI::SoftFP:
CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=softfp"));
break;
case arm::FloatABI::Hard:
CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=hard"));
break;
}
* -mfpmath <value> Which unit to use for fp math
No fixed value.
* -mlimit-float-precision <value>
No fixed value.
* -mlink-bitcode-file <value>
No fixed value. Takes files?
* -mlink-cuda-bitcode <value>
No fixed value. Takes files?
* -mllvm <value> Additional arguments to forward to LLVM's option processing
No fixed value. This is option for LLVM?
* -module-dependency-dir <value>
No fixed value.
* -MQ <value> Specify name of main file output to quote in depfile
No fixed value. Takes files?
* -mregparm <value> Limit the number of registers available for integer arguments
No fixed value. Takes integers?
* -mrelocation-model <value>
ok
static StringRef getRelocModel(ArgList &Args, DiagnosticsEngine &Diags) {
if (Arg *A = Args.getLastArg(OPT_mrelocation_model)) {
StringRef Value = A->getValue();
if (Value == "static" || Value == "pic" || Value == "ropi" ||
Value == "rwpi" || Value == "ropi-rwpi" || Value == "dynamic-no-pic")
return Value;
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value;
}
return "pic";
}
* -mstack-alignment=<value>
Seems it takes integer.
* -mstack-probe-size=<value>
Seems it takes integer.
* -mt-migrate-directory <value>
No fixed value. Path?
* -mthread-model <value> The thread model to use, e.g. posix, single (posix by default)
ok
Opts.ThreadModel = Args.getLastArgValue(OPT_mthread_model, "posix");
if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single")
Diags.Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_mthread_model)->getAsString(Args)
<< Opts.ThreadModel;
* -MT <value> Specify name of main file output in depfile
No fixed value. Files?
* -objcmt-whitelist-dir-path=<value>
No fixed value. Path?
* -opt-record-file <value>
No fixed value. Files?
* -pic-level <value> Value for __PIC__
No fixed value.
* -preamble-bytes=<value> Assume that the precompiled header is a precompiled preamble covering the first N bytes of the main file
No fixed value. Seems it takes int,int
* -resource-dir <value> The directory which holds the compiler resource files
No fixed value. Takes Path.
* -Rpass-analysis=<value> Report transformation analysis from optimization passes whose name matches the given POSIX regular expression
No fixed value.
* -Rpass-missed=<value> Report missed transformations by optimization passes whose name matches the given POSIX regular expression
No fixed value.
* -Rpass=<value> Report transformations performed by optimization passes whose name matches the given POSIX regular expression
No fixed value.
* -split-dwarf-file <value>
No fixed value. Takes File.
* -stack-protector-buffer-size <value>
No fixed value. Takes int.
* -stack-protector <value>
No fixed value. Takes int.
* -stats-file=<value> Filename to write statistics to
No fixed value. Takes File.
* -std=<value> Language standard to compile for
clang/Frontend/LangStandards.def
* -stdlib=<value> C++ standard library to use
ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
// Only use "platform" in tests to override CLANG_DEFAULT_CXX_STDLIB!
if (LibName == "libc++")
return ToolChain::CST_Libcxx;
else if (LibName == "libstdc++")
return ToolChain::CST_Libstdcxx;
else if (LibName == "platform")
return GetDefaultCXXStdlibType();
if (A)
getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
return GetDefaultCXXStdlibType();
}
* -target-abi <value> Target a particular ABI type
ok
Opts.ABI = Args.getLastArgValue(OPT_target_abi);
* -target-cpu <value> Target a specific cpu type
No fixed value. Takes cpu.
* -target-feature <value> Target specific attributes
No fixed value.
* -target-linker-version <value>
No fixed value.
* -triple <value> Specify target triple (e.g. i686-apple-darwin9)
Very hard to implement this.
* -verify-ignore-unexpected=<value>
No fixed value.
* -vtordisp-mode=<value> Control vtordisp placement on win32 targets
No fixed value. Takes int.
* -working-directory <value>
No fixed value. Path?
* -W<warnings>
complete possible warnings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment