Skip to content

Commit d2d59d2

Browse files
committed
Reland [clang][cli] Port ObjCMTAction to new option parsing system
Merge existing marhsalling info kinds and add some primitives to express flag options that contribute to a bitfield. Depends on D82574 Original patch by Daniel Grumberg. Reviewed By: Bigcheese Differential Revision: https://reviews.llvm.org/D82860
1 parent c30ab6c commit d2d59d2

File tree

6 files changed

+207
-239
lines changed

6 files changed

+207
-239
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -340,36 +340,53 @@ def ccc_objcmt_migrate : Separate<["-"], "ccc-objcmt-migrate">,
340340
InternalDriverOpt,
341341
HelpText<"Apply modifications and produces temporary files to migrate to "
342342
"modern ObjC syntax">;
343+
343344
def objcmt_migrate_literals : Flag<["-"], "objcmt-migrate-literals">, Flags<[CC1Option]>,
344-
HelpText<"Enable migration to modern ObjC literals">;
345+
HelpText<"Enable migration to modern ObjC literals">,
346+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_Literals">;
345347
def objcmt_migrate_subscripting : Flag<["-"], "objcmt-migrate-subscripting">, Flags<[CC1Option]>,
346-
HelpText<"Enable migration to modern ObjC subscripting">;
348+
HelpText<"Enable migration to modern ObjC subscripting">,
349+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_Subscripting">;
347350
def objcmt_migrate_property : Flag<["-"], "objcmt-migrate-property">, Flags<[CC1Option]>,
348-
HelpText<"Enable migration to modern ObjC property">;
351+
HelpText<"Enable migration to modern ObjC property">,
352+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_Property">;
349353
def objcmt_migrate_all : Flag<["-"], "objcmt-migrate-all">, Flags<[CC1Option]>,
350-
HelpText<"Enable migration to modern ObjC">;
354+
HelpText<"Enable migration to modern ObjC">,
355+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_MigrateDecls">;
351356
def objcmt_migrate_readonly_property : Flag<["-"], "objcmt-migrate-readonly-property">, Flags<[CC1Option]>,
352-
HelpText<"Enable migration to modern ObjC readonly property">;
357+
HelpText<"Enable migration to modern ObjC readonly property">,
358+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_ReadonlyProperty">;
353359
def objcmt_migrate_readwrite_property : Flag<["-"], "objcmt-migrate-readwrite-property">, Flags<[CC1Option]>,
354-
HelpText<"Enable migration to modern ObjC readwrite property">;
360+
HelpText<"Enable migration to modern ObjC readwrite property">,
361+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_ReadwriteProperty">;
355362
def objcmt_migrate_property_dot_syntax : Flag<["-"], "objcmt-migrate-property-dot-syntax">, Flags<[CC1Option]>,
356-
HelpText<"Enable migration of setter/getter messages to property-dot syntax">;
363+
HelpText<"Enable migration of setter/getter messages to property-dot syntax">,
364+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_PropertyDotSyntax">;
357365
def objcmt_migrate_annotation : Flag<["-"], "objcmt-migrate-annotation">, Flags<[CC1Option]>,
358-
HelpText<"Enable migration to property and method annotations">;
366+
HelpText<"Enable migration to property and method annotations">,
367+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_Annotation">;
359368
def objcmt_migrate_instancetype : Flag<["-"], "objcmt-migrate-instancetype">, Flags<[CC1Option]>,
360-
HelpText<"Enable migration to infer instancetype for method result type">;
369+
HelpText<"Enable migration to infer instancetype for method result type">,
370+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_Instancetype">;
361371
def objcmt_migrate_nsmacros : Flag<["-"], "objcmt-migrate-ns-macros">, Flags<[CC1Option]>,
362-
HelpText<"Enable migration to NS_ENUM/NS_OPTIONS macros">;
372+
HelpText<"Enable migration to NS_ENUM/NS_OPTIONS macros">,
373+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_NsMacros">;
363374
def objcmt_migrate_protocol_conformance : Flag<["-"], "objcmt-migrate-protocol-conformance">, Flags<[CC1Option]>,
364-
HelpText<"Enable migration to add protocol conformance on classes">;
375+
HelpText<"Enable migration to add protocol conformance on classes">,
376+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_ProtocolConformance">;
365377
def objcmt_atomic_property : Flag<["-"], "objcmt-atomic-property">, Flags<[CC1Option]>,
366-
HelpText<"Make migration to 'atomic' properties">;
378+
HelpText<"Make migration to 'atomic' properties">,
379+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_AtomicProperty">;
367380
def objcmt_returns_innerpointer_property : Flag<["-"], "objcmt-returns-innerpointer-property">, Flags<[CC1Option]>,
368-
HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">;
381+
HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">,
382+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_ReturnsInnerPointerProperty">;
369383
def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, Flags<[CC1Option]>,
370-
HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">;
384+
HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">,
385+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty">;
371386
def objcmt_migrate_designated_init : Flag<["-"], "objcmt-migrate-designated-init">, Flags<[CC1Option]>,
372-
HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">;
387+
HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">,
388+
MarshallingInfoBitfieldFlag<"FrontendOpts.ObjCMTAction", "FrontendOptions::ObjCMT_DesignatedInitializer">;
389+
373390
def objcmt_whitelist_dir_path: Joined<["-"], "objcmt-whitelist-dir-path=">, Flags<[CC1Option]>,
374391
HelpText<"Only modify files with a filename contained in the provided directory path">;
375392
// The misspelt "white-list" [sic] alias is due for removal.

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 62 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,24 @@ CompilerInvocationBase::~CompilerInvocationBase() = default;
125125
#include "clang/Driver/Options.inc"
126126
#undef SIMPLE_ENUM_VALUE_TABLE
127127

128+
static llvm::Optional<bool> normalizeSimpleFlag(OptSpecifier Opt,
129+
unsigned TableIndex,
130+
const ArgList &Args,
131+
DiagnosticsEngine &Diags) {
132+
if (Args.hasArg(Opt))
133+
return true;
134+
return None;
135+
}
136+
137+
template <typename T, T Value>
138+
static llvm::Optional<T>
139+
normalizeFlagToValue(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args,
140+
DiagnosticsEngine &Diags) {
141+
if (Args.hasArg(Opt))
142+
return Value;
143+
return None;
144+
}
145+
128146
static llvm::Optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
129147
unsigned TableIndex,
130148
const ArgList &Args,
@@ -146,22 +164,26 @@ static llvm::Optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
146164
return None;
147165
}
148166

149-
static const char *denormalizeSimpleEnum(CompilerInvocation::StringAllocator SA,
150-
unsigned TableIndex, unsigned Value) {
167+
static void denormalizeSimpleEnum(SmallVectorImpl<const char *> &Args,
168+
CompilerInvocation::StringAllocator SA,
169+
unsigned TableIndex, unsigned Value) {
151170
assert(TableIndex < SimpleEnumValueTablesSize);
152171
const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
153-
for (int I = 0, E = Table.Size; I != E; ++I)
154-
if (Value == Table.Table[I].Value)
155-
return Table.Table[I].Name;
172+
for (int I = 0, E = Table.Size; I != E; ++I) {
173+
if (Value == Table.Table[I].Value) {
174+
Args.push_back(Table.Table[I].Name);
175+
return;
176+
}
177+
}
156178

157179
llvm_unreachable("The simple enum value was not correctly defined in "
158180
"the tablegen option description");
159181
}
160182

161-
static const char *denormalizeString(CompilerInvocation::StringAllocator SA,
162-
unsigned TableIndex,
163-
const std::string &Value) {
164-
return SA(Value);
183+
static void denormalizeString(SmallVectorImpl<const char *> &Args,
184+
CompilerInvocation::StringAllocator SA,
185+
unsigned TableIndex, const std::string &Value) {
186+
Args.push_back(SA(Value));
165187
}
166188

167189
static Optional<std::string> normalizeTriple(OptSpecifier Opt, int TableIndex,
@@ -173,6 +195,24 @@ static Optional<std::string> normalizeTriple(OptSpecifier Opt, int TableIndex,
173195
return llvm::Triple::normalize(Arg->getValue());
174196
}
175197

198+
template <typename T, typename U>
199+
static T mergeForwardValue(T KeyPath, U Value) {
200+
return Value;
201+
}
202+
203+
template <typename T, typename U> static T mergeMaskValue(T KeyPath, U Value) {
204+
return KeyPath | Value;
205+
}
206+
207+
template <typename T> static T extractForwardValue(T KeyPath) {
208+
return KeyPath;
209+
}
210+
211+
template <typename T, typename U, U Value>
212+
static T extractMaskValue(T KeyPath) {
213+
return KeyPath & Value;
214+
}
215+
176216
//===----------------------------------------------------------------------===//
177217
// Deserialization (from args)
178218
//===----------------------------------------------------------------------===//
@@ -2010,37 +2050,6 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
20102050
Opts.ARCMTMigrateEmitARCErrors
20112051
= Args.hasArg(OPT_arcmt_migrate_emit_arc_errors);
20122052

2013-
if (Args.hasArg(OPT_objcmt_migrate_literals))
2014-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Literals;
2015-
if (Args.hasArg(OPT_objcmt_migrate_subscripting))
2016-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Subscripting;
2017-
if (Args.hasArg(OPT_objcmt_migrate_property_dot_syntax))
2018-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_PropertyDotSyntax;
2019-
if (Args.hasArg(OPT_objcmt_migrate_property))
2020-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Property;
2021-
if (Args.hasArg(OPT_objcmt_migrate_readonly_property))
2022-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReadonlyProperty;
2023-
if (Args.hasArg(OPT_objcmt_migrate_readwrite_property))
2024-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReadwriteProperty;
2025-
if (Args.hasArg(OPT_objcmt_migrate_annotation))
2026-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Annotation;
2027-
if (Args.hasArg(OPT_objcmt_returns_innerpointer_property))
2028-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ReturnsInnerPointerProperty;
2029-
if (Args.hasArg(OPT_objcmt_migrate_instancetype))
2030-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Instancetype;
2031-
if (Args.hasArg(OPT_objcmt_migrate_nsmacros))
2032-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsMacros;
2033-
if (Args.hasArg(OPT_objcmt_migrate_protocol_conformance))
2034-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_ProtocolConformance;
2035-
if (Args.hasArg(OPT_objcmt_atomic_property))
2036-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_AtomicProperty;
2037-
if (Args.hasArg(OPT_objcmt_ns_nonatomic_iosonly))
2038-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty;
2039-
if (Args.hasArg(OPT_objcmt_migrate_designated_init))
2040-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_DesignatedInitializer;
2041-
if (Args.hasArg(OPT_objcmt_migrate_all))
2042-
Opts.ObjCMTAction |= FrontendOptions::ObjCMT_MigrateDecls;
2043-
20442053
Opts.ObjCMTWhiteListPath =
20452054
std::string(Args.getLastArgValue(OPT_objcmt_whitelist_dir_path));
20462055

@@ -3722,26 +3731,18 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
37223731

37233732
bool CompilerInvocation::parseSimpleArgs(const ArgList &Args,
37243733
DiagnosticsEngine &Diags) {
3725-
#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \
3726-
ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \
3727-
METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \
3728-
KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \
3729-
this->KEYPATH = (Args.hasArg(OPT_##ID) && IS_POSITIVE) || (DEFAULT_VALUE);
3730-
3731-
#define OPTION_WITH_MARSHALLING_STRING( \
3734+
#define OPTION_WITH_MARSHALLING( \
37323735
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
37333736
HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
3734-
TYPE, NORMALIZER, DENORMALIZER, TABLE_INDEX) \
3737+
TYPE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
37353738
{ \
3739+
this->KEYPATH = MERGER(this->KEYPATH, DEFAULT_VALUE); \
37363740
if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, Diags)) \
3737-
this->KEYPATH = static_cast<TYPE>(*MaybeValue); \
3738-
else \
3739-
this->KEYPATH = DEFAULT_VALUE; \
3741+
this->KEYPATH = MERGER(this->KEYPATH, static_cast<TYPE>(*MaybeValue)); \
37403742
}
37413743

37423744
#include "clang/Driver/Options.inc"
3743-
#undef OPTION_WITH_MARSHALLING_STRING
3744-
#undef OPTION_WITH_MARSHALLING_FLAG
3745+
#undef OPTION_WITH_MARSHALLING
37453746
return true;
37463747
}
37473748

@@ -3996,29 +3997,23 @@ std::string CompilerInvocation::getModuleHash() const {
39963997

39973998
void CompilerInvocation::generateCC1CommandLine(
39983999
SmallVectorImpl<const char *> &Args, StringAllocator SA) const {
3999-
#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \
4000-
ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \
4001-
METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \
4002-
KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \
4003-
if ((FLAGS) & options::CC1Option && \
4004-
(ALWAYS_EMIT || this->KEYPATH != (DEFAULT_VALUE))) \
4005-
Args.push_back(SPELLING);
4006-
4007-
#define OPTION_WITH_MARSHALLING_STRING( \
4000+
#define OPTION_WITH_MARSHALLING( \
40084001
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
40094002
HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
4010-
NORMALIZER_RET_TY, NORMALIZER, DENORMALIZER, TABLE_INDEX) \
4003+
TYPE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
40114004
if (((FLAGS) & options::CC1Option) && \
4012-
(ALWAYS_EMIT || this->KEYPATH != DEFAULT_VALUE)) { \
4005+
(ALWAYS_EMIT || EXTRACTOR(this->KEYPATH) != (DEFAULT_VALUE))) { \
4006+
if (Option::KIND##Class == Option::FlagClass) { \
4007+
Args.push_back(SPELLING); \
4008+
} \
40134009
if (Option::KIND##Class == Option::SeparateClass) { \
40144010
Args.push_back(SPELLING); \
4015-
Args.push_back(DENORMALIZER(SA, TABLE_INDEX, this->KEYPATH)); \
4011+
DENORMALIZER(Args, SA, TABLE_INDEX, EXTRACTOR(this->KEYPATH)); \
40164012
} \
40174013
}
40184014

40194015
#include "clang/Driver/Options.inc"
4020-
#undef OPTION_WITH_MARSHALLING_STRING
4021-
#undef OPTION_WITH_MARSHALLING_FLAG
4016+
#undef OPTION_WITH_MARSHALLING
40224017
}
40234018

40244019
IntrusiveRefCntPtr<llvm::vfs::FileSystem>

llvm/include/llvm/Option/OptParser.td

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,17 +97,15 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
9797
OptionGroup Group = ?;
9898
Option Alias = ?;
9999
list<string> AliasArgs = [];
100-
string MarshallingKind = ?;
101100
code KeyPath = ?;
102101
code DefaultValue = ?;
103102
bit ShouldAlwaysEmit = 0;
104-
// Used by the Flag option kind.
105-
bit IsPositive = 1;
106-
// Used by the String option kind.
107103
code NormalizerRetTy = ?;
108104
code NormalizedValuesScope = "";
109105
code Normalizer = "";
110106
code Denormalizer = "";
107+
code ValueMerger = "mergeForwardValue";
108+
code ValueExtractor = "extractForwardValue";
111109
list<code> NormalizedValues = ?;
112110
}
113111

@@ -144,29 +142,39 @@ class ValuesCode<code valuecode> { code ValuesCode = valuecode; }
144142

145143
// Helpers for defining marshalling information.
146144

147-
class DefaultAnyOf<list<Option> defaults> {
148-
code DefaultValue = !foldl("false", defaults, accumulator, option,
149-
!strconcat(accumulator, " || ", !cast<string>(option.KeyPath)));
145+
class DefaultAnyOf<list<Option> options, string default = "false", string separator = " || "> {
146+
code DefaultValue = !foldl(default, options, accumulator, option,
147+
!strconcat(accumulator, separator, !cast<string>(option.KeyPath)));
150148
}
151149

152150
class MarshallingInfo<code keypath, code defaultvalue> {
153151
code KeyPath = keypath;
154152
code DefaultValue = defaultvalue;
155153
}
154+
156155
class MarshallingInfoString<code keypath, code defaultvalue, code normalizerretty>
157156
: MarshallingInfo<keypath, defaultvalue> {
158-
string MarshallingKind = "string";
159157
code NormalizerRetTy = normalizerretty;
160158
}
161159

162-
class MarshallingInfoFlag<code keypath, DefaultAnyOf defaults = DefaultAnyOf<[]>>
160+
class MarshallingInfoFlag<code keypath, DefaultAnyOf defaults = DefaultAnyOf<[]>, code ty="unsigned">
163161
: MarshallingInfo<keypath, defaults.DefaultValue> {
164-
string MarshallingKind = "flag";
162+
code NormalizerRetTy = ty;
163+
code Normalizer = "normalizeSimpleFlag";
164+
}
165+
166+
class MarshallingInfoBitfieldFlag<code keypath, code value>
167+
: MarshallingInfoFlag<keypath, DefaultAnyOf<[], "0u", " | ">, "unsigned"> {
168+
code Normalizer = "(normalizeFlagToValue<unsigned, "#value#">)";
169+
code ValueMerger = "mergeMaskValue";
170+
code ValueExtractor = "(extractMaskValue<unsigned, decltype("#value#"), "#value#">)";
165171
}
166172

167173
// Mixins for additional marshalling attributes.
168174

169-
class IsNegative { bit IsPositive = 0; }
175+
class IsNegative {
176+
// todo: create & apply a normalizer for negative flags
177+
}
170178
class AlwaysEmit { bit ShouldAlwaysEmit = 1; }
171179
class Normalizer<code normalizer> { code Normalizer = normalizer; }
172180
class Denormalizer<code denormalizer> { code Denormalizer = denormalizer; }
@@ -177,6 +185,8 @@ class AutoNormalizeEnum {
177185
code Normalizer = "normalizeSimpleEnum";
178186
code Denormalizer = "denormalizeSimpleEnum";
179187
}
188+
class ValueMerger<code merger> { code ValueMerger = merger; }
189+
class ValueExtractor<code extractor> { code ValueExtractor = extractor; }
180190

181191
// Predefined options.
182192

0 commit comments

Comments
 (0)