1212#include " mlir/Pass/PassManager.h"
1313#include " llvm/ADT/DenseMap.h"
1414#include " llvm/ADT/ScopeExit.h"
15+ #include " llvm/ADT/StringRef.h"
1516#include " llvm/Support/Format.h"
1617#include " llvm/Support/ManagedStatic.h"
1718#include " llvm/Support/MemoryBuffer.h"
@@ -185,6 +186,31 @@ const PassPipelineInfo *mlir::PassPipelineInfo::lookup(StringRef pipelineArg) {
185186// PassOptions
186187// ===----------------------------------------------------------------------===//
187188
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+
188214LogicalResult detail::pass_options::parseCommaSeparatedList (
189215 llvm::cl::Option &opt, StringRef argName, StringRef optionStr,
190216 function_ref<LogicalResult(StringRef)> elementParseFn) {
@@ -213,13 +239,16 @@ LogicalResult detail::pass_options::parseCommaSeparatedList(
213239 size_t nextElePos = findChar (optionStr, 0 , ' ,' );
214240 while (nextElePos != StringRef::npos) {
215241 // Process the portion before the comma.
216- if (failed (elementParseFn (optionStr.substr (0 , nextElePos))))
242+ if (failed (
243+ elementParseFn (extractArgAndUpdateOptions (optionStr, nextElePos))))
217244 return failure ();
218245
219- optionStr = optionStr.substr (nextElePos + 1 );
246+ // Drop the leading ','
247+ optionStr = optionStr.drop_front ();
220248 nextElePos = findChar (optionStr, 0 , ' ,' );
221249 }
222- return elementParseFn (optionStr.substr (0 , nextElePos));
250+ return elementParseFn (
251+ extractArgAndUpdateOptions (optionStr, optionStr.size ()));
223252}
224253
225254// / Out of line virtual function to provide home for the class.
@@ -239,27 +268,6 @@ void detail::PassOptions::copyOptionValuesFrom(const PassOptions &other) {
239268// / `options` string pointing after the parsed option].
240269static std::tuple<StringRef, StringRef, StringRef>
241270parseNextArg (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- };
263271 // Try to process the given punctuation, properly escaping any contained
264272 // characters.
265273 auto tryProcessPunct = [&](size_t ¤tPos, char punct) {
@@ -276,13 +284,13 @@ parseNextArg(StringRef options) {
276284 for (size_t argEndIt = 0 , optionsE = options.size ();; ++argEndIt) {
277285 // Check for the end of the full option.
278286 if (argEndIt == optionsE || options[argEndIt] == ' ' ) {
279- argName = extractArgAndUpdateOptions (argEndIt);
287+ argName = extractArgAndUpdateOptions (options, argEndIt);
280288 return std::make_tuple (argName, StringRef (), options);
281289 }
282290
283291 // Check for the end of the name and the start of the value.
284292 if (options[argEndIt] == ' =' ) {
285- argName = extractArgAndUpdateOptions (argEndIt);
293+ argName = extractArgAndUpdateOptions (options, argEndIt);
286294 options = options.drop_front ();
287295 break ;
288296 }
@@ -292,7 +300,7 @@ parseNextArg(StringRef options) {
292300 for (size_t argEndIt = 0 , optionsE = options.size ();; ++argEndIt) {
293301 // Handle the end of the options string.
294302 if (argEndIt == optionsE || options[argEndIt] == ' ' ) {
295- StringRef value = extractArgAndUpdateOptions (argEndIt);
303+ StringRef value = extractArgAndUpdateOptions (options, argEndIt);
296304 return std::make_tuple (argName, value, options);
297305 }
298306
@@ -344,7 +352,7 @@ LogicalResult detail::PassOptions::parseFromString(StringRef options,
344352
345353// / Print the options held by this struct in a form that can be parsed via
346354// / 'parseFromString'.
347- void detail::PassOptions::print (raw_ostream &os) {
355+ void detail::PassOptions::print (raw_ostream &os) const {
348356 // If there are no options, there is nothing left to do.
349357 if (OptionsMap.empty ())
350358 return ;
0 commit comments