1515namespace clang {
1616namespace tidy {
1717
18- char MissingOptionError::ID;
19- char UnparseableEnumOptionError::ID;
20- char UnparseableIntegerOptionError::ID;
21-
22- std::string MissingOptionError::message () const {
23- llvm::SmallString<128 > Buffer ({" option not found '" , OptionName, " '" });
24- return std::string (Buffer);
25- }
26-
27- std::string UnparseableEnumOptionError::message () const {
28- llvm::SmallString<256 > Buffer ({" invalid configuration value '" , LookupValue,
29- " ' for option '" , LookupName, " '" });
30- if (SuggestedValue)
31- Buffer.append ({" ; did you mean '" , *SuggestedValue, " '?" });
32- return std::string (Buffer);
33- }
34-
35- std::string UnparseableIntegerOptionError::message () const {
36- llvm::SmallString<256 > Buffer ({" invalid configuration value '" , LookupValue,
37- " ' for option '" , LookupName, " '; expected " ,
38- (IsBoolean ? " a bool" : " an integer value" )});
39- return std::string (Buffer);
40- }
41-
4218ClangTidyCheck::ClangTidyCheck (StringRef CheckName, ClangTidyContext *Context)
4319 : CheckName(CheckName), Context(Context),
4420 Options (CheckName, Context->getOptions ().CheckOptions, Context) {
@@ -75,12 +51,12 @@ ClangTidyCheck::OptionsView::OptionsView(
7551 : NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions),
7652 Context(Context) {}
7753
78- llvm::Expected <std::string>
54+ llvm::Optional <std::string>
7955ClangTidyCheck::OptionsView::get (StringRef LocalName) const {
8056 const auto &Iter = CheckOptions.find (NamePrefix + LocalName.str ());
8157 if (Iter != CheckOptions.end ())
8258 return Iter->getValue ().Value ;
83- return llvm::make_error<MissingOptionError>((NamePrefix + LocalName). str ()) ;
59+ return None ;
8460}
8561
8662static ClangTidyOptions::OptionMap::const_iterator
@@ -97,16 +73,16 @@ findPriorityOption(const ClangTidyOptions::OptionMap &Options, StringRef NamePre
9773 return IterGlobal;
9874}
9975
100- llvm::Expected <std::string>
76+ llvm::Optional <std::string>
10177ClangTidyCheck::OptionsView::getLocalOrGlobal (StringRef LocalName) const {
10278 auto Iter = findPriorityOption (CheckOptions, NamePrefix, LocalName);
10379 if (Iter != CheckOptions.end ())
10480 return Iter->getValue ().Value ;
105- return llvm::make_error<MissingOptionError>((NamePrefix + LocalName). str ()) ;
81+ return None ;
10682}
10783
108- static llvm::Expected <bool > getAsBool (StringRef Value,
109- const llvm::Twine &LookupName) {
84+ static Optional <bool > getAsBool (StringRef Value,
85+ const llvm::Twine &LookupName) {
11086
11187 if (llvm::Optional<bool > Parsed = llvm::yaml::parseBool (Value))
11288 return *Parsed;
@@ -115,46 +91,30 @@ static llvm::Expected<bool> getAsBool(StringRef Value,
11591 long long Number;
11692 if (!Value.getAsInteger (10 , Number))
11793 return Number != 0 ;
118- return llvm::make_error<UnparseableIntegerOptionError>(LookupName.str (),
119- Value.str (), true );
94+ return None;
12095}
12196
12297template <>
123- llvm::Expected <bool >
98+ llvm::Optional <bool >
12499ClangTidyCheck::OptionsView::get<bool >(StringRef LocalName) const {
125- llvm::Expected<std::string> ValueOr = get (LocalName);
126- if (ValueOr)
127- return getAsBool (*ValueOr, NamePrefix + LocalName);
128- return ValueOr.takeError ();
129- }
130-
131- template <>
132- bool ClangTidyCheck::OptionsView::get<bool >(StringRef LocalName,
133- bool Default) const {
134- llvm::Expected<bool > ValueOr = get<bool >(LocalName);
135- if (ValueOr)
136- return *ValueOr;
137- reportOptionParsingError (ValueOr.takeError ());
138- return Default;
100+ if (llvm::Optional<std::string> ValueOr = get (LocalName)) {
101+ if (auto Result = getAsBool (*ValueOr, NamePrefix + LocalName))
102+ return Result;
103+ diagnoseBadBooleanOption (NamePrefix + LocalName, *ValueOr);
104+ }
105+ return None;
139106}
140107
141108template <>
142- llvm::Expected <bool >
109+ llvm::Optional <bool >
143110ClangTidyCheck::OptionsView::getLocalOrGlobal<bool >(StringRef LocalName) const {
144111 auto Iter = findPriorityOption (CheckOptions, NamePrefix, LocalName);
145- if (Iter != CheckOptions.end ())
146- return getAsBool (Iter->getValue ().Value , Iter->getKey ());
147- return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str ());
148- }
149-
150- template <>
151- bool ClangTidyCheck::OptionsView::getLocalOrGlobal<bool >(StringRef LocalName,
152- bool Default) const {
153- llvm::Expected<bool > ValueOr = getLocalOrGlobal<bool >(LocalName);
154- if (ValueOr)
155- return *ValueOr;
156- reportOptionParsingError (ValueOr.takeError ());
157- return Default;
112+ if (Iter != CheckOptions.end ()) {
113+ if (auto Result = getAsBool (Iter->getValue ().Value , Iter->getKey ()))
114+ return Result;
115+ diagnoseBadBooleanOption (Iter->getKey (), Iter->getValue ().Value );
116+ }
117+ return None;
158118}
159119
160120void ClangTidyCheck::OptionsView::store (ClangTidyOptions::OptionMap &Options,
@@ -176,14 +136,14 @@ void ClangTidyCheck::OptionsView::store<bool>(
176136 store (Options, LocalName, Value ? StringRef (" true" ) : StringRef (" false" ));
177137}
178138
179- llvm::Expected <int64_t > ClangTidyCheck::OptionsView::getEnumInt (
139+ llvm::Optional <int64_t > ClangTidyCheck::OptionsView::getEnumInt (
180140 StringRef LocalName, ArrayRef<NameAndValue> Mapping, bool CheckGlobal,
181141 bool IgnoreCase) const {
182142 auto Iter = CheckGlobal
183143 ? findPriorityOption (CheckOptions, NamePrefix, LocalName)
184144 : CheckOptions.find ((NamePrefix + LocalName).str ());
185145 if (Iter == CheckOptions.end ())
186- return llvm::make_error<MissingOptionError>((NamePrefix + LocalName). str ()) ;
146+ return None ;
187147
188148 StringRef Value = Iter->getValue ().Value ;
189149 StringRef Closest;
@@ -206,39 +166,54 @@ llvm::Expected<int64_t> ClangTidyCheck::OptionsView::getEnumInt(
206166 }
207167 }
208168 if (EditDistance < 3 )
209- return llvm::make_error<UnparseableEnumOptionError>(
210- Iter->getKey ().str (), Iter->getValue ().Value , Closest.str ());
211- return llvm::make_error<UnparseableEnumOptionError>(Iter->getKey ().str (),
212- Iter->getValue ().Value );
169+ diagnoseBadEnumOption (Iter->getKey ().str (), Iter->getValue ().Value ,
170+ Closest);
171+ else
172+ diagnoseBadEnumOption (Iter->getKey ().str (), Iter->getValue ().Value );
173+ return None;
213174}
214175
215- void ClangTidyCheck::OptionsView::reportOptionParsingError (
216- llvm::Error &&Err) const {
217- if (auto RemainingErrors =
218- llvm::handleErrors (std::move (Err), [](const MissingOptionError &) {}))
219- Context->configurationDiag (llvm::toString (std::move (RemainingErrors)));
176+ static constexpr llvm::StringLiteral ConfigWarning (
177+ " invalid configuration value '%0' for option '%1'%select{|; expected a "
178+ " bool|; expected an integer|; did you mean '%3'?}2" );
179+
180+ void ClangTidyCheck::OptionsView::diagnoseBadBooleanOption (
181+ const Twine &Lookup, StringRef Unparsed) const {
182+ SmallString<64 > Buffer;
183+ Context->configurationDiag (ConfigWarning)
184+ << Unparsed << Lookup.toStringRef (Buffer) << 1 ;
220185}
221186
222- template <>
223- Optional<std::string> ClangTidyCheck::OptionsView::getOptional<std::string>(
224- StringRef LocalName) const {
225- if (auto ValueOr = get (LocalName))
226- return *ValueOr;
227- else
228- consumeError (ValueOr.takeError ());
229- return llvm::None;
187+ void ClangTidyCheck::OptionsView::diagnoseBadIntegerOption (
188+ const Twine &Lookup, StringRef Unparsed) const {
189+ SmallString<64 > Buffer;
190+ Context->configurationDiag (ConfigWarning)
191+ << Unparsed << Lookup.toStringRef (Buffer) << 2 ;
230192}
231193
232- template <>
233- Optional<std::string>
234- ClangTidyCheck::OptionsView::getOptionalLocalOrGlobal<std::string>(
235- StringRef LocalName) const {
236- if (auto ValueOr = getLocalOrGlobal (LocalName))
237- return *ValueOr;
194+ void ClangTidyCheck::OptionsView::diagnoseBadEnumOption (
195+ const Twine &Lookup, StringRef Unparsed, StringRef Suggestion) const {
196+ SmallString<64 > Buffer;
197+ auto Diag = Context->configurationDiag (ConfigWarning)
198+ << Unparsed << Lookup.toStringRef (Buffer);
199+ if (Suggestion.empty ())
200+ Diag << 0 ;
238201 else
239- consumeError (ValueOr.takeError ());
240- return llvm::None;
202+ Diag << 3 << Suggestion;
241203}
242204
205+ std::string ClangTidyCheck::OptionsView::get (StringRef LocalName,
206+ StringRef Default) const {
207+ if (llvm::Optional<std::string> Val = get (LocalName))
208+ return std::move (*Val);
209+ return Default.str ();
210+ }
211+ std::string
212+ ClangTidyCheck::OptionsView::getLocalOrGlobal (StringRef LocalName,
213+ StringRef Default) const {
214+ if (llvm::Optional<std::string> Val = getLocalOrGlobal (LocalName))
215+ return std::move (*Val);
216+ return Default.str ();
217+ }
243218} // namespace tidy
244219} // namespace clang
0 commit comments