Module Cil


module Cil: sig .. end
CIL original API documentation is available as an html version at http://manju.cs.berkeley.edu/cil.
Consult the Plugin Development Guide for additional details.
val info : ('a, Format.formatter, unit) Pervasives.format -> 'a
val err : ('a, Format.formatter, unit) Pervasives.format -> 'a
val log : ?once:bool -> ('a, Format.formatter, unit) Pervasives.format -> 'a
val warn : ?once:bool -> ('a, Format.formatter, unit) Pervasives.format -> 'a
val source : Cil_types.location -> Log.source
val warnOpt : ('a, Format.formatter, unit, unit) Pervasives.format4 -> 'a
val warning : ('a, Format.formatter, unit, unit) Pervasives.format4 -> 'a
val error : ('a, Format.formatter, unit, unit) Pervasives.format4 -> 'a
val abort : ('a, Format.formatter, unit, 'b) Pervasives.format4 -> 'a
val fatal : ('a, Format.formatter, unit, 'b) Pervasives.format4 -> 'a
val error_loc : string * int -> ('a, Format.formatter, unit, unit) Pervasives.format4 -> 'a
val abort_loc : string * int -> ('a, Format.formatter, unit, 'b) Pervasives.format4 -> 'a

CIL original API documentation is available as an html version at http://manju.cs.berkeley.edu/cil.
val initCIL : (unit -> unit) -> unit
Call this function to perform some initialization. Call if after you have set Cil.msvcMode. the argument is the function to call to init logic builtins

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_types.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.

type theMachine = private {
   mutable msvcMode : bool; (*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*)
   mutable useLogicalOperators : bool;
   mutable theMachine : Cil_types.mach;
   mutable lowerConstants : bool; (*Do lower constants (default true)*)
   mutable insertImplicitCasts : bool; (*Do insert implicit casts (default true)*)
   mutable little_endian : bool; (*Whether "char" is unsigned.*)
   mutable char_is_unsigned : bool; (*Whether the compiler generates assembly labels by prepending "_" to the identifier. That is, will function foo() have the label "foo", or "_foo"?*)
   mutable underscore_name : bool; (*Wether enum are signed or not.*)
   mutable enum_are_signed : bool;
   mutable stringLiteralType : Cil_types.typ; (*An unsigned integer type that fits pointers. Depends on Cil.msvcMode*)
   mutable upointType : Cil_types.typ;
   mutable wcharKind : Cil_types.ikind; (*An integer type that fits wchar_t.*)
   mutable wcharType : Cil_types.typ;
   mutable ptrdiffKind : Cil_types.ikind; (*An integer type that fits ptrdiff_t.*)
   mutable ptrdiffType : Cil_types.typ;
   mutable typeOfSizeOf : Cil_types.typ; (*An integer type that is the type of sizeof.*)
   mutable kindOfSizeOf : Cil_types.ikind; (*The integer kind of Cil.typeOfSizeOf.*)
}
val theMachine : theMachine
Current machine description
val selfMachine : Project.Computation.t
val set_msvcMode : bool -> unit
Must be called before Cil.initCIL.

type lineDirectiveStyle =
| LineComment (*Before every element, print the line number in comments. This is ignored by processing tools (thus errors are reproted in the CIL output), but useful for visual inspection*)
| LineCommentSparse (*Like LineComment but only print a line directive for a new source line*)
| LinePreprocessorInput (*Use #line directives*)
| LinePreprocessorOutput (*Use # nnn directives (in gcc mode)*)
Styles of printing line directives

type miscState = {
   mutable lineDirectiveStyle : lineDirectiveStyle option; (*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*)
   mutable print_CIL_Input : bool; (*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.*)
   mutable printCilAsIs : bool; (*The length used when wrapping output lines. Setting this variable to a large integer will prevent wrapping and make #line directives more accurate.*)
   mutable lineLength : int; (*Emit warnings when truncating integer constants (default true)*)
   mutable warnTruncate : bool;
}
val miscState : miscState

type featureDescr = {
   fd_enabled : bool Pervasives.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 : Cil_types.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.*)
}
To be able to add/remove features easily, each feature should be package as an interface with the following interface. These features should be
val compareLoc : Cil_types.location -> Cil_types.location -> int
Comparison function for tsets. * Compares first by filename, then line, then byte

Values for manipulating globals
val emptyFunction : string -> Cil_types.fundec
Make an empty function
val setFormals : Cil_types.fundec -> Cil_types.varinfo list -> unit
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 getReturnType : Cil_types.typ -> Cil_types.typ
Takes as input a function type (or a typename on it) and return its return type.
val setReturnTypeVI : Cil_types.varinfo -> Cil_types.typ -> unit
Change the return type of the function passed as 1st argument to be the type passed as 2nd argument.
val setReturnType : Cil_types.fundec -> Cil_types.typ -> unit
val setFunctionType : Cil_types.fundec -> Cil_types.typ -> 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 setFunctionTypeMakeFormals : Cil_types.fundec -> Cil_types.typ -> unit
Set the type of the function and make formal arguments for them
val setMaxId : Cil_types.fundec -> unit
Update the smaxid after you have populated with locals and formals (unless you constructed those using Cil.makeLocalVar or Cil.makeTempVar.
val selfFormalsDecl : Project.Computation.t
state of the table associating formals to each prototype.
val makeFormalsVarDecl : string * Cil_types.typ * Cil_types.attributes -> Cil_types.varinfo
creates a new varinfo for the parameter of a prototype.
val setFormalsDecl : Cil_types.varinfo -> Cil_types.typ -> unit
Update the formals of a function declaration from its identifier and its type. For a function definition, use Cil.setFormals. Do nothing if the type is not a function type or if the list of argument is empty.
val unsafeSetFormalsDecl : Cil_types.varinfo -> Cil_types.varinfo list -> unit
replace to formals of a function declaration with the given list of varinfo.
val getFormalsDecl : Cil_types.varinfo -> Cil_types.varinfo list
Get the formals of a function declaration registered with Cil.setFormalsDecl.
Raises Not_found if the function is not registered (this is in particular the case for prototypes with an empty list of arguments. See Cil.setFormalsDecl)
val dummyFile : Cil_types.file
A dummy file
val getGlobInit : ?main_name:string -> Cil_types.file -> Cil_types.fundec
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 iterGlobals : Cil_types.file -> (Cil_types.global -> unit) -> unit
Iterate over all globals, including the global initializer
val foldGlobals : Cil_types.file -> ('a -> Cil_types.global -> 'a) -> 'a -> 'a
Fold over all globals, including the global initializer
val mapGlobals : Cil_types.file -> (Cil_types.global -> Cil_types.global) -> unit
Map over all globals, including the global initializer and change things in place
val findOrCreateFunc : Cil_types.file -> string -> Cil_types.typ -> Cil_types.varinfo
Find a function or function prototype with the given name in the file. If it does not exist, create a prototype with the given type, and return the new varinfo. This is useful when you need to call a libc function whose prototype may or may not already exist in the file.

Because the new prototype is added to the start of the file, you shouldn't refer to any struct or union types in the function type.

module Sid: sig .. end
val new_exp : Cil_types.exp_node -> Cil_types.exp
creates an expression with a fresh id
val dummy_exp : Cil_types.exp_node -> Cil_types.exp
creates an expression with a dummy id. Use with caution, i.e. not on expressions that may be put in the AST.
val is_case_label : Cil_types.label -> bool
Return true on case and default labels, false otherwise.
val prepareCFG : ?keepSwitch:bool -> Cil_types.fundec -> unit
Prepare a function for CFG information computation by Cil.computeCFGInfo. This function converts all Break, Switch, Default and Continue Cil_types.stmtkinds and Cil_types.labels into Ifs and Gotos, giving the function body a very CFG-like character. This function modifies its argument in place.
val computeCFGInfo : Cil_types.fundec -> bool -> 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_types.stmtkinds or Cil_types.labels. 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 copyFunction : Cil_types.fundec -> string -> Cil_types.fundec
Create a deep copy of a function. There should be no sharing between the copy and the original function
val pushGlobal : Cil_types.global ->
types:Cil_types.global list Pervasives.ref ->
variables:Cil_types.global list Pervasives.ref -> unit
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 invalidStmt : Cil_types.stmt
An empty statement. Used in pretty printing
module BuiltinFunctions: Computation.HASHTBL_OUTPUT  with type key = string
			     and type data = typ * typ list * bool
A list of the built-in functions for the current compiler (GCC or MSVC, depending on !msvcMode).
val builtinLoc : Cil_types.location
This is used as the location of the prototypes of builtin functions.
val range_loc : Cil_types.location -> Cil_types.location -> Cil_types.location
Returns a location that ranges over the two locations in arguments.

Values for manipulating initializers
val makeZeroInit : Cil_types.typ -> Cil_types.init
Make a initializer for zero-ing a data type
val foldLeftCompound : implicit:bool ->
doinit:(Cil_types.offset -> Cil_types.init -> Cil_types.typ -> 'a -> 'a) ->
ct:Cil_types.typ ->
initl:(Cil_types.offset * Cil_types.init) list -> acc:'a -> 'a
Fold over the list of initializers in a Compound (not also the nested ones). doinit is called on every present initializer, even if it is of compound type. The parameters of doinit are: the offset in the compound (this is Field(f,NoOffset) or Index(i,NoOffset)), the initializer value, expected type of the initializer value, accumulator. In the case of arrays there might be missing zero-initializers at the end of the list. These are scanned only if implicit is true. This is much like List.fold_left except we also pass the type of the initializer.

This is a good way to use it to scan even nested initializers :

  let rec myInit (lv: lval) (i: init) (acc: 'a) : 'a =
      match i with
        SingleInit e -> ... do something with lv and e and acc ...
      | CompoundInit (ct, initl) ->
         foldLeftCompound ~implicit:false
             ~doinit:(fun off' i' t' acc ->
                        myInit (addOffsetLval lv off') i' acc)
             ~ct:ct
             ~initl:initl
             ~acc:acc


Values for manipulating types


val voidType : Cil_types.typ
void
val isVoidType : Cil_types.typ -> bool
is the given type "void"?
val isVoidPtrType : Cil_types.typ -> bool
is the given type "void *"?
val intType : Cil_types.typ
int
val uintType : Cil_types.typ
unsigned int
val longType : Cil_types.typ
long
val ulongType : Cil_types.typ
unsigned long
val ulongLongType : Cil_types.typ
unsigned long long
val charType : Cil_types.typ
char
val charPtrType : Cil_types.typ
char *
val charConstPtrType : Cil_types.typ
char const *
val voidPtrType : Cil_types.typ
void *
val voidConstPtrType : Cil_types.typ
void const *
val intPtrType : Cil_types.typ
int *
val uintPtrType : Cil_types.typ
unsigned int *
val floatType : Cil_types.typ
float
val doubleType : Cil_types.typ
double
val longDoubleType : Cil_types.typ
long double
val isSigned : Cil_types.ikind -> bool
Returns true if and only if the given integer type is signed.
val isSignedInteger : Cil_types.typ -> bool
Returns true if and only if the given type is a signed integer type.
val mkCompInfo : bool ->
string ->
(Cil_types.compinfo ->
(string * Cil_types.typ * int option * Cil_types.attributes *
Cil_types.location)
list) ->
Cil_types.attributes -> Cil_types.compinfo
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 copyCompInfo : Cil_types.compinfo -> string -> Cil_types.compinfo
Makes a shallow copy of a Cil_types.compinfo changing the name and the key.
val missingFieldName : string
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 compFullName : Cil_types.compinfo -> string
Get the full name of a comp
val isCompleteType : Cil_types.typ -> bool
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 unrollType : Cil_types.typ -> Cil_types.typ
Unroll a type until it exposes a non TNamed. Will collect all attributes appearing in TNamed!!!
val unrollTypeDeep : Cil_types.typ -> Cil_types.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 separateStorageModifiers : Cil_types.attribute list ->
Cil_types.attribute list * Cil_types.attribute list
Separate out the storage-modifier name attributes
val isCharType : Cil_types.typ -> bool
True if the argument is a character type (i.e. plain, signed or unsigned)
val isCharPtrType : Cil_types.typ -> bool
True if the argument is a pointer to a character type (i.e. plain, signed or unsigned)
val isCharArrayType : Cil_types.typ -> bool
True if the argument is an array of a character type (i.e. plain, signed or unsigned)
val isIntegralType : Cil_types.typ -> bool
True if the argument is a logic integral type (i.e. integer or enum)
val isLogicIntegralType : Cil_types.logic_type -> bool
True if the argument is an integral type (i.e. integer or enum), either C or mathematical one
val isFloatingType : Cil_types.typ -> bool
True if the argument is a floating point type
val isLogicFloatType : Cil_types.logic_type -> bool
True if the argument is a floating point type
val isLogicRealOrFloatType : Cil_types.logic_type -> bool
True if the argument is a C floating point type or logic 'real' type
val isLogicRealType : Cil_types.logic_type -> bool
True if the argument is the logic 'real' type
val isArithmeticType : Cil_types.typ -> bool
True if the argument is an arithmetic type (i.e. integer, enum or floating point
val isLogicArithmeticType : Cil_types.logic_type -> bool
True if the argument is a logic arithmetic type (i.e. integer, enum or floating point, either C or mathematical one
val isPointerType : Cil_types.typ -> bool
True if the argument is a pointer type
val isTypeTagType : Cil_types.logic_type -> bool
True if the argument is the type for reified C types
val isFunctionType : Cil_types.typ -> bool
True if the argument is a function type.
Consult the Plugin Development Guide for additional details.
val argsToList : (string * Cil_types.typ * Cil_types.attributes) list option ->
(string * Cil_types.typ * Cil_types.attributes) list
Obtain the argument list ([] if None)
val isArrayType : Cil_types.typ -> bool
True if the argument is an array type
val isStructOrUnionType : Cil_types.typ -> bool
True if the argument is a struct of union type
exception LenOfArray
Raised when Cil.lenOfArray fails either because the length is None or because it is a non-constant expression
val lenOfArray : Cil_types.exp option -> int
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 lenOfArray64 : Cil_types.exp option -> Int64.t
val getCompField : Cil_types.compinfo -> string -> Cil_types.fieldinfo
Return a named fieldinfo in compinfo, or raise Not_found

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*)
A datatype to be used in conjunction with existsType
val existsType : (Cil_types.typ -> existsAction) -> Cil_types.typ -> bool
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 splitFunctionType : Cil_types.typ ->
Cil_types.typ * (string * Cil_types.typ * Cil_types.attributes) list option *
bool * Cil_types.attributes
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

Same as Cil.splitFunctionType but takes a varinfo. Prints a nicer error message if the varinfo is not for a function

val splitFunctionTypeVI : Cil_types.varinfo ->
Cil_types.typ * (string * Cil_types.typ * Cil_types.attributes) list option *
bool * Cil_types.attributes

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 Cilutil.equals to compare type signatures because they might still contain circular structures (through attributes, and sizeof)
val typeSig : Cil_types.typ -> Cil_types.typsig
Compute a type signature
val typeSigWithAttrs : ?ignoreSign:bool ->
(Cil_types.attributes -> Cil_types.attributes) ->
Cil_types.typ -> Cil_types.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 setTypeSigAttrs : Cil_types.attributes -> Cil_types.typsig -> Cil_types.typsig
Replace the attributes of a signature (only at top level)
val typeSigAttrs : Cil_types.typsig -> Cil_types.attributes
Get the top-level attributes of a signature

LVALUES
val makeVarinfo : ?logic:bool -> bool -> bool -> string -> Cil_types.typ -> Cil_types.varinfo
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 logic argument defaults to false and should be used to create a varinfo such that varinfo.vlogic=true. The first argument specifies whether the varinfo is for a global and the second is for formals.
val makeFormalVar : Cil_types.fundec ->
?where:string -> string -> Cil_types.typ -> Cil_types.varinfo
Make a formal variable for a function declaration. 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 makeLocalVar : Cil_types.fundec ->
?insert:bool -> string -> Cil_types.typ -> Cil_types.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 makePseudoVar : Cil_types.typ -> Cil_types.varinfo
Make a pseudo-variable to use as placeholder in term to expression conversions. Its logic field is set.
val makeTempVar : Cil_types.fundec ->
?name:string ->
?descr:string -> ?descrpure:bool -> Cil_types.typ -> Cil_types.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. Optionally, you can give the variable a description of its contents.
val makeGlobalVar : ?logic:bool -> string -> Cil_types.typ -> Cil_types.varinfo
Make a global variable. Your responsibility to make sure that the name is unique. logic defaults to false.
val copyVarinfo : Cil_types.varinfo -> string -> Cil_types.varinfo
Make a shallow copy of a varinfo and assign a new identifier. If the original varinfo has an associated logic var, it is copied too and associated to the copied varinfo
val varinfo_from_vid : int -> Cil_types.varinfo
Raises Not_found if the given id does not match any varinfo.
Returns the varinfo corresponding to the given id.
val varinfos_self : Project.Computation.t
State of the varinfos table.
val lastOffset : Cil_types.offset -> Cil_types.offset
Returns the last offset in the chain.
val lastTermOffset : Cil_types.term_offset -> Cil_types.term_offset
Equivalent to lastOffset for terms.
val addOffsetLval : Cil_types.offset -> Cil_types.lval -> Cil_types.lval
Add an offset at the end of an lvalue. Make sure the type of the lvalue and the offset are compatible.
val addTermOffsetLval : Cil_types.term_offset -> Cil_types.term_lval -> Cil_types.term_lval
Equivalent to addOffsetLval for terms.
val addOffset : Cil_types.offset -> Cil_types.offset -> Cil_types.offset
addOffset o1 o2 adds o1 to the end of o2.
val addTermOffset : Cil_types.term_offset -> Cil_types.term_offset -> Cil_types.term_offset
Equivalent to addOffset for terms.
val removeOffsetLval : Cil_types.lval -> Cil_types.lval * Cil_types.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 removeOffset : Cil_types.offset -> Cil_types.offset * Cil_types.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 typeOfLval : Cil_types.lval -> Cil_types.typ
Compute the type of an lvalue
val typeOfTermLval : Cil_types.term_lval -> Cil_types.logic_type
Equivalent to typeOfLval for terms.
val typeOffset : Cil_types.typ -> Cil_types.offset -> Cil_types.typ
Compute the type of an offset from a base type
val typeTermOffset : Cil_types.logic_type -> Cil_types.term_offset -> Cil_types.logic_type
Equivalent to typeOffset for terms.

Values for manipulating expressions
val zero : Cil_types.exp
0
val one : Cil_types.exp
1
val mone : Cil_types.exp
-1
val kinteger64 : Cil_types.ikind -> int64 -> Cil_types.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 kinteger : Cil_types.ikind -> int -> Cil_types.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 integer : int -> Cil_types.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 isInteger : Cil_types.exp -> int64 option
True if the given expression is a (possibly cast'ed) character or an integer constant
val i64_to_int : int64 -> int
Convert a 64-bit int to an OCaml int, or raise an exception if that can't be done.
val isConstant : Cil_types.exp -> bool
True if the expression is a compile-time constant
val isConstantOffset : Cil_types.offset -> bool
True if the given offset contains only field nanmes or constant indices.
val isZero : Cil_types.exp -> bool
True if the given expression is a (possibly cast'ed) integer or character constant with value zero
val isLogicZero : Cil_types.term -> bool
True if the term is the constant 0
val isLogicNull : Cil_types.term -> bool
True if the given term is \null or a constant null pointer
val get_status : Cil_types.code_annotation -> Cil_types.annot_status
Deprecated.Since Beryllium-20090901+dev, use !Db.Properties.Status.code_annotation
val reduce_multichar : Cil_types.typ -> int64 list -> int64
gives the value of a wide char literal.
val interpret_character_constant : int64 list -> Cil_types.constant * Cil_types.typ
gives the value of a char literal.
val charConstToInt : char -> Cil_types.constant
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 constFold : bool -> Cil_types.exp -> Cil_types.exp
Do constant folding on an expression. If the first argument is true then will also compute compiler-dependent expressions such as sizeof. See also Cil.constFoldVisitor, which will run constFold on all expressions in a given AST node.
val constFoldTermNodeAtTop : Cil_types.term_node -> Cil_types.term_node
Do constant folding on an term at toplevel only. This uses compiler-dependent informations and will remove all sizeof and alignof.
val constFoldTerm : bool -> Cil_types.term -> Cil_types.term
Do constant folding on an term at toplevel only. If the first argument is true then will also compute compiler-dependent expressions such as sizeof and alignof.
val constFoldBinOp : bool ->
Cil_types.binop ->
Cil_types.exp -> Cil_types.exp -> Cil_types.typ -> Cil_types.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 compareExp : Cil_types.exp -> Cil_types.exp -> bool
true if the two expressions are syntactically the same.
val compareLval : Cil_types.lval -> Cil_types.lval -> bool
true if the two lval are syntactically the same.
val increm : Cil_types.exp -> int -> Cil_types.exp
Increment an expression. Can be arithmetic or pointer type
val increm64 : Cil_types.exp -> int64 -> Cil_types.exp
Increment an expression. Can be arithmetic or pointer type
val var : Cil_types.varinfo -> Cil_types.lval
Makes an lvalue out of a given variable
val mkAddrOf : Cil_types.lval -> Cil_types.exp
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 "& v0"
val mkAddrOrStartOf : Cil_types.lval -> Cil_types.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 mkMem : addr:Cil_types.exp -> off:Cil_types.offset -> Cil_types.lval
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 mkTermMem : addr:Cil_types.term -> off:Cil_types.term_offset -> Cil_types.term_lval
Equivalent to mkMem for terms.
val mkString : string -> Cil_types.exp
Make an expression that is a string constant (of pointer type)
val need_cast : Cil_types.typ -> Cil_types.typ -> bool
true if both types are not equivalent.
val mkCastT : e:Cil_types.exp -> oldt:Cil_types.typ -> newt:Cil_types.typ -> Cil_types.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 mkCast : e:Cil_types.exp -> newt:Cil_types.typ -> Cil_types.exp
Like Cil.mkCastT but uses typeOf to get oldt
val stripTermCasts : Cil_types.term -> Cil_types.term
Equivalent to stripCasts for terms.
val stripCasts : Cil_types.exp -> Cil_types.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 stripInfo : Cil_types.exp -> Cil_types.exp
Removes info wrappers and return underlying expression
val stripCastsAndInfo : Cil_types.exp -> Cil_types.exp
Removes casts and info wrappers and return underlying expression
val stripCastsButLastInfo : Cil_types.exp -> Cil_types.exp
Removes casts and info wrappers,except last info wrapper, and return underlying expression
val exp_info_of_term : Cil_types.term -> Cil_types.exp_info
Extracts term information in an expression information
val term_of_exp_info : Cil_types.term_node -> Cil_types.exp_info -> Cil_types.term
Constructs a term from a term node and an expression information
val map_under_info : (Cil_types.exp -> Cil_types.exp) -> Cil_types.exp -> Cil_types.exp
Map some function on underlying expression if Info or else on expression
val app_under_info : (Cil_types.exp -> unit) -> Cil_types.exp -> unit
Apply some function on underlying expression if Info or else on expression
val typeOf : Cil_types.exp -> Cil_types.typ
Compute the type of an expression.
Consult the Plugin Development Guide for additional details.
val typeOf_pointed : Cil_types.typ -> Cil_types.typ
Returns the type pointed by the given type. Asserts it is a pointer type.
val is_fully_arithmetic : Cil_types.typ -> bool
Returns true whenever the type contains only arithmetic types
val parseInt : string -> Cil_types.exp
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

Values for manipulating statements
val mkStmt : ?valid_sid:bool -> Cil_types.stmtkind -> Cil_types.stmt
Construct a statement, given its kind. Initialize the sid field to -1 if valid_sid is false, or to a valid sid if valid_sid is true, and labels, succs and preds to the empty list
val mkStmtCfg : before:bool ->
new_stmtkind:Cil_types.stmtkind -> ref_stmt:Cil_types.stmt -> Cil_types.stmt
val mkBlock : Cil_types.stmt list -> Cil_types.block
Construct a block with no attributes, given a list of statements
val mkStmtCfgBlock : Cil_types.stmt list -> Cil_types.stmt
Construct a block with no attributes, given a list of statements and wrap it into the Cfg.
val mkStmtOneInstr : Cil_types.instr -> Cil_types.stmt
Construct a statement consisting of just one instruction

Try to compress statements so as to get maximal basic blocks. use this instead of List.@ because you get fewer basic blocks
val mkEmptyStmt : ?loc:Cil_types.location -> unit -> Cil_types.stmt
Returns an empty statement (of kind Instr)
val dummyInstr : Cil_types.instr
A instr to serve as a placeholder
val dummyStmt : Cil_types.stmt
A statement consisting of just dummyInstr
val mkWhile : guard:Cil_types.exp -> body:Cil_types.stmt list -> Cil_types.stmt list
Make a while loop. Can contain Break or Continue
val mkForIncr : iter:Cil_types.varinfo ->
first:Cil_types.exp ->
stopat:Cil_types.exp ->
incr:Cil_types.exp -> body:Cil_types.stmt list -> Cil_types.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 mkFor : start:Cil_types.stmt list ->
guard:Cil_types.exp ->
next:Cil_types.stmt list -> body:Cil_types.stmt list -> Cil_types.stmt list
Make a for loop for(start; guard; next) { ... }. The body can contain Break but not Continue !!!
val block_from_unspecified_sequence : (Cil_types.stmt * Cil_types.lval list * Cil_types.lval list *
Cil_types.lval list)
list -> Cil_types.block
creates a block with empty attributes from an unspecified sequence.

Values for manipulating 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*)
Various classes of attributes
val registerAttribute : string -> attributeClass -> unit
Add a new attribute with a specified class
val removeAttribute : string -> unit
Remove an attribute previously registered.
val attributeClass : string -> attributeClass
Return the class of an attributes.
val partitionAttributes : default:attributeClass ->
Cil_types.attributes ->
Cil_types.attribute list * Cil_types.attribute list *
Cil_types.attribute list
Partition the attributes into classes:name attributes, function type, and type attributes
val addAttribute : Cil_types.attribute -> Cil_types.attributes -> Cil_types.attributes
Add an attribute. Maintains the attributes in sorted order of the second argument
val addAttributes : Cil_types.attribute list -> Cil_types.attributes -> Cil_types.attributes
Add a list of attributes. Maintains the attributes in sorted order. The second argument must be sorted, but not necessarily the first
val dropAttribute : string -> Cil_types.attributes -> Cil_types.attributes
Remove all attributes with the given name. Maintains the attributes in sorted order.
val dropAttributes : string list -> Cil_types.attributes -> Cil_types.attributes
Remove all attributes with names appearing in the string list. Maintains the attributes in sorted order
val filterAttributes : string -> Cil_types.attributes -> Cil_types.attributes
Retains attributes with the given name
val hasAttribute : string -> Cil_types.attributes -> bool
True if the named attribute appears in the attribute list. The list of attributes must be sorted.
val mkAttrAnnot : string -> string
returns the complete name for an attribute annotation.
val attributeName : Cil_types.attribute -> string
Returns the name of an attribute.
val findAttribute : string -> Cil_types.attribute list -> Cil_types.attrparam list
Returns the list of parameters associated to an attribute. The list is empty if there is no such attribute or it has no parameters at all.
val typeAttrs : Cil_types.typ -> Cil_types.attribute list
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 typeAttr : Cil_types.typ -> Cil_types.attribute list
Returns the attributes of a type.
val setTypeAttrs : Cil_types.typ -> Cil_types.attributes -> Cil_types.typ
val typeAddAttributes : Cil_types.attribute list -> Cil_types.typ -> Cil_types.typ
Add some attributes to a type
val typeRemoveAttributes : string list -> Cil_types.typ -> Cil_types.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 expToAttrParam : Cil_types.exp -> Cil_types.attrparam
Convert an expression into an attrparam, if possible. Otherwise raise NotAnAttrParam with the offending subexpression
val exists_attribute_deep : (Cil_types.attribute -> bool) -> Cil_types.typ -> string list option
Returns the list of field names leading to the wanted attributes
exception NotAnAttrParam of Cil_types.exp

The visitor

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)*)
| JustCopy (*visit the children, but only to make the necessary copies (only useful for copy visitor)*)
| JustCopyPost of ('a -> 'a) (*same as JustCopy + applies the given function to the result.*)
| ChangeTo of 'a (*Replace the expression with the given one*)
| ChangeToPost of 'a * ('a -> 'a) (*applies the expression to the function and gives back the result. Useful to insert some actions in an inheritance chain*)
| 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*)
Different visiting actions. 'a will be instantiated with exp, instr, etc.
Consult the Plugin Development Guide for additional details.
type visitor_behavior 
How the visitor should behave in front of mutable fields: in place modification or copy of the structure. This type is abstract. Use one of the two values below in your classes.
Consult the Plugin Development Guide for additional details.
val inplace_visit : unit -> visitor_behavior
In-place modification. Behavior of the original cil visitor.
Consult the Plugin Development Guide for additional details.
val copy_visit : unit -> visitor_behavior
Makes fresh copies of the mutable structures.
Consult the Plugin Development Guide for additional details.
val is_copy_behavior : visitor_behavior -> bool
true iff the behavior is a copy behavior.
val reset_behavior_varinfo : visitor_behavior -> unit
resets the internal tables used by the given visitor_behavior. If you use fresh instances of visitor for each round of transformation, this should not be needed. In place modifications do not need that at all.
val reset_behavior_compinfo : visitor_behavior -> unit
val reset_behavior_enuminfo : visitor_behavior -> unit
val reset_behavior_enumitem : visitor_behavior -> unit
val reset_behavior_typeinfo : visitor_behavior -> unit
val reset_behavior_stmt : visitor_behavior -> unit
val reset_behavior_logic_info : visitor_behavior -> unit
val reset_behavior_fieldinfo : visitor_behavior -> unit
val get_varinfo : visitor_behavior -> Cil_types.varinfo -> Cil_types.varinfo
retrieve the representative of a given varinfo in the current state of the visitor
val get_compinfo : visitor_behavior -> Cil_types.compinfo -> Cil_types.compinfo
val get_enuminfo : visitor_behavior -> Cil_types.enuminfo -> Cil_types.enuminfo
val get_enumitem : visitor_behavior -> Cil_types.enumitem -> Cil_types.enumitem
val get_typeinfo : visitor_behavior -> Cil_types.typeinfo -> Cil_types.typeinfo
val get_stmt : visitor_behavior -> Cil_types.stmt -> Cil_types.stmt
val get_logic_info : visitor_behavior -> Cil_types.logic_info -> Cil_types.logic_info
val get_fieldinfo : visitor_behavior -> Cil_types.fieldinfo -> Cil_types.fieldinfo
val get_logic_var : visitor_behavior -> Cil_types.logic_var -> Cil_types.logic_var
val get_original_varinfo : visitor_behavior -> Cil_types.varinfo -> Cil_types.varinfo
retrieve the original representative of a given copy of a varinfo in the current state of the visitor.
val get_original_compinfo : visitor_behavior -> Cil_types.compinfo -> Cil_types.compinfo
val get_original_enuminfo : visitor_behavior -> Cil_types.enuminfo -> Cil_types.enuminfo
val get_original_enumitem : visitor_behavior -> Cil_types.enumitem -> Cil_types.enumitem
val get_original_typeinfo : visitor_behavior -> Cil_types.typeinfo -> Cil_types.typeinfo
val get_original_stmt : visitor_behavior -> Cil_types.stmt -> Cil_types.stmt
val get_original_logic_info : visitor_behavior -> Cil_types.logic_info -> Cil_types.logic_info
val get_original_fieldinfo : visitor_behavior -> Cil_types.fieldinfo -> Cil_types.fieldinfo
val get_original_logic_var : visitor_behavior -> Cil_types.logic_var -> Cil_types.logic_var
val set_varinfo : visitor_behavior -> Cil_types.varinfo -> Cil_types.varinfo -> unit
change the representative of a given varinfo in the current state of the visitor. Use with care (i.e. makes sure that the old one is not referenced anywhere in the AST, or sharing will be lost.
val set_compinfo : visitor_behavior -> Cil_types.compinfo -> Cil_types.compinfo -> unit
val set_enuminfo : visitor_behavior -> Cil_types.enuminfo -> Cil_types.enuminfo -> unit
val set_enumitem : visitor_behavior -> Cil_types.enumitem -> Cil_types.enumitem -> unit
val set_typeinfo : visitor_behavior -> Cil_types.typeinfo -> Cil_types.typeinfo -> unit
val set_stmt : visitor_behavior -> Cil_types.stmt -> Cil_types.stmt -> unit
val set_logic_info : visitor_behavior -> Cil_types.logic_info -> Cil_types.logic_info -> unit
val set_fieldinfo : visitor_behavior -> Cil_types.fieldinfo -> Cil_types.fieldinfo -> unit
val set_logic_var : visitor_behavior -> Cil_types.logic_var -> Cil_types.logic_var -> unit
val set_orig_varinfo : visitor_behavior -> Cil_types.varinfo -> Cil_types.varinfo -> unit
change the reference of a given new varinfo in the current state of the visitor. Use with care
val set_orig_compinfo : visitor_behavior -> Cil_types.compinfo -> Cil_types.compinfo -> unit
val set_orig_enuminfo : visitor_behavior -> Cil_types.enuminfo -> Cil_types.enuminfo -> unit
val set_orig_enumitem : visitor_behavior -> Cil_types.enumitem -> Cil_types.enumitem -> unit
val set_orig_typeinfo : visitor_behavior -> Cil_types.typeinfo -> Cil_types.typeinfo -> unit
val set_orig_stmt : visitor_behavior -> Cil_types.stmt -> Cil_types.stmt -> unit
val set_orig_logic_info : visitor_behavior -> Cil_types.logic_info -> Cil_types.logic_info -> unit
val set_orig_fieldinfo : visitor_behavior -> Cil_types.fieldinfo -> Cil_types.fieldinfo -> unit
val set_orig_logic_var : visitor_behavior -> Cil_types.logic_var -> Cil_types.logic_var -> unit
class type cilVisitor = object .. end
A visitor interface for traversing CIL trees.
class genericCilVisitor : ?prj:Project.t -> visitor_behavior -> cilVisitor
generic visitor, parameterized by its copying behavior.
class nopCilVisitor : cilVisitor
Default in place visitor doing nothing and operating on current project.
val doVisit : 'a ->
'a ->
('b -> 'b) -> ('b -> 'b visitAction) -> ('a -> 'b -> 'b) -> 'b -> 'b
doVisit vis deepCopyVisitor copy action children node visits a node (or its copy according to the result of copy) and if needed its children. Do not use it if you don't understand Cil visitor mechanism
val doVisitList : 'a ->
'a ->
('b -> 'b) ->
('b -> 'b list visitAction) -> ('a -> 'b -> 'b) -> 'b -> 'b list
same as above, but can return a list of nodes
val visitCilFileCopy : cilVisitor -> Cil_types.file -> Cil_types.file
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.
Consult the Plugin Development Guide for additional details.
val visitCilFile : cilVisitor -> Cil_types.file -> unit
Same thing, but the result is ignored. The given visitor must thus be an inplace visitor. Nothing is done if the visitor is a copy visitor.
Consult the Plugin Development Guide for additional details.
val visitCilFileSameGlobals : cilVisitor -> Cil_types.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.
Consult the Plugin Development Guide for additional details.
val visitCilGlobal : cilVisitor -> Cil_types.global -> Cil_types.global list
Visit a global
val visitCilFunction : cilVisitor -> Cil_types.fundec -> Cil_types.fundec
Visit a function definition
val visitCilExpr : cilVisitor -> Cil_types.exp -> Cil_types.exp
val visitCilLval : cilVisitor -> Cil_types.lval -> Cil_types.lval
Visit an lvalue
val visitCilOffset : cilVisitor -> Cil_types.offset -> Cil_types.offset
Visit an lvalue or recursive offset
val visitCilInitOffset : cilVisitor -> Cil_types.offset -> Cil_types.offset
Visit an initializer offset
val visitCilInstr : cilVisitor -> Cil_types.instr -> Cil_types.instr list
Visit an instruction
val visitCilStmt : cilVisitor -> Cil_types.stmt -> Cil_types.stmt
Visit a statement
val visitCilBlock : cilVisitor -> Cil_types.block -> Cil_types.block
Visit a block
val visitCilType : cilVisitor -> Cil_types.typ -> Cil_types.typ
Visit a type
val visitCilVarDecl : cilVisitor -> Cil_types.varinfo -> Cil_types.varinfo
Visit a variable declaration
val visitCilInit : cilVisitor ->
Cil_types.varinfo -> Cil_types.offset -> Cil_types.init -> Cil_types.init
Visit an initializer, pass also the global to which this belongs and the offset.
val visitCilAttributes : cilVisitor -> Cil_types.attribute list -> Cil_types.attribute list
Visit a list of attributes
val visitCilAnnotation : cilVisitor -> Cil_types.global_annotation -> Cil_types.global_annotation
val visitCilCodeAnnotation : cilVisitor -> Cil_types.code_annotation -> Cil_types.code_annotation
val visitCilAssigns : cilVisitor ->
Cil_types.identified_term Cil_types.assigns ->
Cil_types.identified_term Cil_types.assigns
val visitCilFunspec : cilVisitor -> Cil_types.funspec -> Cil_types.funspec
val visitCilBehavior : cilVisitor -> Cil_types.funbehavior -> Cil_types.funbehavior
val visitCilBehaviors : cilVisitor -> Cil_types.funbehavior list -> Cil_types.funbehavior list
val visitCilLogicType : cilVisitor -> Cil_types.logic_type -> Cil_types.logic_type
val visitCilPredicate : cilVisitor -> Cil_types.predicate -> Cil_types.predicate
val visitCilPredicateNamed : cilVisitor ->
Cil_types.predicate Cil_types.named -> Cil_types.predicate Cil_types.named
val visitCilPredicates : cilVisitor ->
Cil_types.identified_predicate list -> Cil_types.identified_predicate list
val visitCilTerm : cilVisitor -> Cil_types.term -> Cil_types.term
val visitCilTermLhost : cilVisitor -> Cil_types.term_lhost -> Cil_types.term_lhost
val visitCilTermOffset : cilVisitor -> Cil_types.term_offset -> Cil_types.term_offset
val visitCilLogicInfo : cilVisitor -> Cil_types.logic_info -> Cil_types.logic_info

Utility functions
val is_skip : Cil_types.stmtkind -> bool
val constFoldVisitor : bool -> cilVisitor
A visitor that does constant folding. Pass as argument whether you want machine specific simplifications to be done, or not.
val forgcc : string -> string
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

Debugging support
module CurrentLoc: Computation.REF_OUTPUT  with type data = location
A reference to the current location.
val currentGlobal : Cil_types.global Pervasives.ref
A reference to the current global being visited

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:

ignore (Errormsg.log "Expression %a is not positive (at %s:%i)\n"
                        d_exp e loc.file loc.line)

and here is an example of how you print a fatal error message that stop the execution:

Errormsg.s (Errormsg.bug "Why am I here?")

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:

val d_loc : Format.formatter -> Cil_types.location -> unit
Pretty-print a location
val d_thisloc : Format.formatter -> unit
Pretty-print the (Cil.CurrentLoc.get ())
val d_ikind : Format.formatter -> Cil_types.ikind -> unit
Pretty-print an integer of a given kind
val d_fkind : Format.formatter -> Cil_types.fkind -> unit
Pretty-print a floating-point kind
val d_storage : Format.formatter -> Cil_types.storage -> unit
Pretty-print storage-class information
val d_const : Format.formatter -> Cil_types.constant -> unit
Pretty-print a constant
val empty_funspec : unit -> Cil_types.funspec
returns a dummy specification
val is_empty_funspec : Cil_types.funspec -> bool
returns true if the given spec is empty.
val derefStarLevel : int
val indexLevel : int
val arrowLevel : int
val addrOfLevel : int
val additiveLevel : int
val comparativeLevel : int
val bitwiseLevel : int
val getParenthLevel : Cil_types.exp -> 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 getParenthLevelLogic : Cil_types.term_node -> int

A printer interface for CIL trees. Create instantiations of this type by specializing the class Cil.defaultCilPrinterClass.
class type cilPrinter = object .. end
A printer interface for CIL trees.
class defaultCilPrinterClass : cilPrinter
val defaultCilPrinter : cilPrinter
class type descriptiveCilPrinter = object .. end
class descriptiveCilPrinterClass : descriptiveCilPrinter
Like defaultCilPrinterClass, but instead of temporary variable names it prints the description that was provided when the temp was created.
val descriptiveCilPrinter : descriptiveCilPrinter
val printType : cilPrinter -> Format.formatter -> Cil_types.typ -> unit
Print a type given a pretty printer
val printExp : cilPrinter -> Format.formatter -> Cil_types.exp -> unit
Print an expression given a pretty printer
val printVar : #cilPrinter -> Format.formatter -> Cil_types.varinfo -> unit
pretty-prints a variable
val printLval : cilPrinter -> Format.formatter -> Cil_types.lval -> unit
Print an lvalue given a pretty printer
val printGlobal : cilPrinter -> Format.formatter -> Cil_types.global -> unit
Print a global given a pretty printer
val printAttr : cilPrinter -> Format.formatter -> Cil_types.attribute -> unit
Print an attribute given a pretty printer
val printAttrs : cilPrinter -> Format.formatter -> Cil_types.attributes -> unit
Print a set of attributes given a pretty printer
val printInstr : cilPrinter -> Format.formatter -> Cil_types.instr -> unit
Print an instruction given a pretty printer
val printStmt : cilPrinter -> Format.formatter -> Cil_types.stmt -> unit
Print a statement given a pretty printer. This can take very long (or even overflow the stack) for huge statements.
val printBlock : cilPrinter -> Format.formatter -> Cil_types.block -> unit
Print a block given a pretty printer. This can take very long (or even overflow the stack) for huge block.
val printInit : cilPrinter -> Format.formatter -> Cil_types.init -> unit
Print an initializer given a pretty printer. This can take very long (or even overflow the stack) for huge initializers.
val printTerm_lval : cilPrinter -> Format.formatter -> Cil_types.term_lval -> unit
val printLogic_var : cilPrinter -> Format.formatter -> Cil_types.logic_var -> unit
val printLogic_type : cilPrinter -> Format.formatter -> Cil_types.logic_type -> unit
val printTerm : cilPrinter -> Format.formatter -> Cil_types.term -> unit
val printTerm_offset : cilPrinter -> Format.formatter -> Cil_types.term_offset -> unit
val printPredicate_named : cilPrinter ->
Format.formatter -> Cil_types.predicate Cil_types.named -> unit
val printCode_annotation : cilPrinter -> Format.formatter -> Cil_types.code_annotation -> unit
val printFunspec : cilPrinter -> Format.formatter -> Cil_types.funspec -> unit
val printAnnotation : cilPrinter -> Format.formatter -> Cil_types.global_annotation -> unit
val d_type : Format.formatter -> Cil_types.typ -> unit
Pretty-print a type using Cil.defaultCilPrinter
val d_exp : Format.formatter -> Cil_types.exp -> unit
Pretty-print an expression using Cil.defaultCilPrinter
val d_var : Format.formatter -> Cil_types.varinfo -> unit
val d_lval : Format.formatter -> Cil_types.lval -> unit
Pretty-print an lvalue using Cil.defaultCilPrinter
val d_offset : Format.formatter -> Cil_types.offset -> unit
Pretty-print an offset using Cil.defaultCilPrinter, given the pretty printing for the base.
val d_init : Format.formatter -> Cil_types.init -> unit
Pretty-print an initializer using Cil.defaultCilPrinter. This can be extremely slow (or even overflow the stack) for huge initializers.
val d_binop : Format.formatter -> Cil_types.binop -> unit
Pretty-print a binary operator
val d_unop : Format.formatter -> Cil_types.unop -> unit
Pretty-print a unary operator
val d_attr : Format.formatter -> Cil_types.attribute -> unit
Pretty-print an attribute using Cil.defaultCilPrinter
val d_attrparam : Format.formatter -> Cil_types.attrparam -> unit
Pretty-print an argument of an attribute using Cil.defaultCilPrinter
val d_attrlist : Format.formatter -> Cil_types.attributes -> unit
Pretty-print a list of attributes using Cil.defaultCilPrinter
val d_instr : Format.formatter -> Cil_types.instr -> unit
Pretty-print an instruction using Cil.defaultCilPrinter
val d_label : Format.formatter -> Cil_types.label -> unit
Pretty-print a label using Cil.defaultCilPrinter
val d_stmt : Format.formatter -> Cil_types.stmt -> unit
Pretty-print a statement using Cil.defaultCilPrinter. This can be extremely slow (or even overflow the stack) for huge statements.
val d_block : Format.formatter -> Cil_types.block -> unit
Pretty-print a block using Cil.defaultCilPrinter. This can be extremely slow (or even overflow the stack) for huge blocks.
val d_global : Format.formatter -> Cil_types.global -> unit
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).
val d_term_lval : Format.formatter -> Cil_types.term_lval -> unit
val d_logic_var : Format.formatter -> Cil_types.logic_var -> unit
val d_logic_type : Format.formatter -> Cil_types.logic_type -> unit
val d_term : Format.formatter -> Cil_types.term -> unit
val d_term_offset : Format.formatter -> Cil_types.term_offset -> unit
val d_annotation_status : Format.formatter -> Cil_types.annotation_status -> unit
Since Beryllium-20090601+dev
val d_status : Format.formatter -> Cil_types.annot_status -> unit
val d_predicate_named : Format.formatter -> Cil_types.predicate Cil_types.named -> unit
val d_code_annotation : Format.formatter -> Cil_types.code_annotation -> unit
val d_funspec : Format.formatter -> Cil_types.funspec -> unit
val d_annotation : Format.formatter -> Cil_types.global_annotation -> unit
val d_decreases : Format.formatter -> Cil_types.term Cil_types.variant -> unit
val d_loop_variant : Format.formatter -> Cil_types.term Cil_types.variant -> unit
val dn_exp : Format.formatter -> Cil_types.exp -> unit
Versions of the above pretty printers, that don't print #line directives
val dn_lval : Format.formatter -> Cil_types.lval -> unit
val dn_init : Format.formatter -> Cil_types.init -> unit
val dn_type : Format.formatter -> Cil_types.typ -> unit
val dn_global : Format.formatter -> Cil_types.global -> unit
val dn_attrlist : Format.formatter -> Cil_types.attributes -> unit
val dn_attr : Format.formatter -> Cil_types.attribute -> unit
val dn_attrparam : Format.formatter -> Cil_types.attrparam -> unit
val dn_stmt : Format.formatter -> Cil_types.stmt -> unit
val dn_instr : Format.formatter -> Cil_types.instr -> unit
val dumpFile : cilPrinter -> Pervasives.out_channel -> string -> Cil_types.file -> unit
Pretty-print an entire file. Here you give the channel where the printout should be sent.
val d_file : cilPrinter -> Format.formatter -> Cil_types.file -> unit

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

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
val d_plainexp : Format.formatter -> Cil_types.exp -> unit
Pretty-print the internal representation of an expression
val d_plaininit : Format.formatter -> Cil_types.init -> unit
Pretty-print the internal representation of an integer
val d_plainlval : Format.formatter -> Cil_types.lval -> unit
Pretty-print the internal representation of an lvalue

Pretty-print the internal representation of an lvalue offset val d_plainoffset: Format.formatter -> offset -> Pretty.doc
val d_plaintype : Format.formatter -> Cil_types.typ -> unit
Pretty-print the internal representation of a type
val dd_exp : Format.formatter -> Cil_types.exp -> unit
Pretty-print an expression while printing descriptions rather than names of temporaries.
val dd_lval : Format.formatter -> Cil_types.lval -> unit
Pretty-print an lvalue on the left side of an assignment. If there is an offset or memory dereference, temporaries will be replaced by descriptions as in dd_exp. If the lval is a temp var, that var will not be replaced by a description; use "dd_exp () (Lval lv)" if that's what you want.

ALPHA conversion has been moved to the Alpha module.
val uniqueVarNames : Cil_types.file -> unit
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

Optimization Passes
val peepHole2 : agressive:bool ->
(Cil_types.stmt * Cil_types.stmt -> Cil_types.stmt list option) ->
Cil_types.stmt list -> Cil_types.stmt list
A peephole optimizer that processes two adjacent statements and possibly replaces them both. If some replacement happens and agressive is true, then the new statements are themselves subject to optimization. Each statement in the list is optimized independently.
val peepHole1 : (Cil_types.instr -> Cil_types.instr list option) ->
Cil_types.stmt list -> unit
Similar to peepHole2 except that the optimization window consists of one statement, not two

Machine dependency
exception SizeOfError of string * Cil_types.typ
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
val empty_size_cache : unit -> Cil_types.bitsSizeofTypCache
Create a fresh size cache with Not_Computed
val bitsSizeOf : Cil_types.typ -> int
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 truncateInteger64 : Cil_types.ikind -> int64 -> int64 * bool
val sizeOf : Cil_types.typ -> Cil_types.exp
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_int : Cil_types.typ -> int
The size of a type, in bytes. Raises Cil.SizeOfError when it cannot compute the size.
val alignOf_int : Cil_types.typ -> int
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 bitsOffset : Cil_types.typ -> Cil_types.offset -> int * 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 dExp : string -> Cil_types.exp
Generate an Cil_types.exp to be used in case of errors.
val dInstr : string -> Cil_types.location -> Cil_types.instr
Generate an Cil_types.instr to be used in case of errors.
val dGlobal : string -> Cil_types.location -> Cil_types.global
Generate a Cil_types.global to be used in case of errors.
val mapNoCopy : ('a -> 'a) -> 'a list -> 'a list
Like map but try not to make a copy of the list
val optMapNoCopy : ('a -> 'a) -> 'a option -> 'a option
same as mapNoCopy for options
val mapNoCopyList : ('a -> 'a list) -> 'a list -> 'a list
Like map but each call can return a list. Try not to make a copy of the list
val startsWith : string -> string -> bool
sm: return true if the first is a prefix of the second string

An Interpreter for constructing CIL constructs

type formatArg =
| Fe of Cil_types.exp
| Feo of Cil_types.exp option (*For array lengths*)
| Fu of Cil_types.unop
| Fb of Cil_types.binop
| Fk of Cil_types.ikind
| FE of Cil_types.exp list (*For arguments in a function call*)
| Ff of (string * Cil_types.typ * Cil_types.attributes) (*For a formal argument*)
| FF of (string * Cil_types.typ * Cil_types.attributes) list (*For formal argument lists*)
| Fva of bool (*For the ellipsis in a function type*)
| Fv of Cil_types.varinfo
| Fl of Cil_types.lval
| Flo of Cil_types.lval option
| Fo of Cil_types.offset
| Fc of Cil_types.compinfo
| Fi of Cil_types.instr
| FI of Cil_types.instr list
| Ft of Cil_types.typ
| Fd of int
| Fg of string
| Fs of Cil_types.stmt
| FS of Cil_types.stmt list
| FA of Cil_types.attributes
| Fp of Cil_types.attrparam
| FP of Cil_types.attrparam list
| FX of string
The type of argument for the interpreter
val d_formatarg : Format.formatter -> formatArg -> unit
val stmt_of_instr_list : ?loc:Cil_types.location -> Cil_types.instr list -> Cil_types.stmtkind
val pretty_loc : Format.formatter -> Cil_types.kinstr -> unit
val pretty_loc_simply : Format.formatter -> Cil_types.kinstr -> unit
val cvar_to_lvar : Cil_types.varinfo -> Cil_types.logic_var
Convert a C variable into the corresponding logic variable. The returned logic variable is unique for a given C variable.
val make_temp_logic_var : Cil_types.logic_type -> Cil_types.logic_var
Make a temporary variable to use in annotations
val lzero : ?loc:Cil_types.location -> unit -> Cil_types.term
The constant logic term zero.
Consult the Plugin Development Guide for additional details.
val lconstant : ?loc:Cil_types.location -> Int64.t -> Cil_types.term
The given constant logic term
val close_predicate : Cil_types.predicate Cil_types.named -> Cil_types.predicate Cil_types.named
Bind all free variables with an universal quantifier
val extract_varinfos_from_exp : Cil_types.exp -> Cilutil.VarinfoSet.t
extract varinfo elements from an exp
val extract_varinfos_from_lval : Cil_types.lval -> Cilutil.VarinfoSet.t
extract varinfo elements from an lval
val extract_free_logicvars_from_term : Cil_types.term -> Cilutil.LogicVarSet.t
extract logic_var elements from a term
val extract_free_logicvars_from_predicate : Cil_types.predicate Cil_types.named -> Cilutil.LogicVarSet.t
extract logic_var elements from a predicate
val create_alpha_renaming : Cil_types.varinfo list -> Cil_types.varinfo list -> cilVisitor
creates a visitor that will replace in place uses of var in the first list by their counterpart in the second list.
Raises Invalid_argument if the lists have different lengths.
val print_utf8 : bool Pervasives.ref