]> andersk Git - splint.git/blob - src/mtContextNode.c
*** empty log message ***
[splint.git] / src / mtContextNode.c
1 /*
2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 ** 
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** General Public License for more details.
15 ** 
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
19 **
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
23 */
24 /*
25 ** mtContextNode.c
26 */
27
28 # include "lclintMacros.nf"
29 # include "basic.h"
30
31 static bool mtContextNode_matchesType (mtContextNode, ctype) /*@*/ ;
32
33 static /*@observer@*/ cstring mtContextKind_unparse (mtContextKind ck)
34 {
35   switch (ck)
36     {
37     case MTC_ANY: return cstring_makeLiteralTemp ("any");
38     case MTC_PARAM: return cstring_makeLiteralTemp ("parameter"); 
39     case MTC_RESULT: return cstring_makeLiteralTemp ("result"); 
40     case MTC_REFERENCE: return cstring_makeLiteralTemp ("reference");
41     case MTC_CLAUSE: return cstring_makeLiteralTemp ("clause");
42     case MTC_LITERAL: return cstring_makeLiteralTemp ("literal");
43     case MTC_NULL: return cstring_makeLiteralTemp ("null");
44     }
45
46   BADBRANCH;
47 }
48  
49 static mtContextNode mtContextNode_create (mtContextKind context, ctype ct) 
50 {
51   mtContextNode res = (mtContextNode) dmalloc (sizeof (*res));
52   res->context = context;
53   res->type = ct;
54   DPRINTF (("Create: %s", mtContextNode_unparse (res)));
55   return res;
56 }
57
58 extern mtContextNode mtContextNode_createAny ()
59 {
60   return mtContextNode_create (MTC_ANY, ctype_unknown);
61 }
62
63 extern mtContextNode mtContextNode_createParameter (ctype ct) 
64 {
65   return mtContextNode_create (MTC_PARAM, ct);
66 }
67
68 extern mtContextNode mtContextNode_createResult (ctype ct) 
69 {
70   return mtContextNode_create (MTC_RESULT, ct);
71 }
72
73 extern mtContextNode mtContextNode_createReference (ctype ct) 
74 {
75   return mtContextNode_create (MTC_REFERENCE, ct);
76 }
77
78 extern mtContextNode mtContextNode_createClause (ctype ct) 
79 {
80   return mtContextNode_create (MTC_CLAUSE, ct);
81 }
82
83 extern mtContextNode mtContextNode_createLiteral (ctype ct) 
84 {
85   return mtContextNode_create (MTC_LITERAL, ct);
86 }
87
88 extern mtContextNode mtContextNode_createNull (ctype ct) 
89 {
90   return mtContextNode_create (MTC_NULL, ct);
91 }
92
93 extern void mtContextNode_free (/*@only@*/ mtContextNode node) 
94 {
95   sfree (node);
96 }
97
98 bool mtContextNode_matchesEntry (mtContextNode context, uentry ue)
99 {
100   ctype ct;
101
102   llassert (mtContextNode_isDefined (context));
103
104   DPRINTF (("Matches context: %s / %s",
105             mtContextNode_unparse (context), uentry_unparse (ue)));
106
107   switch (context->context)
108     {
109     case MTC_ANY: break; /* everything matches */
110     case MTC_RESULT:
111       if (!uentry_isFunction (ue))
112         {
113           return FALSE;
114         }
115       break;
116     case MTC_PARAM: 
117       if (!uentry_isParam (ue))
118         {
119           return FALSE;
120         }
121       break;
122     case MTC_LITERAL:
123     case MTC_NULL:
124       return FALSE;
125     case MTC_REFERENCE:
126       break;
127     case MTC_CLAUSE:
128       BADBRANCH;
129     }
130
131   if (uentry_isFunction (ue))
132     {
133       ct = ctype_getReturnType (uentry_getType (ue));
134     }
135   else
136     {
137       ct = uentry_getType (ue);
138     }
139
140   return mtContextNode_matchesType (context, ct);
141 }
142
143 bool mtContextNode_matchesRef (mtContextNode context, sRef sr)
144 {
145   ctype ct;
146
147   llassert (mtContextNode_isDefined (context));
148
149   DPRINTF (("Matches context: %s / %s",
150             mtContextNode_unparse (context), sRef_unparse (sr)));
151
152   switch (context->context)
153     {
154     case MTC_ANY: break; /* everything matches */
155     case MTC_RESULT:
156       DPRINTF (("Result? %s / %s",
157                 sRef_unparseFull (sr),
158                 bool_unparse (sRef_isResult (sr))));
159       return sRef_isResult (sr);
160     case MTC_PARAM: 
161       if (!sRef_isParam (sr))
162         {
163           return FALSE;
164         }
165       break;
166     case MTC_LITERAL:
167       DPRINTF (("Literal: %s", sRef_unparse (sr)));
168       if (!sRef_isConst (sr))
169         {
170           return FALSE;
171         }
172       break;
173     case MTC_NULL:
174     case MTC_REFERENCE:
175       break;
176     case MTC_CLAUSE:
177       BADBRANCH;
178     }
179
180   ct = sRef_getType (sr);
181   return mtContextNode_matchesType (context, ct);
182 }
183
184 bool mtContextNode_matchesRefStrict (mtContextNode context, sRef s)
185 {
186   if (mtContextNode_matchesRef (context, s))
187     {
188       if (ctype_isKnown (context->type) 
189           && (ctype_isUnknown (sRef_getType (s))
190               || ctype_isVoidPointer (sRef_getType (s))))
191         {
192           return FALSE;
193         }
194       else
195         {
196           return TRUE;
197         }
198     }
199   
200   return FALSE;
201 }
202
203 bool mtContextNode_matchesType (mtContextNode context, ctype ct)
204 {
205   DPRINTF (("Context type..."));
206   
207   if (!ctype_match (context->type, ct))
208     {
209       DPRINTF (("Type mismatch: %s / %s",
210                 ctype_unparse (context->type),
211                 ctype_unparse (ct)));
212       return FALSE;
213     }
214   else
215     {
216       DPRINTF (("Type okay: %s / %s",
217                 ctype_unparse (context->type),
218                 ctype_unparse (ct)));
219     }
220   
221   return TRUE;
222 }
223
224 cstring mtContextNode_unparse (mtContextNode node)
225 {
226   if (ctype_isKnown (node->type))
227     {
228       return message ("%s %s", mtContextKind_unparse (node->context),
229                       ctype_unparse (node->type));
230     }
231   else
232     {
233       return message ("%s", mtContextKind_unparse (node->context));
234     }
235 }
236
237 bool mtContextNode_isClause (mtContextNode n)
238 {
239   llassert (mtContextNode_isDefined (n));
240   return (n->context == MTC_CLAUSE);
241 }
242
243 bool mtContextNode_isParameter (mtContextNode n)
244 {
245   llassert (mtContextNode_isDefined (n));
246   return (n->context == MTC_PARAM);
247 }
248
249 bool mtContextNode_isReference (mtContextNode n)
250 {
251   llassert (mtContextNode_isDefined (n));
252   return (n->context == MTC_REFERENCE);
253 }
254
255 bool mtContextNode_isResult (mtContextNode n)
256 {
257   llassert (mtContextNode_isDefined (n));
258   return (n->context == MTC_RESULT);
259 }
260
261 bool mtContextNode_isLiteral (mtContextNode n)
262 {
263   llassert (mtContextNode_isDefined (n));
264   return (n->context == MTC_LITERAL);
265 }
266
267 bool mtContextNode_isNull (mtContextNode n)
268 {
269   llassert (mtContextNode_isDefined (n));
270   return (n->context == MTC_NULL);
271 }
272
273
274
275
This page took 0.050413 seconds and 5 git commands to generate.