summaryrefslogtreecommitdiff
path: root/cil/src/cil.mli
diff options
context:
space:
mode:
Diffstat (limited to 'cil/src/cil.mli')
-rw-r--r--cil/src/cil.mli2455
1 files changed, 0 insertions, 2455 deletions
diff --git a/cil/src/cil.mli b/cil/src/cil.mli
deleted file mode 100644
index 31c4e65..0000000
--- a/cil/src/cil.mli
+++ /dev/null
@@ -1,2455 +0,0 @@
-(* MODIF: Loop constructor replaced by 3 constructors: While, DoWhile, For. *)
-
-(*
- *
- * Copyright (c) 2001-2002,
- * George C. Necula <necula@cs.berkeley.edu>
- * Scott McPeak <smcpeak@cs.berkeley.edu>
- * Wes Weimer <weimer@cs.berkeley.edu>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. The names of the contributors may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *)
-
-(*
- * CIL: An intermediate language for analyzing C programs.
- *
- * George Necula
- *
- *)
-
-(** CIL API Documentation. An html version of this document can be found at
- * http://manju.cs.berkeley.edu/cil. *)
-
-(** Call this function to perform some initialization. Call if after you have
- * set {!Cil.msvcMode}. *)
-val initCIL: unit -> unit
-
-
-(** This are the CIL version numbers. A CIL version is a number of the form
- * M.m.r (major, minor and release) *)
-val cilVersion: string
-val cilVersionMajor: int
-val cilVersionMinor: int
-val cilVersionRevision: int
-
-(** This module defines the abstract syntax of CIL. It also provides utility
- * functions for traversing the CIL data structures, and pretty-printing
- * them. The parser for both the GCC and MSVC front-ends can be invoked as
- * [Frontc.parse: string -> unit ->] {!Cil.file}. This function must be given
- * the name of a preprocessed C file and will return the top-level data
- * structure that describes a whole source file. By default the parsing and
- * elaboration into CIL is done as for GCC source. If you want to use MSVC
- * source you must set the {!Cil.msvcMode} to [true] and must also invoke the
- * function [Frontc.setMSVCMode: unit -> unit]. *)
-
-
-(** {b The Abstract Syntax of CIL} *)
-
-
-(** The top-level representation of a CIL source file (and the result of the
- * parsing and elaboration). Its main contents is the list of global
- * declarations and definitions. You can iterate over the globals in a
- * {!Cil.file} using the following iterators: {!Cil.mapGlobals},
- * {!Cil.iterGlobals} and {!Cil.foldGlobals}. You can also use the
- * {!Cil.dummyFile} when you need a {!Cil.file} as a placeholder. For each
- * global item CIL stores the source location where it appears (using the
- * type {!Cil.location}) *)
-
-type file =
- { mutable fileName: string; (** The complete file name *)
- mutable globals: global list; (** List of globals as they will appear
- in the printed file *)
- mutable globinit: fundec option;
- (** An optional global initializer function. This is a function where
- * you can put stuff that must be executed before the program is
- * started. This function, is conceptually at the end of the file,
- * although it is not part of the globals list. Use {!Cil.getGlobInit}
- * to create/get one. *)
- mutable globinitcalled: bool;
- (** Whether the global initialization function is called in main. This
- * should always be false if there is no global initializer. When you
- * create a global initialization CIL will try to insert code in main
- * to call it. This will not happen if your file does not contain a
- * function called "main" *)
- }
-(** Top-level representation of a C source file *)
-
-and comment = location * string
-
-(** {b Globals}. The main type for representing global declarations and
- * definitions. A list of these form a CIL file. The order of globals in the
- * file is generally important. *)
-
-(** A global declaration or definition *)
-and global =
- | GType of typeinfo * location
- (** A typedef. All uses of type names (through the [TNamed] constructor)
- must be preceded in the file by a definition of the name. The string
- is the defined name and always not-empty. *)
-
- | GCompTag of compinfo * location
- (** Defines a struct/union tag with some fields. There must be one of
- these for each struct/union tag that you use (through the [TComp]
- constructor) since this is the only context in which the fields are
- printed. Consequently nested structure tag definitions must be
- broken into individual definitions with the innermost structure
- defined first. *)
-
- | GCompTagDecl of compinfo * location
- (** Declares a struct/union tag. Use as a forward declaration. This is
- * printed without the fields. *)
-
- | GEnumTag of enuminfo * location
- (** Declares an enumeration tag with some fields. There must be one of
- these for each enumeration tag that you use (through the [TEnum]
- constructor) since this is the only context in which the items are
- printed. *)
-
- | GEnumTagDecl of enuminfo * location
- (** Declares an enumeration tag. Use as a forward declaration. This is
- * printed without the items. *)
-
- | GVarDecl of varinfo * location
- (** A variable declaration (not a definition). If the variable has a
- function type then this is a prototype. There can be several
- declarations and at most one definition for a given variable. If both
- forms appear then they must share the same varinfo structure. A
- prototype shares the varinfo with the fundec of the definition. Either
- has storage Extern or there must be a definition in this file *)
-
- | GVar of varinfo * initinfo * location
- (** A variable definition. Can have an initializer. The initializer is
- * updateable so that you can change it without requiring to recreate
- * the list of globals. There can be at most one definition for a
- * variable in an entire program. Cannot have storage Extern or function
- * type. *)
-
- | GFun of fundec * location
- (** A function definition. *)
-
- | GAsm of string * location (** Global asm statement. These ones
- can contain only a template *)
- | GPragma of attribute * location (** Pragmas at top level. Use the same
- syntax as attributes *)
- | GText of string (** Some text (printed verbatim) at
- top level. E.g., this way you can
- put comments in the output. *)
-
-(** {b Types}. A C type is represented in CIL using the type {!Cil.typ}.
- * Among types we differentiate the integral types (with different kinds
- * denoting the sign and precision), floating point types, enumeration types,
- * array and pointer types, and function types. Every type is associated with
- * a list of attributes, which are always kept in sorted order. Use
- * {!Cil.addAttribute} and {!Cil.addAttributes} to construct list of
- * attributes. If you want to inspect a type, you should use
- * {!Cil.unrollType} or {!Cil.unrollTypeDeep} to see through the uses of
- * named types. *)
-(** CIL is configured at build-time with the sizes and alignments of the
- * underlying compiler (GCC or MSVC). CIL contains functions that can compute
- * the size of a type (in bits) {!Cil.bitsSizeOf}, the alignment of a type
- * (in bytes) {!Cil.alignOf_int}, and can convert an offset into a start and
- * width (both in bits) using the function {!Cil.bitsOffset}. At the moment
- * these functions do not take into account the [packed] attributes and
- * pragmas. *)
-
-and typ =
- TVoid of attributes (** Void type. Also predefined as {!Cil.voidType} *)
- | TInt of ikind * attributes
- (** An integer type. The kind specifies the sign and width. Several
- * useful variants are predefined as {!Cil.intType}, {!Cil.uintType},
- * {!Cil.longType}, {!Cil.charType}. *)
-
-
- | TFloat of fkind * attributes
- (** A floating-point type. The kind specifies the precision. You can
- * also use the predefined constant {!Cil.doubleType}. *)
-
- | TPtr of typ * attributes
- (** Pointer type. Several useful variants are predefined as
- * {!Cil.charPtrType}, {!Cil.charConstPtrType} (pointer to a
- * constant character), {!Cil.voidPtrType},
- * {!Cil.intPtrType} *)
-
- | TArray of typ * exp option * attributes
- (** Array type. It indicates the base type and the array length. *)
-
- | TFun of typ * (string * typ * attributes) list option * bool * attributes
- (** Function type. Indicates the type of the result, the name, type
- * and name attributes of the formal arguments ([None] if no
- * arguments were specified, as in a function whose definition or
- * prototype we have not seen; [Some \[\]] means void). Use
- * {!Cil.argsToList} to obtain a list of arguments. The boolean
- * indicates if it is a variable-argument function. If this is the
- * type of a varinfo for which we have a function declaration then
- * the information for the formals must match that in the
- * function's sformals. Use {!Cil.setFormals}, or
- * {!Cil.setFunctionType}, or {!Cil.makeFormalVar} for this
- * purpose. *)
-
- | TNamed of typeinfo * attributes
- (* The use of a named type. Each such type name must be preceded
- * in the file by a [GType] global. This is printed as just the
- * type name. The actual referred type is not printed here and is
- * carried only to simplify processing. To see through a sequence
- * of named type references, use {!Cil.unrollType} or
- * {!Cil.unrollTypeDeep}. The attributes are in addition to those
- * given when the type name was defined. *)
-
- | TComp of compinfo * attributes
-(** The most delicate issue for C types is that recursion that is possible by
- * using structures and pointers. To address this issue we have a more
- * complex representation for structured types (struct and union). Each such
- * type is represented using the {!Cil.compinfo} type. For each composite
- * type the {!Cil.compinfo} structure must be declared at top level using
- * [GCompTag] and all references to it must share the same copy of the
- * structure. The attributes given are those pertaining to this use of the
- * type and are in addition to the attributes that were given at the
- * definition of the type and which are stored in the {!Cil.compinfo}. *)
-
- | TEnum of enuminfo * attributes
- (** A reference to an enumeration type. All such references must
- share the enuminfo among them and with a [GEnumTag] global that
- precedes all uses. The attributes refer to this use of the
- enumeration and are in addition to the attributes of the
- enumeration itself, which are stored inside the enuminfo *)
-
-
- | TBuiltin_va_list of attributes
- (** This is the same as the gcc's type with the same name *)
-
-(**
- There are a number of functions for querying the kind of a type. These are
- {!Cil.isIntegralType},
- {!Cil.isArithmeticType},
- {!Cil.isPointerType},
- {!Cil.isFunctionType},
- {!Cil.isArrayType}.
-
- There are two easy ways to scan a type. First, you can use the
-{!Cil.existsType} to return a boolean answer about a type. This function
-is controlled by a user-provided function that is queried for each type that is
-used to construct the current type. The function can specify whether to
-terminate the scan with a boolean result or to continue the scan for the
-nested types.
-
- The other method for scanning types is provided by the visitor interface (see
- {!Cil.cilVisitor}).
-
- If you want to compare types (or to use them as hash-values) then you should
-use instead type signatures (represented as {!Cil.typsig}). These
-contain the same information as types but canonicalized such that simple Ocaml
-structural equality will tell whether two types are equal. Use
-{!Cil.typeSig} to compute the signature of a type. If you want to ignore
-certain type attributes then use {!Cil.typeSigWithAttrs}.
-
-*)
-
-
-(** Various kinds of integers *)
-and ikind =
- IChar (** [char] *)
- | ISChar (** [signed char] *)
- | IUChar (** [unsigned char] *)
- | IInt (** [int] *)
- | IUInt (** [unsigned int] *)
- | IShort (** [short] *)
- | IUShort (** [unsigned short] *)
- | ILong (** [long] *)
- | IULong (** [unsigned long] *)
- | ILongLong (** [long long] (or [_int64] on Microsoft Visual C) *)
- | IULongLong (** [unsigned long long] (or [unsigned _int64] on Microsoft
- Visual C) *)
-
-(** Various kinds of floating-point numbers*)
-and fkind =
- FFloat (** [float] *)
- | FDouble (** [double] *)
- | FLongDouble (** [long double] *)
-
-
-(** {b Attributes.} *)
-
-and attribute = Attr of string * attrparam list
-(** An attribute has a name and some optional parameters. The name should not
- * start or end with underscore. When CIL parses attribute names it will
- * strip leading and ending underscores (to ensure that the multitude of GCC
- * attributes such as const, __const and __const__ all mean the same thing.) *)
-
-(** Attributes are lists sorted by the attribute name. Use the functions
- * {!Cil.addAttribute} and {!Cil.addAttributes} to insert attributes in an
- * attribute list and maintain the sortedness. *)
-and attributes = attribute list
-
-(** The type of parameters of attributes *)
-and attrparam =
- | AInt of int (** An integer constant *)
- | AStr of string (** A string constant *)
- | ACons of string * attrparam list (** Constructed attributes. These
- are printed [foo(a1,a2,...,an)].
- The list of parameters can be
- empty and in that case the
- parentheses are not printed. *)
- | ASizeOf of typ (** A way to talk about types *)
- | ASizeOfE of attrparam
- | ASizeOfS of typsig (** Replacement for ASizeOf in type
- signatures. Only used for
- attributes inside typsigs.*)
- | AAlignOf of typ
- | AAlignOfE of attrparam
- | AAlignOfS of typsig
- | AUnOp of unop * attrparam
- | ABinOp of binop * attrparam * attrparam
- | ADot of attrparam * string (** a.foo **)
-
-(** {b Structures.} The {!Cil.compinfo} describes the definition of a
- * structure or union type. Each such {!Cil.compinfo} must be defined at the
- * top-level using the [GCompTag] constructor and must be shared by all
- * references to this type (using either the [TComp] type constructor or from
- * the definition of the fields.
-
- If all you need is to scan the definition of each
- * composite type once, you can do that by scanning all top-level [GCompTag].
-
- * Constructing a {!Cil.compinfo} can be tricky since it must contain fields
- * that might refer to the host {!Cil.compinfo} and furthermore the type of
- * the field might need to refer to the {!Cil.compinfo} for recursive types.
- * Use the {!Cil.mkCompInfo} function to create a {!Cil.compinfo}. You can
- * easily fetch the {!Cil.fieldinfo} for a given field in a structure with
- * {!Cil.getCompField}. *)
-
-(** The definition of a structure or union type. Use {!Cil.mkCompInfo} to
- * make one and use {!Cil.copyCompInfo} to copy one (this ensures that a new
- * key is assigned and that the fields have the right pointers to parents.). *)
-and compinfo = {
- mutable cstruct: bool;
- (** True if struct, False if union *)
- mutable cname: string;
- (** The name. Always non-empty. Use {!Cil.compFullName} to get the full
- * name of a comp (along with the struct or union) *)
- mutable ckey: int;
- (** A unique integer. This is assigned by {!Cil.mkCompInfo} using a
- * global variable in the Cil module. Thus two identical structs in two
- * different files might have different keys. Use {!Cil.copyCompInfo} to
- * copy structures so that a new key is assigned. *)
- mutable cfields: fieldinfo list;
- (** Information about the fields. Notice that each fieldinfo has a
- * pointer back to the host compinfo. This means that you should not
- * share fieldinfo's between two compinfo's *)
- mutable cattr: attributes;
- (** The attributes that are defined at the same time as the composite
- * type. These attributes can be supplemented individually at each
- * reference to this [compinfo] using the [TComp] type constructor. *)
- mutable cdefined: bool;
- (** This boolean flag can be used to distinguish between structures
- that have not been defined and those that have been defined but have
- no fields (such things are allowed in gcc). *)
- mutable creferenced: bool;
- (** True if used. Initially set to false. *)
- }
-
-(** {b Structure fields.} The {!Cil.fieldinfo} structure is used to describe
- * a structure or union field. Fields, just like variables, can have
- * attributes associated with the field itself or associated with the type of
- * the field (stored along with the type of the field). *)
-
-(** Information about a struct/union field *)
-and fieldinfo = {
- mutable fcomp: compinfo;
- (** The host structure that contains this field. There can be only one
- * [compinfo] that contains the field. *)
- mutable fname: string;
- (** The name of the field. Might be the value of {!Cil.missingFieldName}
- * in which case it must be a bitfield and is not printed and it does not
- * participate in initialization *)
- mutable ftype: typ;
- (** The type *)
- mutable fbitfield: int option;
- (** If a bitfield then ftype should be an integer type and the width of
- * the bitfield must be 0 or a positive integer smaller or equal to the
- * width of the integer type. A field of width 0 is used in C to control
- * the alignment of fields. *)
- mutable fattr: attributes;
- (** The attributes for this field (not for its type) *)
- mutable floc: location;
- (** The location where this field is defined *)
-}
-
-
-
-(** {b Enumerations.} Information about an enumeration. This is shared by all
- * references to an enumeration. Make sure you have a [GEnumTag] for each of
- * of these. *)
-
-(** Information about an enumeration *)
-and enuminfo = {
- mutable ename: string;
- (** The name. Always non-empty. *)
- mutable eitems: (string * exp * location) list;
- (** Items with names and values. This list should be non-empty. The item
- * values must be compile-time constants. *)
- mutable eattr: attributes;
- (** The attributes that are defined at the same time as the enumeration
- * type. These attributes can be supplemented individually at each
- * reference to this [enuminfo] using the [TEnum] type constructor. *)
- mutable ereferenced: bool;
- (** True if used. Initially set to false*)
-}
-
-(** {b Enumerations.} Information about an enumeration. This is shared by all
- * references to an enumeration. Make sure you have a [GEnumTag] for each of
- * of these. *)
-
-(** Information about a defined type *)
-and typeinfo = {
- mutable tname: string;
- (** The name. Can be empty only in a [GType] when introducing a composite
- * or enumeration tag. If empty cannot be referred to from the file *)
- mutable ttype: typ;
- (** The actual type. This includes the attributes that were present in
- * the typedef *)
- mutable treferenced: bool;
- (** True if used. Initially set to false*)
-}
-
-(** {b Variables.}
- Each local or global variable is represented by a unique {!Cil.varinfo}
-structure. A global {!Cil.varinfo} can be introduced with the [GVarDecl] or
-[GVar] or [GFun] globals. A local varinfo can be introduced as part of a
-function definition {!Cil.fundec}.
-
- All references to a given global or local variable must refer to the same
-copy of the [varinfo]. Each [varinfo] has a globally unique identifier that
-can be used to index maps and hashtables (the name can also be used for this
-purpose, except for locals from different functions). This identifier is
-constructor using a global counter.
-
- It is very important that you construct [varinfo] structures using only one
- of the following functions:
-- {!Cil.makeGlobalVar} : to make a global variable
-- {!Cil.makeTempVar} : to make a temporary local variable whose name
-will be generated so that to avoid conflict with other locals.
-- {!Cil.makeLocalVar} : like {!Cil.makeTempVar} but you can specify the
-exact name to be used.
-- {!Cil.copyVarinfo}: make a shallow copy of a varinfo assigning a new name
-and a new unique identifier
-
- A [varinfo] is also used in a function type to denote the list of formals.
-
-*)
-
-(** Information about a variable. *)
-and varinfo = {
- mutable vname: string;
- (** The name of the variable. Cannot be empty. It is primarily your
- * responsibility to ensure the uniqueness of a variable name. For local
- * variables {!Cil.makeTempVar} helps you ensure that the name is unique.
- *)
-
- mutable vtype: typ;
- (** The declared type of the variable. *)
-
- mutable vattr: attributes;
- (** A list of attributes associated with the variable.*)
- mutable vstorage: storage;
- (** The storage-class *)
-
- mutable vglob: bool;
- (** True if this is a global variable*)
-
- mutable vinline: bool;
- (** Whether this varinfo is for an inline function. *)
-
- mutable vdecl: location;
- (** Location of variable declaration. *)
-
- mutable vid: int;
- (** A unique integer identifier. This field will be
- * set for you if you use one of the {!Cil.makeFormalVar},
- * {!Cil.makeLocalVar}, {!Cil.makeTempVar}, {!Cil.makeGlobalVar}, or
- * {!Cil.copyVarinfo}. *)
-
- mutable vaddrof: bool;
- (** True if the address of this variable is taken. CIL will set these
- * flags when it parses C, but you should make sure to set the flag
- * whenever your transformation create [AddrOf] expression. *)
-
- mutable vreferenced: bool;
- (** True if this variable is ever referenced. This is computed by
- * [removeUnusedVars]. It is safe to just initialize this to False *)
-}
-
-(** Storage-class information *)
-and storage =
- NoStorage (** The default storage. Nothing is printed *)
- | Static
- | Register
- | Extern
-
-
-(** {b Expressions.} The CIL expression language contains only the side-effect free expressions of
-C. They are represented as the type {!Cil.exp}. There are several
-interesting aspects of CIL expressions:
-
- Integer and floating point constants can carry their textual representation.
-This way the integer 15 can be printed as 0xF if that is how it occurred in the
-source.
-
- CIL uses 64 bits to represent the integer constants and also stores the width
-of the integer type. Care must be taken to ensure that the constant is
-representable with the given width. Use the functions {!Cil.kinteger},
-{!Cil.kinteger64} and {!Cil.integer} to construct constant
-expressions. CIL predefines the constants {!Cil.zero},
-{!Cil.one} and {!Cil.mone} (for -1).
-
- Use the functions {!Cil.isConstant} and {!Cil.isInteger} to test if
-an expression is a constant and a constant integer respectively.
-
- CIL keeps the type of all unary and binary expressions. You can think of that
-type qualifying the operator. Furthermore there are different operators for
-arithmetic and comparisons on arithmetic types and on pointers.
-
- Another unusual aspect of CIL is that the implicit conversion between an
-expression of array type and one of pointer type is made explicit, using the
-[StartOf] expression constructor (which is not printed). If you apply the
-[AddrOf}]constructor to an lvalue of type [T] then you will be getting an
-expression of type [TPtr(T)].
-
- You can find the type of an expression with {!Cil.typeOf}.
-
- You can perform constant folding on expressions using the function
-{!Cil.constFold}.
-*)
-
-(** Expressions (Side-effect free)*)
-and exp =
- Const of constant (** Constant *)
- | Lval of lval (** Lvalue *)
- | SizeOf of typ
- (** sizeof(<type>). Has [unsigned int] type (ISO 6.5.3.4). This is not
- * turned into a constant because some transformations might want to
- * change types *)
-
- | SizeOfE of exp
- (** sizeof(<expression>) *)
-
- | SizeOfStr of string
- (** sizeof(string_literal). We separate this case out because this is the
- * only instance in which a string literal should not be treated as
- * having type pointer to character. *)
-
- | AlignOf of typ
- (** This corresponds to the GCC __alignof_. Has [unsigned int] type *)
- | AlignOfE of exp
-
-
- | UnOp of unop * exp * typ
- (** Unary operation. Includes the type of the result. *)
-
- | BinOp of binop * exp * exp * typ
- (** Binary operation. Includes the type of the result. The arithmetic
- * conversions are made explicit for the arguments. *)
-
- | CastE of typ * exp
- (** Use {!Cil.mkCast} to make casts. *)
-
- | AddrOf of lval
- (** Always use {!Cil.mkAddrOf} to construct one of these. Apply to an
- * lvalue of type [T] yields an expression of type [TPtr(T)] *)
-
- | StartOf of lval
- (** Conversion from an array to a pointer to the beginning of the array.
- * Given an lval of type [TArray(T)] produces an expression of type
- * [TPtr(T)]. In C this operation is implicit, the [StartOf] operator is
- * not printed. We have it in CIL because it makes the typing rules
- * simpler. *)
-
-(** {b Constants.} *)
-
-(** Literal constants *)
-and constant =
- | CInt64 of int64 * ikind * string option
- (** Integer constant. Give the ikind (see ISO9899 6.1.3.2) and the
- * textual representation, if available. (This allows us to print a
- * constant as, for example, 0xF instead of 15.) Use {!Cil.integer} or
- * {!Cil.kinteger} to create these. Watch out for integers that cannot be
- * represented on 64 bits. OCAML does not give Overflow exceptions. *)
- | CStr of string
- (* String constant. The escape characters inside the string have been
- * already interpreted. This constant has pointer to character type! The
- * only case when you would like a string literal to have an array type
- * is when it is an argument to sizeof. In that case you should use
- * SizeOfStr. *)
- | CWStr of int64 list
- (* Wide character string constant. Note that the local interpretation
- * of such a literal depends on {!Cil.wcharType} and {!Cil.wcharKind}.
- * Such a constant has type pointer to {!Cil.wcharType}. The
- * escape characters in the string have not been "interpreted" in
- * the sense that L"A\xabcd" remains "A\xabcd" rather than being
- * represented as the wide character list with two elements: 65 and
- * 43981. That "interpretation" depends on the underlying wide
- * character type. *)
- | CChr of char
- (** Character constant. This has type int, so use charConstToInt
- * to read the value in case sign-extension is needed. *)
- | CReal of float * fkind * string option
- (** Floating point constant. Give the fkind (see ISO 6.4.4.2) and also
- * the textual representation, if available. *)
- | CEnum of exp * string * enuminfo
- (** An enumeration constant with the given value, name, from the given
- * enuminfo. This is used only if {!Cil.lowerConstants} is true
- * (default). Use {!Cil.constFoldVisitor} to replace these with integer
- * constants. *)
-
-(** Unary operators *)
-and unop =
- Neg (** Unary minus *)
- | BNot (** Bitwise complement (~) *)
- | LNot (** Logical Not (!) *)
-
-(** Binary operations *)
-and binop =
- PlusA (** arithmetic + *)
- | PlusPI (** pointer + integer *)
- | IndexPI (** pointer + integer but only when
- * it arises from an expression
- * [e\[i\]] when [e] is a pointer and
- * not an array. This is semantically
- * the same as PlusPI but CCured uses
- * this as a hint that the integer is
- * probably positive. *)
- | MinusA (** arithmetic - *)
- | MinusPI (** pointer - integer *)
- | MinusPP (** pointer - pointer *)
- | Mult (** * *)
- | Div (** / *)
- | Mod (** % *)
- | Shiftlt (** shift left *)
- | Shiftrt (** shift right *)
-
- | Lt (** < (arithmetic comparison) *)
- | Gt (** > (arithmetic comparison) *)
- | Le (** <= (arithmetic comparison) *)
- | Ge (** > (arithmetic comparison) *)
- | Eq (** == (arithmetic comparison) *)
- | Ne (** != (arithmetic comparison) *)
- | BAnd (** bitwise and *)
- | BXor (** exclusive-or *)
- | BOr (** inclusive-or *)
-
- | LAnd (** logical and. Unlike other
- * expressions this one does not
- * always evaluate both operands. If
- * you want to use these, you must
- * set {!Cil.useLogicalOperators}. *)
- | LOr (** logical or. Unlike other
- * expressions this one does not
- * always evaluate both operands. If
- * you want to use these, you must
- * set {!Cil.useLogicalOperators}. *)
-
-(** {b Lvalues.} Lvalues are the sublanguage of expressions that can appear at the left of an assignment or as operand to the address-of operator.
-In C the syntax for lvalues is not always a good indication of the meaning
-of the lvalue. For example the C value
-{v
-a[0][1][2]
- v}
- might involve 1, 2 or 3 memory reads when used in an expression context,
-depending on the declared type of the variable [a]. If [a] has type [int
-\[4\]\[4\]\[4\]] then we have one memory read from somewhere inside the area
-that stores the array [a]. On the other hand if [a] has type [int ***] then
-the expression really means [* ( * ( * (a + 0) + 1) + 2)], in which case it is
-clear that it involves three separate memory operations.
-
-An lvalue denotes the contents of a range of memory addresses. This range
-is denoted as a host object along with an offset within the object. The
-host object can be of two kinds: a local or global variable, or an object
-whose address is in a pointer expression. We distinguish the two cases so
-that we can tell quickly whether we are accessing some component of a
-variable directly or we are accessing a memory location through a pointer.
-To make it easy to
-tell what an lvalue means CIL represents lvalues as a host object and an
-offset (see {!Cil.lval}). The host object (represented as
-{!Cil.lhost}) can be a local or global variable or can be the object
-pointed-to by a pointer expression. The offset (represented as
-{!Cil.offset}) is a sequence of field or array index designators.
-
- Both the typing rules and the meaning of an lvalue is very precisely
-specified in CIL.
-
- The following are a few useful function for operating on lvalues:
-- {!Cil.mkMem} - makes an lvalue of [Mem] kind. Use this to ensure
-that certain equivalent forms of lvalues are canonized.
-For example, [*&x = x].
-- {!Cil.typeOfLval} - the type of an lvalue
-- {!Cil.typeOffset} - the type of an offset, given the type of the
-host.
-- {!Cil.addOffset} and {!Cil.addOffsetLval} - extend sequences
-of offsets.
-- {!Cil.removeOffset} and {!Cil.removeOffsetLval} - shrink sequences
-of offsets.
-
-The following equivalences hold {v
-Mem(AddrOf(Mem a, aoff)), off = Mem a, aoff + off
-Mem(AddrOf(Var v, aoff)), off = Var v, aoff + off
-AddrOf (Mem a, NoOffset) = a
- v}
-
-*)
-(** An lvalue *)
-and lval =
- lhost * offset
-
-(** The host part of an {!Cil.lval}. *)
-and lhost =
- | Var of varinfo
- (** The host is a variable. *)
-
- | Mem of exp
- (** The host is an object of type [T] when the expression has pointer
- * [TPtr(T)]. *)
-
-
-(** The offset part of an {!Cil.lval}. Each offset can be applied to certain
- * kinds of lvalues and its effect is that it advances the starting address
- * of the lvalue and changes the denoted type, essentially focusing to some
- * smaller lvalue that is contained in the original one. *)
-and offset =
- | NoOffset (** No offset. Can be applied to any lvalue and does
- * not change either the starting address or the type.
- * This is used when the lval consists of just a host
- * or as a terminator in a list of other kinds of
- * offsets. *)
-
- | Field of fieldinfo * offset
- (** A field offset. Can be applied only to an lvalue
- * that denotes a structure or a union that contains
- * the mentioned field. This advances the offset to the
- * beginning of the mentioned field and changes the
- * type to the type of the mentioned field. *)
-
- | Index of exp * offset
- (** An array index offset. Can be applied only to an
- * lvalue that denotes an array. This advances the
- * starting address of the lval to the beginning of the
- * mentioned array element and changes the denoted type
- * to be the type of the array element *)
-
-
-(** {b Initializers.}
-A special kind of expressions are those that can appear as initializers for
-global variables (initialization of local variables is turned into
-assignments). The initializers are represented as type {!Cil.init}. You
-can create initializers with {!Cil.makeZeroInit} and you can conveniently
-scan compound initializers them with {!Cil.foldLeftCompound} or with {!Cil.foldLeftCompoundAll}.
-*)
-(** Initializers for global variables. *)
-and init =
- | SingleInit of exp (** A single initializer *)
- | CompoundInit of typ * (offset * init) list
- (** Used only for initializers of structures, unions and arrays. The
- * offsets are all of the form [Field(f, NoOffset)] or [Index(i,
- * NoOffset)] and specify the field or the index being initialized. For
- * structures all fields must have an initializer (except the unnamed
- * bitfields), in the proper order. This is necessary since the offsets
- * are not printed. For unions there must be exactly one initializer. If
- * the initializer is not for the first field then a field designator is
- * printed, so you better be on GCC since MSVC does not understand this.
- * For arrays, however, we allow you to give only a prefix of the
- * initializers. You can scan an initializer list with
- * {!Cil.foldLeftCompound} or with {!Cil.foldLeftCompoundAll}. *)
-
-
-(** We want to be able to update an initializer in a global variable, so we
- * define it as a mutable field *)
-and initinfo = {
- mutable init : init option;
- }
-
-(** {b Function definitions.}
-A function definition is always introduced with a [GFun] constructor at the
-top level. All the information about the function is stored into a
-{!Cil.fundec}. Some of the information (e.g. its name, type,
-storage, attributes) is stored as a {!Cil.varinfo} that is a field of the
-[fundec]. To refer to the function from the expression language you must use
-the [varinfo].
-
- The function definition contains, in addition to the body, a list of all the
-local variables and separately a list of the formals. Both kind of variables
-can be referred to in the body of the function. The formals must also be shared
-with the formals that appear in the function type. For that reason, to
-manipulate formals you should use the provided functions
-{!Cil.makeFormalVar} and {!Cil.setFormals} and {!Cil.makeFormalVar}.
-*)
-(** Function definitions. *)
-and fundec =
- { mutable svar: varinfo;
- (** Holds the name and type as a variable, so we can refer to it
- * easily from the program. All references to this function either
- * in a function call or in a prototype must point to the same
- * [varinfo]. *)
- mutable sformals: varinfo list;
- (** Formals. These must be in the same order and with the same
- * information as the formal information in the type of the function.
- * Use {!Cil.setFormals} or
- * {!Cil.setFunctionType} or {!Cil.makeFormalVar}
- * to set these formals and ensure that they
- * are reflected in the function type. Do not make copies of these
- * because the body refers to them. *)
- mutable slocals: varinfo list;
- (** Locals. Does NOT include the sformals. Do not make copies of
- * these because the body refers to them. *)
- mutable smaxid: int; (** Max local id. Starts at 0. Used for
- * creating the names of new temporary
- * variables. Updated by
- * {!Cil.makeLocalVar} and
- * {!Cil.makeTempVar}. You can also use
- * {!Cil.setMaxId} to set it after you
- * have added the formals and locals. *)
- mutable sbody: block; (** The function body. *)
- mutable smaxstmtid: int option; (** max id of a (reachable) statement
- * in this function, if we have
- * computed it. range = 0 ...
- * (smaxstmtid-1). This is computed by
- * {!Cil.computeCFGInfo}. *)
- mutable sallstmts: stmt list; (** After you call {!Cil.computeCFGInfo}
- * this field is set to contain all
- * statements in the function *)
- }
-
-
-(** A block is a sequence of statements with the control falling through from
- one element to the next *)
-and block =
- { mutable battrs: attributes; (** Attributes for the block *)
- mutable bstmts: stmt list; (** The statements comprising the block*)
- }
-
-
-(** {b Statements}.
-CIL statements are the structural elements that make the CFG. They are
-represented using the type {!Cil.stmt}. Every
-statement has a (possibly empty) list of labels. The
-{!Cil.stmtkind} field of a statement indicates what kind of statement it
-is.
-
- Use {!Cil.mkStmt} to make a statement and the fill-in the fields.
-
-CIL also comes with support for control-flow graphs. The [sid] field in
-[stmt] can be used to give unique numbers to statements, and the [succs]
-and [preds] fields can be used to maintain a list of successors and
-predecessors for every statement. The CFG information is not computed by
-default. Instead you must explicitly use the functions
-{!Cil.prepareCFG} and {!Cil.computeCFGInfo} to do it.
-
-*)
-(** Statements. *)
-and stmt = {
- mutable labels: label list;
- (** Whether the statement starts with some labels, case statements or
- * default statements. *)
-
- mutable skind: stmtkind;
- (** The kind of statement *)
-
- mutable sid: int;
- (** A number (>= 0) that is unique in a function. Filled in only after
- * the CFG is computed. *)
- mutable succs: stmt list;
- (** The successor statements. They can always be computed from the skind
- * and the context in which this statement appears. Filled in only after
- * the CFG is computed. *)
- mutable preds: stmt list;
- (** The inverse of the succs function. *)
- }
-
-(** Labels *)
-and label =
- Label of string * location * bool
- (** A real label. If the bool is "true", the label is from the
- * input source program. If the bool is "false", the label was
- * created by CIL or some other transformation *)
- | Case of exp * location (** A case statement. This expression
- * is lowered into a constant if
- * {!Cil.lowerConstants} is set to
- * true. *)
- | Default of location (** A default statement *)
-
-
-
-(** The various kinds of control-flow statements statements *)
-and stmtkind =
- | Instr of instr list
- (** A group of instructions that do not contain control flow. Control
- * implicitly falls through. *)
-
- | Return of exp option * location
- (** The return statement. This is a leaf in the CFG. *)
-
- | Goto of stmt ref * location
- (** A goto statement. Appears from actual goto's in the code or from
- * goto's that have been inserted during elaboration. The reference
- * points to the statement that is the target of the Goto. This means that
- * you have to update the reference whenever you replace the target
- * statement. The target statement MUST have at least a label. *)
-
- | Break of location
- (** A break to the end of the nearest enclosing loop or Switch *)
-
- | Continue of location
- (** A continue to the start of the nearest enclosing loop *)
- | If of exp * block * block * location
- (** A conditional. Two successors, the "then" and the "else" branches.
- * Both branches fall-through to the successor of the If statement. *)
-
- | Switch of exp * block * (stmt list) * location
- (** A switch statement. The statements that implement the cases can be
- * reached through the provided list. For each such target you can find
- * among its labels what cases it implements. The statements that
- * implement the cases are somewhere within the provided [block]. *)
-
-(*
- | Loop of block * location * (stmt option) * (stmt option)
- (** A [while(1)] loop. The termination test is implemented in the body of
- * a loop using a [Break] statement. If prepareCFG has been called,
- * the first stmt option will point to the stmt containing the continue
- * label for this loop and the second will point to the stmt containing
- * the break label for this loop. *)
-*)
-
- | While of exp * block * location
- (** A [while] loop. *)
-
- | DoWhile of exp * block * location
- (** A [do...while] loop. *)
-
- | For of block * exp * block * block * location
- (** A [for] loop. *)
-
- | Block of block
- (** Just a block of statements. Use it as a way to keep some block
- * attributes local *)
-
- (** On MSVC we support structured exception handling. This is what you
- * might expect. Control can get into the finally block either from the
- * end of the body block, or if an exception is thrown. *)
- | TryFinally of block * block * location
-
- (** On MSVC we support structured exception handling. The try/except
- * statement is a bit tricky:
- [__try { blk }
- __except (e) {
- handler
- }]
-
- The argument to __except must be an expression. However, we keep a
- list of instructions AND an expression in case you need to make
- function calls. We'll print those as a comma expression. The control
- can get to the __except expression only if an exception is thrown.
- After that, depending on the value of the expression the control
- goes to the handler, propagates the exception, or retries the
- exception !!!
- *)
- | TryExcept of block * (instr list * exp) * block * location
-
-
-(** {b Instructions}.
- An instruction {!Cil.instr} is a statement that has no local
-(intraprocedural) control flow. It can be either an assignment,
-function call, or an inline assembly instruction. *)
-
-(** Instructions. *)
-and instr =
- Set of lval * exp * location
- (** An assignment. The type of the expression is guaranteed to be the same
- * with that of the lvalue *)
- | Call of lval option * exp * exp list * location
- (** A function call with the (optional) result placed in an lval. It is
- * possible that the returned type of the function is not identical to
- * that of the lvalue. In that case a cast is printed. The type of the
- * actual arguments are identical to those of the declared formals. The
- * number of arguments is the same as that of the declared formals, except
- * for vararg functions. This construct is also used to encode a call to
- * "__builtin_va_arg". In this case the second argument (which should be a
- * type T) is encoded SizeOf(T) *)
-
- | Asm of attributes * (* Really only const and volatile can appear
- * here *)
- string list * (* templates (CR-separated) *)
- (string * lval) list * (* outputs must be lvals with
- * constraints. I would like these
- * to be actually variables, but I
- * run into some trouble with ASMs
- * in the Linux sources *)
- (string * exp) list * (* inputs with constraints *)
- string list * (* register clobbers *)
- location
- (** There are for storing inline assembly. They follow the GCC
- * specification:
-{v
- asm [volatile] ("...template..." "..template.."
- : "c1" (o1), "c2" (o2), ..., "cN" (oN)
- : "d1" (i1), "d2" (i2), ..., "dM" (iM)
- : "r1", "r2", ..., "nL" );
- v}
-
-where the parts are
-
- - [volatile] (optional): when present, the assembler instruction
- cannot be removed, moved, or otherwise optimized
- - template: a sequence of strings, with %0, %1, %2, etc. in the string to
- refer to the input and output expressions. I think they're numbered
- consecutively, but the docs don't specify. Each string is printed on
- a separate line. This is the only part that is present for MSVC inline
- assembly.
- - "ci" (oi): pairs of constraint-string and output-lval; the
- constraint specifies that the register used must have some
- property, like being a floating-point register; the constraint
- string for outputs also has "=" to indicate it is written, or
- "+" to indicate it is both read and written; 'oi' is the
- name of a C lvalue (probably a variable name) to be used as
- the output destination
- - "dj" (ij): pairs of constraint and input expression; the constraint
- is similar to the "ci"s. the 'ij' is an arbitrary C expression
- to be loaded into the corresponding register
- - "rk": registers to be regarded as "clobbered" by the instruction;
- "memory" may be specified for arbitrary memory effects
-
-an example (from gcc manual):
-{v
- asm volatile ("movc3 %0,%1,%2"
- : /* no outputs */
- : "g" (from), "g" (to), "g" (count)
- : "r0", "r1", "r2", "r3", "r4", "r5");
- v}
-*)
-
-(** Describes a location in a source file. *)
-and location = {
- line: int; (** The line number. -1 means "do not know" *)
- file: string; (** The name of the source file*)
- byte: int; (** The byte position in the source file *)
-}
-
-
-(** Type signatures. Two types are identical iff they have identical
- * signatures. These contain the same information as types but canonicalized.
- * For example, two function types that are identical except for the name of
- * the formal arguments are given the same signature. Also, [TNamed]
- * constructors are unrolled. *)
-and typsig =
- TSArray of typsig * int64 option * attribute list
- | TSPtr of typsig * attribute list
- | TSComp of bool * string * attribute list
- | TSFun of typsig * typsig list * bool * attribute list
- | TSEnum of string * attribute list
- | TSBase of typ
-
-
-
-(** {b Lowering Options} *)
-
-val lowerConstants: bool ref
- (** Do lower constants (default true) *)
-
-val insertImplicitCasts: bool ref
- (** Do insert implicit casts (default true) *)
-
-(** To be able to add/remove features easily, each feature should be package
- * as an interface with the following interface. These features should be *)
-type featureDescr = {
- fd_enabled: bool ref;
- (** The enable flag. Set to default value *)
-
- fd_name: string;
- (** This is used to construct an option "--doxxx" and "--dontxxx" that
- * enable and disable the feature *)
-
- fd_description: string;
- (* A longer name that can be used to document the new options *)
-
- fd_extraopt: (string * Arg.spec * string) list;
- (** Additional command line options *)
-
- fd_doit: (file -> unit);
- (** This performs the transformation *)
-
- fd_post_check: bool;
- (* Whether to perform a CIL consistency checking after this stage, if
- * checking is enabled (--check is passed to cilly). Set this to true if
- * your feature makes any changes for the program. *)
-}
-
-(** Comparison function for locations.
- ** Compares first by filename, then line, then byte *)
-val compareLoc: location -> location -> int
-
-(** {b Values for manipulating globals} *)
-
-(** Make an empty function *)
-val emptyFunction: string -> fundec
-
-(** Update the formals of a [fundec] and make sure that the function type
- has the same information. Will copy the name as well into the type. *)
-val setFormals: fundec -> varinfo list -> unit
-
-(** Set the types of arguments and results as given by the function type
- * passed as the second argument. Will not copy the names from the function
- * type to the formals *)
-val setFunctionType: fundec -> typ -> unit
-
-
-(** Set the type of the function and make formal arguments for them *)
-val setFunctionTypeMakeFormals: fundec -> typ -> unit
-
-(** Update the smaxid after you have populated with locals and formals
- * (unless you constructed those using {!Cil.makeLocalVar} or
- * {!Cil.makeTempVar}. *)
-val setMaxId: fundec -> unit
-
-(** A dummy function declaration handy when you need one as a placeholder. It
- * contains inside a dummy varinfo. *)
-val dummyFunDec: fundec
-
-(** A dummy file *)
-val dummyFile: file
-
-(** Write a {!Cil.file} in binary form to the filesystem. The file can be
- * read back in later using {!Cil.loadBinaryFile}, possibly saving parsing
- * time. The second argument is the name of the file that should be
- * created. *)
-val saveBinaryFile : file -> string -> unit
-
-(** Write a {!Cil.file} in binary form to the filesystem. The file can be
- * read back in later using {!Cil.loadBinaryFile}, possibly saving parsing
- * time. Does not close the channel. *)
-val saveBinaryFileChannel : file -> out_channel -> unit
-
-(** Read a {!Cil.file} in binary form from the filesystem. The first
- * argument is the name of a file previously created by
- * {!Cil.saveBinaryFile}. *)
-val loadBinaryFile : string -> file
-
-(** Get the global initializer and create one if it does not already exist.
- * When it creates a global initializer it attempts to place a call to it in
- * the main function named by the optional argument (default "main") *)
-val getGlobInit: ?main_name:string -> file -> fundec
-
-(** Iterate over all globals, including the global initializer *)
-val iterGlobals: file -> (global -> unit) -> unit
-
-(** Fold over all globals, including the global initializer *)
-val foldGlobals: file -> ('a -> global -> 'a) -> 'a -> 'a
-
-(** Map over all globals, including the global initializer and change things
- in place *)
-val mapGlobals: file -> (global -> global) -> unit
-
-val new_sid : unit -> int
-
-(** Prepare a function for CFG information computation by
- * {!Cil.computeCFGInfo}. This function converts all [Break], [Switch],
- * [Default] and [Continue] {!Cil.stmtkind}s and {!Cil.label}s into [If]s
- * and [Goto]s, giving the function body a very CFG-like character. This
- * function modifies its argument in place. *)
-val prepareCFG: fundec -> unit
-
-(** Compute the CFG information for all statements in a fundec and return a
- * list of the statements. The input fundec cannot have [Break], [Switch],
- * [Default], or [Continue] {!Cil.stmtkind}s or {!Cil.label}s. Use
- * {!Cil.prepareCFG} to transform them away. The second argument should
- * be [true] if you wish a global statement number, [false] if you wish a
- * local (per-function) statement numbering. The list of statements is set
- * in the sallstmts field of a fundec.
- *
- * NOTE: unless you want the simpler control-flow graph provided by
- * prepareCFG, or you need the function's smaxstmtid and sallstmt fields
- * filled in, we recommend you use {!Cfg.computeFileCFG} instead of this
- * function to compute control-flow information.
- * {!Cfg.computeFileCFG} is newer and will handle switch, break, and
- * continue correctly.*)
-val computeCFGInfo: fundec -> bool -> unit
-
-
-(** Create a deep copy of a function. There should be no sharing between the
- * copy and the original function *)
-val copyFunction: fundec -> string -> fundec
-
-
-(** CIL keeps the types at the beginning of the file and the variables at the
- * end of the file. This function will take a global and add it to the
- * corresponding stack. Its operation is actually more complicated because if
- * the global declares a type that contains references to variables (e.g. in
- * sizeof in an array length) then it will also add declarations for the
- * variables to the types stack *)
-val pushGlobal: global -> types: global list ref
- -> variables: global list ref -> unit
-
-(** An empty statement. Used in pretty printing *)
-val invalidStmt: stmt
-
-(** A list of the GCC built-in functions. Maps the name to the result and
- * argument types, and whether it is vararg *)
-val gccBuiltins: (string, typ * typ list * bool) Hashtbl.t
-
-
-(** A list of the MSVC built-in functions. Maps the name to the result and
- * argument types, and whether it is vararg *)
-val msvcBuiltins: (string, typ * typ list * bool) Hashtbl.t
-
-(** {b Values for manipulating initializers} *)
-
-
-(** Make a initializer for zero-ing a data type *)
-val makeZeroInit: typ -> init
-
-
-(** Fold over the list of initializers in a Compound. [doinit] is called on
- * every present initializer, even if it is of compound type. In the case of
- * arrays there might be missing zero-initializers at the end of the list.
- * These are not scanned. This is much like [List.fold_left] except we also
- * pass the type of the initializer *)
-val foldLeftCompound:
- doinit: (offset -> init -> typ -> 'a -> 'a) ->
- ct: typ ->
- initl: (offset * init) list ->
- acc: 'a -> 'a
-
-
-(** Fold over the list of initializers in a Compound, like
- * {!Cil.foldLeftCompound} but in the case of an array it scans even missing
- * zero initializers at the end of the array *)
-val foldLeftCompoundAll:
- doinit: (offset -> init -> typ -> 'a -> 'a) ->
- ct: typ ->
- initl: (offset * init) list ->
- acc: 'a -> 'a
-
-
-
-(** {b Values for manipulating types} *)
-
-(** void *)
-val voidType: typ
-
-(* is the given type "void"? *)
-val isVoidType: typ -> bool
-
-(* is the given type "void *"? *)
-val isVoidPtrType: typ -> bool
-
-(** int *)
-val intType: typ
-
-(** unsigned int *)
-val uintType: typ
-
-(** long *)
-val longType: typ
-
-(** unsigned long *)
-val ulongType: typ
-
-(** char *)
-val charType: typ
-
-(** char * *)
-val charPtrType: typ
-
-(** wchar_t (depends on architecture) and is set when you call
- * {!Cil.initCIL}. *)
-val wcharKind: ikind ref
-val wcharType: typ ref
-
-(** char const * *)
-val charConstPtrType: typ
-
-(** void * *)
-val voidPtrType: typ
-
-(** int * *)
-val intPtrType: typ
-
-(** unsigned int * *)
-val uintPtrType: typ
-
-(** double *)
-val doubleType: typ
-
-(* An unsigned integer type that fits pointers. Depends on {!Cil.msvcMode}
- * and is set when you call {!Cil.initCIL}. *)
-val upointType: typ ref
-
-(* An unsigned integer type that is the type of sizeof. Depends on
- * {!Cil.msvcMode} and is set when you call {!Cil.initCIL}. *)
-val typeOfSizeOf: typ ref
-
-(** Returns true if and only if the given integer type is signed. *)
-val isSigned: ikind -> bool
-
-
-(** Creates a a (potentially recursive) composite type. The arguments are:
- * (1) a boolean indicating whether it is a struct or a union, (2) the name
- * (always non-empty), (3) a function that when given a representation of the
- * structure type constructs the type of the fields recursive type (the first
- * argument is only useful when some fields need to refer to the type of the
- * structure itself), and (4) a list of attributes to be associated with the
- * composite type. The resulting compinfo has the field "cdefined" only if
- * the list of fields is non-empty. *)
-val mkCompInfo: bool -> (* whether it is a struct or a union *)
- string -> (* name of the composite type; cannot be empty *)
- (compinfo ->
- (string * typ * int option * attributes * location) list) ->
- (* a function that when given a forward
- representation of the structure type constructs the type of
- the fields. The function can ignore this argument if not
- constructing a recursive type. *)
- attributes -> compinfo
-
-(** Makes a shallow copy of a {!Cil.compinfo} changing the name and the key.*)
-val copyCompInfo: compinfo -> string -> compinfo
-
-(** This is a constant used as the name of an unnamed bitfield. These fields
- do not participate in initialization and their name is not printed. *)
-val missingFieldName: string
-
-(** Get the full name of a comp *)
-val compFullName: compinfo -> string
-
-(** Returns true if this is a complete type.
- This means that sizeof(t) makes sense.
- Incomplete types are not yet defined
- structures and empty arrays. *)
-val isCompleteType: typ -> bool
-
-(** Unroll a type until it exposes a non
- * [TNamed]. Will collect all attributes appearing in [TNamed]!!! *)
-val unrollType: typ -> typ
-
-(** Unroll all the TNamed in a type (even under type constructors such as
- * [TPtr], [TFun] or [TArray]. Does not unroll the types of fields in [TComp]
- * types. Will collect all attributes *)
-val unrollTypeDeep: typ -> typ
-
-(** Separate out the storage-modifier name attributes *)
-val separateStorageModifiers: attribute list -> attribute list * attribute list
-
-(** True if the argument is an integral type (i.e. integer or enum) *)
-val isIntegralType: typ -> bool
-
-(** True if the argument is an arithmetic type (i.e. integer, enum or
- floating point *)
-val isArithmeticType: typ -> bool
-
-(**True if the argument is a pointer type *)
-val isPointerType: typ -> bool
-
-(** True if the argument is a function type *)
-val isFunctionType: typ -> bool
-
-(** Obtain the argument list ([] if None) *)
-val argsToList: (string * typ * attributes) list option
- -> (string * typ * attributes) list
-
-(** True if the argument is an array type *)
-val isArrayType: typ -> bool
-
-(** Raised when {!Cil.lenOfArray} fails either because the length is [None]
- * or because it is a non-constant expression *)
-exception LenOfArray
-
-(** Call to compute the array length as present in the array type, to an
- * integer. Raises {!Cil.LenOfArray} if not able to compute the length, such
- * as when there is no length or the length is not a constant. *)
-val lenOfArray: exp option -> int
-
-(** Return a named fieldinfo in compinfo, or raise Not_found *)
-val getCompField: compinfo -> string -> fieldinfo
-
-
-(** A datatype to be used in conjunction with [existsType] *)
-type existsAction =
- ExistsTrue (* We have found it *)
- | ExistsFalse (* Stop processing this branch *)
- | ExistsMaybe (* This node is not what we are
- * looking for but maybe its
- * successors are *)
-
-(** Scans a type by applying the function on all elements.
- When the function returns ExistsTrue, the scan stops with
- true. When the function returns ExistsFalse then the current branch is not
- scanned anymore. Care is taken to
- apply the function only once on each composite type, thus avoiding
- circularity. When the function returns ExistsMaybe then the types that
- construct the current type are scanned (e.g. the base type for TPtr and
- TArray, the type of fields for a TComp, etc). *)
-val existsType: (typ -> existsAction) -> typ -> bool
-
-
-(** Given a function type split it into return type,
- * arguments, is_vararg and attributes. An error is raised if the type is not
- * a function type *)
-val splitFunctionType:
- typ -> typ * (string * typ * attributes) list option * bool * attributes
-(** Same as {!Cil.splitFunctionType} but takes a varinfo. Prints a nicer
- * error message if the varinfo is not for a function *)
-val splitFunctionTypeVI:
- varinfo -> typ * (string * typ * attributes) list option * bool * attributes
-
-
-(** {b Type signatures} *)
-
-(** Type signatures. Two types are identical iff they have identical
- * signatures. These contain the same information as types but canonicalized.
- * For example, two function types that are identical except for the name of
- * the formal arguments are given the same signature. Also, [TNamed]
- * constructors are unrolled. You shoud use [Util.equals] to compare type
- * signatures because they might still contain circular structures (through
- * attributes, and sizeof) *)
-
-(** Print a type signature *)
-val d_typsig: unit -> typsig -> Pretty.doc
-
-(** Compute a type signature *)
-val typeSig: typ -> typsig
-
-(** Like {!Cil.typeSig} but customize the incorporation of attributes.
- Use ~ignoreSign:true to convert all signed integer types to unsigned,
- so that signed and unsigned will compare the same. *)
-val typeSigWithAttrs: ?ignoreSign:bool -> (attributes -> attributes) -> typ -> typsig
-
-(** Replace the attributes of a signature (only at top level) *)
-val setTypeSigAttrs: attributes -> typsig -> typsig
-
-(** Get the top-level attributes of a signature *)
-val typeSigAttrs: typsig -> attributes
-
-(*********************************************************)
-(** LVALUES *)
-
-(** Make a varinfo. Use this (rarely) to make a raw varinfo. Use other
- * functions to make locals ({!Cil.makeLocalVar} or {!Cil.makeFormalVar} or
- * {!Cil.makeTempVar}) and globals ({!Cil.makeGlobalVar}). Note that this
- * function will assign a new identifier. The first argument specifies
- * whether the varinfo is for a global. *)
-val makeVarinfo: bool -> string -> typ -> varinfo
-
-(** Make a formal variable for a function. Insert it in both the sformals
- and the type of the function. You can optionally specify where to insert
- this one. If where = "^" then it is inserted first. If where = "$" then
- it is inserted last. Otherwise where must be the name of a formal after
- which to insert this. By default it is inserted at the end. *)
-val makeFormalVar: fundec -> ?where:string -> string -> typ -> varinfo
-
-(** Make a local variable and add it to a function's slocals (only if insert =
- true, which is the default). Make sure you know what you are doing if you
- set insert=false. *)
-val makeLocalVar: fundec -> ?insert:bool -> string -> typ -> varinfo
-
-(** Make a temporary variable and add it to a function's slocals. The name of
- the temporary variable will be generated based on the given name hint so
- that to avoid conflicts with other locals. *)
-val makeTempVar: fundec -> ?name: string -> typ -> varinfo
-
-
-(** Make a global variable. Your responsibility to make sure that the name
- is unique *)
-val makeGlobalVar: string -> typ -> varinfo
-
-(** Make a shallow copy of a [varinfo] and assign a new identifier *)
-val copyVarinfo: varinfo -> string -> varinfo
-
-
-(** Generate a new variable ID. This will be different than any variable ID
- * that is generated by {!Cil.makeLocalVar} and friends *)
-val newVID: unit -> int
-
-(** Add an offset at the end of an lvalue. Make sure the type of the lvalue
- * and the offset are compatible. *)
-val addOffsetLval: offset -> lval -> lval
-
-(** [addOffset o1 o2] adds [o1] to the end of [o2]. *)
-val addOffset: offset -> offset -> offset
-
-(** Remove ONE offset from the end of an lvalue. Returns the lvalue with the
- * trimmed offset and the final offset. If the final offset is [NoOffset]
- * then the original [lval] did not have an offset. *)
-val removeOffsetLval: lval -> lval * offset
-
-(** Remove ONE offset from the end of an offset sequence. Returns the
- * trimmed offset and the final offset. If the final offset is [NoOffset]
- * then the original [lval] did not have an offset. *)
-val removeOffset: offset -> offset * offset
-
-(** Compute the type of an lvalue *)
-val typeOfLval: lval -> typ
-
-(** Compute the type of an offset from a base type *)
-val typeOffset: typ -> offset -> typ
-
-
-(*******************************************************)
-(** {b Values for manipulating expressions} *)
-
-
-(* Construct integer constants *)
-
-(** 0 *)
-val zero: exp
-
-(** 1 *)
-val one: exp
-
-(** -1 *)
-val mone: exp
-
-
-(** Construct an integer of a given kind, using OCaml's int64 type. If needed
- * it will truncate the integer to be within the representable range for the
- * given kind. *)
-val kinteger64: ikind -> int64 -> exp
-
-(** Construct an integer of a given kind. Converts the integer to int64 and
- * then uses kinteger64. This might truncate the value if you use a kind
- * that cannot represent the given integer. This can only happen for one of
- * the Char or Short kinds *)
-val kinteger: ikind -> int -> exp
-
-(** Construct an integer of kind IInt. You can use this always since the
- OCaml integers are 31 bits and are guaranteed to fit in an IInt *)
-val integer: int -> exp
-
-
-(** True if the given expression is a (possibly cast'ed)
- character or an integer constant *)
-val isInteger: exp -> int64 option
-
-(** True if the expression is a compile-time constant *)
-val isConstant: exp -> bool
-
-(** True if the given expression is a (possibly cast'ed) integer or character
- constant with value zero *)
-val isZero: exp -> bool
-
-(** Given the character c in a (CChr c), sign-extend it to 32 bits.
- (This is the official way of interpreting character constants, according to
- ISO C 6.4.4.4.10, which says that character constants are chars cast to ints)
- Returns CInt64(sign-extened c, IInt, None) *)
-val charConstToInt: char -> constant
-
-(** Do constant folding on an expression. If the first argument is true then
- will also compute compiler-dependent expressions such as sizeof *)
-val constFold: bool -> exp -> exp
-
-(** Do constant folding on a binary operation. The bulk of the work done by
- [constFold] is done here. If the first argument is true then
- will also compute compiler-dependent expressions such as sizeof *)
-val constFoldBinOp: bool -> binop -> exp -> exp -> typ -> exp
-
-(** Increment an expression. Can be arithmetic or pointer type *)
-val increm: exp -> int -> exp
-
-
-(** Makes an lvalue out of a given variable *)
-val var: varinfo -> lval
-
-(** Make an AddrOf. Given an lvalue of type T will give back an expression of
- type ptr(T). It optimizes somewhat expressions like "& v" and "& v[0]" *)
-val mkAddrOf: lval -> exp
-
-
-(** Like mkAddrOf except if the type of lval is an array then it uses
- StartOf. This is the right operation for getting a pointer to the start
- of the storage denoted by lval. *)
-val mkAddrOrStartOf: lval -> exp
-
-(** Make a Mem, while optimizing AddrOf. The type of the addr must be
- TPtr(t) and the type of the resulting lval is t. Note that in CIL the
- implicit conversion between an array and the pointer to the first
- element does not apply. You must do the conversion yourself using
- StartOf *)
-val mkMem: addr:exp -> off:offset -> lval
-
-(** Make an expression that is a string constant (of pointer type) *)
-val mkString: string -> exp
-
-(** Construct a cast when having the old type of the expression. If the new
- * type is the same as the old type, then no cast is added. *)
-val mkCastT: e:exp -> oldt:typ -> newt:typ -> exp
-
-(** Like {!Cil.mkCastT} but uses typeOf to get [oldt] *)
-val mkCast: e:exp -> newt:typ -> exp
-
-(** Removes casts from this expression, but ignores casts within
- other expression constructs. So we delete the (A) and (B) casts from
- "(A)(B)(x + (C)y)", but leave the (C) cast. *)
-val stripCasts: exp -> exp
-
-(** Compute the type of an expression *)
-val typeOf: exp -> typ
-
-(** Convert a string representing a C integer literal to an expression.
- * Handles the prefixes 0x and 0 and the suffixes L, U, UL, LL, ULL *)
-val parseInt: string -> exp
-
-
-(**********************************************)
-(** {b Values for manipulating statements} *)
-
-(** Construct a statement, given its kind. Initialize the [sid] field to -1,
- and [labels], [succs] and [preds] to the empty list *)
-val mkStmt: stmtkind -> stmt
-
-(** Construct a block with no attributes, given a list of statements *)
-val mkBlock: stmt list -> block
-
-(** Construct a statement consisting of just one instruction *)
-val mkStmtOneInstr: instr -> stmt
-
-(** Try to compress statements so as to get maximal basic blocks *)
-(* use this instead of List.@ because you get fewer basic blocks *)
-val compactStmts: stmt list -> stmt list
-
-(** Returns an empty statement (of kind [Instr]) *)
-val mkEmptyStmt: unit -> stmt
-
-(** A instr to serve as a placeholder *)
-val dummyInstr: instr
-
-(** A statement consisting of just [dummyInstr] *)
-val dummyStmt: stmt
-
-(** Make a while loop. Can contain Break or Continue *)
-val mkWhile: guard:exp -> body:stmt list -> stmt list
-
-(** Make a for loop for(i=start; i<past; i += incr) \{ ... \}. The body
- can contain Break but not Continue. Can be used with i a pointer
- or an integer. Start and done must have the same type but incr
- must be an integer *)
-val mkForIncr: iter:varinfo -> first:exp -> stopat:exp -> incr:exp
- -> body:stmt list -> stmt list
-
-(** Make a for loop for(start; guard; next) \{ ... \}. The body can
- contain Break but not Continue !!! *)
-val mkFor: start:stmt list -> guard:exp -> next: stmt list ->
- body: stmt list -> stmt list
-
-
-
-(**************************************************)
-(** {b Values for manipulating attributes} *)
-
-(** Various classes of attributes *)
-type attributeClass =
- AttrName of bool
- (** Attribute of a name. If argument is true and we are on MSVC then
- the attribute is printed using __declspec as part of the storage
- specifier *)
- | AttrFunType of bool
- (** Attribute of a function type. If argument is true and we are on
- MSVC then the attribute is printed just before the function name *)
- | AttrType (** Attribute of a type *)
-
-(** This table contains the mapping of predefined attributes to classes.
- Extend this table with more attributes as you need. This table is used to
- determine how to associate attributes with names or types *)
-val attributeHash: (string, attributeClass) Hashtbl.t
-
-(** Partition the attributes into classes:name attributes, function type,
- and type attributes *)
-val partitionAttributes: default:attributeClass ->
- attributes -> attribute list * (* AttrName *)
- attribute list * (* AttrFunType *)
- attribute list (* AttrType *)
-
-(** Add an attribute. Maintains the attributes in sorted order of the second
- argument *)
-val addAttribute: attribute -> attributes -> attributes
-
-(** Add a list of attributes. Maintains the attributes in sorted order. The
- second argument must be sorted, but not necessarily the first *)
-val addAttributes: attribute list -> attributes -> attributes
-
-(** Remove all attributes with the given name. Maintains the attributes in
- sorted order. *)
-val dropAttribute: string -> attributes -> attributes
-
-(** Remove all attributes with names appearing in the string list.
- * Maintains the attributes in sorted order *)
-val dropAttributes: string list -> attributes -> attributes
-
-(** Retains attributes with the given name *)
-val filterAttributes: string -> attributes -> attributes
-
-(** True if the named attribute appears in the attribute list. The list of
- attributes must be sorted. *)
-val hasAttribute: string -> attributes -> bool
-
-(** Returns all the attributes contained in a type. This requires a traversal
- of the type structure, in case of composite, enumeration and named types *)
-val typeAttrs: typ -> attribute list
-
-val setTypeAttrs: typ -> attributes -> typ (* Resets the attributes *)
-
-
-(** Add some attributes to a type *)
-val typeAddAttributes: attribute list -> typ -> typ
-
-(** Remove all attributes with the given names from a type. Note that this
- does not remove attributes from typedef and tag definitions, just from
- their uses *)
-val typeRemoveAttributes: string list -> typ -> typ
-
-
-(******************
- ****************** VISITOR
- ******************)
-(** {b The visitor} *)
-
-(** Different visiting actions. 'a will be instantiated with [exp], [instr],
- etc. *)
-type 'a visitAction =
- SkipChildren (** Do not visit the children. Return
- the node as it is. *)
- | DoChildren (** Continue with the children of this
- node. Rebuild the node on return
- if any of the children changes
- (use == test) *)
- | ChangeTo of 'a (** Replace the expression with the
- given one *)
- | ChangeDoChildrenPost of 'a * ('a -> 'a) (** First consider that the entire
- exp is replaced by the first
- parameter. Then continue with
- the children. On return rebuild
- the node if any of the children
- has changed and then apply the
- function on the node *)
-
-
-
-(** A visitor interface for traversing CIL trees. Create instantiations of
- * this type by specializing the class {!Cil.nopCilVisitor}. Each of the
- * specialized visiting functions can also call the [queueInstr] to specify
- * that some instructions should be inserted before the current instruction
- * or statement. Use syntax like [self#queueInstr] to call a method
- * associated with the current object. *)
-class type cilVisitor = object
- method vvdec: varinfo -> varinfo visitAction
- (** Invoked for each variable declaration. The subtrees to be traversed
- * are those corresponding to the type and attributes of the variable.
- * Note that variable declarations are all the [GVar], [GVarDecl], [GFun],
- * all the [varinfo] in formals of function types, and the formals and
- * locals for function definitions. This means that the list of formals
- * in a function definition will be traversed twice, once as part of the
- * function type and second as part of the formals in a function
- * definition. *)
-
- method vvrbl: varinfo -> varinfo visitAction
- (** Invoked on each variable use. Here only the [SkipChildren] and
- * [ChangeTo] actions make sense since there are no subtrees. Note that
- * the type and attributes of the variable are not traversed for a
- * variable use *)
-
- method vexpr: exp -> exp visitAction
- (** Invoked on each expression occurrence. The subtrees are the
- * subexpressions, the types (for a [Cast] or [SizeOf] expression) or the
- * variable use. *)
-
- method vlval: lval -> lval visitAction
- (** Invoked on each lvalue occurrence *)
-
- method voffs: offset -> offset visitAction
- (** Invoked on each offset occurrence that is *not* as part
- * of an initializer list specification, i.e. in an lval or
- * recursively inside an offset. *)
-
- method vinitoffs: offset -> offset visitAction
- (** Invoked on each offset appearing in the list of a
- * CompoundInit initializer. *)
-
- method vinst: instr -> instr list visitAction
- (** Invoked on each instruction occurrence. The [ChangeTo] action can
- * replace this instruction with a list of instructions *)
-
- method vstmt: stmt -> stmt visitAction
- (** Control-flow statement. The default [DoChildren] action does not
- * create a new statement when the components change. Instead it updates
- * the contents of the original statement. This is done to preserve the
- * sharing with [Goto] and [Case] statements that point to the original
- * statement. If you use the [ChangeTo] action then you should take care
- * of preserving that sharing yourself. *)
-
- method vblock: block -> block visitAction (** Block. *)
- method vfunc: fundec -> fundec visitAction (** Function definition.
- Replaced in place. *)
- method vglob: global -> global list visitAction (** Global (vars, types,
- etc.) *)
- method vinit: init -> init visitAction (** Initializers for globals *)
- method vtype: typ -> typ visitAction (** Use of some type. Note
- * that for structure/union
- * and enumeration types the
- * definition of the
- * composite type is not
- * visited. Use [vglob] to
- * visit it. *)
- method vattr: attribute -> attribute list visitAction
- (** Attribute. Each attribute can be replaced by a list *)
- method vattrparam: attrparam -> attrparam visitAction
- (** Attribute parameters. *)
-
- (** Add here instructions while visiting to queue them to preceede the
- * current statement or instruction being processed. Use this method only
- * when you are visiting an expression that is inside a function body, or
- * a statement, because otherwise there will no place for the visitor to
- * place your instructions. *)
- method queueInstr: instr list -> unit
-
- (** Gets the queue of instructions and resets the queue. This is done
- * automatically for you when you visit statments. *)
- method unqueueInstr: unit -> instr list
-
-end
-
-(** Default Visitor. Traverses the CIL tree without modifying anything *)
-class nopCilVisitor: cilVisitor
-
-(* other cil constructs *)
-
-(** Visit a file. This will will re-cons all globals TWICE (so that it is
- * tail-recursive). Use {!Cil.visitCilFileSameGlobals} if your visitor will
- * not change the list of globals. *)
-val visitCilFile: cilVisitor -> file -> unit
-
-(** A visitor for the whole file that does not change the globals (but maybe
- * changes things inside the globals). Use this function instead of
- * {!Cil.visitCilFile} whenever appropriate because it is more efficient for
- * long files. *)
-val visitCilFileSameGlobals: cilVisitor -> file -> unit
-
-(** Visit a global *)
-val visitCilGlobal: cilVisitor -> global -> global list
-
-(** Visit a function definition *)
-val visitCilFunction: cilVisitor -> fundec -> fundec
-
-(* Visit an expression *)
-val visitCilExpr: cilVisitor -> exp -> exp
-
-(** Visit an lvalue *)
-val visitCilLval: cilVisitor -> lval -> lval
-
-(** Visit an lvalue or recursive offset *)
-val visitCilOffset: cilVisitor -> offset -> offset
-
-(** Visit an initializer offset *)
-val visitCilInitOffset: cilVisitor -> offset -> offset
-
-(** Visit an instruction *)
-val visitCilInstr: cilVisitor -> instr -> instr list
-
-(** Visit a statement *)
-val visitCilStmt: cilVisitor -> stmt -> stmt
-
-(** Visit a block *)
-val visitCilBlock: cilVisitor -> block -> block
-
-(** Visit a type *)
-val visitCilType: cilVisitor -> typ -> typ
-
-(** Visit a variable declaration *)
-val visitCilVarDecl: cilVisitor -> varinfo -> varinfo
-
-(** Visit an initializer *)
-val visitCilInit: cilVisitor -> init -> init
-
-
-(** Visit a list of attributes *)
-val visitCilAttributes: cilVisitor -> attribute list -> attribute list
-
-(* And some generic visitors. The above are built with these *)
-
-
-(** {b Utility functions} *)
-
-(** Whether the pretty printer should print output for the MS VC compiler.
- Default is GCC. After you set this function you should call {!Cil.initCIL}. *)
-val msvcMode: bool ref
-
-
-(** Whether to use the logical operands LAnd and LOr. By default, do not use
- * them because they are unlike other expressions and do not evaluate both of
- * their operands *)
-val useLogicalOperators: bool ref
-
-
-(** A visitor that does constant folding. Pass as argument whether you want
- * machine specific simplifications to be done, or not. *)
-val constFoldVisitor: bool -> cilVisitor
-
-(** Styles of printing line directives *)
-type lineDirectiveStyle =
- | LineComment
- | LinePreprocessorInput
- | LinePreprocessorOutput
-
-(** How to print line directives *)
-val lineDirectiveStyle: lineDirectiveStyle option ref
-
-(** Whether we print something that will only be used as input to our own
- * parser. In that case we are a bit more liberal in what we print *)
-val print_CIL_Input: bool ref
-
-(** Whether to print the CIL as they are, without trying to be smart and
- * print nicer code. Normally this is false, in which case the pretty
- * printer will turn the while(1) loops of CIL into nicer loops, will not
- * print empty "else" blocks, etc. These is one case howewer in which if you
- * turn this on you will get code that does not compile: if you use varargs
- * the __builtin_va_arg function will be printed in its internal form. *)
-val printCilAsIs: bool ref
-
-(** The length used when wrapping output lines. Setting this variable to
- * a large integer will prevent wrapping and make #line directives more
- * accurate.
- *)
-val lineLength: int ref
-
-(** Return the string 's' if we're printing output for gcc, suppres
- * it if we're printing for CIL to parse back in. the purpose is to
- * hide things from gcc that it complains about, but still be able
- * to do lossless transformations when CIL is the consumer *)
-val forgcc: string -> string
-
-(** {b Debugging support} *)
-
-(** A reference to the current location. If you are careful to set this to
- * the current location then you can use some built-in logging functions that
- * will print the location. *)
-val currentLoc: location ref
-
-(** A reference to the current global being visited *)
-val currentGlobal: global ref
-
-
-(** CIL has a fairly easy to use mechanism for printing error messages. This
- * mechanism is built on top of the pretty-printer mechanism (see
- * {!Pretty.doc}) and the error-message modules (see {!Errormsg.error}).
-
- Here is a typical example for printing a log message: {v
-ignore (Errormsg.log "Expression %a is not positive (at %s:%i)\n"
- d_exp e loc.file loc.line)
- v}
-
- and here is an example of how you print a fatal error message that stop the
-* execution: {v
-Errormsg.s (Errormsg.bug "Why am I here?")
- v}
-
- Notice that you can use C format strings with some extension. The most
-useful extension is "%a" that means to consumer the next two argument from
-the argument list and to apply the first to [unit] and then to the second
-and to print the resulting {!Pretty.doc}. For each major type in CIL there is
-a corresponding function that pretty-prints an element of that type:
-*)
-
-
-(** Pretty-print a location *)
-val d_loc: unit -> location -> Pretty.doc
-
-(** Pretty-print the {!Cil.currentLoc} *)
-val d_thisloc: unit -> Pretty.doc
-
-(** Pretty-print an integer of a given kind *)
-val d_ikind: unit -> ikind -> Pretty.doc
-
-(** Pretty-print a floating-point kind *)
-val d_fkind: unit -> fkind -> Pretty.doc
-
-(** Pretty-print storage-class information *)
-val d_storage: unit -> storage -> Pretty.doc
-
-(** Pretty-print a constant *)
-val d_const: unit -> constant -> Pretty.doc
-
-
-val derefStarLevel: int
-val indexLevel: int
-val arrowLevel: int
-val addrOfLevel: int
-val additiveLevel: int
-val comparativeLevel: int
-val bitwiseLevel: int
-
-(** Parentheses level. An expression "a op b" is printed parenthesized if its
- * parentheses level is >= that that of its context. Identifiers have the
- * lowest level and weakly binding operators (e.g. |) have the largest level.
- * The correctness criterion is that a smaller level MUST correspond to a
- * stronger precedence!
- *)
-val getParenthLevel: exp -> int
-
-(** A printer interface for CIL trees. Create instantiations of
- * this type by specializing the class {!Cil.defaultCilPrinterClass}. *)
-class type cilPrinter = object
- method pVDecl: unit -> varinfo -> Pretty.doc
- (** Invoked for each variable declaration. Note that variable
- * declarations are all the [GVar], [GVarDecl], [GFun], all the [varinfo]
- * in formals of function types, and the formals and locals for function
- * definitions. *)
-
- method pVar: varinfo -> Pretty.doc
- (** Invoked on each variable use. *)
-
- method pLval: unit -> lval -> Pretty.doc
- (** Invoked on each lvalue occurrence *)
-
- method pOffset: Pretty.doc -> offset -> Pretty.doc
- (** Invoked on each offset occurrence. The second argument is the base. *)
-
- method pInstr: unit -> instr -> Pretty.doc
- (** Invoked on each instruction occurrence. *)
-
- method pLabel: unit -> label -> Pretty.doc
- (** Print a label. *)
-
- method pStmt: unit -> stmt -> Pretty.doc
- (** Control-flow statement. This is used by
- * {!Cil.printGlobal} and by {!Cil.dumpGlobal}. *)
-
- method dStmt: out_channel -> int -> stmt -> unit
- (** Dump a control-flow statement to a file with a given indentation.
- * This is used by {!Cil.dumpGlobal}. *)
-
- method dBlock: out_channel -> int -> block -> unit
- (** Dump a control-flow block to a file with a given indentation.
- * This is used by {!Cil.dumpGlobal}. *)
-
- method pBlock: unit -> block -> Pretty.doc
-
- method pBlock: unit -> block -> Pretty.doc
- (** Print a block. *)
-
- method pGlobal: unit -> global -> Pretty.doc
- (** Global (vars, types, etc.). This can be slow and is used only by
- * {!Cil.printGlobal} but not by {!Cil.dumpGlobal}. *)
-
- method dGlobal: out_channel -> global -> unit
- (** Dump a global to a file with a given indentation. This is used by
- * {!Cil.dumpGlobal} *)
-
- method pFieldDecl: unit -> fieldinfo -> Pretty.doc
- (** A field declaration *)
-
- method pType: Pretty.doc option -> unit -> typ -> Pretty.doc
- (* Use of some type in some declaration. The first argument is used to print
- * the declared element, or is None if we are just printing a type with no
- * name being declared. Note that for structure/union and enumeration types
- * the definition of the composite type is not visited. Use [vglob] to
- * visit it. *)
-
- method pAttr: attribute -> Pretty.doc * bool
- (** Attribute. Also return an indication whether this attribute must be
- * printed inside the __attribute__ list or not. *)
-
- method pAttrParam: unit -> attrparam -> Pretty.doc
- (** Attribute parameter *)
-
- method pAttrs: unit -> attributes -> Pretty.doc
- (** Attribute lists *)
-
- method pLineDirective: ?forcefile:bool -> location -> Pretty.doc
- (** Print a line-number. This is assumed to come always on an empty line.
- * If the forcefile argument is present and is true then the file name
- * will be printed always. Otherwise the file name is printed only if it
- * is different from the last time time this function is called. The last
- * file name is stored in a private field inside the cilPrinter object. *)
-
- method pStmtKind: stmt -> unit -> stmtkind -> Pretty.doc
- (** Print a statement kind. The code to be printed is given in the
- * {!Cil.stmtkind} argument. The initial {!Cil.stmt} argument
- * records the statement which follows the one being printed;
- * {!Cil.defaultCilPrinterClass} uses this information to prettify
- * statement printing in certain special cases. *)
-
- method pExp: unit -> exp -> Pretty.doc
- (** Print expressions *)
-
- method pInit: unit -> init -> Pretty.doc
- (** Print initializers. This can be slow and is used by
- * {!Cil.printGlobal} but not by {!Cil.dumpGlobal}. *)
-
- method dInit: out_channel -> int -> init -> unit
- (** Dump a global to a file with a given indentation. This is used by
- * {!Cil.dumpGlobal} *)
-end
-
-class defaultCilPrinterClass: cilPrinter
-val defaultCilPrinter: cilPrinter
-
-(** These are pretty-printers that will show you more details on the internal
- * CIL representation, without trying hard to make it look like C *)
-class plainCilPrinterClass: cilPrinter
-val plainCilPrinter: cilPrinter
-
-(* zra: This is the pretty printer that Maincil will use.
- by default it is set to defaultCilPrinter *)
-val printerForMaincil: cilPrinter ref
-
-(* Top-level printing functions *)
-(** Print a type given a pretty printer *)
-val printType: cilPrinter -> unit -> typ -> Pretty.doc
-
-(** Print an expression given a pretty printer *)
-val printExp: cilPrinter -> unit -> exp -> Pretty.doc
-
-(** Print an lvalue given a pretty printer *)
-val printLval: cilPrinter -> unit -> lval -> Pretty.doc
-
-(** Print a global given a pretty printer *)
-val printGlobal: cilPrinter -> unit -> global -> Pretty.doc
-
-(** Print an attribute given a pretty printer *)
-val printAttr: cilPrinter -> unit -> attribute -> Pretty.doc
-
-(** Print a set of attributes given a pretty printer *)
-val printAttrs: cilPrinter -> unit -> attributes -> Pretty.doc
-
-(** Print an instruction given a pretty printer *)
-val printInstr: cilPrinter -> unit -> instr -> Pretty.doc
-
-(** Print a statement given a pretty printer. This can take very long
- * (or even overflow the stack) for huge statements. Use {!Cil.dumpStmt}
- * instead. *)
-val printStmt: cilPrinter -> unit -> stmt -> Pretty.doc
-
-(** Print a block given a pretty printer. This can take very long
- * (or even overflow the stack) for huge block. Use {!Cil.dumpBlock}
- * instead. *)
-val printBlock: cilPrinter -> unit -> block -> Pretty.doc
-
-(** Dump a statement to a file using a given indentation. Use this instead of
- * {!Cil.printStmt} whenever possible. *)
-val dumpStmt: cilPrinter -> out_channel -> int -> stmt -> unit
-
-(** Dump a block to a file using a given indentation. Use this instead of
- * {!Cil.printBlock} whenever possible. *)
-val dumpBlock: cilPrinter -> out_channel -> int -> block -> unit
-
-(** Print an initializer given a pretty printer. This can take very long
- * (or even overflow the stack) for huge initializers. Use {!Cil.dumpInit}
- * instead. *)
-val printInit: cilPrinter -> unit -> init -> Pretty.doc
-
-(** Dump an initializer to a file using a given indentation. Use this instead of
- * {!Cil.printInit} whenever possible. *)
-val dumpInit: cilPrinter -> out_channel -> int -> init -> unit
-
-(** Pretty-print a type using {!Cil.defaultCilPrinter} *)
-val d_type: unit -> typ -> Pretty.doc
-
-(** Pretty-print an expression using {!Cil.defaultCilPrinter} *)
-val d_exp: unit -> exp -> Pretty.doc
-
-(** Pretty-print an lvalue using {!Cil.defaultCilPrinter} *)
-val d_lval: unit -> lval -> Pretty.doc
-
-(** Pretty-print an offset using {!Cil.defaultCilPrinter}, given the pretty
- * printing for the base. *)
-val d_offset: Pretty.doc -> unit -> offset -> Pretty.doc
-
-(** Pretty-print an initializer using {!Cil.defaultCilPrinter}. This can be
- * extremely slow (or even overflow the stack) for huge initializers. Use
- * {!Cil.dumpInit} instead. *)
-val d_init: unit -> init -> Pretty.doc
-
-(** Pretty-print a binary operator *)
-val d_binop: unit -> binop -> Pretty.doc
-
-(** Pretty-print a unary operator *)
-val d_unop: unit -> unop -> Pretty.doc
-
-(** Pretty-print an attribute using {!Cil.defaultCilPrinter} *)
-val d_attr: unit -> attribute -> Pretty.doc
-
-(** Pretty-print an argument of an attribute using {!Cil.defaultCilPrinter} *)
-val d_attrparam: unit -> attrparam -> Pretty.doc
-
-(** Pretty-print a list of attributes using {!Cil.defaultCilPrinter} *)
-val d_attrlist: unit -> attributes -> Pretty.doc
-
-(** Pretty-print an instruction using {!Cil.defaultCilPrinter} *)
-val d_instr: unit -> instr -> Pretty.doc
-
-(** Pretty-print a label using {!Cil.defaultCilPrinter} *)
-val d_label: unit -> label -> Pretty.doc
-
-(** Pretty-print a statement using {!Cil.defaultCilPrinter}. This can be
- * extremely slow (or even overflow the stack) for huge statements. Use
- * {!Cil.dumpStmt} instead. *)
-val d_stmt: unit -> stmt -> Pretty.doc
-
-(** Pretty-print a block using {!Cil.defaultCilPrinter}. This can be
- * extremely slow (or even overflow the stack) for huge blocks. Use
- * {!Cil.dumpBlock} instead. *)
-val d_block: unit -> block -> Pretty.doc
-
-(** Pretty-print the internal representation of a global using
- * {!Cil.defaultCilPrinter}. This can be extremely slow (or even overflow the
- * stack) for huge globals (such as arrays with lots of initializers). Use
- * {!Cil.dumpGlobal} instead. *)
-val d_global: unit -> global -> Pretty.doc
-
-
-(** Versions of the above pretty printers, that don't print #line directives *)
-val dn_exp : unit -> exp -> Pretty.doc
-val dn_lval : unit -> lval -> Pretty.doc
-(* dn_offset is missing because it has a different interface *)
-val dn_init : unit -> init -> Pretty.doc
-val dn_type : unit -> typ -> Pretty.doc
-val dn_global : unit -> global -> Pretty.doc
-val dn_attrlist : unit -> attributes -> Pretty.doc
-val dn_attr : unit -> attribute -> Pretty.doc
-val dn_attrparam : unit -> attrparam -> Pretty.doc
-val dn_stmt : unit -> stmt -> Pretty.doc
-val dn_instr : unit -> instr -> Pretty.doc
-
-
-(** Pretty-print a short description of the global. This is useful for error
- * messages *)
-val d_shortglobal: unit -> global -> Pretty.doc
-
-(** Pretty-print a global. Here you give the channel where the printout
- * should be sent. *)
-val dumpGlobal: cilPrinter -> out_channel -> global -> unit
-
-(** Pretty-print an entire file. Here you give the channel where the printout
- * should be sent. *)
-val dumpFile: cilPrinter -> out_channel -> string -> file -> unit
-
-
-(* the following error message producing functions also print a location in
- * the code. use {!Errormsg.bug} and {!Errormsg.unimp} if you do not want
- * that *)
-
-(** Like {!Errormsg.bug} except that {!Cil.currentLoc} is also printed *)
-val bug: ('a,unit,Pretty.doc) format -> 'a
-
-(** Like {!Errormsg.unimp} except that {!Cil.currentLoc}is also printed *)
-val unimp: ('a,unit,Pretty.doc) format -> 'a
-
-(** Like {!Errormsg.error} except that {!Cil.currentLoc} is also printed *)
-val error: ('a,unit,Pretty.doc) format -> 'a
-
-(** Like {!Cil.error} except that it explicitly takes a location argument,
- * instead of using the {!Cil.currentLoc} *)
-val errorLoc: location -> ('a,unit,Pretty.doc) format -> 'a
-
-(** Like {!Errormsg.warn} except that {!Cil.currentLoc} is also printed *)
-val warn: ('a,unit,Pretty.doc) format -> 'a
-
-
-(** Like {!Errormsg.warnOpt} except that {!Cil.currentLoc} is also printed.
- * This warning is printed only of {!Errormsg.warnFlag} is set. *)
-val warnOpt: ('a,unit,Pretty.doc) format -> 'a
-
-(** Like {!Errormsg.warn} except that {!Cil.currentLoc} and context
- is also printed *)
-val warnContext: ('a,unit,Pretty.doc) format -> 'a
-
-(** Like {!Errormsg.warn} except that {!Cil.currentLoc} and context is also
- * printed. This warning is printed only of {!Errormsg.warnFlag} is set. *)
-val warnContextOpt: ('a,unit,Pretty.doc) format -> 'a
-
-(** Like {!Cil.warn} except that it explicitly takes a location argument,
- * instead of using the {!Cil.currentLoc} *)
-val warnLoc: location -> ('a,unit,Pretty.doc) format -> 'a
-
-(** Sometimes you do not want to see the syntactic sugar that the above
- * pretty-printing functions add. In that case you can use the following
- * pretty-printing functions. But note that the output of these functions is
- * not valid C *)
-
-(** Pretty-print the internal representation of an expression *)
-val d_plainexp: unit -> exp -> Pretty.doc
-
-(** Pretty-print the internal representation of an integer *)
-val d_plaininit: unit -> init -> Pretty.doc
-
-(** Pretty-print the internal representation of an lvalue *)
-val d_plainlval: unit -> lval -> Pretty.doc
-
-(** Pretty-print the internal representation of an lvalue offset
-val d_plainoffset: unit -> offset -> Pretty.doc *)
-
-(** Pretty-print the internal representation of a type *)
-val d_plaintype: unit -> typ -> Pretty.doc
-
-
-
-(** {b ALPHA conversion} has been moved to the Alpha module. *)
-
-
-(** Assign unique names to local variables. This might be necessary after you
- * transformed the code and added or renamed some new variables. Names are
- * not used by CIL internally, but once you print the file out the compiler
- * downstream might be confused. You might
- * have added a new global that happens to have the same name as a local in
- * some function. Rename the local to ensure that there would never be
- * confusioin. Or, viceversa, you might have added a local with a name that
- * conflicts with a global *)
-val uniqueVarNames: file -> unit
-
-(** {b Optimization Passes} *)
-
-(** A peephole optimizer that processes two adjacent statements and possibly
- replaces them both. If some replacement happens, then the new statements
- are themselves subject to optimization *)
-val peepHole2: (instr * instr -> instr list option) -> stmt list -> unit
-
-(** Similar to [peepHole2] except that the optimization window consists of
- one statement, not two *)
-val peepHole1: (instr -> instr list option) -> stmt list -> unit
-
-(** {b Machine dependency} *)
-
-
-(** Raised when one of the bitsSizeOf functions cannot compute the size of a
- * type. This can happen because the type contains array-length expressions
- * that we don't know how to compute or because it is a type whose size is
- * not defined (e.g. TFun or an undefined compinfo). The string is an
- * explanation of the error *)
-exception SizeOfError of string * typ
-
-(** The size of a type, in bits. Trailing padding is added for structs and
- * arrays. Raises {!Cil.SizeOfError} when it cannot compute the size. This
- * function is architecture dependent, so you should only call this after you
- * call {!Cil.initCIL}. Remember that on GCC sizeof(void) is 1! *)
-val bitsSizeOf: typ -> int
-
-(* The size of a type, in bytes. Returns a constant expression or a "sizeof"
- * expression if it cannot compute the size. This function is architecture
- * dependent, so you should only call this after you call {!Cil.initCIL}. *)
-val sizeOf: typ -> exp
-
-(** The minimum alignment (in bytes) for a type. This function is
- * architecture dependent, so you should only call this after you call
- * {!Cil.initCIL}. *)
-val alignOf_int: typ -> int
-
-(** Give a type of a base and an offset, returns the number of bits from the
- * base address and the width (also expressed in bits) for the subobject
- * denoted by the offset. Raises {!Cil.SizeOfError} when it cannot compute
- * the size. This function is architecture dependent, so you should only call
- * this after you call {!Cil.initCIL}. *)
-val bitsOffset: typ -> offset -> int * int
-
-
-(** Whether "char" is unsigned. Set after you call {!Cil.initCIL} *)
-val char_is_unsigned: bool ref
-
-(** Whether the machine is little endian. Set after you call {!Cil.initCIL} *)
-val little_endian: bool ref
-
-(** Whether the compiler generates assembly labels by prepending "_" to the
- identifier. That is, will function foo() have the label "foo", or "_foo"?
- Set after you call {!Cil.initCIL} *)
-val underscore_name: bool ref
-
-(** Represents a location that cannot be determined *)
-val locUnknown: location
-
-(** Return the location of an instruction *)
-val get_instrLoc: instr -> location
-
-(** Return the location of a global, or locUnknown *)
-val get_globalLoc: global -> location
-
-(** Return the location of a statement, or locUnknown *)
-val get_stmtLoc: stmtkind -> location
-
-
-(** Generate an {!Cil.exp} to be used in case of errors. *)
-val dExp: Pretty.doc -> exp
-
-(** Generate an {!Cil.instr} to be used in case of errors. *)
-val dInstr: Pretty.doc -> location -> instr
-
-(** Generate a {!Cil.global} to be used in case of errors. *)
-val dGlobal: Pretty.doc -> location -> global
-
-(** Like map but try not to make a copy of the list *)
-val mapNoCopy: ('a -> 'a) -> 'a list -> 'a list
-
-(** Like map but each call can return a list. Try not to make a copy of the
- list *)
-val mapNoCopyList: ('a -> 'a list) -> 'a list -> 'a list
-
-(** sm: return true if the first is a prefix of the second string *)
-val startsWith: string -> string -> bool
-
-
-(** {b An Interpreter for constructing CIL constructs} *)
-
-(** The type of argument for the interpreter *)
-type formatArg =
- Fe of exp
- | Feo of exp option (** For array lengths *)
- | Fu of unop
- | Fb of binop
- | Fk of ikind
- | FE of exp list (** For arguments in a function call *)
- | Ff of (string * typ * attributes) (** For a formal argument *)
- | FF of (string * typ * attributes) list (** For formal argument lists *)
- | Fva of bool (** For the ellipsis in a function type *)
- | Fv of varinfo
- | Fl of lval
- | Flo of lval option
-
- | Fo of offset
-
- | Fc of compinfo
- | Fi of instr
- | FI of instr list
- | Ft of typ
- | Fd of int
- | Fg of string
- | Fs of stmt
- | FS of stmt list
- | FA of attributes
-
- | Fp of attrparam
- | FP of attrparam list
-
- | FX of string
-
-
-(** Pretty-prints a format arg *)
-val d_formatarg: unit -> formatArg -> Pretty.doc
-
-val lowerConstants: bool ref
- (** Do lower constant expressions into constants (default true) *)