xref: /aosp_15_r20/external/clang/bindings/python/examples/cindex/cindex-dump.py (revision 67e74705e28f6214e480b399dd47ea732279e315)
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