clang-tools  9.0.0
run-find-all-symbols.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 #=- run-find-all-symbols.py - Parallel find-all-symbols runner -*- python -*-=#
4 #
5 # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6 # See https://llvm.org/LICENSE.txt for license information.
7 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 #
9 #===------------------------------------------------------------------------===#
10 
11 """
12 Parallel find-all-symbols runner
13 ================================
14 
15 Runs find-all-symbols over all files in a compilation database.
16 
17 Example invocations.
18 - Run find-all-symbols on all files in the current working directory.
19  run-find-all-symbols.py <source-file>
20 
21 Compilation database setup:
22 http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
23 """
24 
25 import argparse
26 import json
27 import multiprocessing
28 import os
29 import Queue
30 import shutil
31 import subprocess
32 import sys
33 import tempfile
34 import threading
35 
36 
38  """Adjusts the directory until a compilation database is found."""
39  result = './'
40  while not os.path.isfile(os.path.join(result, path)):
41  if os.path.realpath(result) == '/':
42  print 'Error: could not find compilation database.'
43  sys.exit(1)
44  result += '../'
45  return os.path.realpath(result)
46 
47 
48 def MergeSymbols(directory, args):
49  """Merge all symbol files (yaml) in a given directaory into a single file."""
50  invocation = [args.binary, '-merge-dir='+directory, args.saving_path]
51  subprocess.call(invocation)
52  print 'Merge is finished. Saving results in ' + args.saving_path
53 
54 
55 def run_find_all_symbols(args, tmpdir, build_path, queue):
56  """Takes filenames out of queue and runs find-all-symbols on them."""
57  while True:
58  name = queue.get()
59  invocation = [args.binary, name, '-output-dir='+tmpdir, '-p='+build_path]
60  sys.stdout.write(' '.join(invocation) + '\n')
61  subprocess.call(invocation)
62  queue.task_done()
63 
64 
65 def main():
66  parser = argparse.ArgumentParser(description='Runs find-all-symbols over all'
67  'files in a compilation database.')
68  parser.add_argument('-binary', metavar='PATH',
69  default='./bin/find-all-symbols',
70  help='path to find-all-symbols binary')
71  parser.add_argument('-j', type=int, default=0,
72  help='number of instances to be run in parallel.')
73  parser.add_argument('-p', dest='build_path',
74  help='path used to read a compilation database.')
75  parser.add_argument('-saving-path', default='./find_all_symbols_db.yaml',
76  help='result saving path')
77  args = parser.parse_args()
78 
79  db_path = 'compile_commands.json'
80 
81  if args.build_path is not None:
82  build_path = args.build_path
83  else:
84  build_path = find_compilation_database(db_path)
85 
86  tmpdir = tempfile.mkdtemp()
87 
88  # Load the database and extract all files.
89  database = json.load(open(os.path.join(build_path, db_path)))
90  files = [entry['file'] for entry in database]
91 
92  max_task = args.j
93  if max_task == 0:
94  max_task = multiprocessing.cpu_count()
95 
96  try:
97  # Spin up a bunch of tidy-launching threads.
98  queue = Queue.Queue(max_task)
99  for _ in range(max_task):
100  t = threading.Thread(target=run_find_all_symbols,
101  args=(args, tmpdir, build_path, queue))
102  t.daemon = True
103  t.start()
104 
105  # Fill the queue with files.
106  for name in files:
107  queue.put(name)
108 
109  # Wait for all threads to be done.
110  queue.join()
111 
112  MergeSymbols(tmpdir, args)
113 
114 
115  except KeyboardInterrupt:
116  # This is a sad hack. Unfortunately subprocess goes
117  # bonkers with ctrl-c and we start forking merrily.
118  print '\nCtrl-C detected, goodbye.'
119  os.kill(0, 9)
120 
121 
122 if __name__ == '__main__':
123  main()
def run_find_all_symbols(args, tmpdir, build_path, queue)
def MergeSymbols(directory, args)
static std::string join(ArrayRef< SpecialMemberFunctionsCheck::SpecialMemberFunctionKind > SMFS, llvm::StringRef AndOr)