1from __future__ import print_function 2 3import copy 4import glob 5import re 6import subprocess 7import sys 8 9if sys.version_info[0] > 2: 10 class string: 11 expandtabs = str.expandtabs 12else: 13 import string 14 15##### Common utilities for update_*test_checks.py 16 17 18_verbose = False 19 20def parse_commandline_args(parser): 21 parser.add_argument('-v', '--verbose', action='store_true', 22 help='Show verbose output') 23 parser.add_argument('-u', '--update-only', action='store_true', 24 help='Only update test if it was already autogened') 25 parser.add_argument('--force-update', action='store_true', 26 help='Update test even if it was autogened by a different script') 27 parser.add_argument('--enable', action='store_true', dest='enabled', default=True, 28 help='Activate CHECK line generation from this point forward') 29 parser.add_argument('--disable', action='store_false', dest='enabled', 30 help='Deactivate CHECK line generation from this point forward') 31 args = parser.parse_args() 32 global _verbose 33 _verbose = args.verbose 34 return args 35 36 37class InputLineInfo(object): 38 def __init__(self, line, line_number, args, argv): 39 self.line = line 40 self.line_number = line_number 41 self.args = args 42 self.argv = argv 43 44 45class TestInfo(object): 46 def __init__(self, test, parser, script_name, input_lines, args, argv, 47 comment_prefix, argparse_callback): 48 self.parser = parser 49 self.argparse_callback = argparse_callback 50 self.path = test 51 self.args = args 52 self.argv = argv 53 self.input_lines = input_lines 54 self.run_lines = find_run_lines(test, self.input_lines) 55 self.comment_prefix = comment_prefix 56 if self.comment_prefix is None: 57 if self.path.endswith('.mir'): 58 self.comment_prefix = '#' 59 else: 60 self.comment_prefix = ';' 61 self.autogenerated_note_prefix = self.comment_prefix + ' ' + UTC_ADVERT 62 self.test_autogenerated_note = self.autogenerated_note_prefix + script_name 63 self.test_autogenerated_note += get_autogennote_suffix(parser, self.args) 64 65 def iterlines(self, output_lines): 66 output_lines.append(self.test_autogenerated_note) 67 for line_num, input_line in enumerate(self.input_lines): 68 # Discard any previous script advertising. 69 if input_line.startswith(self.autogenerated_note_prefix): 70 continue 71 self.args, self.argv = check_for_command(input_line, self.parser, 72 self.args, self.argv, self.argparse_callback) 73 if not self.args.enabled: 74 output_lines.append(input_line) 75 continue 76 yield InputLineInfo(input_line, line_num, self.args, self.argv) 77 78 79def itertests(test_patterns, parser, script_name, comment_prefix=None, argparse_callback=None): 80 for pattern in test_patterns: 81 # On Windows we must expand the patterns ourselves. 82 tests_list = glob.glob(pattern) 83 if not tests_list: 84 warn("Test file pattern '%s' was not found. Ignoring it." % (pattern,)) 85 continue 86 for test in tests_list: 87 with open(test) as f: 88 input_lines = [l.rstrip() for l in f] 89 args = parser.parse_args() 90 if argparse_callback is not None: 91 argparse_callback(args) 92 argv = sys.argv[:] 93 first_line = input_lines[0] if input_lines else "" 94 if UTC_ADVERT in first_line: 95 if script_name not in first_line and not args.force_update: 96 warn("Skipping test which wasn't autogenerated by " + script_name, test) 97 continue 98 args, argv = check_for_command(first_line, parser, args, argv, argparse_callback) 99 elif args.update_only: 100 assert UTC_ADVERT not in first_line 101 warn("Skipping test which isn't autogenerated: " + test) 102 continue 103 yield TestInfo(test, parser, script_name, input_lines, args, argv, 104 comment_prefix, argparse_callback) 105 106 107def should_add_line_to_output(input_line, prefix_set): 108 # Skip any blank comment lines in the IR. 109 if input_line.strip() == ';': 110 return False 111 # Skip any blank lines in the IR. 112 #if input_line.strip() == '': 113 # return False 114 # And skip any CHECK lines. We're building our own. 115 m = CHECK_RE.match(input_line) 116 if m and m.group(1) in prefix_set: 117 return False 118 119 return True 120 121# Invoke the tool that is being tested. 122def invoke_tool(exe, cmd_args, ir): 123 with open(ir) as ir_file: 124 # TODO Remove the str form which is used by update_test_checks.py and 125 # update_llc_test_checks.py 126 # The safer list form is used by update_cc_test_checks.py 127 if isinstance(cmd_args, list): 128 stdout = subprocess.check_output([exe] + cmd_args, stdin=ir_file) 129 else: 130 stdout = subprocess.check_output(exe + ' ' + cmd_args, 131 shell=True, stdin=ir_file) 132 if sys.version_info[0] > 2: 133 stdout = stdout.decode() 134 # Fix line endings to unix CR style. 135 return stdout.replace('\r\n', '\n') 136 137##### LLVM IR parser 138RUN_LINE_RE = re.compile(r'^\s*(?://|[;#])\s*RUN:\s*(.*)$') 139CHECK_PREFIX_RE = re.compile(r'--?check-prefix(?:es)?[= ](\S+)') 140PREFIX_RE = re.compile('^[a-zA-Z0-9_-]+$') 141CHECK_RE = re.compile(r'^\s*(?://|[;#])\s*([^:]+?)(?:-NEXT|-NOT|-DAG|-LABEL|-SAME|-EMPTY)?:') 142 143UTC_ARGS_KEY = 'UTC_ARGS:' 144UTC_ARGS_CMD = re.compile(r'.*' + UTC_ARGS_KEY + '\s*(?P<cmd>.*)\s*$') 145UTC_ADVERT = 'NOTE: Assertions have been autogenerated by ' 146 147OPT_FUNCTION_RE = re.compile( 148 r'^(\s*;\s*Function\sAttrs:\s(?P<attrs>[\w\s]+?))?\s*define\s+(?:internal\s+)?[^@]*@(?P<func>[\w.-]+?)\s*' 149 r'(?P<args_and_sig>\((\)|(.*?[\w.-]+?)\))[^{]*\{)\n(?P<body>.*?)^\}$', 150 flags=(re.M | re.S)) 151 152ANALYZE_FUNCTION_RE = re.compile( 153 r'^\s*\'(?P<analysis>[\w\s-]+?)\'\s+for\s+function\s+\'(?P<func>[\w.-]+?)\':' 154 r'\s*\n(?P<body>.*)$', 155 flags=(re.X | re.S)) 156 157IR_FUNCTION_RE = re.compile(r'^\s*define\s+(?:internal\s+)?[^@]*@([\w.-]+)\s*\(') 158TRIPLE_IR_RE = re.compile(r'^\s*target\s+triple\s*=\s*"([^"]+)"$') 159TRIPLE_ARG_RE = re.compile(r'-mtriple[= ]([^ ]+)') 160MARCH_ARG_RE = re.compile(r'-march[= ]([^ ]+)') 161 162SCRUB_LEADING_WHITESPACE_RE = re.compile(r'^(\s+)') 163SCRUB_WHITESPACE_RE = re.compile(r'(?!^(| \w))[ \t]+', flags=re.M) 164SCRUB_TRAILING_WHITESPACE_RE = re.compile(r'[ \t]+$', flags=re.M) 165SCRUB_TRAILING_WHITESPACE_TEST_RE = SCRUB_TRAILING_WHITESPACE_RE 166SCRUB_TRAILING_WHITESPACE_AND_ATTRIBUTES_RE = re.compile(r'([ \t]|(#[0-9]+))+$', flags=re.M) 167SCRUB_KILL_COMMENT_RE = re.compile(r'^ *#+ +kill:.*\n') 168SCRUB_LOOP_COMMENT_RE = re.compile( 169 r'# =>This Inner Loop Header:.*|# in Loop:.*', flags=re.M) 170SCRUB_TAILING_COMMENT_TOKEN_RE = re.compile(r'(?<=\S)+[ \t]*#$', flags=re.M) 171 172 173def error(msg, test_file=None): 174 if test_file: 175 msg = '{}: {}'.format(msg, test_file) 176 print('ERROR: {}'.format(msg), file=sys.stderr) 177 178def warn(msg, test_file=None): 179 if test_file: 180 msg = '{}: {}'.format(msg, test_file) 181 print('WARNING: {}'.format(msg), file=sys.stderr) 182 183def debug(*args, **kwargs): 184 # Python2 does not allow def debug(*args, file=sys.stderr, **kwargs): 185 if 'file' not in kwargs: 186 kwargs['file'] = sys.stderr 187 if _verbose: 188 print(*args, **kwargs) 189 190def find_run_lines(test, lines): 191 debug('Scanning for RUN lines in test file:', test) 192 raw_lines = [m.group(1) 193 for m in [RUN_LINE_RE.match(l) for l in lines] if m] 194 run_lines = [raw_lines[0]] if len(raw_lines) > 0 else [] 195 for l in raw_lines[1:]: 196 if run_lines[-1].endswith('\\'): 197 run_lines[-1] = run_lines[-1].rstrip('\\') + ' ' + l 198 else: 199 run_lines.append(l) 200 debug('Found {} RUN lines in {}:'.format(len(run_lines), test)) 201 for l in run_lines: 202 debug(' RUN: {}'.format(l)) 203 return run_lines 204 205def scrub_body(body): 206 # Scrub runs of whitespace out of the assembly, but leave the leading 207 # whitespace in place. 208 body = SCRUB_WHITESPACE_RE.sub(r' ', body) 209 # Expand the tabs used for indentation. 210 body = string.expandtabs(body, 2) 211 # Strip trailing whitespace. 212 body = SCRUB_TRAILING_WHITESPACE_TEST_RE.sub(r'', body) 213 return body 214 215def do_scrub(body, scrubber, scrubber_args, extra): 216 if scrubber_args: 217 local_args = copy.deepcopy(scrubber_args) 218 local_args[0].extra_scrub = extra 219 return scrubber(body, *local_args) 220 return scrubber(body, *scrubber_args) 221 222# Build up a dictionary of all the function bodies. 223class function_body(object): 224 def __init__(self, string, extra, args_and_sig, attrs): 225 self.scrub = string 226 self.extrascrub = extra 227 self.args_and_sig = args_and_sig 228 self.attrs = attrs 229 def is_same_except_arg_names(self, extrascrub, args_and_sig, attrs): 230 arg_names = set() 231 def drop_arg_names(match): 232 arg_names.add(match.group(3)) 233 return match.group(1) + match.group(match.lastindex) 234 def repl_arg_names(match): 235 if match.group(3) is not None and match.group(3) in arg_names: 236 return match.group(1) + match.group(match.lastindex) 237 return match.group(1) + match.group(2) + match.group(match.lastindex) 238 if self.attrs != attrs: 239 return False 240 ans0 = IR_VALUE_RE.sub(drop_arg_names, self.args_and_sig) 241 ans1 = IR_VALUE_RE.sub(drop_arg_names, args_and_sig) 242 if ans0 != ans1: 243 return False 244 es0 = IR_VALUE_RE.sub(repl_arg_names, self.extrascrub) 245 es1 = IR_VALUE_RE.sub(repl_arg_names, extrascrub) 246 es0 = SCRUB_IR_COMMENT_RE.sub(r'', es0) 247 es1 = SCRUB_IR_COMMENT_RE.sub(r'', es1) 248 return es0 == es1 249 250 def __str__(self): 251 return self.scrub 252 253def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_tool_output, prefixes, func_dict, verbose, record_args, check_attributes): 254 for m in function_re.finditer(raw_tool_output): 255 if not m: 256 continue 257 func = m.group('func') 258 body = m.group('body') 259 attrs = m.group('attrs') if check_attributes else '' 260 # Determine if we print arguments, the opening brace, or nothing after the function name 261 if record_args and 'args_and_sig' in m.groupdict(): 262 args_and_sig = scrub_body(m.group('args_and_sig').strip()) 263 elif 'args_and_sig' in m.groupdict(): 264 args_and_sig = '(' 265 else: 266 args_and_sig = '' 267 scrubbed_body = do_scrub(body, scrubber, scrubber_args, extra = False) 268 scrubbed_extra = do_scrub(body, scrubber, scrubber_args, extra = True) 269 if 'analysis' in m.groupdict(): 270 analysis = m.group('analysis') 271 if analysis.lower() != 'cost model analysis': 272 warn('Unsupported analysis mode: %r!' % (analysis,)) 273 if func.startswith('stress'): 274 # We only use the last line of the function body for stress tests. 275 scrubbed_body = '\n'.join(scrubbed_body.splitlines()[-1:]) 276 if verbose: 277 print('Processing function: ' + func, file=sys.stderr) 278 for l in scrubbed_body.splitlines(): 279 print(' ' + l, file=sys.stderr) 280 for prefix in prefixes: 281 if func in func_dict[prefix]: 282 if str(func_dict[prefix][func]) != scrubbed_body or (func_dict[prefix][func] and (func_dict[prefix][func].args_and_sig != args_and_sig or func_dict[prefix][func].attrs != attrs)): 283 if func_dict[prefix][func] and func_dict[prefix][func].is_same_except_arg_names(scrubbed_extra, args_and_sig, attrs): 284 func_dict[prefix][func].scrub = scrubbed_extra 285 func_dict[prefix][func].args_and_sig = args_and_sig 286 continue 287 else: 288 if prefix == prefixes[-1]: 289 warn('Found conflicting asm under the same prefix: %r!' % (prefix,)) 290 else: 291 func_dict[prefix][func] = None 292 continue 293 294 func_dict[prefix][func] = function_body(scrubbed_body, scrubbed_extra, args_and_sig, attrs) 295 296##### Generator of LLVM IR CHECK lines 297 298SCRUB_IR_COMMENT_RE = re.compile(r'\s*;.*') 299 300# TODO: We should also derive check lines for global, debug, loop declarations, etc.. 301 302class NamelessValue: 303 def __init__(self, check_prefix, ir_prefix, ir_regexp): 304 self.check_prefix = check_prefix 305 self.ir_prefix = ir_prefix 306 self.ir_regexp = ir_regexp 307 308# Description of the different "unnamed" values we match in the IR, e.g., 309# (local) ssa values, (debug) metadata, etc. 310nameless_values = [ 311 NamelessValue(r'TMP', r'%', r'[\w.-]+?'), 312 NamelessValue(r'GLOB', r'@', r'[0-9]+?'), 313 NamelessValue(r'ATTR', r'#', r'[0-9]+?'), 314 NamelessValue(r'DBG', r'!dbg !', r'[0-9]+?'), 315 NamelessValue(r'TBAA', r'!tbaa !', r'[0-9]+?'), 316 NamelessValue(r'RNG', r'!range !', r'[0-9]+?'), 317 NamelessValue(r'LOOP', r'!llvm.loop !', r'[0-9]+?'), 318 NamelessValue(r'META', r'metadata !', r'[0-9]+?'), 319] 320 321# Build the regexp that matches an "IR value". This can be a local variable, 322# argument, global, or metadata, anything that is "named". It is important that 323# the PREFIX and SUFFIX below only contain a single group, if that changes 324# other locations will need adjustment as well. 325IR_VALUE_REGEXP_PREFIX = r'(\s+)' 326IR_VALUE_REGEXP_STRING = r'' 327for nameless_value in nameless_values: 328 if IR_VALUE_REGEXP_STRING: 329 IR_VALUE_REGEXP_STRING += '|' 330 IR_VALUE_REGEXP_STRING += nameless_value.ir_prefix + r'(' + nameless_value.ir_regexp + r')' 331IR_VALUE_REGEXP_SUFFIX = r'([,\s\(\)]|\Z)' 332IR_VALUE_RE = re.compile(IR_VALUE_REGEXP_PREFIX + r'(' + IR_VALUE_REGEXP_STRING + r')' + IR_VALUE_REGEXP_SUFFIX) 333 334# The entire match is group 0, the prefix has one group (=1), the entire 335# IR_VALUE_REGEXP_STRING is one group (=2), and then the nameless values start. 336first_nameless_group_in_ir_value_match = 3 337 338# Check a match for IR_VALUE_RE and inspect it to determine if it was a local 339# value, %..., global @..., debug number !dbg !..., etc. See the PREFIXES above. 340def get_idx_from_ir_value_match(match): 341 for i in range(first_nameless_group_in_ir_value_match, match.lastindex): 342 if match.group(i) is not None: 343 return i - first_nameless_group_in_ir_value_match 344 error("Unable to identify the kind of IR value from the match!") 345 return 0; 346 347# See get_idx_from_ir_value_match 348def get_name_from_ir_value_match(match): 349 return match.group(get_idx_from_ir_value_match(match) + first_nameless_group_in_ir_value_match) 350 351# Return the nameless prefix we use for this kind or IR value, see also 352# get_idx_from_ir_value_match 353def get_nameless_check_prefix_from_ir_value_match(match): 354 return nameless_values[get_idx_from_ir_value_match(match)].check_prefix 355 356# Return the IR prefix we use for this kind or IR value, e.g., % for locals, 357# see also get_idx_from_ir_value_match 358def get_ir_prefix_from_ir_value_match(match): 359 return nameless_values[get_idx_from_ir_value_match(match)].ir_prefix 360 361# Return true if this kind or IR value is "local", basically if it matches '%{{.*}}'. 362def is_local_ir_value_match(match): 363 return nameless_values[get_idx_from_ir_value_match(match)].ir_prefix == '%' 364 365# Create a FileCheck variable name based on an IR name. 366def get_value_name(var, match): 367 if var.isdigit(): 368 var = get_nameless_check_prefix_from_ir_value_match(match) + var 369 var = var.replace('.', '_') 370 var = var.replace('-', '_') 371 return var.upper() 372 373# Create a FileCheck variable from regex. 374def get_value_definition(var, match): 375 return '[[' + get_value_name(var, match) + ':' + get_ir_prefix_from_ir_value_match(match) + '.*]]' 376 377# Use a FileCheck variable. 378def get_value_use(var, match): 379 return '[[' + get_value_name(var, match) + ']]' 380 381# Replace IR value defs and uses with FileCheck variables. 382def generalize_check_lines(lines, is_analyze, vars_seen, global_vars_seen): 383 # This gets called for each match that occurs in 384 # a line. We transform variables we haven't seen 385 # into defs, and variables we have seen into uses. 386 def transform_line_vars(match): 387 pre = get_ir_prefix_from_ir_value_match(match) 388 var = get_name_from_ir_value_match(match) 389 for nameless_value in nameless_values: 390 if re.match(r'^' + nameless_value.check_prefix + r'[0-9]+?$', var, re.IGNORECASE): 391 warn("Change IR value name '%s' to prevent possible conflict with scripted FileCheck name." % (var,)) 392 if (pre, var) in vars_seen or (pre, var) in global_vars_seen: 393 rv = get_value_use(var, match) 394 else: 395 if is_local_ir_value_match(match): 396 vars_seen.add((pre, var)) 397 else: 398 global_vars_seen.add((pre, var)) 399 rv = get_value_definition(var, match) 400 # re.sub replaces the entire regex match 401 # with whatever you return, so we have 402 # to make sure to hand it back everything 403 # including the commas and spaces. 404 return match.group(1) + rv + match.group(match.lastindex) 405 406 lines_with_def = [] 407 408 for i, line in enumerate(lines): 409 # An IR variable named '%.' matches the FileCheck regex string. 410 line = line.replace('%.', '%dot') 411 # Ignore any comments, since the check lines will too. 412 scrubbed_line = SCRUB_IR_COMMENT_RE.sub(r'', line) 413 lines[i] = scrubbed_line 414 if not is_analyze: 415 # It can happen that two matches are back-to-back and for some reason sub 416 # will not replace both of them. For now we work around this by 417 # substituting until there is no more match. 418 changed = True 419 while changed: 420 (lines[i], changed) = IR_VALUE_RE.subn(transform_line_vars, lines[i], count=1) 421 return lines 422 423 424def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, is_asm, is_analyze, global_vars_seen_dict): 425 # prefix_exclusions are prefixes we cannot use to print the function because it doesn't exist in run lines that use these prefixes as well. 426 prefix_exclusions = set() 427 printed_prefixes = [] 428 for p in prefix_list: 429 checkprefixes = p[0] 430 # If not all checkprefixes of this run line produced the function we cannot check for it as it does not 431 # exist for this run line. A subset of the check prefixes might know about the function but only because 432 # other run lines created it. 433 if any(map(lambda checkprefix: func_name not in func_dict[checkprefix], checkprefixes)): 434 prefix_exclusions |= set(checkprefixes) 435 continue 436 437 # prefix_exclusions is constructed, we can now emit the output 438 for p in prefix_list: 439 checkprefixes = p[0] 440 for checkprefix in checkprefixes: 441 if checkprefix in printed_prefixes: 442 break 443 444 # Check if the prefix is excluded. 445 if checkprefix in prefix_exclusions: 446 continue 447 448 # If we do not have output for this prefix we skip it. 449 if not func_dict[checkprefix][func_name]: 450 continue 451 452 # Add some space between different check prefixes, but not after the last 453 # check line (before the test code). 454 if is_asm: 455 if len(printed_prefixes) != 0: 456 output_lines.append(comment_marker) 457 458 if checkprefix not in global_vars_seen_dict: 459 global_vars_seen_dict[checkprefix] = set() 460 global_vars_seen = global_vars_seen_dict[checkprefix] 461 462 vars_seen = set() 463 printed_prefixes.append(checkprefix) 464 attrs = str(func_dict[checkprefix][func_name].attrs) 465 attrs = '' if attrs == 'None' else attrs 466 if attrs: 467 output_lines.append('%s %s: Function Attrs: %s' % (comment_marker, checkprefix, attrs)) 468 args_and_sig = str(func_dict[checkprefix][func_name].args_and_sig) 469 args_and_sig = generalize_check_lines([args_and_sig], is_analyze, vars_seen, global_vars_seen)[0] 470 if '[[' in args_and_sig: 471 output_lines.append(check_label_format % (checkprefix, func_name, '')) 472 output_lines.append('%s %s-SAME: %s' % (comment_marker, checkprefix, args_and_sig)) 473 else: 474 output_lines.append(check_label_format % (checkprefix, func_name, args_and_sig)) 475 func_body = str(func_dict[checkprefix][func_name]).splitlines() 476 477 # For ASM output, just emit the check lines. 478 if is_asm: 479 output_lines.append('%s %s: %s' % (comment_marker, checkprefix, func_body[0])) 480 for func_line in func_body[1:]: 481 if func_line.strip() == '': 482 output_lines.append('%s %s-EMPTY:' % (comment_marker, checkprefix)) 483 else: 484 output_lines.append('%s %s-NEXT: %s' % (comment_marker, checkprefix, func_line)) 485 break 486 487 # For IR output, change all defs to FileCheck variables, so we're immune 488 # to variable naming fashions. 489 func_body = generalize_check_lines(func_body, is_analyze, vars_seen, global_vars_seen) 490 491 # This could be selectively enabled with an optional invocation argument. 492 # Disabled for now: better to check everything. Be safe rather than sorry. 493 494 # Handle the first line of the function body as a special case because 495 # it's often just noise (a useless asm comment or entry label). 496 #if func_body[0].startswith("#") or func_body[0].startswith("entry:"): 497 # is_blank_line = True 498 #else: 499 # output_lines.append('%s %s: %s' % (comment_marker, checkprefix, func_body[0])) 500 # is_blank_line = False 501 502 is_blank_line = False 503 504 for func_line in func_body: 505 if func_line.strip() == '': 506 is_blank_line = True 507 continue 508 # Do not waste time checking IR comments. 509 func_line = SCRUB_IR_COMMENT_RE.sub(r'', func_line) 510 511 # Skip blank lines instead of checking them. 512 if is_blank_line: 513 output_lines.append('{} {}: {}'.format( 514 comment_marker, checkprefix, func_line)) 515 else: 516 output_lines.append('{} {}-NEXT: {}'.format( 517 comment_marker, checkprefix, func_line)) 518 is_blank_line = False 519 520 # Add space between different check prefixes and also before the first 521 # line of code in the test function. 522 output_lines.append(comment_marker) 523 break 524 525def add_ir_checks(output_lines, comment_marker, prefix_list, func_dict, 526 func_name, preserve_names, function_sig, global_vars_seen_dict): 527 # Label format is based on IR string. 528 function_def_regex = 'define {{[^@]+}}' if function_sig else '' 529 check_label_format = '{} %s-LABEL: {}@%s%s'.format(comment_marker, function_def_regex) 530 add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, 531 check_label_format, False, preserve_names, global_vars_seen_dict) 532 533def add_analyze_checks(output_lines, comment_marker, prefix_list, func_dict, func_name): 534 check_label_format = '{} %s-LABEL: \'%s%s\''.format(comment_marker) 535 global_vars_seen_dict = {} 536 add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, 537 check_label_format, False, True, global_vars_seen_dict) 538 539 540def check_prefix(prefix): 541 if not PREFIX_RE.match(prefix): 542 hint = "" 543 if ',' in prefix: 544 hint = " Did you mean '--check-prefixes=" + prefix + "'?" 545 warn(("Supplied prefix '%s' is invalid. Prefix must contain only alphanumeric characters, hyphens and underscores." + hint) % 546 (prefix)) 547 548 549def verify_filecheck_prefixes(fc_cmd): 550 fc_cmd_parts = fc_cmd.split() 551 for part in fc_cmd_parts: 552 if "check-prefix=" in part: 553 prefix = part.split('=', 1)[1] 554 check_prefix(prefix) 555 elif "check-prefixes=" in part: 556 prefixes = part.split('=', 1)[1].split(',') 557 for prefix in prefixes: 558 check_prefix(prefix) 559 if prefixes.count(prefix) > 1: 560 warn("Supplied prefix '%s' is not unique in the prefix list." % (prefix,)) 561 562 563def get_autogennote_suffix(parser, args): 564 autogenerated_note_args = '' 565 for action in parser._actions: 566 if not hasattr(args, action.dest): 567 continue # Ignore options such as --help that aren't included in args 568 # Ignore parameters such as paths to the binary or the list of tests 569 if action.dest in ('tests', 'update_only', 'opt_binary', 'llc_binary', 570 'clang', 'opt', 'llvm_bin', 'verbose'): 571 continue 572 value = getattr(args, action.dest) 573 if action.const is not None: # action stores a constant (usually True/False) 574 # Skip actions with different constant values (this happens with boolean 575 # --foo/--no-foo options) 576 if value != action.const: 577 continue 578 if parser.get_default(action.dest) == value: 579 continue # Don't add default values 580 autogenerated_note_args += action.option_strings[0] + ' ' 581 if action.const is None: # action takes a parameter 582 autogenerated_note_args += '%s ' % value 583 if autogenerated_note_args: 584 autogenerated_note_args = ' %s %s' % (UTC_ARGS_KEY, autogenerated_note_args[:-1]) 585 return autogenerated_note_args 586 587 588def check_for_command(line, parser, args, argv, argparse_callback): 589 cmd_m = UTC_ARGS_CMD.match(line) 590 if cmd_m: 591 cmd = cmd_m.group('cmd').strip().split(' ') 592 argv = argv + cmd 593 args = parser.parse_args(filter(lambda arg: arg not in args.tests, argv)) 594 if argparse_callback is not None: 595 argparse_callback(args) 596 return args, argv 597