summaryrefslogtreecommitdiffstats
path: root/Tools/c-analyzer/c_analyzer/variables/find.py
blob: 3fe7284fc00a7950bddec992a89fe1de1fb072dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from ..common import files
from ..common.info import UNKNOWN
from ..parser import (
        find as p_find,
        )
from ..symbols import (
        info as s_info,
        find as s_find,
        )
from .info import Variable

# XXX need tests:
# * vars_from_source


def _remove_cached(cache, var):
    if not cache:
        return
    try:
        cached = cache[var.filename]
        cached.remove(var)
    except (KeyError, IndexError):
        pass


def vars_from_binary(binfile, *,
                     known=None,
                     filenames=None,
                     handle_id=None,
                     check_filename=None,
                     handle_var=Variable.from_id,
                     _iter_vars=s_find.variables,
                     _get_symbol_resolver=s_find.get_resolver,
                     ):
    """Yield a Variable for each found Symbol.

    Details are filled in from the given "known" variables and types.
    """
    cache = {}
    resolve = _get_symbol_resolver(filenames, known,
                                   handle_var=handle_var,
                                   check_filename=check_filename,
                                   perfilecache=cache,
                                   )
    for var, symbol in _iter_vars(binfile,
                                  resolve=resolve,
                                  handle_id=handle_id,
                                  ):
        if var is None:
            var = Variable(symbol.id, UNKNOWN, UNKNOWN)
        yield var
        _remove_cached(cache, var)


def vars_from_source(filenames, *,
                     preprocessed=None,
                     known=None,
                     handle_id=None,
                     handle_var=Variable.from_id,
                     iter_vars=p_find.variables,
                     ):
    """Yield a Variable for each declaration in the raw source code.

    Details are filled in from the given "known" variables and types.
    """
    cache = {}
    for varid, decl in iter_vars(filenames or (),
                                 perfilecache=cache,
                                 preprocessed=preprocessed,
                                 known=known,
                                 handle_id=handle_id,
                                 ):
        var = handle_var(varid, decl)
        yield var
        _remove_cached(cache, var)