Skip to content

Commit 82289aa

Browse files
committed
[clang-tidy] Remove OptionError
The interface served a purpose, but since the ability to emit diagnostics when parsing configuration was added, its become mostly redundant. Emitting the diagnostic and removing the boilerplate is much cleaner. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D97614
1 parent e745f7c commit 82289aa

File tree

4 files changed

+239
-358
lines changed

4 files changed

+239
-358
lines changed

clang-tools-extra/clang-tidy/ClangTidyCheck.cpp

Lines changed: 63 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,6 @@
1515
namespace clang {
1616
namespace 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-
4218
ClangTidyCheck::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>
7955
ClangTidyCheck::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

8662
static 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>
10177
ClangTidyCheck::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

12297
template <>
123-
llvm::Expected<bool>
98+
llvm::Optional<bool>
12499
ClangTidyCheck::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

141108
template <>
142-
llvm::Expected<bool>
109+
llvm::Optional<bool>
143110
ClangTidyCheck::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

160120
void 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

Comments
 (0)