PageRenderTime 66ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 1ms

/src/cil.ml

http://github.com/kerneis/cil
OCaml | 7133 lines | 4914 code | 843 blank | 1376 comment | 749 complexity | 2516d5954db74d71c239e40812629e61 MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. (*
  2. *
  3. * Copyright (c) 2001-2003,
  4. * George C. Necula <necula@cs.berkeley.edu>
  5. * Scott McPeak <smcpeak@cs.berkeley.edu>
  6. * Wes Weimer <weimer@cs.berkeley.edu>
  7. * Ben Liblit <liblit@cs.berkeley.edu>
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are
  12. * met:
  13. *
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. *
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in the
  19. * documentation and/or other materials provided with the distribution.
  20. *
  21. * 3. The names of the contributors may not be used to endorse or promote
  22. * products derived from this software without specific prior written
  23. * permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  26. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  27. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  28. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  29. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  30. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  31. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  32. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  33. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  34. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36. *
  37. *)
  38. open Escape
  39. open Pretty
  40. open Cilint
  41. (* open Trace (\* sm: 'trace' function *\) *)
  42. module E = Errormsg
  43. module H = Hashtbl
  44. module IH = Inthash
  45. (*
  46. * CIL: An intermediate language for analyzing C progams.
  47. *
  48. * Scott McPeak, George Necula, Wes Weimer
  49. *
  50. *)
  51. (* The module Cilversion is generated automatically by Makefile from
  52. * information in configure.in *)
  53. let cilVersion = Cilversion.cilVersion
  54. let cilVersionMajor = Cilversion.cilVersionMajor
  55. let cilVersionMinor = Cilversion.cilVersionMinor
  56. let cilVersionRevision = Cilversion.cilVersionRev
  57. (* A few globals that control the interpretation of C source *)
  58. let msvcMode = ref false (* Whether the pretty printer should
  59. * print output for the MS VC
  60. * compiler. Default is GCC *)
  61. let c99Mode = ref false (* True to handle ISO C 99 vs 90 changes.
  62. So far only affects integer parsing. *)
  63. (* Set this to true to get old-style handling of gcc's extern inline C extension:
  64. old-style: the extern inline definition is used until the actual definition is
  65. seen (as long as optimization is enabled)
  66. new-style: the extern inline definition is used only if there is no actual
  67. definition (as long as optimization is enabled)
  68. Note that CIL assumes that optimization is always enabled ;-) *)
  69. let oldstyleExternInline = ref false
  70. let makeStaticGlobal = ref true
  71. let useLogicalOperators = ref false
  72. let useComputedGoto = ref false
  73. let useCaseRange = ref false
  74. module M = Machdep
  75. (* Cil.initCil will set this to the current machine description.
  76. Makefile.cil generates the file src/machdep.ml,
  77. which contains the descriptions of gcc and msvc. *)
  78. let envMachine : M.mach option ref = ref None
  79. let lowerConstants: bool ref = ref true
  80. (** Do lower constants (default true) *)
  81. let insertImplicitCasts: bool ref = ref true
  82. (** Do insert implicit casts (default true) *)
  83. let little_endian = ref true
  84. let char_is_unsigned = ref false
  85. let underscore_name = ref false
  86. type lineDirectiveStyle =
  87. | LineComment (** Before every element, print the line
  88. * number in comments. This is ignored by
  89. * processing tools (thus errors are reproted
  90. * in the CIL output), but useful for
  91. * visual inspection *)
  92. | LineCommentSparse (** Like LineComment but only print a line
  93. * directive for a new source line *)
  94. | LinePreprocessorInput (** Use #line directives *)
  95. | LinePreprocessorOutput (** Use # nnn directives (in gcc mode) *)
  96. let lineDirectiveStyle = ref (Some LinePreprocessorInput)
  97. let print_CIL_Input = ref false
  98. let printCilAsIs = ref false
  99. let lineLength = ref 80
  100. let warnTruncate = ref true
  101. (* sm: return the string 's' if we're printing output for gcc, suppres
  102. * it if we're printing for CIL to parse back in. the purpose is to
  103. * hide things from gcc that it complains about, but still be able
  104. * to do lossless transformations when CIL is the consumer *)
  105. let forgcc (s: string) : string =
  106. if (!print_CIL_Input) then "" else s
  107. let debugConstFold = false
  108. (** The Abstract Syntax of CIL *)
  109. (** The top-level representation of a CIL source file. Its main contents is
  110. the list of global declarations and definitions. *)
  111. type file =
  112. { mutable fileName: string; (** The complete file name *)
  113. mutable globals: global list; (** List of globals as they will appear
  114. in the printed file *)
  115. mutable globinit: fundec option;
  116. (** An optional global initializer function. This is a function where
  117. * you can put stuff that must be executed before the program is
  118. * started. This function, is conceptually at the end of the file,
  119. * although it is not part of the globals list. Use {!Cil.getGlobInit}
  120. * to create/get one. *)
  121. mutable globinitcalled: bool;
  122. (** Whether the global initialization function is called in main. This
  123. should always be false if there is no global initializer. When
  124. you create a global initialization CIL will try to insert code in
  125. main to call it. *)
  126. }
  127. and comment = location * string
  128. (** The main type for representing global declarations and definitions. A list
  129. of these form a CIL file. The order of globals in the file is generally
  130. important. *)
  131. and global =
  132. | GType of typeinfo * location
  133. (** A typedef. All uses of type names (through the [TNamed] constructor)
  134. must be preceeded in the file by a definition of the name. The string
  135. is the defined name and always not-empty. *)
  136. | GCompTag of compinfo * location
  137. (** Defines a struct/union tag with some fields. There must be one of
  138. these for each struct/union tag that you use (through the [TComp]
  139. constructor) since this is the only context in which the fields are
  140. printed. Consequently nested structure tag definitions must be
  141. broken into individual definitions with the innermost structure
  142. defined first. *)
  143. | GCompTagDecl of compinfo * location
  144. (** Declares a struct/union tag. Use as a forward declaration. This is
  145. * printed without the fields. *)
  146. | GEnumTag of enuminfo * location
  147. (** Declares an enumeration tag with some fields. There must be one of
  148. these for each enumeration tag that you use (through the [TEnum]
  149. constructor) since this is the only context in which the items are
  150. printed. *)
  151. | GEnumTagDecl of enuminfo * location
  152. (** Declares an enumeration tag. Use as a forward declaration. This is
  153. * printed without the items. *)
  154. | GVarDecl of varinfo * location
  155. (** A variable declaration (not a definition). If the variable has a
  156. function type then this is a prototype. There can be several
  157. declarations and at most one definition for a given variable. If both
  158. forms appear then they must share the same varinfo structure. A
  159. prototype shares the varinfo with the fundec of the definition. Either
  160. has storage Extern or there must be a definition in this file *)
  161. | GVar of varinfo * initinfo * location
  162. (** A variable definition. Can have an initializer. The initializer is
  163. * updateable so that you can change it without requiring to recreate
  164. * the list of globals. There can be at most one definition for a
  165. * variable in an entire program. Cannot have storage Extern or function
  166. * type. *)
  167. | GFun of fundec * location
  168. (** A function definition. *)
  169. | GAsm of string * location (** Global asm statement. These ones
  170. can contain only a template *)
  171. | GPragma of attribute * location (** Pragmas at top level. Use the same
  172. syntax as attributes *)
  173. | GText of string (** Some text (printed verbatim) at
  174. top level. E.g., this way you can
  175. put comments in the output. *)
  176. (** The various types available. Every type is associated with a list of
  177. * attributes, which are always kept in sorted order. Use {!Cil.addAttribute}
  178. * and {!Cil.addAttributes} to construct list of attributes. If you want to
  179. * inspect a type, you should use {!Cil.unrollType} to see through the uses
  180. * of named types. *)
  181. and typ =
  182. TVoid of attributes (** Void type *)
  183. | TInt of ikind * attributes (** An integer type. The kind specifies
  184. the sign and width. *)
  185. | TFloat of fkind * attributes (** A floating-point type. The kind
  186. specifies the precision. *)
  187. | TPtr of typ * attributes
  188. (** Pointer type. *)
  189. | TArray of typ * exp option * attributes
  190. (** Array type. It indicates the base type and the array length. *)
  191. | TFun of typ * (string * typ * attributes) list option * bool * attributes
  192. (** Function type. Indicates the type of the result, the name, type
  193. * and name attributes of the formal arguments ([None] if no
  194. * arguments were specified, as in a function whose definition or
  195. * prototype we have not seen; [Some \[\]] means void). Use
  196. * {!Cil.argsToList} to obtain a list of arguments. The boolean
  197. * indicates if it is a variable-argument function. If this is the
  198. * type of a varinfo for which we have a function declaration then
  199. * the information for the formals must match that in the
  200. * function's sformals. *)
  201. | TNamed of typeinfo * attributes
  202. (** The use of a named type. All uses of the same type name must
  203. * share the typeinfo. Each such type name must be preceeded
  204. * in the file by a [GType] global. This is printed as just the
  205. * type name. The actual referred type is not printed here and is
  206. * carried only to simplify processing. To see through a sequence
  207. * of named type references, use {!Cil.unrollType}. The attributes
  208. * are in addition to those given when the type name was defined. *)
  209. | TComp of compinfo * attributes
  210. (** A reference to a struct or a union type. All references to the
  211. same struct or union must share the same compinfo among them and
  212. with a [GCompTag] global that preceeds all uses (except maybe
  213. those that are pointers to the composite type). The attributes
  214. given are those pertaining to this use of the type and are in
  215. addition to the attributes that were given at the definition of
  216. the type and which are stored in the compinfo. *)
  217. | TEnum of enuminfo * attributes
  218. (** A reference to an enumeration type. All such references must
  219. share the enuminfo among them and with a [GEnumTag] global that
  220. preceeds all uses. The attributes refer to this use of the
  221. enumeration and are in addition to the attributes of the
  222. enumeration itself, which are stored inside the enuminfo *)
  223. | TBuiltin_va_list of attributes
  224. (** This is the same as the gcc's type with the same name *)
  225. (** Various kinds of integers *)
  226. and ikind =
  227. IChar (** [char] *)
  228. | ISChar (** [signed char] *)
  229. | IUChar (** [unsigned char] *)
  230. | IBool (** [_Bool (C99)] *)
  231. | IInt (** [int] *)
  232. | IUInt (** [unsigned int] *)
  233. | IShort (** [short] *)
  234. | IUShort (** [unsigned short] *)
  235. | ILong (** [long] *)
  236. | IULong (** [unsigned long] *)
  237. | ILongLong (** [long long] (or [_int64] on Microsoft Visual C) *)
  238. | IULongLong (** [unsigned long long] (or [unsigned _int64] on Microsoft
  239. Visual C) *)
  240. (** Various kinds of floating-point numbers*)
  241. and fkind =
  242. FFloat (** [float] *)
  243. | FDouble (** [double] *)
  244. | FLongDouble (** [long double] *)
  245. (** An attribute has a name and some optional parameters *)
  246. and attribute = Attr of string * attrparam list
  247. (** Attributes are lists sorted by the attribute name *)
  248. and attributes = attribute list
  249. (** The type of parameters in attributes *)
  250. and attrparam =
  251. | AInt of int (** An integer constant *)
  252. | AStr of string (** A string constant *)
  253. | ACons of string * attrparam list (** Constructed attributes. These
  254. are printed [foo(a1,a2,...,an)].
  255. The list of parameters can be
  256. empty and in that case the
  257. parentheses are not printed. *)
  258. | ASizeOf of typ (** A way to talk about types *)
  259. | ASizeOfE of attrparam
  260. | ASizeOfS of typsig (** Replacement for ASizeOf in type
  261. signatures. Only used for
  262. attributes inside typsigs.*)
  263. | AAlignOf of typ
  264. | AAlignOfE of attrparam
  265. | AAlignOfS of typsig
  266. | AUnOp of unop * attrparam
  267. | ABinOp of binop * attrparam * attrparam
  268. | ADot of attrparam * string (** a.foo **)
  269. | AStar of attrparam (** * a *)
  270. | AAddrOf of attrparam (** & a **)
  271. | AIndex of attrparam * attrparam (** a1[a2] *)
  272. | AQuestion of attrparam * attrparam * attrparam (** a1 ? a2 : a3 **)
  273. (** Information about a composite type (a struct or a union). Use
  274. {!Cil.mkCompInfo}
  275. to create non-recursive or (potentially) recursive versions of this. Make
  276. sure you have a [GCompTag] for each one of these. *)
  277. and compinfo = {
  278. mutable cstruct: bool; (** True if struct, False if union *)
  279. mutable cname: string; (** The name. Always non-empty. Use
  280. * {!Cil.compFullName} to get the
  281. * full name of a comp (along with
  282. * the struct or union) *)
  283. mutable ckey: int; (** A unique integer constructed from
  284. * the name. Use {!Hashtbl.hash} on
  285. * the string returned by
  286. * {!Cil.compFullName}. All compinfo
  287. * for a given key are shared. *)
  288. mutable cfields: fieldinfo list; (** Information about the fields *)
  289. mutable cattr: attributes; (** The attributes that are defined at
  290. the same time as the composite
  291. type *)
  292. mutable cdefined: bool; (** Whether this is a defined
  293. * compinfo. *)
  294. mutable creferenced: bool; (** True if used. Initially set to
  295. * false *)
  296. }
  297. (** Information about a struct/union field *)
  298. and fieldinfo = {
  299. mutable fcomp: compinfo; (** The compinfo of the host. Note
  300. that this must be shared with the
  301. host since there can be only one
  302. compinfo for a given id *)
  303. mutable fname: string; (** The name of the field. Might be
  304. * the value of
  305. * {!Cil.missingFieldName} in which
  306. * case it must be a bitfield and is
  307. * not printed and it does not
  308. * participate in initialization *)
  309. mutable ftype: typ; (** The type *)
  310. mutable fbitfield: int option; (** If a bitfield then ftype should be
  311. an integer type *)
  312. mutable fattr: attributes; (** The attributes for this field
  313. * (not for its type) *)
  314. mutable floc: location; (** The location where this field
  315. * is defined *)
  316. }
  317. (** Information about an enumeration. This is shared by all references to an
  318. enumeration. Make sure you have a [GEnumTag] for each of of these. *)
  319. and enuminfo = {
  320. mutable ename: string; (** The name. Always non-empty *)
  321. mutable eitems: (string * exp * location) list; (** Items with names
  322. and values. This list
  323. should be
  324. non-empty. The item
  325. values must be
  326. compile-time
  327. constants. *)
  328. mutable eattr: attributes; (** Attributes *)
  329. mutable ereferenced: bool; (** True if used. Initially set to false*)
  330. mutable ekind: ikind;
  331. (** The integer kind used to represent this enum. Per ANSI-C, this
  332. * should always be IInt, but gcc allows other integer kinds *)
  333. }
  334. (** Information about a defined type *)
  335. and typeinfo = {
  336. mutable tname: string;
  337. (** The name. Can be empty only in a [GType] when introducing a composite
  338. * or enumeration tag. If empty cannot be refered to from the file *)
  339. mutable ttype: typ;
  340. (** The actual type. *)
  341. mutable treferenced: bool;
  342. (** True if used. Initially set to false*)
  343. }
  344. (** Information about a variable. These structures are shared by all
  345. * references to the variable. So, you can change the name easily, for
  346. * example. Use one of the {!Cil.makeLocalVar}, {!Cil.makeTempVar} or
  347. * {!Cil.makeGlobalVar} to create instances of this data structure. *)
  348. and varinfo = {
  349. mutable vname: string; (** The name of the variable. Cannot
  350. * be empty. *)
  351. mutable vtype: typ; (** The declared type of the
  352. * variable. *)
  353. mutable vattr: attributes; (** A list of attributes associated
  354. * with the variable. *)
  355. mutable vstorage: storage; (** The storage-class *)
  356. (* The other fields are not used in varinfo when they appear in the formal
  357. * argument list in a [TFun] type *)
  358. mutable vglob: bool; (** True if this is a global variable*)
  359. (** Whether this varinfo is for an inline function. *)
  360. mutable vinline: bool;
  361. mutable vdecl: location; (** Location of variable declaration *)
  362. vinit: initinfo;
  363. (** Optional initializer. Only used for static and global variables.
  364. * Initializers for other types of local variables are turned into
  365. * assignments. *)
  366. mutable vid: int; (** A unique integer identifier. *)
  367. mutable vaddrof: bool; (** True if the address of this
  368. variable is taken. CIL will set
  369. * these flags when it parses C, but
  370. * you should make sure to set the
  371. * flag whenever your transformation
  372. * create [AddrOf] expression. *)
  373. mutable vreferenced: bool; (** True if this variable is ever
  374. referenced. This is computed by
  375. [removeUnusedVars]. It is safe to
  376. just initialize this to False *)
  377. mutable vdescr: doc; (** For most temporary variables, a
  378. description of what the var holds.
  379. (e.g. for temporaries used for
  380. function call results, this string
  381. is a representation of the function
  382. call.) *)
  383. mutable vdescrpure: bool; (** Indicates whether the vdescr above
  384. is a pure expression or call.
  385. True for all CIL expressions and
  386. Lvals, but false for e.g. function
  387. calls.
  388. Printing a non-pure vdescr more
  389. than once may yield incorrect
  390. results. *)
  391. }
  392. (** Storage-class information *)
  393. and storage =
  394. NoStorage | (** The default storage. Nothing is
  395. * printed *)
  396. Static |
  397. Register |
  398. Extern
  399. (** Expressions (Side-effect free)*)
  400. and exp =
  401. Const of constant (** Constant *)
  402. | Lval of lval (** Lvalue *)
  403. | SizeOf of typ (** sizeof(<type>). Has [unsigned
  404. * int] type (ISO 6.5.3.4). This is
  405. * not turned into a constant because
  406. * some transformations might want to
  407. * change types *)
  408. | SizeOfE of exp (** sizeof(<expression>) *)
  409. | SizeOfStr of string
  410. (** sizeof(string_literal). We separate this case out because this is the
  411. * only instance in which a string literal should not be treated as
  412. * having type pointer to character. *)
  413. | AlignOf of typ (** Has [unsigned int] type *)
  414. | AlignOfE of exp
  415. | UnOp of unop * exp * typ (** Unary operation. Includes
  416. the type of the result *)
  417. | BinOp of binop * exp * exp * typ
  418. (** Binary operation. Includes the
  419. type of the result. The arithemtic
  420. conversions are made explicit
  421. for the arguments *)
  422. | Question of exp * exp * exp * typ
  423. (** (a ? b : c) operation. Includes
  424. the type of the result *)
  425. | CastE of typ * exp (** Use {!Cil.mkCast} to make casts *)
  426. | AddrOf of lval (** Always use {!Cil.mkAddrOf} to
  427. * construct one of these. Apply to an
  428. * lvalue of type [T] yields an
  429. * expression of type [TPtr(T)] *)
  430. | AddrOfLabel of stmt ref
  431. | StartOf of lval (** There is no C correspondent for this. C has
  432. * implicit coercions from an array to the address
  433. * of the first element. [StartOf] is used in CIL to
  434. * simplify type checking and is just an explicit
  435. * form of the above mentioned implicit conversion.
  436. * It is not printed. Given an lval of type
  437. * [TArray(T)] produces an expression of type
  438. * [TPtr(T)]. *)
  439. (** Literal constants *)
  440. and constant =
  441. | CInt64 of int64 * ikind * string option
  442. (** Integer constant. Give the ikind (see ISO9899 6.1.3.2)
  443. * and the textual representation, if available. Use
  444. * {!Cil.integer} or {!Cil.kinteger} to create these. Watch
  445. * out for integers that cannot be represented on 64 bits.
  446. * OCAML does not give Overflow exceptions. *)
  447. | CStr of string (** String constant (of pointer type) *)
  448. | CWStr of int64 list (** Wide string constant (of type "wchar_t *") *)
  449. | CChr of char (** Character constant. This has type int, so use
  450. * charConstToInt to read the value in case
  451. * sign-extension is needed. *)
  452. | CReal of float * fkind * string option (** Floating point constant. Give
  453. the fkind (see ISO 6.4.4.2) and
  454. also the textual representation,
  455. if available *)
  456. | CEnum of exp * string * enuminfo
  457. (** An enumeration constant with the given value, name, from the given
  458. * enuminfo. This is not used if {!Cil.lowerEnum} is false (default).
  459. * Use {!Cillower.lowerEnumVisitor} to replace these with integer
  460. * constants. *)
  461. (** Unary operators *)
  462. and unop =
  463. Neg (** Unary minus *)
  464. | BNot (** Bitwise complement (~) *)
  465. | LNot (** Logical Not (!) *)
  466. (** Binary operations *)
  467. and binop =
  468. PlusA (** arithmetic + *)
  469. | PlusPI (** pointer + integer *)
  470. | IndexPI (** pointer + integer but only when
  471. * it arises from an expression
  472. * [e\[i\]] when [e] is a pointer and
  473. * not an array. This is semantically
  474. * the same as PlusPI but CCured uses
  475. * this as a hint that the integer is
  476. * probably positive. *)
  477. | MinusA (** arithmetic - *)
  478. | MinusPI (** pointer - integer *)
  479. | MinusPP (** pointer - pointer *)
  480. | Mult (** * *)
  481. | Div (** / *)
  482. | Mod (** % *)
  483. | Shiftlt (** shift left *)
  484. | Shiftrt (** shift right *)
  485. | Lt (** < (arithmetic comparison) *)
  486. | Gt (** > (arithmetic comparison) *)
  487. | Le (** <= (arithmetic comparison) *)
  488. | Ge (** > (arithmetic comparison) *)
  489. | Eq (** == (arithmetic comparison) *)
  490. | Ne (** != (arithmetic comparison) *)
  491. | BAnd (** bitwise and *)
  492. | BXor (** exclusive-or *)
  493. | BOr (** inclusive-or *)
  494. | LAnd (** logical and *)
  495. | LOr (** logical or *)
  496. (** An lvalue denotes the contents of a range of memory addresses. This range
  497. * is denoted as a host object along with an offset within the object. The
  498. * host object can be of two kinds: a local or global variable, or an object
  499. * whose address is in a pointer expression. We distinguish the two cases so
  500. * that we can tell quickly whether we are accessing some component of a
  501. * variable directly or we are accessing a memory location through a pointer.*)
  502. and lval =
  503. lhost * offset
  504. (** The host part of an {!Cil.lval}. *)
  505. and lhost =
  506. | Var of varinfo
  507. (** The host is a variable. *)
  508. | Mem of exp
  509. (** The host is an object of type [T] when the expression has pointer
  510. * [TPtr(T)]. *)
  511. (** The offset part of an {!Cil.lval}. Each offset can be applied to certain
  512. * kinds of lvalues and its effect is that it advances the starting address
  513. * of the lvalue and changes the denoted type, essentially focussing to some
  514. * smaller lvalue that is contained in the original one. *)
  515. and offset =
  516. | NoOffset (** No offset. Can be applied to any lvalue and does
  517. * not change either the starting address or the type.
  518. * This is used when the lval consists of just a host
  519. * or as a terminator in a list of other kinds of
  520. * offsets. *)
  521. | Field of fieldinfo * offset
  522. (** A field offset. Can be applied only to an lvalue
  523. * that denotes a structure or a union that contains
  524. * the mentioned field. This advances the offset to the
  525. * beginning of the mentioned field and changes the
  526. * type to the type of the mentioned field. *)
  527. | Index of exp * offset
  528. (** An array index offset. Can be applied only to an
  529. * lvalue that denotes an array. This advances the
  530. * starting address of the lval to the beginning of the
  531. * mentioned array element and changes the denoted type
  532. * to be the type of the array element *)
  533. (* The following equivalences hold *)
  534. (* Mem(AddrOf(Mem a, aoff)), off = Mem a, aoff + off *)
  535. (* Mem(AddrOf(Var v, aoff)), off = Var v, aoff + off *)
  536. (* AddrOf (Mem a, NoOffset) = a *)
  537. (** Initializers for global variables. You can create an initializer with
  538. * {!Cil.makeZeroInit}. *)
  539. and init =
  540. | SingleInit of exp (** A single initializer *)
  541. | CompoundInit of typ * (offset * init) list
  542. (** Used only for initializers of structures, unions and arrays.
  543. * The offsets are all of the form [Field(f, NoOffset)] or
  544. * [Index(i, NoOffset)] and specify the field or the index being
  545. * initialized. For structures all fields
  546. * must have an initializer (except the unnamed bitfields), in
  547. * the proper order. This is necessary since the offsets are not
  548. * printed. For arrays the list must contain a prefix of the
  549. * initializers; the rest are 0-initialized.
  550. * For unions there must be exactly one initializer. If
  551. * the initializer is not for the first field then a field
  552. * designator is printed, so you better be on GCC since MSVC does
  553. * not understand this. You can scan an initializer list with
  554. * {!Cil.foldLeftCompound}. *)
  555. (** We want to be able to update an initializer in a global variable, so we
  556. * define it as a mutable field *)
  557. and initinfo = {
  558. mutable init : init option;
  559. }
  560. (** Function definitions. *)
  561. and fundec =
  562. { mutable svar: varinfo;
  563. (** Holds the name and type as a variable, so we can refer to it
  564. * easily from the program. All references to this function either
  565. * in a function call or in a prototype must point to the same
  566. * varinfo. *)
  567. mutable sformals: varinfo list;
  568. (** Formals. These must be shared with the formals that appear in the
  569. * type of the function. Use {!Cil.setFormals} or
  570. * {!Cil.setFunctionType} to set these
  571. * formals and ensure that they are reflected in the function type.
  572. * Do not make copies of these because the body refers to them. *)
  573. mutable slocals: varinfo list;
  574. (** Locals. Does not include the sformals. Do not make copies of
  575. * these because the body refers to them. *)
  576. mutable smaxid: int; (** Max local id. Starts at 0. *)
  577. mutable sbody: block; (** The function body. *)
  578. mutable smaxstmtid: int option; (** max id of a (reachable) statement
  579. * in this function, if we have
  580. * computed it. range = 0 ...
  581. * (smaxstmtid-1). This is computed by
  582. * {!Cil.computeCFGInfo}. *)
  583. mutable sallstmts: stmt list; (** After you call {!Cil.computeCFGInfo}
  584. * this field is set to contain all
  585. * statements in the function *)
  586. }
  587. (** A block is a sequence of statements with the control falling through from
  588. one element to the next *)
  589. and block =
  590. { mutable battrs: attributes; (** Attributes for the block *)
  591. mutable bstmts: stmt list; (** The statements comprising the block*)
  592. }
  593. (** Statements.
  594. The statement is the structural unit in the control flow graph. Use mkStmt
  595. to make a statement and then fill in the fields. *)
  596. and stmt = {
  597. mutable labels: label list; (** Whether the statement starts with
  598. some labels, case statements or
  599. default statement *)
  600. mutable skind: stmtkind; (** The kind of statement *)
  601. (* Now some additional control flow information. Initially this is not
  602. * filled in. *)
  603. mutable sid: int; (** A number (>= 0) that is unique
  604. in a function. *)
  605. mutable succs: stmt list; (** The successor statements. They can
  606. always be computed from the skind
  607. and the context in which this
  608. statement appears *)
  609. mutable preds: stmt list; (** The inverse of the succs function*)
  610. }
  611. (** Labels *)
  612. and label =
  613. Label of string * location * bool
  614. (** A real label. If the bool is "true", the label is from the
  615. * input source program. If the bool is "false", the label was
  616. * created by CIL or some other transformation *)
  617. | Case of exp * location (** A case statement *)
  618. | CaseRange of exp * exp * location (** A case statement corresponding to a
  619. range of values *)
  620. | Default of location (** A default statement *)
  621. (* The various kinds of statements *)
  622. and stmtkind =
  623. | Instr of instr list (** A group of instructions that do not
  624. contain control flow. Control
  625. implicitly falls through. *)
  626. | Return of exp option * location (** The return statement. This is a
  627. leaf in the CFG. *)
  628. | Goto of stmt ref * location (** A goto statement. Appears from
  629. actual goto's in the code. *)
  630. | ComputedGoto of exp * location
  631. | Break of location (** A break to the end of the nearest
  632. enclosing Loop or Switch *)
  633. | Continue of location (** A continue to the start of the
  634. nearest enclosing [Loop] *)
  635. | If of exp * block * block * location (** A conditional.
  636. Two successors, the "then" and
  637. the "else" branches. Both
  638. branches fall-through to the
  639. successor of the If statement *)
  640. | Switch of exp * block * (stmt list) * location
  641. (** A switch statement. The block
  642. contains within all of the cases.
  643. We also have direct pointers to the
  644. statements that implement the
  645. cases. Which cases they implement
  646. you can get from the labels of the
  647. statement *)
  648. | Loop of block * location * (stmt option) * (stmt option)
  649. (** A [while(1)] loop. The
  650. * termination test is implemented
  651. * in the body of a loop using a
  652. * [Break] statement. If
  653. * prepareCFG has been called, the
  654. * first stmt option will point to
  655. * the stmt containing the
  656. * continue label for this loop
  657. * and the second will point to
  658. * the stmt containing the break
  659. * label for this loop. *)
  660. | Block of block (** Just a block of statements. Use it
  661. as a way to keep some attributes
  662. local *)
  663. (** On MSVC we support structured exception handling. This is what you
  664. * might expect. Control can get into the finally block either from the
  665. * end of the body block, or if an exception is thrown. The location
  666. * corresponds to the try keyword. *)
  667. | TryFinally of block * block * location
  668. (** On MSVC we support structured exception handling. The try/except
  669. * statement is a bit tricky:
  670. __try { blk }
  671. __except (e) {
  672. handler
  673. }
  674. The argument to __except must be an expression. However, we keep a
  675. list of instructions AND an expression in case you need to make
  676. function calls. We'll print those as a comma expression. The control
  677. can get to the __except expression only if an exception is thrown.
  678. After that, depending on the value of the expression the control
  679. goes to the handler, propagates the exception, or retries the
  680. exception !!! The location corresponds to the try keyword.
  681. *)
  682. | TryExcept of block * (instr list * exp) * block * location
  683. (** Instructions. They may cause effects directly but may not have control
  684. flow.*)
  685. and instr =
  686. Set of lval * exp * location (** An assignment. A cast is present
  687. if the exp has different type
  688. from lval *)
  689. | Call of lval option * exp * exp list * location
  690. (** optional: result is an lval. A cast might be
  691. necessary if the declared result type of the
  692. function is not the same as that of the
  693. destination. If the function is declared then
  694. casts are inserted for those arguments that
  695. correspond to declared formals. (The actual
  696. number of arguments might be smaller or larger
  697. than the declared number of arguments. C allows
  698. this.) If the type of the result variable is not
  699. the same as the declared type of the function
  700. result then an implicit cast exists. *)
  701. (* See the GCC specification for the meaning of ASM.
  702. * If the source is MS VC then only the templates
  703. * are used *)
  704. (* sm: I've added a notes.txt file which contains more
  705. * information on interpreting Asm instructions *)
  706. | Asm of attributes * (* Really only const and volatile can appear
  707. * here *)
  708. string list * (* templates (CR-separated) *)
  709. (string option * string * lval) list *
  710. (* outputs must be lvals with
  711. * optional names and constraints.
  712. * I would like these
  713. * to be actually variables, but I
  714. * run into some trouble with ASMs
  715. * in the Linux sources *)
  716. (string option * string * exp) list *
  717. (* inputs with optional names and constraints *)
  718. string list * (* register clobbers *)
  719. location
  720. (** An inline assembly instruction. The arguments are (1) a list of
  721. attributes (only const and volatile can appear here and only for
  722. GCC), (2) templates (CR-separated), (3) a list of
  723. outputs, each of which is an lvalue with a constraint, (4) a list
  724. of input expressions along with constraints, (5) clobbered
  725. registers, and (5) location information *)
  726. (** Describes a location in a source file *)
  727. and location = {
  728. line: int; (** The line number. -1 means "do not know" *)
  729. file: string; (** The name of the source file*)
  730. byte: int; (** The byte position in the source file *)
  731. }
  732. (* Type signatures. Two types are identical iff they have identical
  733. * signatures *)
  734. and typsig =
  735. TSArray of typsig * int64 option * attribute list
  736. | TSPtr of typsig * attribute list
  737. | TSComp of bool * string * attribute list
  738. | TSFun of typsig * typsig list option * bool * attribute list
  739. | TSEnum of string * attribute list
  740. | TSBase of typ
  741. let locUnknown = { line = -1;
  742. file = "";
  743. byte = -1;}
  744. (* A reference to the current location *)
  745. let currentLoc : location ref = ref locUnknown
  746. (* A reference to the current global being visited *)
  747. let currentGlobal: global ref = ref (GText "dummy")
  748. let compareLoc (a: location) (b: location) : int =
  749. let namecmp = compare a.file b.file in
  750. if namecmp != 0
  751. then namecmp
  752. else
  753. let linecmp = a.line - b.line in
  754. if linecmp != 0
  755. then linecmp
  756. else a.byte - b.byte
  757. let argsToList : (string * typ * attributes) list option
  758. -> (string * typ * attributes) list
  759. = function
  760. None -> []
  761. | Some al -> al
  762. (* A hack to allow forward reference of d_exp *)
  763. let pd_exp : (unit -> exp -> doc) ref =
  764. ref (fun _ -> E.s (E.bug "pd_exp not initialized"))
  765. let pd_type : (unit -> typ -> doc) ref =
  766. ref (fun _ -> E.s (E.bug "pd_type not initialized"))
  767. let pd_attr : (unit -> attribute -> doc) ref =
  768. ref (fun _ -> E.s (E.bug "pd_attr not initialized"))
  769. (** Different visiting actions. 'a will be instantiated with [exp], [instr],
  770. etc. *)
  771. type 'a visitAction =
  772. SkipChildren (** Do not visit the children. Return
  773. the node as it is. *)
  774. | DoChildren (** Continue with the children of this
  775. node. Rebuild the node on return
  776. if any of the children changes
  777. (use == test) *)
  778. | ChangeTo of 'a (** Replace the expression with the
  779. given one *)
  780. | ChangeDoChildrenPost of 'a * ('a -> 'a) (** First consider that the entire
  781. exp is replaced by the first
  782. parameter. Then continue with
  783. the children. On return rebuild
  784. the node if any of the children
  785. has changed and then apply the
  786. function on the node *)
  787. (* sm/gn: cil visitor interface for traversing Cil trees. *)
  788. (* Use visitCilStmt and/or visitCilFile to use this. *)
  789. (* Some of the nodes are changed in place if the children are changed. Use
  790. * one of Change... actions if you want to copy the node *)
  791. (** A visitor interface for traversing CIL trees. Create instantiations of
  792. * this type by specializing the class {!Cil.nopCilVisitor}. *)
  793. class type cilVisitor = object
  794. method vvdec: varinfo -> varinfo visitAction
  795. (** Invoked for each variable declaration. The subtrees to be traversed
  796. * are those corresponding to the type and attributes of the variable.
  797. * Note that variable declarations are all the [GVar], [GVarDecl], [GFun],
  798. * all the [varinfo] in formals of function types, and the formals and
  799. * locals for function definitions. This means that the list of formals
  800. * in a function definition will be traversed twice, once as part of the
  801. * function type and second as part of the formals in a function
  802. * definition. *)
  803. method vvrbl: varinfo -> varinfo visitAction
  804. (** Invoked on each variable use. Here only the [SkipChildren] and
  805. * [ChangeTo] actions make sense since there are no subtrees. Note that
  806. * the type and attributes of the variable are not traversed for a
  807. * variable use *)
  808. method vexpr: exp -> exp visitAction
  809. (** Invoked on each expression occurence. The subtrees are the
  810. * subexpressions, the types (for a [Cast] or [SizeOf] expression) or the
  811. * variable use. *)
  812. method vlval: lval -> lval visitAction
  813. (** Invoked on each lvalue occurence *)
  814. method voffs: offset -> offset visitAction
  815. (** Invoked on each offset occurrence that is *not* as part
  816. * of an initializer list specification, i.e. in an lval or
  817. * recursively inside an offset. *)
  818. method vinitoffs: offset -> offset visitAction
  819. (** Invoked on each offset appearing in the list of a
  820. * CompoundInit initializer. *)
  821. method vinst: instr -> instr list visitAction
  822. (** Invoked on each instruction occurrence. The [ChangeTo] action can
  823. * replace this instruction with a list of instructions *)
  824. method vstmt: stmt -> stmt visitAction
  825. (** Control-flow statement. *)
  826. method vblock: block -> block visitAction (** Block. Replaced in
  827. place. *)
  828. method vfunc: fundec -> fundec visitAction (** Function definition.
  829. Replaced in place. *)
  830. method vglob: global -> global list visitAction (** Global (vars, types,
  831. etc.) *)
  832. method vinit: varinfo -> offset -> init -> init visitAction
  833. (** Initializers for globals,
  834. * pass the global where this
  835. * occurs, and the offset *)
  836. method vtype: typ -> typ visitAction (** Use of some type. Note
  837. * that for structure/union
  838. * and enumeration types the
  839. * definition of the
  840. * composite type is not
  841. * visited. Use [vglob] to
  842. * visit it. *)
  843. method vattr: attribute -> attribute list visitAction
  844. (** Attribute. Each attribute can be replaced by a list *)
  845. method vattrparam: attrparam -> attrparam visitAction
  846. (** Attribute parameters. *)
  847. (** Add here instructions while visiting to queue them to
  848. * preceede the current statement or instruction being processed *)
  849. method queueInstr: instr list -> unit
  850. (** Gets the queue of instructions and resets the queue *)
  851. method unqueueInstr: unit -> instr list
  852. end
  853. (* the default visitor does nothing at each node, but does *)
  854. (* not stop; hence they return true *)
  855. class nopCilVisitor : cilVisitor = object
  856. method vvrbl (v:varinfo) = DoChildren (* variable *)
  857. method vvdec (v:varinfo) = DoChildren (* variable
  858. * declaration *)
  859. method vexpr (e:exp) = DoChildren (* expression *)
  860. method vlval (l:lval) = DoChildren (* lval (base is 1st
  861. * field) *)
  862. method voffs (o:offset) = DoChildren (* lval or recursive offset *)

Large files files are truncated, but you can click here to view the full file