Skip to content

Commit a16104e

Browse files
committed
[Option] Add "Visibility" field and clone the OptTable APIs to use it
This splits OptTable's "Flags" field into "Flags" and "Visibility", updates the places where we instantiate Option tables, and adds variants of the OptTable APIs that use Visibility mask instead of Include/Exclude flags. We need to do this to clean up a bunch of complexity in the clang driver's option handling - there's a whole slew of flags like CoreOption, NoDriverOption, and FlangOnlyOption there today to try to handle all of the permutations of flags that the various drivers need, but it really doesn't scale well, as can be seen by things like the somewhat recently introduced CLDXCOption. Instead, we'll provide an additive model for visibility that's separate from the other flags. For things like "HelpHidden", which is used as a "subtractive" modifier for option visibility, we leave that in "Flags" and handle it as a special case. Note that we don't actually update the users of the Include/Exclude APIs here or change the flags that exist in clang at all - that will come in a follow up that refactors clang's Options.td to use the increased flexibility this change allows. Differential Revision: https://reviews.llvm.org/D157149
1 parent f50eaea commit a16104e

File tree

29 files changed

+337
-80
lines changed

29 files changed

+337
-80
lines changed

clang-tools-extra/clangd/CompileCommands.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {
494494
static constexpr llvm::ArrayRef<llvm::StringLiteral> NAME( \
495495
NAME##_init, std::size(NAME##_init) - 1);
496496
#define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \
497-
FLAGS, PARAM, HELP, METAVAR, VALUES) \
497+
FLAGS, VISIBILITY, PARAM, HELP, METAVAR, VALUES) \
498498
Prefixes[DriverID::OPT_##ID] = PREFIX;
499499
#include "clang/Driver/Options.inc"
500500
#undef OPTION
@@ -506,7 +506,7 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {
506506
const void *AliasArgs;
507507
} AliasTable[] = {
508508
#define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \
509-
FLAGS, PARAM, HELP, METAVAR, VALUES) \
509+
FLAGS, VISIBILITY, PARAM, HELP, METAVAR, VALUES) \
510510
{DriverID::OPT_##ID, DriverID::OPT_##ALIAS, ALIASARGS},
511511
#include "clang/Driver/Options.inc"
512512
#undef OPTION

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,9 @@ static T extractMaskValue(T KeyPath) {
423423

424424
#define PARSE_OPTION_WITH_MARSHALLING( \
425425
ARGS, DIAGS, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, \
426-
FLAGS, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, \
427-
KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \
428-
DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
426+
FLAGS, VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, \
427+
ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, \
428+
NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
429429
if ((FLAGS)&options::CC1Option) { \
430430
KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \
431431
if (IMPLIED_CHECK) \
@@ -440,9 +440,9 @@ static T extractMaskValue(T KeyPath) {
440440
// with lifetime extension of the reference.
441441
#define GENERATE_OPTION_WITH_MARSHALLING( \
442442
CONSUMER, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
443-
PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
444-
DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
445-
MERGER, EXTRACTOR, TABLE_INDEX) \
443+
VISIBILKITY, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, \
444+
KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \
445+
DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
446446
if ((FLAGS)&options::CC1Option) { \
447447
[&](const auto &Extracted) { \
448448
if (ALWAYS_EMIT || \

lld/MachO/DriverUtils.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ using namespace lld::macho;
4444

4545
// Create table mapping all options defined in Options.td
4646
static constexpr OptTable::Info optInfo[] = {
47-
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
48-
{X1, X2, X10, X11, OPT_##ID, Option::KIND##Class, \
49-
X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
47+
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
48+
VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \
49+
{PREFIX, NAME, HELPTEXT, \
50+
METAVAR, OPT_##ID, opt::Option::KIND##Class, \
51+
PARAM, FLAGS, VISIBILITY, \
52+
OPT_##GROUP, OPT_##ALIAS, ALIASARGS, \
53+
VALUES},
5054
#include "Options.inc"
5155
#undef OPTION
5256
};

lld/MinGW/Driver.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,13 @@ enum {
7171

7272
// Create table mapping all options defined in Options.td
7373
static constexpr opt::OptTable::Info infoTable[] = {
74-
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
75-
{X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
76-
X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
74+
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
75+
VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \
76+
{PREFIX, NAME, HELPTEXT, \
77+
METAVAR, OPT_##ID, opt::Option::KIND##Class, \
78+
PARAM, FLAGS, VISIBILITY, \
79+
OPT_##GROUP, OPT_##ALIAS, ALIASARGS, \
80+
VALUES},
7781
#include "Options.inc"
7882
#undef OPTION
7983
};

lld/wasm/Driver.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,13 @@ bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
111111

112112
// Create table mapping all options defined in Options.td
113113
static constexpr opt::OptTable::Info optInfo[] = {
114-
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
115-
{X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
116-
X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
114+
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
115+
VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \
116+
{PREFIX, NAME, HELPTEXT, \
117+
METAVAR, OPT_##ID, opt::Option::KIND##Class, \
118+
PARAM, FLAGS, VISIBILITY, \
119+
OPT_##GROUP, OPT_##ALIAS, ALIASARGS, \
120+
VALUES},
117121
#include "Options.inc"
118122
#undef OPTION
119123
};

llvm/include/llvm/Option/OptParser.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ def RenderJoined : OptionFlag;
7373
// (only sensible on joined options).
7474
def RenderSeparate : OptionFlag;
7575

76+
// Define Visibility categories
77+
78+
class OptionVisibility {}
79+
80+
// Explicit specifier for default visibility
81+
def Default : OptionVisibility;
82+
7683
// Define the option group class.
7784

7885
class OptionGroup<string name> {
@@ -81,6 +88,7 @@ class OptionGroup<string name> {
8188
string HelpText = ?;
8289
OptionGroup Group = ?;
8390
list<OptionFlag> Flags = [];
91+
list<OptionVisibility> Vis = [];
8492
}
8593

8694
// Define the option class.
@@ -97,6 +105,7 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
97105
string Values = ?;
98106
code ValuesCode = ?;
99107
list<OptionFlag> Flags = [];
108+
list<OptionVisibility> Vis = [Default];
100109
OptionGroup Group = ?;
101110
Option Alias = ?;
102111
list<string> AliasArgs = [];
@@ -141,6 +150,7 @@ class Alias<Option alias> { Option Alias = alias; }
141150
class AliasArgs<list<string> aliasargs> { list<string> AliasArgs = aliasargs; }
142151
class EnumName<string name> { string EnumName = name; }
143152
class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
153+
class Vis<list<OptionVisibility> vis> { list<OptionVisibility> Vis = vis; }
144154
class Group<OptionGroup group> { OptionGroup Group = group; }
145155
class HelpText<string text> { string HelpText = text; }
146156
class MetaVarName<string name> { string MetaVarName = name; }

llvm/include/llvm/Option/OptTable.h

Lines changed: 89 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ class ArgList;
3030
class InputArgList;
3131
class Option;
3232

33+
/// Helper for overload resolution while transitioning from
34+
/// FlagsToInclude/FlagsToExclude APIs to VisibilityMask APIs.
35+
class Visibility {
36+
unsigned Mask = ~0U;
37+
38+
public:
39+
explicit Visibility(unsigned Mask) : Mask(Mask) {}
40+
Visibility() = default;
41+
42+
operator unsigned() const { return Mask; }
43+
};
44+
3345
/// Provide access to the Option info table.
3446
///
3547
/// The OptTable class provides a layer of indirection which allows Option
@@ -51,6 +63,7 @@ class OptTable {
5163
unsigned char Kind;
5264
unsigned char Param;
5365
unsigned int Flags;
66+
unsigned int Visibility;
5467
unsigned short GroupID;
5568
unsigned short AliasID;
5669
const char *AliasArgs;
@@ -180,10 +193,8 @@ class OptTable {
180193
/// string includes prefix dashes "-" as well as values "=l".
181194
/// \param [out] NearestString - The nearest option string found in the
182195
/// OptTable.
183-
/// \param [in] FlagsToInclude - Only find options with any of these flags.
184-
/// Zero is the default, which includes all flags.
185-
/// \param [in] FlagsToExclude - Don't find options with this flag. Zero
186-
/// is the default, and means exclude nothing.
196+
/// \param [in] VisibilityMask - Only include options with any of these
197+
/// visibility flags set.
187198
/// \param [in] MinimumLength - Don't find options shorter than this length.
188199
/// For example, a minimum length of 3 prevents "-x" from being considered
189200
/// near to "-S".
@@ -192,13 +203,29 @@ class OptTable {
192203
///
193204
/// \return The edit distance of the nearest string found.
194205
unsigned findNearest(StringRef Option, std::string &NearestString,
195-
unsigned FlagsToInclude = 0, unsigned FlagsToExclude = 0,
206+
Visibility VisibilityMask = Visibility(),
196207
unsigned MinimumLength = 4,
197208
unsigned MaximumDistance = UINT_MAX) const;
198209

210+
unsigned findNearest(StringRef Option, std::string &NearestString,
211+
unsigned FlagsToInclude, unsigned FlagsToExclude = 0,
212+
unsigned MinimumLength = 4,
213+
unsigned MaximumDistance = UINT_MAX) const;
214+
215+
private:
216+
unsigned
217+
internalFindNearest(StringRef Option, std::string &NearestString,
218+
unsigned MinimumLength, unsigned MaximumDistance,
219+
std::function<bool(const Info &)> ExcludeOption) const;
220+
221+
public:
222+
bool findExact(StringRef Option, std::string &ExactString,
223+
Visibility VisibilityMask = Visibility()) const {
224+
return findNearest(Option, ExactString, VisibilityMask, 4, 0) == 0;
225+
}
226+
199227
bool findExact(StringRef Option, std::string &ExactString,
200-
unsigned FlagsToInclude = 0,
201-
unsigned FlagsToExclude = 0) const {
228+
unsigned FlagsToInclude, unsigned FlagsToExclude = 0) const {
202229
return findNearest(Option, ExactString, FlagsToInclude, FlagsToExclude, 4,
203230
0) == 0;
204231
}
@@ -209,18 +236,26 @@ class OptTable {
209236
/// \param [in,out] Index - The current parsing position in the argument
210237
/// string list; on return this will be the index of the next argument
211238
/// string to parse.
212-
/// \param [in] FlagsToInclude - Only parse options with any of these flags.
213-
/// Zero is the default which includes all flags.
214-
/// \param [in] FlagsToExclude - Don't parse options with this flag. Zero
215-
/// is the default and means exclude nothing.
239+
/// \param [in] VisibilityMask - Only include options with any of these
240+
/// visibility flags set.
216241
///
217242
/// \return The parsed argument, or 0 if the argument is missing values
218243
/// (in which case Index still points at the conceptual next argument string
219244
/// to parse).
245+
std::unique_ptr<Arg>
246+
ParseOneArg(const ArgList &Args, unsigned &Index,
247+
Visibility VisibilityMask = Visibility()) const;
248+
220249
std::unique_ptr<Arg> ParseOneArg(const ArgList &Args, unsigned &Index,
221-
unsigned FlagsToInclude = 0,
222-
unsigned FlagsToExclude = 0) const;
250+
unsigned FlagsToInclude,
251+
unsigned FlagsToExclude) const;
252+
253+
private:
254+
std::unique_ptr<Arg>
255+
internalParseOneArg(const ArgList &Args, unsigned &Index,
256+
std::function<bool(const Option &)> ExcludeOption) const;
223257

258+
public:
224259
/// Parse an list of arguments into an InputArgList.
225260
///
226261
/// The resulting InputArgList will reference the strings in [\p ArgBegin,
@@ -233,16 +268,25 @@ class OptTable {
233268
/// \param MissingArgIndex - On error, the index of the option which could
234269
/// not be parsed.
235270
/// \param MissingArgCount - On error, the number of missing options.
236-
/// \param FlagsToInclude - Only parse options with any of these flags.
237-
/// Zero is the default which includes all flags.
238-
/// \param FlagsToExclude - Don't parse options with this flag. Zero
239-
/// is the default and means exclude nothing.
271+
/// \param VisibilityMask - Only include options with any of these
272+
/// visibility flags set.
240273
/// \return An InputArgList; on error this will contain all the options
241274
/// which could be parsed.
242275
InputArgList ParseArgs(ArrayRef<const char *> Args, unsigned &MissingArgIndex,
243-
unsigned &MissingArgCount, unsigned FlagsToInclude = 0,
276+
unsigned &MissingArgCount,
277+
Visibility VisibilityMask = Visibility()) const;
278+
279+
InputArgList ParseArgs(ArrayRef<const char *> Args, unsigned &MissingArgIndex,
280+
unsigned &MissingArgCount, unsigned FlagsToInclude,
244281
unsigned FlagsToExclude = 0) const;
245282

283+
private:
284+
InputArgList
285+
internalParseArgs(ArrayRef<const char *> Args, unsigned &MissingArgIndex,
286+
unsigned &MissingArgCount,
287+
std::function<bool(const Option &)> ExcludeOption) const;
288+
289+
public:
246290
/// A convenience helper which handles optional initial options populated from
247291
/// an environment variable, expands response files recursively and parses
248292
/// options.
@@ -253,26 +297,32 @@ class OptTable {
253297
/// could be parsed.
254298
InputArgList parseArgs(int Argc, char *const *Argv, OptSpecifier Unknown,
255299
StringSaver &Saver,
256-
function_ref<void(StringRef)> ErrorFn) const;
300+
std::function<void(StringRef)> ErrorFn) const;
257301

258302
/// Render the help text for an option table.
259303
///
260304
/// \param OS - The stream to write the help text to.
261305
/// \param Usage - USAGE: Usage
262306
/// \param Title - OVERVIEW: Title
263-
/// \param FlagsToInclude - If non-zero, only include options with any
264-
/// of these flags set.
265-
/// \param FlagsToExclude - Exclude options with any of these flags set.
307+
/// \param VisibilityMask - Only in Visibility VisibilityMask,clude options with any of these
308+
/// visibility flags set.
309+
/// \param ShowHidden - If true, display options marked as HelpHidden
266310
/// \param ShowAllAliases - If true, display all options including aliases
267311
/// that don't have help texts. By default, we display
268312
/// only options that are not hidden and have help
269313
/// texts.
314+
void printHelp(raw_ostream &OS, const char *Usage, const char *Title,
315+
bool ShowHidden = false, bool ShowAllAliases = false,
316+
Visibility VisibilityMask = Visibility()) const;
317+
270318
void printHelp(raw_ostream &OS, const char *Usage, const char *Title,
271319
unsigned FlagsToInclude, unsigned FlagsToExclude,
272320
bool ShowAllAliases) const;
273321

274-
void printHelp(raw_ostream &OS, const char *Usage, const char *Title,
275-
bool ShowHidden = false, bool ShowAllAliases = false) const;
322+
private:
323+
void internalPrintHelp(raw_ostream &OS, const char *Usage, const char *Title,
324+
bool ShowHidden, bool ShowAllAliases,
325+
std::function<bool(const Info &)> ExcludeOption) const;
276326
};
277327

278328
/// Specialization of OptTable
@@ -305,31 +355,32 @@ class PrecomputedOptTable : public OptTable {
305355

306356
} // end namespace llvm
307357

308-
#define LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(ID_PREFIX, PREFIX, PREFIXED_NAME, ID, \
309-
KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
310-
PARAM, HELPTEXT, METAVAR, VALUES) \
358+
#define LLVM_MAKE_OPT_ID_WITH_ID_PREFIX( \
359+
ID_PREFIX, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \
360+
FLAGS, VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \
311361
ID_PREFIX##ID
312362

313363
#define LLVM_MAKE_OPT_ID(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, \
314-
ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, VALUES) \
364+
ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, \
365+
METAVAR, VALUES) \
315366
LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(OPT_, PREFIX, PREFIXED_NAME, ID, KIND, \
316-
GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
317-
HELPTEXT, METAVAR, VALUE)
367+
GROUP, ALIAS, ALIASARGS, FLAGS, VISIBILITY, \
368+
PARAM, HELPTEXT, METAVAR, VALUE)
318369

319370
#define LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX( \
320371
ID_PREFIX, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \
321-
FLAGS, PARAM, HELPTEXT, METAVAR, VALUES) \
372+
FLAGS, VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES) \
322373
llvm::opt::OptTable::Info { \
323374
PREFIX, PREFIXED_NAME, HELPTEXT, METAVAR, ID_PREFIX##ID, \
324-
llvm::opt::Option::KIND##Class, PARAM, FLAGS, ID_PREFIX##GROUP, \
325-
ID_PREFIX##ALIAS, ALIASARGS, VALUES \
375+
llvm::opt::Option::KIND##Class, PARAM, FLAGS, VISIBILITY, \
376+
ID_PREFIX##GROUP, ID_PREFIX##ALIAS, ALIASARGS, VALUES \
326377
}
327378

328379
#define LLVM_CONSTRUCT_OPT_INFO(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, \
329-
ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, \
330-
VALUES) \
331-
LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(OPT_, PREFIX, PREFIXED_NAME, ID, \
332-
KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
333-
PARAM, HELPTEXT, METAVAR, VALUES)
380+
ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, \
381+
METAVAR, VALUES) \
382+
LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX( \
383+
OPT_, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
384+
VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES)
334385

335386
#endif // LLVM_OPTION_OPTTABLE_H

llvm/include/llvm/Option/Option.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ enum DriverFlag {
3737
RenderSeparate = (1 << 3)
3838
};
3939

40+
enum DriverVisibility {
41+
Default = (1 << 0),
42+
};
43+
4044
/// Option - Abstract representation for a single form of driver
4145
/// argument.
4246
///
@@ -183,6 +187,11 @@ class Option {
183187
return Info->Flags & Val;
184188
}
185189

190+
/// Test if this option has the visibility flag \a Val.
191+
bool hasVisibilityFlag(unsigned Val) const {
192+
return Info->Visibility & Val;
193+
}
194+
186195
/// getUnaliasedOption - Return the final option this option
187196
/// aliases (itself, if the option has no alias).
188197
const Option getUnaliasedOption() const {

llvm/lib/ExecutionEngine/JITLink/COFFDirectiveParser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static constexpr const ArrayRef<StringLiteral>
3636
PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1);
3737

3838
// Create table mapping all options defined in COFFOptions.td
39+
using namespace llvm::opt;
3940
static constexpr opt::OptTable::Info infoTable[] = {
4041
#define OPTION(...) \
4142
LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX(COFF_OPT_, __VA_ARGS__),

0 commit comments

Comments
 (0)