[PATCH] D106243: [Utils] Support class template specializations in update_cc_test_checks
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG0e79a94836d7: [Utils] Support class template specializations in update_cc_test_checks (authored by jrtc27). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D106243/new/ https://reviews.llvm.org/D106243 Files: clang/test/utils/update_cc_test_checks/Inputs/explicit-template-instantiation.cpp clang/test/utils/update_cc_test_checks/Inputs/explicit-template-instantiation.cpp.expected clang/test/utils/update_cc_test_checks/explicit-template-instantiation.test llvm/utils/update_cc_test_checks.py Index: llvm/utils/update_cc_test_checks.py === --- llvm/utils/update_cc_test_checks.py +++ llvm/utils/update_cc_test_checks.py @@ -33,8 +33,8 @@ '%clangxx': ['--driver-mode=g++'], } -def get_line2spell_and_mangled(args, clang_args): - ret = {} +def get_line2func_list(args, clang_args): + ret = collections.defaultdict(list) # Use clang's JSON AST dump to get the mangled name json_dump_args = [args.clang] + clang_args + ['-fsyntax-only', '-o', '-'] if '-cc1' not in json_dump_args: @@ -55,26 +55,37 @@ # Parse the clang JSON and add all children of type FunctionDecl. # TODO: Should we add checks for global variables being emitted? - def parse_clang_ast_json(node): + def parse_clang_ast_json(node, loc, search): node_kind = node['kind'] # Recurse for the following nodes that can contain nested function decls: if node_kind in ('NamespaceDecl', 'LinkageSpecDecl', 'TranslationUnitDecl', - 'CXXRecordDecl'): + 'CXXRecordDecl', 'ClassTemplateSpecializationDecl'): + # Specializations must use the loc from the specialization, not the + # template, and search for the class's spelling as the specialization + # does not mention the method names in the source. + if node_kind == 'ClassTemplateSpecializationDecl': +inner_loc = node['loc'] +inner_search = node['name'] + else: +inner_loc = None +inner_search = None if 'inner' in node: for inner in node['inner']: - parse_clang_ast_json(inner) + parse_clang_ast_json(inner, inner_loc, inner_search) # Otherwise we ignore everything except functions: if node_kind not in ('FunctionDecl', 'CXXMethodDecl', 'CXXConstructorDecl', 'CXXDestructorDecl', 'CXXConversionDecl'): return +if loc is None: + loc = node['loc'] if node.get('isImplicit') is True and node.get('storageClass') == 'extern': - common.debug('Skipping builtin function:', node['name'], '@', node['loc']) + common.debug('Skipping builtin function:', node['name'], '@', loc) return -common.debug('Found function:', node['kind'], node['name'], '@', node['loc']) -line = node['loc'].get('line') +common.debug('Found function:', node['kind'], node['name'], '@', loc) +line = loc.get('line') # If there is no line it is probably a builtin function -> skip if line is None: - common.debug('Skipping function without line number:', node['name'], '@', node['loc']) + common.debug('Skipping function without line number:', node['name'], '@', loc) return # If there is no 'inner' object, it is a function declaration and we can @@ -88,20 +99,23 @@ has_body = True break if not has_body: - common.debug('Skipping function without body:', node['name'], '@', node['loc']) + common.debug('Skipping function without body:', node['name'], '@', loc) return spell = node['name'] +if search is None: + search = spell mangled = node.get('mangledName', spell) -ret[int(line)-1] = (spell, mangled) +ret[int(line)-1].append((spell, mangled, search)) ast = json.loads(stdout) if ast['kind'] != 'TranslationUnitDecl': common.error('Clang AST dump JSON format changed?') sys.exit(2) - parse_clang_ast_json(ast) + parse_clang_ast_json(ast, None, None) - for line, func_name in sorted(ret.items()): -common.debug('line {}: found function {}'.format(line+1, func_name), file=sys.stderr) + for line, funcs in sorted(ret.items()): +for func in funcs: + common.debug('line {}: found function {}'.format(line+1, func), file=sys.stderr) if not ret: common.warn('Did not find any functions using', ' '.join(json_dump_args)) return ret @@ -222,7 +236,7 @@ comment_prefix='//', argparse_callback=infer_dependent_args): # Build a list of filechecked and non-filechecked RUN lines. run_list = [] -line2spell_and_mangled_list = collections.defaultdict(list) +line2func_list = collections.defaultdict(list) subs = { '%s' : ti.path, @@ -296,8 +310,8 @@ # Invoke clang -Xclang
[PATCH] D106243: [Utils] Support class template specializations in update_cc_test_checks
arichardson accepted this revision. arichardson added a comment. This revision is now accepted and ready to land. LGTM Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D106243/new/ https://reviews.llvm.org/D106243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D106243: [Utils] Support class template specializations in update_cc_test_checks
jrtc27 updated this revision to Diff 359643. jrtc27 added a comment. Drop the --llvm-bin test; only basic-cplusplus.test does that (which happened to be the one I used as a reference), and that only needs to be done for one file as it has no relation to the input. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D106243/new/ https://reviews.llvm.org/D106243 Files: clang/test/utils/update_cc_test_checks/Inputs/explicit-template-instantiation.cpp clang/test/utils/update_cc_test_checks/Inputs/explicit-template-instantiation.cpp.expected clang/test/utils/update_cc_test_checks/explicit-template-instantiation.test llvm/utils/update_cc_test_checks.py Index: llvm/utils/update_cc_test_checks.py === --- llvm/utils/update_cc_test_checks.py +++ llvm/utils/update_cc_test_checks.py @@ -33,8 +33,8 @@ '%clangxx': ['--driver-mode=g++'], } -def get_line2spell_and_mangled(args, clang_args): - ret = {} +def get_line2func_list(args, clang_args): + ret = collections.defaultdict(list) # Use clang's JSON AST dump to get the mangled name json_dump_args = [args.clang] + clang_args + ['-fsyntax-only', '-o', '-'] if '-cc1' not in json_dump_args: @@ -55,26 +55,37 @@ # Parse the clang JSON and add all children of type FunctionDecl. # TODO: Should we add checks for global variables being emitted? - def parse_clang_ast_json(node): + def parse_clang_ast_json(node, loc, search): node_kind = node['kind'] # Recurse for the following nodes that can contain nested function decls: if node_kind in ('NamespaceDecl', 'LinkageSpecDecl', 'TranslationUnitDecl', - 'CXXRecordDecl'): + 'CXXRecordDecl', 'ClassTemplateSpecializationDecl'): + # Specializations must use the loc from the specialization, not the + # template, and search for the class's spelling as the specialization + # does not mention the method names in the source. + if node_kind == 'ClassTemplateSpecializationDecl': +inner_loc = node['loc'] +inner_search = node['name'] + else: +inner_loc = None +inner_search = None if 'inner' in node: for inner in node['inner']: - parse_clang_ast_json(inner) + parse_clang_ast_json(inner, inner_loc, inner_search) # Otherwise we ignore everything except functions: if node_kind not in ('FunctionDecl', 'CXXMethodDecl', 'CXXConstructorDecl', 'CXXDestructorDecl', 'CXXConversionDecl'): return +if loc is None: + loc = node['loc'] if node.get('isImplicit') is True and node.get('storageClass') == 'extern': - common.debug('Skipping builtin function:', node['name'], '@', node['loc']) + common.debug('Skipping builtin function:', node['name'], '@', loc) return -common.debug('Found function:', node['kind'], node['name'], '@', node['loc']) -line = node['loc'].get('line') +common.debug('Found function:', node['kind'], node['name'], '@', loc) +line = loc.get('line') # If there is no line it is probably a builtin function -> skip if line is None: - common.debug('Skipping function without line number:', node['name'], '@', node['loc']) + common.debug('Skipping function without line number:', node['name'], '@', loc) return # If there is no 'inner' object, it is a function declaration and we can @@ -88,20 +99,23 @@ has_body = True break if not has_body: - common.debug('Skipping function without body:', node['name'], '@', node['loc']) + common.debug('Skipping function without body:', node['name'], '@', loc) return spell = node['name'] +if search is None: + search = spell mangled = node.get('mangledName', spell) -ret[int(line)-1] = (spell, mangled) +ret[int(line)-1].append((spell, mangled, search)) ast = json.loads(stdout) if ast['kind'] != 'TranslationUnitDecl': common.error('Clang AST dump JSON format changed?') sys.exit(2) - parse_clang_ast_json(ast) + parse_clang_ast_json(ast, None, None) - for line, func_name in sorted(ret.items()): -common.debug('line {}: found function {}'.format(line+1, func_name), file=sys.stderr) + for line, funcs in sorted(ret.items()): +for func in funcs: + common.debug('line {}: found function {}'.format(line+1, func), file=sys.stderr) if not ret: common.warn('Did not find any functions using', ' '.join(json_dump_args)) return ret @@ -222,7 +236,7 @@ comment_prefix='//', argparse_callback=infer_dependent_args): # Build a list of filechecked and non-filechecked RUN lines. run_list = [] -line2spell_and_mangled_list = collections.defaultdict(list) +line2func_list = collections.defaultdict(list) subs = { '%s' : ti.path, @@ -296,8 +310,8 @@ # Invoke cla
[PATCH] D106243: [Utils] Support class template specializations in update_cc_test_checks
jrtc27 created this revision. jrtc27 added reviewers: arichardson, jdoerfert. jrtc27 requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits. ClassTemplateSpecializationDecl not within a ClassTemplateDecl represents an explicit instatiation of a template and so should be handled as if it were a normal CXXRecordDecl. Unfortunately, having an equivalent for FunctionTemplateDecl remains a TODO in ASTDumper's VisitFunctionTemplateDecl, with all the explicit instantiations just being emitted inside the FunctionTemplateDecl along with all the other specializations, meaning we can't easily support explicit function instantiations in update_cc_test_checks. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D106243 Files: clang/test/utils/update_cc_test_checks/Inputs/explicit-template-instantiation.cpp clang/test/utils/update_cc_test_checks/Inputs/explicit-template-instantiation.cpp.expected clang/test/utils/update_cc_test_checks/explicit-template-instantiation.test llvm/utils/update_cc_test_checks.py Index: llvm/utils/update_cc_test_checks.py === --- llvm/utils/update_cc_test_checks.py +++ llvm/utils/update_cc_test_checks.py @@ -33,8 +33,8 @@ '%clangxx': ['--driver-mode=g++'], } -def get_line2spell_and_mangled(args, clang_args): - ret = {} +def get_line2func_list(args, clang_args): + ret = collections.defaultdict(list) # Use clang's JSON AST dump to get the mangled name json_dump_args = [args.clang] + clang_args + ['-fsyntax-only', '-o', '-'] if '-cc1' not in json_dump_args: @@ -55,26 +55,37 @@ # Parse the clang JSON and add all children of type FunctionDecl. # TODO: Should we add checks for global variables being emitted? - def parse_clang_ast_json(node): + def parse_clang_ast_json(node, loc, search): node_kind = node['kind'] # Recurse for the following nodes that can contain nested function decls: if node_kind in ('NamespaceDecl', 'LinkageSpecDecl', 'TranslationUnitDecl', - 'CXXRecordDecl'): + 'CXXRecordDecl', 'ClassTemplateSpecializationDecl'): + # Specializations must use the loc from the specialization, not the + # template, and search for the class's spelling as the specialization + # does not mention the method names in the source. + if node_kind == 'ClassTemplateSpecializationDecl': +inner_loc = node['loc'] +inner_search = node['name'] + else: +inner_loc = None +inner_search = None if 'inner' in node: for inner in node['inner']: - parse_clang_ast_json(inner) + parse_clang_ast_json(inner, inner_loc, inner_search) # Otherwise we ignore everything except functions: if node_kind not in ('FunctionDecl', 'CXXMethodDecl', 'CXXConstructorDecl', 'CXXDestructorDecl', 'CXXConversionDecl'): return +if loc is None: + loc = node['loc'] if node.get('isImplicit') is True and node.get('storageClass') == 'extern': - common.debug('Skipping builtin function:', node['name'], '@', node['loc']) + common.debug('Skipping builtin function:', node['name'], '@', loc) return -common.debug('Found function:', node['kind'], node['name'], '@', node['loc']) -line = node['loc'].get('line') +common.debug('Found function:', node['kind'], node['name'], '@', loc) +line = loc.get('line') # If there is no line it is probably a builtin function -> skip if line is None: - common.debug('Skipping function without line number:', node['name'], '@', node['loc']) + common.debug('Skipping function without line number:', node['name'], '@', loc) return # If there is no 'inner' object, it is a function declaration and we can @@ -88,20 +99,23 @@ has_body = True break if not has_body: - common.debug('Skipping function without body:', node['name'], '@', node['loc']) + common.debug('Skipping function without body:', node['name'], '@', loc) return spell = node['name'] +if search is None: + search = spell mangled = node.get('mangledName', spell) -ret[int(line)-1] = (spell, mangled) +ret[int(line)-1].append((spell, mangled, search)) ast = json.loads(stdout) if ast['kind'] != 'TranslationUnitDecl': common.error('Clang AST dump JSON format changed?') sys.exit(2) - parse_clang_ast_json(ast) + parse_clang_ast_json(ast, None, None) - for line, func_name in sorted(ret.items()): -common.debug('line {}: found function {}'.format(line+1, func_name), file=sys.stderr) + for line, funcs in sorted(ret.items()): +for func in funcs: + common.debug('line {}: found function {}'.format(line+1, func), file=sys.stderr) if not ret: common.warn('Did not find any functions using', ' '.join(json_dump_args)) return ret @@ -