class ast

An Abstract Syntax Tree (AST).

ASTs are available for C/C++ and binary analyses only. For C# and Java analyses, plug-ins that rely on AST properties and relationships will generally not produce useful information.

Every ast has…

An ast can be traversed by an ast_iterator , whose behavior is governed by ast_traverse_directives and ast_traverse_flags .

Properties of an ast object can be tested against an ast_pattern or examined directly.

ast Details

class cs.ast

An Abstract Syntax Tree (AST).

__cmp__(other)

Comparison function for ast .

Parameters:other (ast) – The ast object to compare against.
Return type:int
Returns:An integer N such that:
  • N==0 if the two objects compare equal
  • N<0 if self < other
  • N>0 if self > other
>>> cu = next(c for c in project.current().compunits() if c.name().endswith('apitest.cpp'))
>>> cuast = cu.get_ast()
>>> abiast = cuast.get(ast_ordinal.NC_ABI)
>>> abiast.__cmp__(cuast)
-1
__contains__(ord)

Check: is the designated field present in an ast ?

Parameters:ord (ast_ordinal) – An ast_ordinal denoting the field to check.
Return type:bool
Returns:True if the ast_field corresponding to ord is present in the ast ; False otherwise.

Use this form for fields with named ordinals.

>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> ast_ordinal.NC_LONG in v2
False
__contains__(ord)

Check: is the designated field present in an ast ?

Parameters:ord (int) – A numeric ordinal denoting the field to check.
Return type:bool
Returns:True if the ast_field corresponding to ord is present in the ast ; False otherwise.
Raises:result.ERROR_INVALID_ARGUMENT if ord<=0.

Use this form for fields with numeric ordinals.

>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> 153 in v2
False
__eq__(b)

Equality operator for ast .

Parameters:b (ast) – The ast to compare against.
Return type:bool
Returns:True if self and b compare equal, False otherwise.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v3 = v1.get_type()
>>> v3 == v2
False
__ge__(b)

Greater-than-or-equal operator for ast .

Parameters:b (ast) – The ast to compare against.
Return type:bool
Returns:True if self >= b , False otherwise.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v3 = v1.get_type()
>>> v3 >= v2
False
__getitem__(ord)

Get the designated field from an ast .

Parameters:ord (ast_ordinal) – An ast_ordinal denoting the field to retrieve.
Return type:ast | sfileinst | symbol | bool | float | int | str | bytes
Returns:The ast_field corresponding to ord.
Raises:ast_field_not_found_error if there is no such field.

Use this form for fields with named ordinals.

myast[ord] == myast.get(ord) when ast myast contains a field with ordinal ord, but they have different behavior when the field is not present:

>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_type()
>>> v2[ast_ordinal.BASE_IS_COMPLETE]
True
__getitem__(ord)

Get the designated field from an ast .

Parameters:

ord (int) – A numeric ordinal for the field to retrieve.

Return type:

ast | sfileinst | symbol | bool | float | int | str | bytes

Returns:

The ast_field corresponding to ord.

Raises:

Use this form for fields with numeric ordinals.

myast[ord] == myast.get(ord) when ast myast contains a field with ordinal ord, but they have different behavior when the field is not present:

>>> v0 = project.current()
>>> v1 = v0.procedures_vector()
>>> v2 = v1[2].get_symbol()
>>> v3 = v2.get_ast()
>>> v3[1]
'bar'
__gt__(b)

Greater-than operator for ast .

Parameters:b (ast) – The ast to compare against.
Return type:bool
Returns:True if self > b , False otherwise.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v3 = v1.get_type()
>>> v2 > v3
True
__hash__()

Get a hash value for a ast .

Return type:int
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> hash(v2)
837178976
__iter__()

Get an iterator over the fields (ast_field) in an ast.

Return type:tuple_iterator
Returns:An iterator over the ast’s fields (ast_field).
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> for f in v1.get_type():  # ast.__iter__() and tuple_iterator.__next__() underlyingly manage iteration
...    print(f)
...
return-type:[c:pointer] const char*
size:0
alignment:1
is-const:false
is-volatile:false
is-near:false
is-far:false
is-unaligned:false
is-restrict:false
is-nonstatic-member:false
is-complete:true
prototyped:true
has-ellipsis:false
value-returned-by-cctor:false
__le__(b)

Less-than-or-equal operator for ast .

Parameters:b (ast) – The ast to compare against.
Return type:bool
Returns:True if self <= b , False otherwise.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v3 = v1.get_type()
>>> v2 <= v3
False
__len__()

Get the number of fields in an ast (that is, the number of children plus the number of attributes).

Return type:int
Returns:The number of fields.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> len(v2)
7
__lt__(b)

Less-than operator for ast .

Parameters:b (ast) – The ast to compare against.
Return type:bool
Returns:True if self < b , False otherwise.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_type()
>>> v2 < v2
False
__ne__(b)

Inequality operator for ast .

Parameters:b (ast) – The ast to compare against.
Return type:bool
Returns:False if self and b compare equal, True otherwise.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v3 = v1.get_type()
>>> v2 != v3
True
__repr__()

Get a representation of a ast object that includes information useful for debugging.

Return type:str
Returns:The string representation.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> repr(v2)
'<cs.ast [c:routine] foo>'
__str__()

Get a simple string representation of a ast object.

Return type:str
Returns:The string representation.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_type()
>>> str(v2)
'const char* ()'
attributes()

Get all attributes of an ast .

Return type:[ast_field]
Returns:A list populated with the attributes ( ast_field ). The ordering is fixed (but arbitrary): two ast objects with the same set of attribute ordinals will have the same ordering.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v2.attributes()
(<cs.ast_field type:[c:routine-type] const char* ()>, <cs.ast_field storage-class:unspecified>, <cs.ast_field is-member:false>, <cs.ast_field is-virtual:false>, <cs.ast_field noreturn:false>, <cs.ast_field abs-loc:<cs.symbol foo>>)
children()

Get all children of an ast .

Return type:[ast_field]
Returns:A list populated with the children ( ast_field ). The ordering is fixed (but arbitrary): two ast objects with the same set of child ordinals will have the same ordering.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_type()
>>> v2.children()
(<cs.ast_field return-type:[c:pointer] const char*>,)
dump([attribute_depth = 2])

Get an ASCII art tree rendering of an ast .

Parameters:attribute_depth (int) – (optional) The maximum depth of attribute subtrees that will be displayed in the tree. Attributes can give rise to cycles, so attribute subtrees must have a bounded height in order to bound the size of the dump.
Return type:str
Returns:The rendering.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> print(v2.dump(1))
(c:routine)-+-name:"foo"
+-type:(c:routine-type)-+-return-type:(c:pointer)-<...>
|                       +-size:0
|                       +-alignment:1
|                       +-is-const:false
|                       +-is-volatile:false
|                       +-is-near:false
|                       +-is-far:false
|                       +-is-unaligned:false
|                       +-is-restrict:false
|                       +-is-nonstatic-member:false
|                       +-is-complete:true
|                       +-prototyped:true
|                       +-has-ellipsis:false
|                       `-value-returned-by-cctor:false
+-storage-class:unspecified
+-is-member:false
+-is-virtual:false
+-noreturn:false
`-abs-loc:foo
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> print(v2.dump())
(c:routine)-+-name:"foo"
+-type:(c:routine-type)-+-return-type:(c:pointer)-+-size:4
|                       |                         +-alignment:4
|                       |                         +-is-const:false
|                       |                         +-is-volatile:false
|                       |                         +-is-near:false
|                       |                         +-is-far:false
|                       |                         +-is-unaligned:false
|                       |                         +-is-restrict:false
|                       |                         +-is-complete:true
|                       |                         `-pointed-to:(c:integer)-<...>
|                       +-size:0
|                       +-alignment:1
|                       +-is-const:false
|                       +-is-volatile:false
|                       +-is-near:false
|                       +-is-far:false
|                       +-is-unaligned:false
|                       +-is-restrict:false
|                       +-is-nonstatic-member:false
|                       +-is-complete:true
|                       +-prototyped:true
|                       +-has-ellipsis:false
|                       `-value-returned-by-cctor:false
+-storage-class:unspecified
+-is-member:false
+-is-virtual:false
+-noreturn:false
`-abs-loc:foo
fields()

Get all fields (that is, all children and all attributes) of an ast .

Return type:[ast_field]
Returns:A list populated with the fields ( ast_field ): all children, followed by all attributes. The ordering is fixed (but arbitrary): two ast objects with the same set of field ordinals will have the same ordering.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v2.fields()
(<cs.ast_field name:foo>, <cs.ast_field type:[c:routine-type] const char* ()>, <cs.ast_field storage-class:unspecified>, <cs.ast_field is-member:false>, <cs.ast_field is-virtual:false>, <cs.ast_field noreturn:false>, <cs.ast_field abs-loc:<cs.symbol foo>>)
get(ord)

Get the designated field from an ast .

Parameters:ord (ast_ordinal) – An ast_ordinal denoting the field to retrieve.
Return type:ast | sfileinst | symbol | NoneType | bool | float | int | str | bytes

Use this form for fields with named ordinals.

myast[ord] == myast.get(ord) when ast myast contains a field with ordinal ord, but they have different behavior when the field is not present:

>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v2.get(ast_ordinal.UC_LENGTH)
get(ord)

Get the designated field from an ast .

Parameters:ord (int) – A numeric ordinal for the field to retrieve.
Return type:ast | sfileinst | symbol | NoneType | bool | float | int | str | bytes
Raises:result.ERROR_INVALID_ARGUMENT if ord<=0.

Use this form for fields with numeric ordinals.

myast[ord] == myast.get(ord) when ast myast contains a field with ordinal ord, but they have different behavior when the field is not present:

>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v2.get(134217728)
get_class()

Get ast_class to which an ast belongs.

Return type:ast_class
Returns:The most specific ast_class to which the ast belongs.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_type()
>>> v2.get_class()
<cs.ast_class c:routine-type>
is_a(c)

Check: is an ast an instance of the specified ast_class ?

Parameters:c (ast_class) – The ast_class of interest.
Return type:bool
Returns:True if the ast belongs to c, or to a subclass of c; False otherwise
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_type()
>>> v2.is_a(ast_class.NC_FIELD)
False
pretty_print([limit = SIZE_MAX])

Get a pretty-printed version of an ast .

Parameters:

limit (int) – (optional) Upper bound on the length of the pretty-printed string. If the full pretty-printed rendering is longer than this, it will be truncated. Set to SIZE_MAX for no bound.

Return type:

str

Returns:

The pretty-printed version of the ast.

Raises:
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v2.pretty_print(375)
'foo'
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v2.pretty_print()
'foo'
stable_cmp(other)

Compare with another ast , with stable results across sufficiently-similar analyses.

Parameters:other (ast) – The ast to compare against.
Return type:int
Returns:An integer N, such that:
  • N<0 if self considered less than other
  • N==0 if self and other are the same object
  • N>0 if self considered greater than other

The comparison is stable in the following sense. Suppose there are two analyses A1 and A2 generated with exactly the same inputs (including identical analyzed code, underlying build commands and ordering, command line and configuration settings, increment order and contents). Let a1 and b1 be two ast objects in A1, and a2 and b2 be the ast objects in A2 that correspond to a1 and b1 respectively. Then a1.stable_cmp(b1)==a2.stable_cmp(b2).

If you don’t need comparison relationships to be stable across analyses, use ast.__cmp__(): it has better performance.

>>> v0 = project.current()
>>> v1 = v0.compunits_vector()
>>> v2 = v0.lookup_symbol('foo')
>>> v3 = v1[0].get_ast()
>>> v4 = v2.get_ast(ast_family.C_NORMALIZED)
>>> v4.stable_cmp(v3)
1
to_dict()

Get the ast fields as a dictionary.

Return type:{ast_ordinal: ast | sfileinst | symbol | bool | float | int | str | bytes}
Returns:The ast fields, as a dictionary mapping ast_ordinal to field value.
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_ast()
>>> v2.to_dict()
{<cs.ast_ordinal is-member>: False, <cs.ast_ordinal is-virtual>: False, <cs.ast_ordinal abs-loc>: <cs.symbol foo>, <cs.ast_ordinal type>: <cs.ast [c:routine-type] const char* ()>, <cs.ast_ordinal storage-class>: 'unspecified', <cs.ast_ordinal noreturn>: False, <cs.ast_ordinal name>: 'foo'}
traverse([flags =  ast_traverse_flags.NONE])

Get an iterator over an ast .

Parameters:flags (ast_traverse_flags) – (optional) Specify the order in which the returned iterator will traverse the tree.
Return type:ast_iterator
Returns:An initialized ast_iterator .
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_type()
>>> v2.traverse(ast_traverse_flags.NONE)
<cs.ast_iterator begin>
>>> v0 = project.current()
>>> v1 = v0.lookup_symbol('foo')
>>> v2 = v1.get_type()
>>> v2.traverse()
<cs.ast_iterator begin>