Skip to content

Commit 4a7c57a

Browse files
committed
[llvm] Construct option's prefixed name at compile-time
Some Clang command-line handling code could benefit from the option's prefixed name being a `StringLiteral`. This patch changes the `llvm::opt` TableGen backend to generate and emit that into the .inc file. Depends on D157028. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D157029
1 parent d394ab6 commit 4a7c57a

File tree

9 files changed

+64
-76
lines changed

9 files changed

+64
-76
lines changed

clang-tools-extra/clangd/CompileCommands.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,8 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {
466466
// Also grab prefixes for each option, these are not fully exposed.
467467
const char *const *Prefixes[DriverID::LastOption] = {nullptr};
468468
#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;
469-
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
470-
HELP, METAVAR, VALUES) \
469+
#define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \
470+
FLAGS, PARAM, HELP, METAVAR, VALUES) \
471471
Prefixes[DriverID::OPT_##ID] = PREFIX;
472472
#include "clang/Driver/Options.inc"
473473
#undef OPTION
@@ -478,8 +478,8 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {
478478
DriverID AliasID;
479479
const void *AliasArgs;
480480
} AliasTable[] = {
481-
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
482-
HELP, METAVAR, VALUES) \
481+
#define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \
482+
FLAGS, PARAM, HELP, METAVAR, VALUES) \
483483
{DriverID::OPT_##ID, DriverID::OPT_##ALIAS, ALIASARGS},
484484
#include "clang/Driver/Options.inc"
485485
#undef OPTION

clang/lib/Driver/Driver.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
228228
}
229229

230230
void Driver::setDriverMode(StringRef Value) {
231-
static const std::string OptName =
231+
static StringRef OptName =
232232
getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
233233
if (auto M = llvm::StringSwitch<llvm::Optional<DriverMode>>(Value)
234234
.Case("gcc", GCCMode)
@@ -6322,7 +6322,7 @@ bool clang::driver::willEmitRemarks(const ArgList &Args) {
63226322

63236323
llvm::StringRef clang::driver::getDriverMode(StringRef ProgName,
63246324
ArrayRef<const char *> Args) {
6325-
static const std::string OptName =
6325+
static StringRef OptName =
63266326
getDriverOptTable().getOption(options::OPT_driver_mode).getPrefixedName();
63276327
llvm::StringRef Opt;
63286328
for (StringRef Arg : Args) {

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,8 @@ static T extractMaskValue(T KeyPath) {
450450
}
451451

452452
#define PARSE_OPTION_WITH_MARSHALLING( \
453-
ARGS, DIAGS, PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
454-
PARAM, HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, \
453+
ARGS, DIAGS, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, \
454+
FLAGS, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, \
455455
KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \
456456
DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
457457
if ((FLAGS)&options::CC1Option) { \
@@ -467,10 +467,10 @@ static T extractMaskValue(T KeyPath) {
467467
// Capture the extracted value as a lambda argument to avoid potential issues
468468
// with lifetime extension of the reference.
469469
#define GENERATE_OPTION_WITH_MARSHALLING( \
470-
CONSUMER, PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
471-
PARAM, HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, \
472-
KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \
473-
DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
470+
CONSUMER, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
471+
PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
472+
DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
473+
MERGER, EXTRACTOR, TABLE_INDEX) \
474474
if ((FLAGS)&options::CC1Option) { \
475475
[&](const auto &Extracted) { \
476476
if (ALWAYS_EMIT || \

clang/lib/Tooling/Tooling.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,14 +268,14 @@ void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
268268
return;
269269
const auto &Table = driver::getDriverOptTable();
270270
// --target=X
271-
const std::string TargetOPT =
271+
StringRef TargetOPT =
272272
Table.getOption(driver::options::OPT_target).getPrefixedName();
273273
// -target X
274-
const std::string TargetOPTLegacy =
274+
StringRef TargetOPTLegacy =
275275
Table.getOption(driver::options::OPT_target_legacy_spelling)
276276
.getPrefixedName();
277277
// --driver-mode=X
278-
const std::string DriverModeOPT =
278+
StringRef DriverModeOPT =
279279
Table.getOption(driver::options::OPT_driver_mode).getPrefixedName();
280280
auto TargetMode =
281281
driver::ToolChain::getTargetAndModeFromProgramName(InvokedAs);
@@ -295,7 +295,7 @@ void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
295295
}
296296
if (ShouldAddTarget) {
297297
CommandLine.insert(++CommandLine.begin(),
298-
TargetOPT + TargetMode.TargetPrefix);
298+
(TargetOPT + TargetMode.TargetPrefix).str());
299299
}
300300
}
301301

llvm/include/llvm/Option/OptTable.h

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class OptTable {
4444
/// A null terminated array of prefix strings to apply to name while
4545
/// matching.
4646
const char *const *Prefixes;
47-
const char *Name;
47+
StringLiteral PrefixedName;
4848
const char *HelpText;
4949
const char *MetaVar;
5050
unsigned ID;
@@ -55,6 +55,11 @@ class OptTable {
5555
unsigned short AliasID;
5656
const char *AliasArgs;
5757
const char *Values;
58+
59+
StringRef getName() const {
60+
unsigned PrefixLength = !Prefixes ? 0 : StringRef(Prefixes[0]).size();
61+
return PrefixedName.drop_front(PrefixLength);
62+
}
5863
};
5964

6065
private:
@@ -103,7 +108,7 @@ class OptTable {
103108

104109
/// Lookup the name of the given option.
105110
const char *getOptionName(OptSpecifier id) const {
106-
return getInfo(id).Name;
111+
return getInfo(id).getName().data();
107112
}
108113

109114
/// Get the kind of the given option.
@@ -262,32 +267,33 @@ class OptTable {
262267

263268
} // end namespace llvm
264269

265-
#define LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(ID_PREFIX, PREFIX, NAME, ID, KIND, \
266-
GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
267-
HELPTEXT, METAVAR, VALUES) \
270+
#define LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(ID_PREFIX, PREFIX, PREFIXED_NAME, ID, \
271+
KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
272+
PARAM, HELPTEXT, METAVAR, VALUES) \
268273
ID_PREFIX##ID
269274

270-
#define LLVM_MAKE_OPT_ID(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \
271-
FLAGS, PARAM, HELPTEXT, METAVAR, VALUES) \
272-
LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(OPT_, PREFIX, NAME, ID, KIND, GROUP, ALIAS, \
273-
ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, \
274-
VALUE)
275+
#define LLVM_MAKE_OPT_ID(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, \
276+
ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, VALUES) \
277+
LLVM_MAKE_OPT_ID_WITH_ID_PREFIX(OPT_, PREFIX, PREFIXED_NAME, ID, KIND, \
278+
GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
279+
HELPTEXT, METAVAR, VALUE)
275280

276281
#define LLVM_CONSTRUCT_OPT_INFO_WITH_ID_PREFIX( \
277-
ID_PREFIX, PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
278-
HELPTEXT, METAVAR, VALUES) \
282+
ID_PREFIX, PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \
283+
FLAGS, PARAM, HELPTEXT, METAVAR, VALUES) \
279284
llvm::opt::OptTable::Info { \
280-
ID_PREFIX##PREFIX, NAME, HELPTEXT, METAVAR, ID_PREFIX##ID, \
285+
ID_PREFIX##PREFIX, PREFIXED_NAME, HELPTEXT, METAVAR, ID_PREFIX##ID, \
281286
llvm::opt::Option::KIND##Class, PARAM, FLAGS, ID_PREFIX##GROUP, \
282287
ID_PREFIX##ALIAS, ALIASARGS, VALUES \
283288
}
284289

285-
#define LLVM_CONSTRUCT_OPT_INFO(PREFIX, NAME, ID, KIND, GROUP, ALIAS, \
290+
#define LLVM_CONSTRUCT_OPT_INFO(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, \
286291
ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, \
287292
VALUES) \
288293
llvm::opt::OptTable::Info { \
289-
PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
290-
PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS, VALUES \
294+
PREFIX, PREFIXED_NAME, HELPTEXT, METAVAR, OPT_##ID, \
295+
llvm::opt::Option::KIND##Class, PARAM, FLAGS, OPT_##GROUP, \
296+
OPT_##ALIAS, ALIASARGS, VALUES \
291297
}
292298

293299
#endif // LLVM_OPTION_OPTTABLE_H

llvm/include/llvm/Option/Option.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class Option {
9797
/// Get the name of this option without any prefix.
9898
StringRef getName() const {
9999
assert(Info && "Must have a valid info!");
100-
return Info->Name;
100+
return Info->getName();
101101
}
102102

103103
const Option getGroup() const {
@@ -129,10 +129,9 @@ class Option {
129129
}
130130

131131
/// Get the name of this option with the default prefix.
132-
std::string getPrefixedName() const {
133-
std::string Ret(getPrefix());
134-
Ret += getName();
135-
return Ret;
132+
StringLiteral getPrefixedName() const {
133+
assert(Info && "Must have a valid info!");
134+
return Info->PrefixedName;
136135
}
137136

138137
/// Get the help text for this option.

llvm/lib/Option/OptTable.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) {
6767
if (&A == &B)
6868
return false;
6969

70-
if (int N = StrCmpOptionName(A.Name, B.Name))
70+
if (int N = StrCmpOptionName(A.getName().data(), B.getName().data()))
7171
return N < 0;
7272

7373
for (const char * const *APre = A.Prefixes,
@@ -87,7 +87,7 @@ static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) {
8787

8888
// Support lower_bound between info and an option name.
8989
static inline bool operator<(const OptTable::Info &I, const char *Name) {
90-
return StrCmpOptionNameIgnoreCase(I.Name, Name) < 0;
90+
return StrCmpOptionNameIgnoreCase(I.getName().data(), Name) < 0;
9191
}
9292

9393
} // end namespace opt
@@ -183,10 +183,10 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str,
183183
StringRef Prefix(*Pre);
184184
if (Str.startswith(Prefix)) {
185185
StringRef Rest = Str.substr(Prefix.size());
186-
bool Matched = IgnoreCase ? Rest.startswith_insensitive(I->Name)
187-
: Rest.startswith(I->Name);
186+
bool Matched = IgnoreCase ? Rest.startswith_insensitive(I->getName())
187+
: Rest.startswith(I->getName());
188188
if (Matched)
189-
return Prefix.size() + StringRef(I->Name).size();
189+
return Prefix.size() + StringRef(I->getName()).size();
190190
}
191191
}
192192
return 0;
@@ -195,7 +195,7 @@ static unsigned matchOption(const OptTable::Info *I, StringRef Str,
195195
// Returns true if one of the Prefixes + In.Names matches Option
196196
static bool optionMatches(const OptTable::Info &In, StringRef Option) {
197197
if (In.Prefixes) {
198-
StringRef InName(In.Name);
198+
StringRef InName(In.getName());
199199
for (size_t I = 0; In.Prefixes[I]; I++)
200200
if (Option.endswith(InName))
201201
if (Option.slice(0, Option.size() - InName.size()) == In.Prefixes[I])
@@ -238,7 +238,7 @@ OptTable::findByPrefix(StringRef Cur, unsigned int DisableFlags) const {
238238
continue;
239239

240240
for (int I = 0; In.Prefixes[I]; I++) {
241-
std::string S = std::string(In.Prefixes[I]) + std::string(In.Name) + "\t";
241+
std::string S = std::string(In.Prefixes[I]) + std::string(In.getName()) + "\t";
242242
if (In.HelpText)
243243
S += In.HelpText;
244244
if (StringRef(S).startswith(Cur) && S != std::string(Cur) + "\t")
@@ -258,7 +258,7 @@ unsigned OptTable::findNearest(StringRef Option, std::string &NearestString,
258258
unsigned BestDistance = UINT_MAX;
259259
for (const Info &CandidateInfo :
260260
ArrayRef<Info>(OptionInfos).drop_front(FirstSearchableIndex)) {
261-
StringRef CandidateName = CandidateInfo.Name;
261+
StringRef CandidateName = CandidateInfo.getName();
262262

263263
// We can eliminate some option prefix/name pairs as candidates right away:
264264
// * Ignore option candidates with empty names, such as "--", or names
@@ -535,7 +535,7 @@ InputArgList OptTable::parseArgs(int Argc, char *const *Argv,
535535

536536
static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) {
537537
const Option O = Opts.getOption(Id);
538-
std::string Name = O.getPrefixedName();
538+
std::string Name = O.getPrefixedName().str();
539539

540540
// Add metavar, if used.
541541
switch (O.getKind()) {

llvm/unittests/Option/OptionMarshallingTest.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,28 @@
99
#include "gtest/gtest.h"
1010

1111
struct OptionWithMarshallingInfo {
12-
const char *Name;
12+
llvm::StringLiteral PrefixedName;
1313
const char *KeyPath;
1414
const char *ImpliedCheck;
1515
const char *ImpliedValue;
1616
};
1717

1818
static const OptionWithMarshallingInfo MarshallingTable[] = {
1919
#define OPTION_WITH_MARSHALLING( \
20-
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
21-
HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
20+
PREFIX_TYPE, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
21+
PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
2222
DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
2323
MERGER, EXTRACTOR, TABLE_INDEX) \
24-
{NAME, #KEYPATH, #IMPLIED_CHECK, #IMPLIED_VALUE},
24+
{PREFIXED_NAME, #KEYPATH, #IMPLIED_CHECK, #IMPLIED_VALUE},
2525
#include "Opts.inc"
2626
#undef OPTION_WITH_MARSHALLING
2727
};
2828

2929
TEST(OptionMarshalling, EmittedOrderSameAsDefinitionOrder) {
30-
ASSERT_STREQ(MarshallingTable[0].Name, "marshalled-flag-d");
31-
ASSERT_STREQ(MarshallingTable[1].Name, "marshalled-flag-c");
32-
ASSERT_STREQ(MarshallingTable[2].Name, "marshalled-flag-b");
33-
ASSERT_STREQ(MarshallingTable[3].Name, "marshalled-flag-a");
30+
ASSERT_EQ(MarshallingTable[0].PrefixedName, "-marshalled-flag-d");
31+
ASSERT_EQ(MarshallingTable[1].PrefixedName, "-marshalled-flag-c");
32+
ASSERT_EQ(MarshallingTable[2].PrefixedName, "-marshalled-flag-b");
33+
ASSERT_EQ(MarshallingTable[3].PrefixedName, "-marshalled-flag-a");
3434
}
3535

3636
TEST(OptionMarshalling, EmittedSpecifiedKeyPath) {

llvm/utils/TableGen/OptParserEmitter.cpp

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,29 +34,14 @@ static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) {
3434
return OS;
3535
}
3636

37-
static std::string getOptionSpelling(const Record &R, size_t &PrefixLength) {
37+
static std::string getOptionPrefixedName(const Record &R) {
3838
std::vector<StringRef> Prefixes = R.getValueAsListOfStrings("Prefixes");
3939
StringRef Name = R.getValueAsString("Name");
4040

41-
if (Prefixes.empty()) {
42-
PrefixLength = 0;
41+
if (Prefixes.empty())
4342
return Name.str();
44-
}
45-
46-
PrefixLength = Prefixes[0].size();
47-
return (Twine(Prefixes[0]) + Twine(Name)).str();
48-
}
4943

50-
static std::string getOptionSpelling(const Record &R) {
51-
size_t PrefixLength;
52-
return getOptionSpelling(R, PrefixLength);
53-
}
54-
55-
static void emitNameUsingSpelling(raw_ostream &OS, const Record &R) {
56-
size_t PrefixLength;
57-
OS << "&";
58-
write_cstring(OS, StringRef(getOptionSpelling(R, PrefixLength)));
59-
OS << "[" << PrefixLength << "]";
44+
return (Prefixes[0] + Twine(Name)).str();
6045
}
6146

6247
class MarshallingInfo {
@@ -104,8 +89,6 @@ struct SimpleEnumValueTable {
10489
}
10590

10691
void emit(raw_ostream &OS) const {
107-
write_cstring(OS, StringRef(getOptionSpelling(R)));
108-
OS << ", ";
10992
OS << ShouldParse;
11093
OS << ", ";
11194
OS << ShouldAlwaysEmit;
@@ -310,8 +293,8 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
310293
std::vector<StringRef> RPrefixes = R.getValueAsListOfStrings("Prefixes");
311294
OS << Prefixes[PrefixKeyT(RPrefixes.begin(), RPrefixes.end())] << ", ";
312295

313-
// The option string.
314-
emitNameUsingSpelling(OS, R);
296+
// The option prefixed name.
297+
write_cstring(OS, getOptionPrefixedName(R));
315298

316299
// The option identifier name.
317300
OS << ", " << getOptionName(R);

0 commit comments

Comments
 (0)