4747from chc .invariants .CFunInvariantTable import CFunInvariantTable
4848from chc .invariants .CInvariantFact import CInvariantFact
4949
50- from chc .proof .CFunPODictionary import CFunPODictionary
50+ from chc .proof .CFunctionAnalysisDigest import CFunctionAnalysisDigests
5151from chc .proof .CFunctionCallsiteSPOs import CFunctionCallsiteSPOs
5252from chc .proof .CFunctionPO import CFunctionPO
5353from chc .proof .CFunctionPPO import CFunctionPPO
5454from chc .proof .CFunctionProofs import CFunctionProofs
5555from chc .proof .CFunctionSPOs import CFunctionSPOs
56+ from chc .proof .CFunPODictionary import CFunPODictionary
5657
5758import chc .util .fileutil as UF
5859from chc .util .loggingutil import chklogger
6970 from chc .app .CVarInfo import CVarInfo
7071
7172
72- class CandidateOutputParameter :
73-
74- def __init__ (
75- self ,
76- cfun : "CFunction" ,
77- cvar : "CVarInfo" ,
78- offsets : List ["COffset" ]) -> None :
79- self ._cfun = cfun
80- self ._cvar = cvar
81- self ._offsets = offsets
82-
83- @property
84- def cfun (self ) -> "CFunction" :
85- return self ._cfun
86-
87- @property
88- def parameter (self ) -> "CVarInfo" :
89- return self ._cvar
90-
91- @property
92- def offsets (self ) -> List ["COffset" ]:
93- return self ._offsets
94-
95- def __str__ (self ) -> str :
96- return (
97- self .parameter .vname + "[" + ", " .join (str (o ) for o in self .offsets ) + "]" )
98-
99-
100- class CAnalysisInfo :
101-
102- def __init__ (self , xnode : Optional [ET .Element ], cfun : "CFunction" ) -> None :
103- self ._xnode = xnode
104- self ._cfun = cfun
105-
106- @property
107- def cfun (self ) -> "CFunction" :
108- return self ._cfun
109-
110- @property
111- def cdictionary (self ) -> "CDictionary" :
112- return self .cfun .cdictionary
113-
114- @property
115- def cfiledecls (self ) -> "CFileDeclarations" :
116- return self .cfun .cfiledecls
117-
118- @property
119- def analysis (self ) -> str :
120- if self ._xnode is None :
121- return "undefined-behavior"
122- else :
123- return self ._xnode .get ("name" , "unknown" )
124-
125- @property
126- def candidate_parameters (self ) -> List [CandidateOutputParameter ]:
127- result : List [CandidateOutputParameter ] = []
128- if self ._xnode is not None :
129- if self .analysis == "output-parameters" :
130- xparams = self ._xnode .find ("candidate-parameters" )
131- if xparams is not None :
132- xparamlist = xparams .findall ("vinfo" )
133- for xparam in xparamlist :
134- xid = int (xparam .get ("xid" , "-1" ))
135- if xid > 0 :
136- vinfo = self .cfiledecls .get_varinfo (xid )
137- xoffsets = xparam .get ("offsets" , "" )
138- if xoffsets is not None :
139- offsets = list (
140- self .cdictionary .get_offset (int (i ))
141- for i in xoffsets .split ("," ))
142-
143- result .append (CandidateOutputParameter (
144- self .cfun , vinfo , offsets ))
145- return result
146-
147- def __str__ (self ) -> str :
148- return ", " .join (str (vinfo ) for vinfo in self .candidate_parameters )
149-
150-
15173class CFunction :
15274 """Function implementation."""
15375
@@ -167,7 +89,7 @@ def __init__(self, cfile: "CFile", xnode: ET.Element, fname: str) -> None:
16789 self ._vard : Optional [CFunVarDictionary ] = None
16890 self ._invd : Optional [CFunInvDictionary ] = None
16991 self ._invarianttable : Optional [CFunInvariantTable ] = None
170- self ._analysisinfo : Optional [CAnalysisInfo ] = None
92+ self ._analysis_digests : Optional [CFunctionAnalysisDigests ] = None
17193
17294 def xmsg (self , txt : str ) -> str :
17395 return "Function " + self .name + ": " + txt
@@ -375,6 +297,32 @@ def podictionary(self) -> CFunPODictionary:
375297 self ._podictionary = CFunPODictionary (self , pxnode )
376298 return self ._podictionary
377299
300+ @property
301+ def analysis_digests (self ) -> CFunctionAnalysisDigests :
302+ if self ._analysis_digests is None :
303+ adnode = UF .get_adg_xnode (
304+ self .targetpath ,
305+ self .projectname ,
306+ self .cfilepath ,
307+ self .cfilename ,
308+ self .name )
309+ if adnode is None :
310+ print ("DEBUG: No adg file found" )
311+ adgnode = None
312+ # raise UF.CHCError(self.xmsg("adg file not found"))
313+ else :
314+ adgnode = adnode .find ("analysis-digests" )
315+ self ._analysis_digests = CFunctionAnalysisDigests (self , adgnode )
316+ return self ._analysis_digests
317+
318+ def callsites (self ) -> List [CCallInstr ]:
319+ callinstrs = self .capp .get_callinstrs ()
320+ result : List [CCallInstr ] = []
321+ for instr in callinstrs :
322+ if str (instr .callee ) == self .name :
323+ result .append (instr )
324+ return result
325+
378326 @property
379327 def returnsites (self ) -> List [CFunctionReturnSite ]:
380328 if self ._returnsites is None :
@@ -433,30 +381,6 @@ def proofs(self) -> CFunctionProofs:
433381 self ._proofs = CFunctionProofs (self , xxpponode , xxsponode )
434382 return self ._proofs
435383
436- @property
437- def analysis_info (self ) -> CAnalysisInfo :
438- if self ._analysisinfo is None :
439- if UF .has_ppo_file (
440- self .targetpath ,
441- self .projectname ,
442- self .cfilepath ,
443- self .cfilename ,
444- self .name ):
445- xpponode = UF .get_ppo_xnode (
446- self .targetpath ,
447- self .projectname ,
448- self .cfilepath ,
449- self .cfilename ,
450- self .name )
451- if xpponode is not None :
452- self ._analysisinfo = (
453- CAnalysisInfo (xpponode .find ("analysis-info" ), self ))
454- else :
455- self ._analysisinfo = CAnalysisInfo (None , self )
456- else :
457- self ._analysisinfo = CAnalysisInfo (None , self )
458- return self ._analysisinfo
459-
460384 def reinitialize_tables (self ) -> None :
461385 self ._api = None
462386 self ._podictionary = None
@@ -547,7 +471,7 @@ def get_source_code_file(self) -> str:
547471 def has_line_number (self ) -> bool :
548472 if self .has_source_code_file ():
549473 srcfile = self .get_source_code_file ()
550- return self .cfile .cfilename + ".c" == srcfile
474+ return self .cfile .name + ".c" == srcfile
551475 else :
552476 return False
553477
0 commit comments