Skip to content

Commit 39a2a23

Browse files
committed
[clang][cli] Parse Lang and CodeGen options separately
This patch moves the parsing of `{Lang,CodeGen}Options` from `parseSimpleArgs` to the original `Parse{Lang,CodeGen}Args` functions. This ensures all marshalled `LangOptions` are being parsed **after** the call `setLangDefaults`, which in turn enables us to marshall `LangOptions` that somehow depend on the defaults. (In a future patch.) Now, `CodeGenOptions` need to be parsed **after** `LangOptions`, because `-cl-mad-enable` (a `CodeGenOpt`) depends on the value of `-cl-fast-relaxed-math` and `-cl-unsafe-math-optimizations` (`LangOpts`). Unfortunately, this removes the nice property that marshalled options get parsed in the exact order they appear in the `.td` file. Now we cannot be sure that a TableGen record referenced in `ImpliedByAnyOf` has already been parsed. This might cause an ordering issues (i.e. reading value of uninitialized variable). I plan to mitigate this by moving each `XxxOpt` group from `parseSimpleArgs` back to their original parsing function. With this setup, if an option from group `A` references option from group `B` in TableGen, the compiler will require us to make the `CompilerInvocation` member for `B` visible in the parsing function for `A`. That's where we notice that `B` didn't get parsed yet. Reviewed By: Bigcheese Differential Revision: https://reviews.llvm.org/D94682
1 parent 831a143 commit 39a2a23

File tree

4 files changed

+75
-28
lines changed

4 files changed

+75
-28
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def clang_ignored_gcc_optimization_f_Group : OptionGroup<
244244
class DiagnosticOpts<string base>
245245
: KeyPathAndMacro<"DiagnosticOpts->", base, "DIAG_"> {}
246246
class LangOpts<string base>
247-
: KeyPathAndMacro<"LangOpts->", base> {}
247+
: KeyPathAndMacro<"LangOpts->", base, "LANG_"> {}
248248
class TargetOpts<string base>
249249
: KeyPathAndMacro<"TargetOpts->", base> {}
250250
class FrontendOpts<string base>
@@ -254,7 +254,7 @@ class PreprocessorOutputOpts<string base>
254254
class DependencyOutputOpts<string base>
255255
: KeyPathAndMacro<"DependencyOutputOpts.", base> {}
256256
class CodeGenOpts<string base>
257-
: KeyPathAndMacro<"CodeGenOpts.", base> {}
257+
: KeyPathAndMacro<"CodeGenOpts.", base, "CODEGEN_"> {}
258258
class HeaderSearchOpts<string base>
259259
: KeyPathAndMacro<"HeaderSearchOpts->", base> {}
260260
class PreprocessorOpts<string base>
@@ -510,6 +510,9 @@ multiclass BoolGOption<string flag_base, KeyPathAndMacro kpm,
510510
Group<g_Group>;
511511
}
512512

513+
// Key paths that are constant during parsing of options with the same key path prefix.
514+
defvar open_cl = LangOpts<"OpenCL">;
515+
513516
/////////
514517
// Options
515518

@@ -1820,9 +1823,13 @@ defm experimental_relative_cxx_abi_vtables : BoolFOption<"experimental-relative-
18201823
def flat__namespace : Flag<["-"], "flat_namespace">;
18211824
def flax_vector_conversions_EQ : Joined<["-"], "flax-vector-conversions=">, Group<f_Group>,
18221825
HelpText<"Enable implicit vector bit-casts">, Values<"none,integer,all">, Flags<[CC1Option]>,
1823-
NormalizedValuesScope<"LangOptions::LaxVectorConversionKind">,
1824-
NormalizedValues<["None", "Integer", "All"]>,
1825-
MarshallingInfoString<LangOpts<"LaxVectorConversions">, "All">, AutoNormalizeEnum;
1826+
NormalizedValues<["LangOptions::LaxVectorConversionKind::None",
1827+
"LangOptions::LaxVectorConversionKind::Integer",
1828+
"LangOptions::LaxVectorConversionKind::All"]>,
1829+
MarshallingInfoString<LangOpts<"LaxVectorConversions">,
1830+
!strconcat(open_cl.KeyPath, " ? LangOptions::LaxVectorConversionKind::None"
1831+
" : LangOptions::LaxVectorConversionKind::All")>,
1832+
AutoNormalizeEnum;
18261833
def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>,
18271834
Alias<flax_vector_conversions_EQ>, AliasArgs<["integer"]>;
18281835
def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;

clang/include/clang/Frontend/CompilerInvocation.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ class CompilerInvocation : public CompilerInvocationBase {
258258
static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args,
259259
InputKind IK, DiagnosticsEngine &Diags,
260260
const llvm::Triple &T,
261-
const std::string &OutputFile);
261+
const std::string &OutputFile,
262+
const LangOptions &LangOptsRef);
262263
};
263264

264265
IntrusiveRefCntPtr<llvm::vfs::FileSystem>

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,21 @@ static T extractMaskValue(T KeyPath) {
385385
return KeyPath & Value;
386386
}
387387

388+
#define PARSE_OPTION_WITH_MARSHALLING(ARGS, DIAGS, SUCCESS, ID, FLAGS, PARAM, \
389+
SHOULD_PARSE, KEYPATH, DEFAULT_VALUE, \
390+
IMPLIED_CHECK, IMPLIED_VALUE, \
391+
NORMALIZER, MERGER, TABLE_INDEX) \
392+
if ((FLAGS)&options::CC1Option) { \
393+
KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \
394+
if (IMPLIED_CHECK) \
395+
KEYPATH = MERGER(KEYPATH, IMPLIED_VALUE); \
396+
if (SHOULD_PARSE) \
397+
if (auto MaybeValue = \
398+
NORMALIZER(OPT_##ID, TABLE_INDEX, ARGS, DIAGS, SUCCESS)) \
399+
KEYPATH = \
400+
MERGER(KEYPATH, static_cast<decltype(KEYPATH)>(*MaybeValue)); \
401+
}
402+
388403
static void FixupInvocation(CompilerInvocation &Invocation,
389404
DiagnosticsEngine &Diags,
390405
const InputArgList &Args) {
@@ -911,7 +926,8 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
911926
InputKind IK,
912927
DiagnosticsEngine &Diags,
913928
const llvm::Triple &T,
914-
const std::string &OutputFile) {
929+
const std::string &OutputFile,
930+
const LangOptions &LangOptsRef) {
915931
bool Success = true;
916932

917933
unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
@@ -926,6 +942,25 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
926942
}
927943
Opts.OptimizationLevel = OptimizationLevel;
928944

945+
// The key paths of codegen options defined in Options.td start with
946+
// "CodeGenOpts.". Let's provide the expected variable name and type.
947+
CodeGenOptions &CodeGenOpts = Opts;
948+
// Some codegen options depend on language options. Let's provide the expected
949+
// variable name and type.
950+
const LangOptions *LangOpts = &LangOptsRef;
951+
952+
#define CODEGEN_OPTION_WITH_MARSHALLING( \
953+
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
954+
HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
955+
DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
956+
MERGER, EXTRACTOR, TABLE_INDEX) \
957+
PARSE_OPTION_WITH_MARSHALLING(Args, Diags, Success, ID, FLAGS, PARAM, \
958+
SHOULD_PARSE, KEYPATH, DEFAULT_VALUE, \
959+
IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \
960+
MERGER, TABLE_INDEX)
961+
#include "clang/Driver/Options.inc"
962+
#undef CODEGEN_OPTION_WITH_MARSHALLING
963+
929964
// At O0 we want to fully disable inlining outside of cases marked with
930965
// 'alwaysinline' that are required for correctness.
931966
Opts.setInlining((Opts.OptimizationLevel == 0)
@@ -1367,21 +1402,6 @@ static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes,
13671402
return Success;
13681403
}
13691404

1370-
#define PARSE_OPTION_WITH_MARSHALLING(ARGS, DIAGS, SUCCESS, ID, FLAGS, PARAM, \
1371-
SHOULD_PARSE, KEYPATH, DEFAULT_VALUE, \
1372-
IMPLIED_CHECK, IMPLIED_VALUE, \
1373-
NORMALIZER, MERGER, TABLE_INDEX) \
1374-
if ((FLAGS)&options::CC1Option) { \
1375-
KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \
1376-
if (IMPLIED_CHECK) \
1377-
KEYPATH = MERGER(KEYPATH, IMPLIED_VALUE); \
1378-
if (SHOULD_PARSE) \
1379-
if (auto MaybeValue = \
1380-
NORMALIZER(OPT_##ID, TABLE_INDEX, ARGS, DIAGS, SUCCESS)) \
1381-
KEYPATH = \
1382-
MERGER(KEYPATH, static_cast<decltype(KEYPATH)>(*MaybeValue)); \
1383-
}
1384-
13851405
bool CompilerInvocation::parseSimpleArgs(const ArgList &Args,
13861406
DiagnosticsEngine &Diags) {
13871407
bool Success = true;
@@ -1468,8 +1488,6 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
14681488
return Success;
14691489
}
14701490

1471-
#undef PARSE_OPTION_WITH_MARSHALLING
1472-
14731491
/// Parse the argument to the -ftest-module-file-extension
14741492
/// command-line argument.
14751493
///
@@ -1997,7 +2015,6 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
19972015
if (Opts.OpenCL) {
19982016
Opts.AltiVec = 0;
19992017
Opts.ZVector = 0;
2000-
Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::None);
20012018
Opts.setDefaultFPContractMode(LangOptions::FPM_On);
20022019
Opts.NativeHalfType = 1;
20032020
Opts.NativeHalfArgsAndReturns = 1;
@@ -2226,6 +2243,23 @@ void CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
22262243

22272244
CompilerInvocation::setLangDefaults(Opts, IK, T, Includes, LangStd);
22282245

2246+
// The key paths of codegen options defined in Options.td start with
2247+
// "LangOpts->". Let's provide the expected variable name and type.
2248+
LangOptions *LangOpts = &Opts;
2249+
bool Success = true;
2250+
2251+
#define LANG_OPTION_WITH_MARSHALLING( \
2252+
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
2253+
HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
2254+
DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
2255+
MERGER, EXTRACTOR, TABLE_INDEX) \
2256+
PARSE_OPTION_WITH_MARSHALLING(Args, Diags, Success, ID, FLAGS, PARAM, \
2257+
SHOULD_PARSE, KEYPATH, DEFAULT_VALUE, \
2258+
IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \
2259+
MERGER, TABLE_INDEX)
2260+
#include "clang/Driver/Options.inc"
2261+
#undef LANG_OPTION_WITH_MARSHALLING
2262+
22292263
if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
22302264
StringRef Name = A->getValue();
22312265
if (Name == "full" || Name == "branch") {
@@ -2959,8 +2993,6 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
29592993
LangOpts.IsHeaderFile);
29602994
ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
29612995
llvm::Triple T(Res.getTargetOpts().Triple);
2962-
Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
2963-
Res.getFrontendOpts().OutputFile);
29642996
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args,
29652997
Res.getFileSystemOpts().WorkingDir);
29662998
if (DashX.getFormat() == InputKind::Precompiled ||
@@ -3002,6 +3034,9 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
30023034
if (LangOpts.OpenMPIsDevice)
30033035
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
30043036

3037+
Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
3038+
Res.getFrontendOpts().OutputFile, LangOpts);
3039+
30053040
// FIXME: Override value name discarding when asan or msan is used because the
30063041
// backend passes depend on the name of the alloca in order to print out
30073042
// names.
@@ -3179,9 +3214,13 @@ void CompilerInvocation::generateCC1CommandLine(
31793214
EXTRACTOR, TABLE_INDEX)
31803215

31813216
#define DIAG_OPTION_WITH_MARSHALLING OPTION_WITH_MARSHALLING
3217+
#define LANG_OPTION_WITH_MARSHALLING OPTION_WITH_MARSHALLING
3218+
#define CODEGEN_OPTION_WITH_MARSHALLING OPTION_WITH_MARSHALLING
31823219

31833220
#include "clang/Driver/Options.inc"
31843221

3222+
#undef CODEGEN_OPTION_WITH_MARSHALLING
3223+
#undef LANG_OPTION_WITH_MARSHALLING
31853224
#undef DIAG_OPTION_WITH_MARSHALLING
31863225
#undef OPTION_WITH_MARSHALLING
31873226
#undef GENERATE_OPTION_WITH_MARSHALLING

clang/test/Frontend/diagnostics-order.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
//
88
// CHECK: error: invalid value '-foo' in '-verify='
99
// CHECK-NEXT: note: -verify prefixes must start with a letter and contain only alphanumeric characters, hyphens, and underscores
10-
// CHECK-NEXT: warning: optimization level '-O999' is not supported
1110
// CHECK-NEXT: error: invalid value 'bogus' in '-std=bogus'
1211
// CHECK-NEXT: note: use {{.*}} for {{.*}} standard
12+
// CHECK: warning: optimization level '-O999' is not supported

0 commit comments

Comments
 (0)