[PATCH] D106243: [Utils] Support class template specializations in update_cc_test_checks

2021-07-28 Thread Jessica Clarke via Phabricator via cfe-commits
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

2021-07-18 Thread Alexander Richardson via Phabricator via cfe-commits
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

2021-07-18 Thread Jessica Clarke via Phabricator via cfe-commits
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

2021-07-18 Thread Jessica Clarke via Phabricator via cfe-commits
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
@@ -