Source code for chc.app.CFunDeclarations

# ------------------------------------------------------------------------------
# CodeHawk C Analyzer
# Author: Henny Sipma
# ------------------------------------------------------------------------------
# The MIT License (MIT)
#
# Copyright (c) 2017-2020 Kestrel Technology LLC
# Copyright (c) 2020-2022 Henny B. Sipma
# Copyright (c) 2023-2024 Aarno Labs LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ------------------------------------------------------------------------------
"""Local variable declarations at the function level."""

import xml.etree.ElementTree as ET

from typing import Dict, List, TYPE_CHECKING

import chc.util.fileutil as UF
from chc.util.IndexedTable import IndexedTable, IndexedTableValue

from chc.app.CVarInfo import CVarInfo

if TYPE_CHECKING:
    from chc.app.CFile import CFile
    from chc.app.CFileDeclarations import CFileDeclarations
    from chc.app.CFunction import CFunction
    from chc.app.CLocation import CLocation


[docs]class CFunDeclarations: """Function parameter and local variable declarations. This information is generated by cchcil/cHCilFunDeclarations and stored on disk in <fname>_cfun.xml, in the <declarations> element. """ def __init__(self, cfun: "CFunction", xnode: ET.Element) -> None: self._cfun = cfun self.xnode = xnode self._varinfos: Dict[int, CVarInfo] = {} # indexed by vid self.local_varinfo_table = IndexedTable("local-varinfo-table") self.initialize(xnode) @property def cfun(self) -> "CFunction": return self._cfun @property def cfile(self) -> "CFile": return self.cfun.cfile @property def fdecls(self) -> "CFileDeclarations": return self.cfile.declarations @property def varinfos(self) -> Dict[int, CVarInfo]: if len(self._varinfos) == 0: for itv in self.local_varinfo_table.values(): vinfo = CVarInfo(self.cfile.declarations, itv) self._varinfos[vinfo.vid] = vinfo return self._varinfos @property def formals(self) -> List[CVarInfo]: return [x for x in self.varinfos.values() if x.vparam > 0] @property def locals(self) -> List[CVarInfo]: return [x for x in self.varinfos.values() if x.vparam == 0]
[docs] def get_varinfo(self, vid: int) -> CVarInfo: if vid in self.varinfos: return self.varinfos[vid] return self.cfun.cfile.get_global_varinfo(vid)
[docs] def get_local_varinfo(self, ix: int) -> CVarInfo: return CVarInfo( self.cfile.declarations, self.local_varinfo_table.retrieve(ix))
[docs] def get_local_varinfo_map(self) -> Dict[int, IndexedTableValue]: return self.local_varinfo_table.objectmap(self.get_local_varinfo)
[docs] def get_global_varinfo_by_name(self, name: str) -> CVarInfo: return self.cfile.get_global_varinfo_by_name(name)
[docs] def get_location(self, ix: int) -> "CLocation": return self.fdecls.get_location(ix)
# --------------------------- printing -------------------------------------
[docs] def objectmap_to_string(self, name: str) -> str: if name == "local-varinfo": objmap = self.get_local_varinfo_map() lines: List[str] = [] for (ix, obj) in objmap.items(): lines.append(str(ix).rjust(3) + " " + str(obj)) return "\n".join(lines) else: raise UF.CHCError( "Name: " + name + " does not correspond to a table")
def __str__(self) -> str: lines: List[str] = [] lines.append("\nVarinfos:") lines.append("-" * 40) for vid in sorted(self.varinfos): lines.append(str(vid).rjust(5) + " " + self.varinfos[vid].vname) return "\n".join(lines)
[docs] def initialize(self, xnode: ET.Element) -> None: xtable = xnode.find(self.local_varinfo_table.name) if xtable is not None: self.local_varinfo_table.reset() self.local_varinfo_table.read_xml(xtable, "n") else: raise UF.CHCError( "Local-varinfo-table not found in cfun for " + self.cfun.name)