diff --git a/ClangTidyCheck.h b/ClangTidyCheck.h index 17e9df9..656a2f0 100644 --- a/ClangTidyCheck.h +++ b/ClangTidyCheck.h @@ -184,13 +184,13 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { /// integral type ``T``. /// /// Reads the option with the check-local name \p LocalName from the - /// ``CheckOptions``. If the corresponding key is not present, return - /// ``std::nullopt``. + /// ``CheckOptions``. If the corresponding key is not present, + /// return ``std::nullopt``. /// /// If the corresponding key can't be parsed as a ``T``, emit a /// diagnostic and return ``std::nullopt``. template - std::enable_if_t::value, std::optional> + std::enable_if_t, std::optional> get(StringRef LocalName) const { if (std::optional Value = get(LocalName)) { T Result{}; @@ -201,6 +201,31 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { return std::nullopt; } + /// Read a named option from the ``Context`` and parse it as an + /// integral type ``T``. + /// + /// Reads the option with the check-local name \p LocalName from the + /// ``CheckOptions``. If the corresponding key is `none`, `null`, + /// `-1` or empty, return ``std::nullopt``. If the corresponding + /// key is not present, return \p Default. + /// + /// If the corresponding key can't be parsed as a ``T``, emit a + /// diagnostic and return \p Default. + template + std::enable_if_t, std::optional> + get(StringRef LocalName, std::optional Default) const { + if (std::optional Value = get(LocalName)) { + if (Value == "" || Value == "none" || Value == "null" || + (std::is_unsigned_v && Value == "-1")) + return std::nullopt; + T Result{}; + if (!StringRef(*Value).getAsInteger(10, Result)) + return Result; + diagnoseBadIntegerOption(NamePrefix + LocalName, *Value); + } + return Default; + } + /// Read a named option from the ``Context`` and parse it as an /// integral type ``T``. /// @@ -211,8 +236,8 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { /// If the corresponding key can't be parsed as a ``T``, emit a /// diagnostic and return \p Default. template - std::enable_if_t::value, T> get(StringRef LocalName, - T Default) const { + std::enable_if_t, T> get(StringRef LocalName, + T Default) const { return get(LocalName).value_or(Default); } @@ -227,7 +252,7 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { /// If the corresponding key can't be parsed as a ``T``, emit a /// diagnostic and return ``std::nullopt``. template - std::enable_if_t::value, std::optional> + std::enable_if_t, std::optional> getLocalOrGlobal(StringRef LocalName) const { std::optional ValueOr = get(LocalName); bool IsGlobal = false; @@ -245,6 +270,39 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { return std::nullopt; } + /// Read a named option from the ``Context`` and parse it as an + /// integral type ``T``. + /// + /// Reads the option with the check-local name \p LocalName from local or + /// global ``CheckOptions``. Gets local option first. If local is not + /// present, falls back to get global option. If global option is not + /// present either, return \p Default. If the value value was found + /// and equals ``none``, ``null``, ``-1`` or empty, return ``std::nullopt``. + /// + /// If the corresponding key can't be parsed as a ``T``, emit a + /// diagnostic and return \p Default. + template + std::enable_if_t, std::optional> + getLocalOrGlobal(StringRef LocalName, std::optional Default) const { + std::optional ValueOr = get(LocalName); + bool IsGlobal = false; + if (!ValueOr) { + IsGlobal = true; + ValueOr = getLocalOrGlobal(LocalName); + if (!ValueOr) + return Default; + } + T Result{}; + if (ValueOr == "" || ValueOr == "none" || ValueOr == "null" || + (std::is_unsigned_v && ValueOr == "-1")) + return std::nullopt; + if (!StringRef(*ValueOr).getAsInteger(10, Result)) + return Result; + diagnoseBadIntegerOption( + IsGlobal ? Twine(LocalName) : NamePrefix + LocalName, *ValueOr); + return Default; + } + /// Read a named option from the ``Context`` and parse it as an /// integral type ``T``. /// @@ -256,7 +314,7 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { /// If the corresponding key can't be parsed as a ``T``, emit a /// diagnostic and return \p Default. template - std::enable_if_t::value, T> + std::enable_if_t, T> getLocalOrGlobal(StringRef LocalName, T Default) const { return getLocalOrGlobal(LocalName).value_or(Default); } @@ -274,7 +332,7 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to /// supply the mapping required to convert between ``T`` and a string. template - std::enable_if_t::value, std::optional> + std::enable_if_t, std::optional> get(StringRef LocalName, bool IgnoreCase = false) const { if (std::optional ValueOr = getEnumInt(LocalName, typeEraseMapping(), false, IgnoreCase)) @@ -286,8 +344,8 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { /// enum type ``T``. /// /// Reads the option with the check-local name \p LocalName from the - /// ``CheckOptions``. If the corresponding key is not present, return - /// \p Default. + /// ``CheckOptions``. If the corresponding key is not present, + /// return \p Default. /// /// If the corresponding key can't be parsed as a ``T``, emit a /// diagnostic and return \p Default. @@ -295,8 +353,8 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to /// supply the mapping required to convert between ``T`` and a string. template - std::enable_if_t::value, T> - get(StringRef LocalName, T Default, bool IgnoreCase = false) const { + std::enable_if_t, T> get(StringRef LocalName, T Default, + bool IgnoreCase = false) const { return get(LocalName, IgnoreCase).value_or(Default); } @@ -314,7 +372,7 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to /// supply the mapping required to convert between ``T`` and a string. template - std::enable_if_t::value, std::optional> + std::enable_if_t, std::optional> getLocalOrGlobal(StringRef LocalName, bool IgnoreCase = false) const { if (std::optional ValueOr = getEnumInt(LocalName, typeEraseMapping(), true, IgnoreCase)) @@ -336,7 +394,7 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to /// supply the mapping required to convert between ``T`` and a string. template - std::enable_if_t::value, T> + std::enable_if_t, T> getLocalOrGlobal(StringRef LocalName, T Default, bool IgnoreCase = false) const { return getLocalOrGlobal(LocalName, IgnoreCase).value_or(Default); @@ -350,19 +408,32 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { /// Stores an option with the check-local name \p LocalName with /// integer value \p Value to \p Options. template - std::enable_if_t::value> + std::enable_if_t> store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value) const { storeInt(Options, LocalName, Value); } + /// Stores an option with the check-local name \p LocalName with + /// integer value \p Value to \p Options. If the value is empty + /// stores `` + template + std::enable_if_t> + store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, + std::optional Value) const { + if (Value) + storeInt(Options, LocalName, *Value); + else + store(Options, LocalName, "none"); + } + /// Stores an option with the check-local name \p LocalName as the string /// representation of the Enum \p Value to \p Options. /// /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to /// supply the mapping required to convert between ``T`` and a string. template - std::enable_if_t::value> + std::enable_if_t> store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value) const { ArrayRef> Mapping = @@ -383,7 +454,7 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { bool CheckGlobal, bool IgnoreCase) const; template - std::enable_if_t::value, std::vector> + std::enable_if_t, std::vector> typeEraseMapping() const { ArrayRef> Mapping = OptionEnumMapping::getEnumMapping(); diff --git a/ClangTidyDiagnosticConsumer.h b/ClangTidyDiagnosticConsumer.h index 15f1b67..9280eb1 100644 --- a/ClangTidyDiagnosticConsumer.h +++ b/ClangTidyDiagnosticConsumer.h @@ -70,7 +70,8 @@ class ClangTidyContext { public: /// Initializes \c ClangTidyContext instance. ClangTidyContext(std::unique_ptr OptionsProvider, - bool AllowEnablingAnalyzerAlphaCheckers = false); + bool AllowEnablingAnalyzerAlphaCheckers = false, + bool EnableModuleHeadersParsing = false); /// Sets the DiagnosticsEngine that diag() will emit diagnostics to. // FIXME: this is required initialization, and should be a constructor param. // Fix the context -> diag engine -> consumer -> context initialization cycle. @@ -86,10 +87,10 @@ class ClangTidyContext { /// tablegen'd diagnostic IDs. /// FIXME: Figure out a way to manage ID spaces. DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc, - StringRef Message, + StringRef Description, DiagnosticIDs::Level Level = DiagnosticIDs::Warning); - DiagnosticBuilder diag(StringRef CheckName, StringRef Message, + DiagnosticBuilder diag(StringRef CheckName, StringRef Description, DiagnosticIDs::Level Level = DiagnosticIDs::Warning); DiagnosticBuilder diag(const tooling::Diagnostic &Error); @@ -198,6 +199,12 @@ class ClangTidyContext { return AllowEnablingAnalyzerAlphaCheckers; } + // This method determines whether preprocessor-level module header parsing is + // enabled using the `--experimental-enable-module-headers-parsing` option. + bool canEnableModuleHeadersParsing() const { + return EnableModuleHeadersParsing; + } + void setSelfContainedDiags(bool Value) { SelfContainedDiags = Value; } bool areDiagsSelfContained() const { return SelfContainedDiags; } @@ -205,11 +212,11 @@ class ClangTidyContext { using DiagLevelAndFormatString = std::pair; DiagLevelAndFormatString getDiagLevelAndFormatString(unsigned DiagnosticID, SourceLocation Loc) { - return DiagLevelAndFormatString( + return { static_cast( DiagEngine->getDiagnosticLevel(DiagnosticID, Loc)), std::string( - DiagEngine->getDiagnosticIDs()->getDescription(DiagnosticID))); + DiagEngine->getDiagnosticIDs()->getDescription(DiagnosticID))}; } void setOptionsCollector(llvm::StringSet<> *Collector) { @@ -221,7 +228,7 @@ class ClangTidyContext { // Writes to Stats. friend class ClangTidyDiagnosticConsumer; - DiagnosticsEngine *DiagEngine; + DiagnosticsEngine *DiagEngine = nullptr; std::unique_ptr OptionsProvider; std::string CurrentFile; @@ -241,12 +248,13 @@ class ClangTidyContext { llvm::DenseMap CheckNamesByDiagnosticID; - bool Profile; + bool Profile = false; std::string ProfilePrefix; bool AllowEnablingAnalyzerAlphaCheckers; + bool EnableModuleHeadersParsing; - bool SelfContainedDiags; + bool SelfContainedDiags = false; NoLintDirectiveHandler NoLintHandler; llvm::StringSet<> *OptionsCollector = nullptr; @@ -305,9 +313,9 @@ class ClangTidyDiagnosticConsumer : public DiagnosticConsumer { bool EnableNolintBlocks; std::vector Errors; std::unique_ptr HeaderFilter; - bool LastErrorRelatesToUserCode; - bool LastErrorPassesLineFilter; - bool LastErrorWasIgnored; + bool LastErrorRelatesToUserCode = false; + bool LastErrorPassesLineFilter = false; + bool LastErrorWasIgnored = false; }; } // end namespace tidy diff --git a/ClangTidyModule.h b/ClangTidyModule.h index 0e55c1e..28f5433 100644 --- a/ClangTidyModule.h +++ b/ClangTidyModule.h @@ -70,7 +70,7 @@ class ClangTidyCheckFactories { std::vector> createChecksForLanguage(ClangTidyContext *Context) const; - typedef llvm::StringMap FactoryMap; + using FactoryMap = llvm::StringMap; FactoryMap::const_iterator begin() const { return Factories.begin(); } FactoryMap::const_iterator end() const { return Factories.end(); } bool empty() const { return Factories.empty(); } diff --git a/ClangTidyModuleRegistry.h b/ClangTidyModuleRegistry.h index 30ffe18..78d914b 100644 --- a/ClangTidyModuleRegistry.h +++ b/ClangTidyModuleRegistry.h @@ -14,7 +14,7 @@ namespace clang::tidy { -typedef llvm::Registry ClangTidyModuleRegistry; +using ClangTidyModuleRegistry = llvm::Registry; } // namespace clang::tidy diff --git a/ClangTidyOptions.h b/ClangTidyOptions.h index b3b7143..e7636cb 100644 --- a/ClangTidyOptions.h +++ b/ClangTidyOptions.h @@ -30,7 +30,7 @@ struct FileFilter { std::string Name; /// LineRange is a pair (inclusive). - typedef std::pair LineRange; + using LineRange = std::pair; /// A list of line ranges in this file, for which we show warnings. std::vector LineRanges; @@ -118,13 +118,13 @@ struct ClangTidyOptions { /// files to disambiguate local vs global value from different levels. unsigned Priority = 0; }; - typedef std::pair StringPair; - typedef llvm::StringMap OptionMap; + using StringPair = std::pair; + using OptionMap = llvm::StringMap; /// Key-value mapping used to store check-specific options. OptionMap CheckOptions; - typedef std::vector ArgList; + using ArgList = std::vector; /// Add extra compilation arguments to the end of the list. std::optional ExtraArgs; @@ -165,7 +165,7 @@ class ClangTidyOptionsProvider { /// commandline option is specified, clang-tidy will ignore the /// configuration file. /// * '-checks' commandline option. - typedef std::pair OptionsSource; + using OptionsSource = std::pair; /// Returns an ordered vector of OptionsSources, in order of increasing /// priority. @@ -199,9 +199,7 @@ class FileOptionsBaseProvider : public DefaultOptionsProvider { protected: // A pair of configuration file base name and a function parsing // configuration from text in the corresponding format. - typedef std::pair( - llvm::MemoryBufferRef)>> - ConfigFileHandler; + using ConfigFileHandler = std::pair (llvm::MemoryBufferRef)>>; /// Configuration file handlers listed in the order of priority. /// @@ -220,7 +218,7 @@ class FileOptionsBaseProvider : public DefaultOptionsProvider { /// /// With the order of handlers shown above, the ".my-tidy-config" file would /// take precedence over ".clang-tidy" if both reside in the same directory. - typedef std::vector ConfigFileHandlers; + using ConfigFileHandlers = std::vector; FileOptionsBaseProvider(ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions, @@ -232,7 +230,6 @@ class FileOptionsBaseProvider : public DefaultOptionsProvider { ClangTidyOptions OverrideOptions, ConfigFileHandlers ConfigHandlers); -protected: void addRawFileOptions(llvm::StringRef AbsolutePath, std::vector &CurOptions); diff --git a/FileExtensionsSet.h b/FileExtensionsSet.h index 417b1b6..7ca4e6e 100644 --- a/FileExtensionsSet.h +++ b/FileExtensionsSet.h @@ -13,7 +13,7 @@ #include "llvm/ADT/StringRef.h" namespace clang::tidy { -typedef llvm::SmallSet FileExtensionsSet; +using FileExtensionsSet = llvm::SmallSet; } // namespace clang::tidy #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FILE_EXTENSIONS_SET_H