12
12
#include " mlir/Pass/PassManager.h"
13
13
#include " llvm/ADT/DenseMap.h"
14
14
#include " llvm/ADT/ScopeExit.h"
15
+ #include " llvm/ADT/StringRef.h"
15
16
#include " llvm/Support/Format.h"
16
17
#include " llvm/Support/ManagedStatic.h"
17
18
#include " llvm/Support/MemoryBuffer.h"
@@ -185,6 +186,31 @@ const PassPipelineInfo *mlir::PassPipelineInfo::lookup(StringRef pipelineArg) {
185
186
// PassOptions
186
187
// ===----------------------------------------------------------------------===//
187
188
189
+ // / Extract an argument from 'options' and update it to point after the arg.
190
+ // / Returns the cleaned argument string.
191
+ static StringRef extractArgAndUpdateOptions (StringRef &options,
192
+ size_t argSize) {
193
+ StringRef str = options.take_front (argSize).trim ();
194
+ options = options.drop_front (argSize).ltrim ();
195
+
196
+ // Early exit if there's no escape sequence.
197
+ if (str.size () <= 2 )
198
+ return str;
199
+
200
+ const auto escapePairs = {std::make_pair (' \' ' , ' \' ' ),
201
+ std::make_pair (' "' , ' "' ), std::make_pair (' {' , ' }' )};
202
+ for (const auto &escape : escapePairs) {
203
+ if (str.front () == escape.first && str.back () == escape.second ) {
204
+ // Drop the escape characters and trim.
205
+ str = str.drop_front ().drop_back ().trim ();
206
+ // Don't process additional escape sequences.
207
+ break ;
208
+ }
209
+ }
210
+
211
+ return str;
212
+ }
213
+
188
214
LogicalResult detail::pass_options::parseCommaSeparatedList (
189
215
llvm::cl::Option &opt, StringRef argName, StringRef optionStr,
190
216
function_ref<LogicalResult(StringRef)> elementParseFn) {
@@ -213,13 +239,16 @@ LogicalResult detail::pass_options::parseCommaSeparatedList(
213
239
size_t nextElePos = findChar (optionStr, 0 , ' ,' );
214
240
while (nextElePos != StringRef::npos) {
215
241
// Process the portion before the comma.
216
- if (failed (elementParseFn (optionStr.substr (0 , nextElePos))))
242
+ if (failed (
243
+ elementParseFn (extractArgAndUpdateOptions (optionStr, nextElePos))))
217
244
return failure ();
218
245
219
- optionStr = optionStr.substr (nextElePos + 1 );
246
+ // Drop the leading ','
247
+ optionStr = optionStr.drop_front ();
220
248
nextElePos = findChar (optionStr, 0 , ' ,' );
221
249
}
222
- return elementParseFn (optionStr.substr (0 , nextElePos));
250
+ return elementParseFn (
251
+ extractArgAndUpdateOptions (optionStr, optionStr.size ()));
223
252
}
224
253
225
254
// / Out of line virtual function to provide home for the class.
@@ -239,27 +268,6 @@ void detail::PassOptions::copyOptionValuesFrom(const PassOptions &other) {
239
268
// / `options` string pointing after the parsed option].
240
269
static std::tuple<StringRef, StringRef, StringRef>
241
270
parseNextArg (StringRef options) {
242
- // Functor used to extract an argument from 'options' and update it to point
243
- // after the arg.
244
- auto extractArgAndUpdateOptions = [&](size_t argSize) {
245
- StringRef str = options.take_front (argSize).trim ();
246
- options = options.drop_front (argSize).ltrim ();
247
- // Handle escape sequences
248
- if (str.size () > 2 ) {
249
- const auto escapePairs = {std::make_pair (' \' ' , ' \' ' ),
250
- std::make_pair (' "' , ' "' ),
251
- std::make_pair (' {' , ' }' )};
252
- for (const auto &escape : escapePairs) {
253
- if (str.front () == escape.first && str.back () == escape.second ) {
254
- // Drop the escape characters and trim.
255
- str = str.drop_front ().drop_back ().trim ();
256
- // Don't process additional escape sequences.
257
- break ;
258
- }
259
- }
260
- }
261
- return str;
262
- };
263
271
// Try to process the given punctuation, properly escaping any contained
264
272
// characters.
265
273
auto tryProcessPunct = [&](size_t ¤tPos, char punct) {
@@ -276,13 +284,13 @@ parseNextArg(StringRef options) {
276
284
for (size_t argEndIt = 0 , optionsE = options.size ();; ++argEndIt) {
277
285
// Check for the end of the full option.
278
286
if (argEndIt == optionsE || options[argEndIt] == ' ' ) {
279
- argName = extractArgAndUpdateOptions (argEndIt);
287
+ argName = extractArgAndUpdateOptions (options, argEndIt);
280
288
return std::make_tuple (argName, StringRef (), options);
281
289
}
282
290
283
291
// Check for the end of the name and the start of the value.
284
292
if (options[argEndIt] == ' =' ) {
285
- argName = extractArgAndUpdateOptions (argEndIt);
293
+ argName = extractArgAndUpdateOptions (options, argEndIt);
286
294
options = options.drop_front ();
287
295
break ;
288
296
}
@@ -292,7 +300,7 @@ parseNextArg(StringRef options) {
292
300
for (size_t argEndIt = 0 , optionsE = options.size ();; ++argEndIt) {
293
301
// Handle the end of the options string.
294
302
if (argEndIt == optionsE || options[argEndIt] == ' ' ) {
295
- StringRef value = extractArgAndUpdateOptions (argEndIt);
303
+ StringRef value = extractArgAndUpdateOptions (options, argEndIt);
296
304
return std::make_tuple (argName, value, options);
297
305
}
298
306
@@ -344,7 +352,7 @@ LogicalResult detail::PassOptions::parseFromString(StringRef options,
344
352
345
353
// / Print the options held by this struct in a form that can be parsed via
346
354
// / 'parseFromString'.
347
- void detail::PassOptions::print (raw_ostream &os) {
355
+ void detail::PassOptions::print (raw_ostream &os) const {
348
356
// If there are no options, there is nothing left to do.
349
357
if (OptionsMap.empty ())
350
358
return ;
0 commit comments