15
15
namespace clang {
16
16
namespace tidy {
17
17
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
-
42
18
ClangTidyCheck::ClangTidyCheck (StringRef CheckName, ClangTidyContext *Context)
43
19
: CheckName(CheckName), Context(Context),
44
20
Options (CheckName, Context->getOptions ().CheckOptions, Context) {
@@ -75,12 +51,12 @@ ClangTidyCheck::OptionsView::OptionsView(
75
51
: NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions),
76
52
Context(Context) {}
77
53
78
- llvm::Expected <std::string>
54
+ llvm::Optional <std::string>
79
55
ClangTidyCheck::OptionsView::get (StringRef LocalName) const {
80
56
const auto &Iter = CheckOptions.find (NamePrefix + LocalName.str ());
81
57
if (Iter != CheckOptions.end ())
82
58
return Iter->getValue ().Value ;
83
- return llvm::make_error<MissingOptionError>((NamePrefix + LocalName). str ()) ;
59
+ return None ;
84
60
}
85
61
86
62
static ClangTidyOptions::OptionMap::const_iterator
@@ -97,16 +73,16 @@ findPriorityOption(const ClangTidyOptions::OptionMap &Options, StringRef NamePre
97
73
return IterGlobal;
98
74
}
99
75
100
- llvm::Expected <std::string>
76
+ llvm::Optional <std::string>
101
77
ClangTidyCheck::OptionsView::getLocalOrGlobal (StringRef LocalName) const {
102
78
auto Iter = findPriorityOption (CheckOptions, NamePrefix, LocalName);
103
79
if (Iter != CheckOptions.end ())
104
80
return Iter->getValue ().Value ;
105
- return llvm::make_error<MissingOptionError>((NamePrefix + LocalName). str ()) ;
81
+ return None ;
106
82
}
107
83
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) {
110
86
111
87
if (llvm::Optional<bool > Parsed = llvm::yaml::parseBool (Value))
112
88
return *Parsed;
@@ -115,46 +91,30 @@ static llvm::Expected<bool> getAsBool(StringRef Value,
115
91
long long Number;
116
92
if (!Value.getAsInteger (10 , Number))
117
93
return Number != 0 ;
118
- return llvm::make_error<UnparseableIntegerOptionError>(LookupName.str (),
119
- Value.str (), true );
94
+ return None;
120
95
}
121
96
122
97
template <>
123
- llvm::Expected <bool >
98
+ llvm::Optional <bool >
124
99
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;
139
106
}
140
107
141
108
template <>
142
- llvm::Expected <bool >
109
+ llvm::Optional <bool >
143
110
ClangTidyCheck::OptionsView::getLocalOrGlobal<bool >(StringRef LocalName) const {
144
111
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;
158
118
}
159
119
160
120
void ClangTidyCheck::OptionsView::store (ClangTidyOptions::OptionMap &Options,
@@ -176,14 +136,14 @@ void ClangTidyCheck::OptionsView::store<bool>(
176
136
store (Options, LocalName, Value ? StringRef (" true" ) : StringRef (" false" ));
177
137
}
178
138
179
- llvm::Expected <int64_t > ClangTidyCheck::OptionsView::getEnumInt (
139
+ llvm::Optional <int64_t > ClangTidyCheck::OptionsView::getEnumInt (
180
140
StringRef LocalName, ArrayRef<NameAndValue> Mapping, bool CheckGlobal,
181
141
bool IgnoreCase) const {
182
142
auto Iter = CheckGlobal
183
143
? findPriorityOption (CheckOptions, NamePrefix, LocalName)
184
144
: CheckOptions.find ((NamePrefix + LocalName).str ());
185
145
if (Iter == CheckOptions.end ())
186
- return llvm::make_error<MissingOptionError>((NamePrefix + LocalName). str ()) ;
146
+ return None ;
187
147
188
148
StringRef Value = Iter->getValue ().Value ;
189
149
StringRef Closest;
@@ -206,39 +166,54 @@ llvm::Expected<int64_t> ClangTidyCheck::OptionsView::getEnumInt(
206
166
}
207
167
}
208
168
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;
213
174
}
214
175
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 ;
220
185
}
221
186
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 ;
230
192
}
231
193
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 ;
238
201
else
239
- consumeError (ValueOr.takeError ());
240
- return llvm::None;
202
+ Diag << 3 << Suggestion;
241
203
}
242
204
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
+ }
243
218
} // namespace tidy
244
219
} // namespace clang
0 commit comments