1 #!/usr/bin/env python 2 3 #===- cindex-dump.py - cindex/Python Source Dump -------------*- 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 A simple command line tool for dumping a source file using the Clang Index 14 Library. 15 """ 16 17 def get_diag_info(diag): 18 return { 'severity' : diag.severity, 19 'location' : diag.location, 20 'spelling' : diag.spelling, 21 'ranges' : diag.ranges, 22 'fixits' : diag.fixits } 23 24 def get_cursor_id(cursor, cursor_list = []): 25 if not opts.showIDs: 26 return None 27 28 if cursor is None: 29 return None 30 31 # FIXME: This is really slow. It would be nice if the index API exposed 32 # something that let us hash cursors. 33 for i,c in enumerate(cursor_list): 34 if cursor == c: 35 return i 36 cursor_list.append(cursor) 37 return len(cursor_list) - 1 38 39 def get_info(node, depth=0): 40 if opts.maxDepth is not None and depth >= opts.maxDepth: 41 children = None 42 else: 43 children = [get_info(c, depth+1) 44 for c in node.get_children()] 45 return { 'id' : get_cursor_id(node), 46 'kind' : node.kind, 47 'usr' : node.get_usr(), 48 'spelling' : node.spelling, 49 'location' : node.location, 50 'extent.start' : node.extent.start, 51 'extent.end' : node.extent.end, 52 'is_definition' : node.is_definition(), 53 'definition id' : get_cursor_id(node.get_definition()), 54 'children' : children } 55 56 def main(): 57 from clang.cindex import Index 58 from pprint import pprint 59 60 from optparse import OptionParser, OptionGroup 61 62 global opts 63 64 parser = OptionParser("usage: %prog [options] {filename} [clang-args*]") 65 parser.add_option("", "--show-ids", dest="showIDs", 66 help="Don't compute cursor IDs (very slow)", 67 default=False) 68 parser.add_option("", "--max-depth", dest="maxDepth", 69 help="Limit cursor expansion to depth N", 70 metavar="N", type=int, default=None) 71 parser.disable_interspersed_args() 72 (opts, args) = parser.parse_args() 73 74 if len(args) == 0: 75 parser.error('invalid number arguments') 76 77 index = Index.create() 78 tu = index.parse(None, args) 79 if not tu: 80 parser.error("unable to load input") 81 82 pprint(('diags', map(get_diag_info, tu.diagnostics))) 83 pprint(('nodes', get_info(tu.cursor))) 84 85 if __name__ == '__main__': 86 main() 87 88