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