2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 University of Virginia,
4 ** Massachusetts Institute of Technology
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.
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.
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.
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
28 # include "lclintMacros.nf"
31 static bool mtContextNode_matchesType (mtContextNode, ctype) /*@*/ ;
33 static /*@observer@*/ cstring mtContextKind_unparse (mtContextKind ck)
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");
49 static mtContextNode mtContextNode_create (mtContextKind context, ctype ct)
51 mtContextNode res = (mtContextNode) dmalloc (sizeof (*res));
52 res->context = context;
54 DPRINTF (("Create: %s", mtContextNode_unparse (res)));
58 extern mtContextNode mtContextNode_createAny ()
60 return mtContextNode_create (MTC_ANY, ctype_unknown);
63 extern mtContextNode mtContextNode_createParameter (ctype ct)
65 return mtContextNode_create (MTC_PARAM, ct);
68 extern mtContextNode mtContextNode_createResult (ctype ct)
70 return mtContextNode_create (MTC_RESULT, ct);
73 extern mtContextNode mtContextNode_createReference (ctype ct)
75 return mtContextNode_create (MTC_REFERENCE, ct);
78 extern mtContextNode mtContextNode_createClause (ctype ct)
80 return mtContextNode_create (MTC_CLAUSE, ct);
83 extern mtContextNode mtContextNode_createLiteral (ctype ct)
85 return mtContextNode_create (MTC_LITERAL, ct);
88 extern mtContextNode mtContextNode_createNull (ctype ct)
90 return mtContextNode_create (MTC_NULL, ct);
93 extern void mtContextNode_free (/*@only@*/ mtContextNode node)
98 bool mtContextNode_matchesEntry (mtContextNode context, uentry ue)
102 llassert (mtContextNode_isDefined (context));
104 DPRINTF (("Matches context: %s / %s",
105 mtContextNode_unparse (context), uentry_unparse (ue)));
107 switch (context->context)
109 case MTC_ANY: break; /* everything matches */
111 if (!uentry_isFunction (ue))
117 if (!uentry_isParam (ue))
131 if (uentry_isFunction (ue))
133 ct = ctype_getReturnType (uentry_getType (ue));
137 ct = uentry_getType (ue);
140 return mtContextNode_matchesType (context, ct);
143 bool mtContextNode_matchesRef (mtContextNode context, sRef sr)
147 llassert (mtContextNode_isDefined (context));
149 DPRINTF (("Matches context: %s / %s",
150 mtContextNode_unparse (context), sRef_unparse (sr)));
152 switch (context->context)
154 case MTC_ANY: break; /* everything matches */
156 DPRINTF (("Result? %s / %s",
157 sRef_unparseFull (sr),
158 bool_unparse (sRef_isResult (sr))));
159 return sRef_isResult (sr);
161 if (!sRef_isParam (sr))
167 DPRINTF (("Literal: %s", sRef_unparse (sr)));
168 if (!sRef_isConst (sr))
180 ct = sRef_getType (sr);
181 return mtContextNode_matchesType (context, ct);
184 bool mtContextNode_matchesRefStrict (mtContextNode context, sRef s)
186 if (mtContextNode_matchesRef (context, s))
188 if (ctype_isKnown (context->type)
189 && (ctype_isUnknown (sRef_getType (s))
190 || ctype_isVoidPointer (sRef_getType (s))))
203 bool mtContextNode_matchesType (mtContextNode context, ctype ct)
205 DPRINTF (("Context type..."));
207 if (!ctype_match (context->type, ct))
209 DPRINTF (("Type mismatch: %s / %s",
210 ctype_unparse (context->type),
211 ctype_unparse (ct)));
216 DPRINTF (("Type okay: %s / %s",
217 ctype_unparse (context->type),
218 ctype_unparse (ct)));
224 cstring mtContextNode_unparse (mtContextNode node)
226 if (ctype_isKnown (node->type))
228 return message ("%s %s", mtContextKind_unparse (node->context),
229 ctype_unparse (node->type));
233 return message ("%s", mtContextKind_unparse (node->context));
237 bool mtContextNode_isClause (mtContextNode n)
239 llassert (mtContextNode_isDefined (n));
240 return (n->context == MTC_CLAUSE);
243 bool mtContextNode_isParameter (mtContextNode n)
245 llassert (mtContextNode_isDefined (n));
246 return (n->context == MTC_PARAM);
249 bool mtContextNode_isReference (mtContextNode n)
251 llassert (mtContextNode_isDefined (n));
252 return (n->context == MTC_REFERENCE);
255 bool mtContextNode_isResult (mtContextNode n)
257 llassert (mtContextNode_isDefined (n));
258 return (n->context == MTC_RESULT);
261 bool mtContextNode_isLiteral (mtContextNode n)
263 llassert (mtContextNode_isDefined (n));
264 return (n->context == MTC_LITERAL);
267 bool mtContextNode_isNull (mtContextNode n)
269 llassert (mtContextNode_isDefined (n));
270 return (n->context == MTC_NULL);