Skip to content

Instantly share code, notes, and snippets.

@yamaguchi1024
Created June 16, 2017 06:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yamaguchi1024/29cca4fe2d067b8d7b9eff527915f372 to your computer and use it in GitHub Desktop.
Save yamaguchi1024/29cca4fe2d067b8d7b9eff527915f372 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>
// -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>
// 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>
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>
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>
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>
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>
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)) {
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>
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>
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>
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
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
// -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
--linker-option=<value> Add linker option
-main-file-name <value> Main file name to use for debug info
-mcode-model <value> The code model to use
-mdebug-pass <value> Enable additional debug output
-meabi <value> Set EABI type, e.g. 4, 5 or gnu (default depends on triple)
-mfloat-abi <value> The float ABI to use
-mfpmath <value> Which unit to use for fp math
-mlimit-float-precision <value>
Limit float precision to the given value
-mlink-bitcode-file <value>
-mlink-cuda-bitcode <value>
-mllvm <value> Additional arguments to forward to LLVM's option processing
-module-dependency-dir <value>
-MQ <value> Specify name of main file output to quote in depfile
-mregparm <value> Limit the number of registers available for integer arguments
-mrelocation-model <value>
-mstack-alignment=<value>
-mstack-probe-size=<value>
-mt-migrate-directory <value>
-mthread-model <value> The thread model to use, e.g. posix, single (posix by default)
-MT <value> Specify name of main file output in depfile
-objcmt-whitelist-dir-path=<value>
-opt-record-file <value>
-pic-level <value> Value for __PIC__
-preamble-bytes=<value> Assume that the precompiled header is a precompiled preamble covering the first N bytes of the main file
-resource-dir <value> The directory which holds the compiler resource files
-Rpass-analysis=<value> Report transformation analysis from optimization passes whose name matches the given POSIX regular expression
-Rpass-missed=<value> Report missed transformations by optimization passes whose name matches the given POSIX regular expression
-Rpass=<value> Report transformations performed by optimization passes whose name matches the given POSIX regular expression
-split-dwarf-file <value>
-stack-protector-buffer-size <value>
-stack-protector <value>
-stats-file=<value> Filename to write statistics to
-std=<value> Language standard to compile for
-stdlib=<value> C++ standard library to use
-target-abi <value> Target a particular ABI type
-target-cpu <value> Target a specific cpu type
-target-feature <value> Target specific attributes
-target-linker-version <value>
-triple <value> Specify target triple (e.g. i686-apple-darwin9)
-verify-ignore-unexpected=<value>
-vtordisp-mode=<value> Control vtordisp placement on win32 targets
-working-directory <value>
* -W
complete possible warnings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment