29.01.2014 Views

A CIL Tutorial - Department of Computer Science - ETH Zürich

A CIL Tutorial - Department of Computer Science - ETH Zürich

A CIL Tutorial - Department of Computer Science - ETH Zürich

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

CHAPTER 9. TYPE QUALIFIER INFERENCE 72<br />

in, a subtype <strong>of</strong>, etc...} type B when the colors <strong>of</strong> type A are a subset <strong>of</strong> the colors <strong>of</strong> type B. For<br />

example, a Red int is also a Red Blue int. Thus, the subset lattice <strong>of</strong> the colors denes the subtype<br />

relation <strong>of</strong> our type system, and we can use it to nd the least-upper-bound <strong>of</strong> two types, which<br />

will be important for the inference algorithm below.<br />

9.1.1 Mark types with node IDs<br />

First we'll introduce two visitors and two functions that run the visitors over les. The rst visitor<br />

marks each type node in the AST with a unique numeric ID held in an attribute. The second visitor<br />

removes these marks, which we must do before we pass the code on to gcc. The function nodeAttr<br />

creates an attribute called "Node" parameterized by an integer node ID.<br />

let nodeStr = "Node"<br />

let nodeAttr (id : int) : attributes = [Attr(nodeStr, [AInt id])]<br />

The function node <strong>of</strong> type returns the integer node ID <strong>of</strong> a type. Since, we are adding the "Node"<br />

attributes ourselves, it is a bug if one is malformed. Hence, we use E.bug. If there is no "Node"<br />

attribute, this implies that t is the result <strong>of</strong> calling typeOf on a constant. We group all <strong>of</strong> these<br />

types at node 0 in the graph. Later, we'll see that this node is unreachable, and so we won't try to<br />

infer a type qualier for it.<br />

let node <strong>of</strong> type (t : typ) : int =<br />

match filterAttributes nodeStr (typeAttrs t) with<br />

| [(Attr( , [AInt id]))] → id<br />

| [ ] → 0<br />

| → E.s (E.bug "%a: Malformed node id on %a" d loc (!currentLoc) d type t)<br />

The visitor typeNodeMarker visits every typ node in the AST and assigns them unique node IDs<br />

by placing a "Node" attribute on them.<br />

class typeNodeMarker (node count : int ref) = object(self)<br />

inherit nopCilVisitor<br />

method vtype (t : typ) =<br />

let action t =<br />

if ¬(hasAttribute nodeStr (typeAttrs t)) then begin<br />

let attr = nodeAttr (!node count) in<br />

incr node count;<br />

typeAddAttributes attr t<br />

end else t<br />

in<br />

ChangeDoChildrenPost(t, action)<br />

end<br />

The function addNodeMarks invokes the typeNodeMarker visitor on a le and returns the largest ID<br />

assigned by the visitor. This will be the number <strong>of</strong> nodes we need in our graph.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!