@@ -27,13 +27,6 @@ class CompilerInstance;
27
27
28
28
namespace tidy {
29
29
30
- // / This class should be specialized by any enum type that needs to be converted
31
- // / to and from an \ref llvm::StringRef.
32
- template <class T > struct OptionEnumMapping {
33
- // Specializations of this struct must implement this function.
34
- static ArrayRef<std::pair<T, StringRef>> getEnumMapping () = delete;
35
- };
36
-
37
30
template <typename T> class OptionError : public llvm ::ErrorInfo<T> {
38
31
std::error_code convertToErrorCode () const override {
39
32
return llvm::inconvertibleErrorCode ();
@@ -320,80 +313,77 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
320
313
}
321
314
322
315
// / Read a named option from the ``Context`` and parse it as an
323
- // / enum type ``T``.
316
+ // / enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set,
317
+ // / it will search the mapping ignoring the case.
324
318
// /
325
319
// / Reads the option with the check-local name \p LocalName from the
326
320
// / ``CheckOptions``. If the corresponding key is not present, returns a
327
321
// / ``MissingOptionError``. If the key can't be parsed as a ``T`` returns a
328
322
// / ``UnparseableEnumOptionError``.
329
- // /
330
- // / \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
331
- // / supply the mapping required to convert between ``T`` and a string.
332
323
template <typename T>
333
324
std::enable_if_t <std::is_enum<T>::value, llvm::Expected<T>>
334
- get (StringRef LocalName, bool IgnoreCase = false ) {
335
- if (llvm::Expected<int64_t > ValueOr =
336
- getEnumInt (LocalName, typeEraseMapping<T>(), false , IgnoreCase))
325
+ get (StringRef LocalName, ArrayRef<std::pair<StringRef, T>> Mapping,
326
+ bool IgnoreCase = false ) {
327
+ if (llvm::Expected<int64_t > ValueOr = getEnumInt (
328
+ LocalName, typeEraseMapping (Mapping), false , IgnoreCase))
337
329
return static_cast <T>(*ValueOr);
338
330
else
339
331
return std::move (ValueOr.takeError ());
340
332
}
341
333
342
334
// / Read a named option from the ``Context`` and parse it as an
343
- // / enum type ``T``.
335
+ // / enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set,
336
+ // / it will search the mapping ignoring the case.
344
337
// /
345
338
// / Reads the option with the check-local name \p LocalName from the
346
339
// / ``CheckOptions``. If the corresponding key is not present or it can't be
347
340
// / parsed as a ``T``, returns \p Default.
348
- // /
349
- // / \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
350
- // / supply the mapping required to convert between ``T`` and a string.
351
341
template <typename T>
352
342
std::enable_if_t <std::is_enum<T>::value, T>
353
- get (StringRef LocalName, T Default, bool IgnoreCase = false ) {
354
- if (auto ValueOr = get<T>(LocalName, IgnoreCase))
343
+ get (StringRef LocalName, ArrayRef<std::pair<StringRef, T>> Mapping,
344
+ T Default, bool IgnoreCase = false ) {
345
+ if (auto ValueOr = get (LocalName, Mapping, IgnoreCase))
355
346
return *ValueOr;
356
347
else
357
348
logErrToStdErr (ValueOr.takeError ());
358
349
return Default;
359
350
}
360
351
361
352
// / Read a named option from the ``Context`` and parse it as an
362
- // / enum type ``T``.
353
+ // / enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set,
354
+ // / it will search the mapping ignoring the case.
363
355
// /
364
356
// / Reads the option with the check-local name \p LocalName from local or
365
357
// / global ``CheckOptions``. Gets local option first. If local is not
366
358
// / present, falls back to get global option. If global option is not
367
359
// / present either, returns a ``MissingOptionError``. If the key can't be
368
360
// / parsed as a ``T`` returns a ``UnparseableEnumOptionError``.
369
- // /
370
- // / \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
371
- // / supply the mapping required to convert between ``T`` and a string.
372
361
template <typename T>
373
362
std::enable_if_t <std::is_enum<T>::value, llvm::Expected<T>>
374
363
getLocalOrGlobal (StringRef LocalName,
364
+ ArrayRef<std::pair<StringRef, T>> Mapping,
375
365
bool IgnoreCase = false ) {
376
- if (llvm::Expected<int64_t > ValueOr =
377
- getEnumInt ( LocalName, typeEraseMapping<T>( ), true , IgnoreCase))
366
+ if (llvm::Expected<int64_t > ValueOr = getEnumInt (
367
+ LocalName, typeEraseMapping (Mapping ), true , IgnoreCase))
378
368
return static_cast <T>(*ValueOr);
379
369
else
380
370
return std::move (ValueOr.takeError ());
381
371
}
382
372
383
373
// / Read a named option from the ``Context`` and parse it as an
384
- // / enum type ``T``.
374
+ // / enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set,
375
+ // / it will search the mapping ignoring the case.
385
376
// /
386
377
// / Reads the option with the check-local name \p LocalName from local or
387
378
// / global ``CheckOptions``. Gets local option first. If local is not
388
379
// / present, falls back to get global option. If global option is not
389
380
// / present either or it can't be parsed as a ``T``, returns \p Default.
390
- // /
391
- // / \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
392
- // / supply the mapping required to convert between ``T`` and a string.
393
381
template <typename T>
394
382
std::enable_if_t <std::is_enum<T>::value, T>
395
- getLocalOrGlobal (StringRef LocalName, T Default, bool IgnoreCase = false ) {
396
- if (auto ValueOr = getLocalOrGlobal<T>(LocalName, IgnoreCase))
383
+ getLocalOrGlobal (StringRef LocalName,
384
+ ArrayRef<std::pair<StringRef, T>> Mapping, T Default,
385
+ bool IgnoreCase = false ) {
386
+ if (auto ValueOr = getLocalOrGlobal (LocalName, Mapping, IgnoreCase))
397
387
return *ValueOr;
398
388
else
399
389
logErrToStdErr (ValueOr.takeError ());
@@ -411,40 +401,34 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
411
401
int64_t Value) const ;
412
402
413
403
// / Stores an option with the check-local name \p LocalName as the string
414
- // / representation of the Enum \p Value to \p Options.
415
- // /
416
- // / \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
417
- // / supply the mapping required to convert between ``T`` and a string.
404
+ // / representation of the Enum \p Value using the \p Mapping to \p Options.
418
405
template <typename T>
419
406
std::enable_if_t <std::is_enum<T>::value>
420
- store (ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value) {
421
- ArrayRef<std::pair<T, StringRef>> Mapping =
422
- OptionEnumMapping<T>::getEnumMapping ();
407
+ store (ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value,
408
+ ArrayRef<std::pair<StringRef, T>> Mapping) {
423
409
auto Iter = llvm::find_if (
424
- Mapping, [&](const std::pair<T, StringRef > &NameAndEnum) {
425
- return NameAndEnum.first == Value;
410
+ Mapping, [&](const std::pair<StringRef, T > &NameAndEnum) {
411
+ return NameAndEnum.second == Value;
426
412
});
427
413
assert (Iter != Mapping.end () && " Unknown Case Value" );
428
- store (Options, LocalName, Iter->second );
414
+ store (Options, LocalName, Iter->first );
429
415
}
430
416
431
417
private:
432
- using NameAndValue = std::pair<int64_t , StringRef >;
418
+ using NameAndValue = std::pair<StringRef, int64_t >;
433
419
434
420
llvm::Expected<int64_t > getEnumInt (StringRef LocalName,
435
421
ArrayRef<NameAndValue> Mapping,
436
422
bool CheckGlobal, bool IgnoreCase);
437
423
438
424
template <typename T>
439
425
std::enable_if_t <std::is_enum<T>::value, std::vector<NameAndValue>>
440
- typeEraseMapping () {
441
- ArrayRef<std::pair<T, StringRef>> Mapping =
442
- OptionEnumMapping<T>::getEnumMapping ();
426
+ typeEraseMapping (ArrayRef<std::pair<StringRef, T>> Mapping) {
443
427
std::vector<NameAndValue> Result;
444
428
Result.reserve (Mapping.size ());
445
429
for (auto &MappedItem : Mapping) {
446
- Result.emplace_back (static_cast < int64_t >( MappedItem.first ) ,
447
- MappedItem.second );
430
+ Result.emplace_back (MappedItem.first ,
431
+ static_cast < int64_t >( MappedItem.second ) );
448
432
}
449
433
return Result;
450
434
}
0 commit comments