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