def createMain(self): #Main Function #Declaration z1 = c_ast.TypeDecl('args',[],c_ast.IdentifierType(['int'])) args = c_ast.Decl('args',[],[],[],z1,None,None) z2= c_ast.PtrDecl([],c_ast.TypeDecl('argv',[],c_ast.IdentifierType(['char']))) z3=c_ast.ArrayDecl(z2,None,[]) argv = c_ast.Decl('argv',[],[],[],z3,None,None) params=c_ast.ParamList([args,argv]) mainDec=c_ast.FuncDecl(params,c_ast.TypeDecl('main',[],c_ast.IdentifierType(['int']))) # insertTest(functionName,varVals,varTypes) #Body ##Signal sigalrm=c_ast.ID(name="14") funcCast=c_ast.TypeDecl(declname = None,quals=[],type=c_ast.IdentifierType(['void'])) paramCast=c_ast.ParamList([c_ast.Typename(name=None,quals=[],type=c_ast.TypeDecl(declname = None,quals=[],type=c_ast.IdentifierType(['int'])))]) typeFunc=c_ast.PtrDecl(type=c_ast.FuncDecl(paramCast,funcCast),quals=[]) kchild=c_ast.Cast(to_type=c_ast.Typename(name=None, quals=[],type=typeFunc),expr=c_ast.ID(name="kill_child")) expressList = [sigalrm,kchild] signalStmt=c_ast.FuncCall(c_ast.ID(name="signal"),c_ast.ExprList(expressList)) ##Return returnStmt=c_ast.Return(c_ast.Constant(type="int",value="0")) comp=c_ast.Compound([signalStmt,returnStmt]) return c_ast.FuncDef(mainDec,None,comp)
def define_sizeof_modifier_type(t): # setup the toplevel call if t.get_typename(): argument_ast = t.get_reference()("storage") else: argument_ast = t.define("storage") prefix = "fffc_get_sizeof_" desired_name = CGenerator().visit(argument_ast) suffix = encode_hash(desired_name) function_name = prefix + suffix # build the underlying function call underlying_call = get_sizeof_pointer_to_type(t.underlying_type, c_ast.ID("storage")) # build this just as above, except with the call in place of the sizeof storage_tdecl = c_ast.Decl("storage", [], [], [], c_ast.PtrDecl([], argument_ast), None, None) func_tdecl = c_ast.TypeDecl( function_name, [], c_ast.IdentifierType(["long", "long", "unsigned"])) funcdecl = c_ast.FuncDecl(c_ast.ParamList([storage_tdecl]), func_tdecl) funcdef = c_ast.FuncDef( c_ast.Decl(function_name, [], [], [], funcdecl, None, None), None, c_ast.Compound([c_ast.Return(underlying_call)]), ) comment = "/* " + desired_name + "*/\n" kr_funcdecl = c_ast.FuncDecl(c_ast.ParamList([]), func_tdecl) return comment, kr_funcdecl, funcdef
def make_mutator_decl_from_arg_type(arg_type, generator=CGenerator(), seen={}, point=True, change_name=False): # memoize if arg_type in seen: return seen[arg_type] mut_name = "fffc_mutator_for_target_type" # change the type declname if change_name: change_declname(arg_type, "storage") # first, wrap the type in a pointer to match the necessary mutator semantics if point: arg_type_ptr = c_ast.PtrDecl([], arg_type) else: arg_type_ptr = arg_type # next, wrap that in a decl with the right name arg_decl = c_ast.ParamList( [c_ast.Decl("storage", [], [], [], arg_type_ptr, None, None)]) # next, generate the desired decl ret_type = c_ast.IdentifierType(["int"]) ret_decl = c_ast.TypeDecl(mut_name, [], ret_type) desired_decl = c_ast.FuncDecl(arg_decl, ret_decl) # now build the mangled name desired_name = generator.visit(desired_decl) suffix = encode_hash(desired_name) actual_name = "_Z_fffc_mutator_" + suffix desired_decl.type.declname = actual_name # build the output out = c_ast.Decl(actual_name, [], [], [], desired_decl, None, None) # save the result seen[arg_type] = (desired_name, out) # and go home return desired_name, out
def rename_array_args(funcdef): """ Rename and copy arrays passed as arguments to funcdef. """ # For each argument for param in funcdef.decl.type.args.params: if isinstance(param.type, c_ast.ArrayDecl): # Rename and copy array arg_decl = copy.deepcopy(param) # Rename array v = inline.RenameVisitor() v.new_visit(get_decl_name(param), get_decl_name(param) + "_rename", funcdef.body) # Add copy and declarations funcdef.body.block_items = rename_array_decl( arg_decl) + funcdef.body.block_items elif isinstance(param.type, c_ast.TypeDecl): # Simple variable passing, don't need to handle pass elif isinstance(param.type, c_ast.PtrDecl): # Don't copy pointer arguments return """ Param of form: type *var is copied in the function body using: type var_rename _temp = *var; type *var_rename = &var_rename_temp; """ # General pointer arguments old_name = get_decl_name(param) new_name = old_name + "_rename" temp_name = new_name + "_temp" # Rename variable use in function body v = inline.RenameVisitor() v.new_visit(old_name, new_name, funcdef.body) # type var_rename_temp = *var; decl1 = c_ast.Decl( temp_name, None, None, None, c_ast.TypeDecl(temp_name, None, param.type.type.type), c_ast.UnaryOp('*', c_ast.ID(old_name)), None) # type *var_rename = &var_rename_temp; decl2 = c_ast.Decl( new_name, None, None, None, c_ast.PtrDecl([], c_ast.TypeDecl(new_name, None, param.type.type.type)), c_ast.UnaryOp('&', c_ast.ID(temp_name)), None) # Insert into function body funcdef.body.block_items.insert(0, decl2) funcdef.body.block_items.insert(0, decl1) else: print_node(param) param.show(nodenames=True, showcoord=True) raise Exception( "Unhandled argument type %s. Implement or verify that it can be ignored." % (type(param.type)))
def visit_FuncDef(self, node): # Skip if no loop counters exist if self.loop_counter_size == 0: return # Create loop_counter declaration/initialization constants = [c_ast.Constant("int", '0') for i in range(self.loop_counter_size)] init_list = c_ast.InitList(constants) identifier_type = c_ast.IdentifierType(["int"]) type_decl = c_ast.TypeDecl("loop_counter", [], identifier_type) dim = c_ast.Constant("int", str(self.loop_counter_size)) array_decl = c_ast.ArrayDecl(type_decl, dim, []) decl = c_ast.Decl("loop_counter", [], [], [], array_decl, init_list, None) node.body.block_items.insert(0, decl) # Label for return values to goto start_label = c_ast.Label("print_loop_counter", c_ast.EmptyStatement()) # Start and end labels used for inserting preprocessor commands for #if DEBUG_EN end_label = c_ast.Label("print_loop_counter_end", c_ast.EmptyStatement()) # Write to file if self.write_to_file: stmt = c_ast.ID("write_array(loop_counter, %d)\n" % (self.loop_counter_size)) compound = c_ast.Compound([start_label, stmt, end_label]) # Print to stdout else: # Add printf to the end of function # Start of printing stmt_start = c_ast.ID("printf(\"loop counter = (\")") # For loop # int i; identifier_type = c_ast.IdentifierType(["int"]) type_decl = c_ast.TypeDecl("i", [], identifier_type) for_decl = c_ast.Decl("i", [], [], [], type_decl, [], None) # i = 0 init = c_ast.Assignment("=", c_ast.ID("i"), c_ast.Constant("int", '0')) # i < self.loop_counter_size cond = c_ast.BinaryOp("<", c_ast.ID("i"), c_ast.Constant("int", str(self.loop_counter_size))) # i++ next_stmt = c_ast.UnaryOp("p++", c_ast.ID("i")) # printf in for stmt = c_ast.ID("printf(\"%d, \", loop_counter[i])") # Cosntruct for loop stmt_for = c_ast.For(init, cond, next_stmt, stmt) # End of printing stmt_end = c_ast.ID("printf(\")\\n\")") # Put it all together body = c_ast.Compound([stmt_start, for_decl, stmt_for, stmt_end]) # Surround with labels compound = c_ast.Compound([start_label, body, end_label]) node.body.block_items.append(compound)
def MakePrintfStyleDecl(name: str, type_names: List[str], is_pointer=False): parameter_fd = c_ast.Decl("fd", [], [], [], MakeSimpleTypeDecl("fd", ["int"]), None, None) parameter_value = c_ast.Decl("value", [], [], [], MakeSimpleTypeDecl("value", type_names), None, None) if is_pointer: parameter_value.type = c_ast.PtrDecl([], parameter_value.type) fun_result = MakeSimpleTypeDecl(name, ["int"]) return c_ast.Decl( name, [], [], [], c_ast.FuncDecl(c_ast.ParamList([parameter_fd, parameter_value]), fun_result), None, None)
def push_literal(lookup, stack, code, lit): name = gensym() const = c_ast.Constant(lit.type, lit.value) tdecl = c_ast.TypeDecl(name, [], c_ast.IdentifierType([lit.type])) decl = c_ast.Decl(name, [], [], [], tdecl, const, None) code.append(decl) stack.setdefault(lit.type, []).append(decl)
def visit_FuncCall(self, node): # It is important that it is checked for an error call before checking for non-determinism, # since __VERIFIER_error() is by default non-deterministic. if self.is_error_call(node): return list(), self.get_error_stmt() elif self.is_nondet_call(node): func_name = get_name(node) statements_to_prepend = [] nondet_var_name = func_name.split('(')[0].strip() nondet_var_name += str(self.var_counter) self.var_counter += 1 nondet_var_type = self.get_type(node) nondet_type_decl = self._build_nondet_type_decl( nondet_var_name, nondet_var_type) nondet_init = self._get_nondet_init(nondet_var_name, nondet_var_type) nondet_var = a.Decl(nondet_var_name, list(), list(), list(), nondet_type_decl, nondet_init, None) statements_to_prepend.append(nondet_var) nondet_marker = self.get_nondet_marker(nondet_var_name, nondet_var_type) if nondet_marker is not None: statements_to_prepend.append(nondet_marker) return statements_to_prepend, a.ID( nondet_var_name ) # Replace __VERIFIER_nondet_X() with new nondet var else: p, node.name = self.visit(node.name) q, node.args = self.visit(node.args) return p + q, node
def _build_handle_function(functions): """ Wraps the switch statement in a function definition """ case_statement = _build_case(functions) available_check = c_ast.If( c_ast.BinaryOp( '<', c_ast.FuncCall( c_ast.ID('mailbox_available'), c_ast.ExprList([c_ast.Constant('int', '2')]) ), c_ast.Constant('int', '4') ), c_ast.Return(None), None ) handle_decl = c_ast.FuncDecl( None, c_ast.TypeDecl('_handle_events', [], c_ast.IdentifierType(['void'])), ) command_decl = c_ast.Decl('command', [], [], [], c_ast.TypeDecl('command', [], c_ast.IdentifierType(['int'])), [], []) command_read = _generate_read('command') body = c_ast.Compound([available_check, command_decl, command_read, case_statement]) return c_ast.FuncDef(handle_decl, [], body)
def __for_loop(self, depth: int) -> c_ast.For: """ A helper function to construct a for loop corresponding to allocating one dimension of an array. Recursively calls itself to generate next levels or generates an initialisation line if it is the last level. Example: for(i_2 = 0; i_2 < N; i_2++) { ... } :param depth: :return: C-ast.For """ i = self.counter_prefix + str(depth) init = c_ast.DeclList([ c_ast.Decl(c_ast.ID(i), [], [], [], c_ast.TypeDecl(i, [], c_ast.IdentifierType(['int'])), c_ast.Constant('int', '0'), '') ]) cond = c_ast.BinaryOp('<', c_ast.ID(i), self.sizes[depth]) nxt = c_ast.Assignment('++', c_ast.ID(i), None) stmt = c_ast.Compound([]) if depth < len(self.sizes) - 1: stmt.block_items = [ self.__malloc_assign(depth + 1), self.__for_loop(depth + 1) ] else: stmt.block_items = [self.initialiser(depth + 1)] return c_ast.For(init, cond, nxt, stmt)
def pre_argument(self, name): commands = [] commands.append( _generate_decl( name + '_int', c_ast.TypeDecl(name + '_int', [], c_ast.IdentifierType(['unsigned', 'int'])))) commands.append(_generate_read(name + '_int')) commands.append( c_ast.Assignment('|=', c_ast.ID(name + '_int'), c_ast.Constant('int', PTR_OFFSET))) commands.append( c_ast.Decl( name, [], [], [], c_ast.PtrDecl( [], c_ast.TypeDecl(name, [], c_ast.IdentifierType(['void'])), ), c_ast.Cast( c_ast.Typename( None, [], c_ast.PtrDecl([], c_ast.TypeDecl( None, [], c_ast.IdentifierType(['void'])))), c_ast.ID(name + '_int')), [])) return commands
def astVeriNon(): veryidt = c_ast.IdentifierType(['int']) verytype = c_ast.TypeDecl('rand', [], veryidt) bifunc = c_ast.FuncCall(c_ast.ID('__VERIFIER_nondet'), None) verybina = c_ast.BinaryOp('%', bifunc, c_ast.ID('N')) simdecl = c_ast.Decl('rand', [], [], [], verytype, verybina, None, None) return simdecl
def nested_for_loop(node, inner_loop_body, loop_iterator_base, rename_index=0): """ Recursively create nested for loops for copying a multi-dimensional array. """ if isinstance(node.type.type, c_ast.ArrayDecl): # Multi-dimensional array, recurse to generate inner loop for_loop_body = nested_for_loop(node.type, inner_loop_body, loop_iterator_base, rename_index + 1) else: # Single or last dimension of array for_loop_body = [inner_loop_body] # Declare iterator loop_iterator = c_ast.ID("%s_i%d" % (loop_iterator_base, rename_index)) loop_iterator_decl = c_ast.Decl( loop_iterator.name, [], [], [], c_ast.TypeDecl(loop_iterator.name, [], c_ast.IdentifierType(["int"])), None, None) # For loop array_size = node.type.dim for_loop = c_ast.For( c_ast.Assignment('=', loop_iterator, c_ast.Constant("int", "0")), c_ast.BinaryOp('<', loop_iterator, array_size), c_ast.UnaryOp('p++', loop_iterator), c_ast.Compound(for_loop_body)) return [loop_iterator_decl, for_loop]
def _generate_decl(name, decl): """ Generates a new declaration with a difference name but same type as the provided decl. """ typedecl = c_ast.TypeDecl(name, [], decl.type) return c_ast.Decl(name, [], [], [], typedecl, [], [])
def createTest(block,functionName,varVals,varTypes): #Main Function #Declaration z1 = c_ast.TypeDecl('args',[],c_ast.IdentifierType(['int'])) args = c_ast.Decl('args',[],[],[],z1,None,None) z2= c_ast.PtrDecl([],c_ast.TypeDecl('argv',[],c_ast.IdentifierType(['char']))) z3=c_ast.ArrayDecl(z2,None,[]) argv = c_ast.Decl('argv',[],[],[],z3,None,None) params=c_ast.ParamList([args,argv]) mainDec=c_ast.FuncDecl(params,c_ast.TypeDecl('main',[],c_ast.IdentifierType(['int']))) insertTest(functionName,varVals,varTypes) #Body returnStmt=c_ast.Return(c_ast.Constant(type="int",value="0")) comp=c_ast.Compound([returnStmt]) main= c_ast.FuncDef(mainDec,None,comp) insertTest(main,"func",['1','2'],['int','int'])
def type_to_string(type: Type) -> str: if isinstance(type, TypeDecl) and isinstance(type.type, (ca.Struct, ca.Union)): su = "struct" if isinstance(type.type, ca.Struct) else "union" return type.type.name or f"anon {su}" else: decl = ca.Decl("", [], [], [], type, None, None) set_decl_name(decl) return to_c(decl)
def eliminateParams(self): self.params=c_ast.ParamList([]) mainDec=c_ast.Decl(name='mainFake',quals=[],init=None,bitsize=None,storage=[],funcspec=[],type=c_ast.FuncDecl(self.params,c_ast.TypeDecl('mainFake',[],c_ast.IdentifierType(['int'])))) self.main = c_ast.FuncDef(mainDec,None,self.main.body) for i,func in enumerate(self.ast.ext): if(isinstance(func,c_ast.FuncDef)): if func.decl.name == 'main': self.ast.ext[i]=self.main
def _generate_arraydecl(name, decl, length): """ Generates a new declaration with an array type base on an existing declaration """ typedecl = c_ast.TypeDecl(name, [], decl.type) arraydecl = c_ast.ArrayDecl(typedecl, length, []) return c_ast.Decl(name, [], [], [], arraydecl, [], [])
def make_internal_fn_decl(name): '''str -> c_ast''' # don't you wish python had a macro system? return c_ast.Decl( name, [], [], [], c_ast.FuncDecl( c_ast.ParamList([ c_ast.Decl( utils.args_tag, [], [], [], c_ast.PtrDecl([], c_ast.TypeDecl( utils.args_tag, [], c_ast.IdentifierType([ '%s%s' % (utils.decomp_tag, utils.args_tag) ]))), None, None) ]), c_ast.TypeDecl(name, [], c_ast.IdentifierType(['void']))), None, None)
def new_ivar(self, name, init, c_type, parent=None): var_type = c_ast.IdentifierType([c_type]) decl_type = c_ast.TypeDecl(name, [], var_type) var = c_ast.Decl(name, [], [], [], decl_type, init, None) var.parent = parent var_type.parent = var decl_type.parent = var init.parent = var return var
def visit_FuncDef(self, node): label = c_ast.Label("predict_exec_time", c_ast.EmptyStatement()) decl = c_ast.Decl("exec_time", None, None, None, c_ast.TypeDecl("exec_time", None, c_ast.IdentifierType(["float"])), None, None) assignment = c_ast.Assignment('=', c_ast.ID("exec_time"), c_ast.Constant("int", 0)) ret = c_ast.Return(c_ast.ID("exec_time")) compound = c_ast.Compound([label, decl, assignment, ret]) node.body.block_items.append(compound)
def replace_target_decl(self): raw = self.template_data placeholder = b"___FFFC_TARGET_DECL___" # Now you need to declare a pointer to the function whose name is FFFC_replacement funcref = self.func.declare("FFFC_target") funcptr = c_ast.PtrDecl([], funcref) ast = c_ast.Decl("FFFC_target", [], [], [], funcptr, None, None) replacement = self.generator.visit(ast) + ";" raw = raw.replace(placeholder, bytes(replacement, "utf-8")) self.template_data = raw
def createDecl(api): apitype = 'sai_' + api + '_api_t' apivar = 'sai_' + api + '_api_tbl' return c_ast.Decl( apivar, list(), list(), list(), c_ast.PtrDecl( list(), c_ast.TypeDecl(apivar, list(), c_ast.IdentifierType([ apitype, ]))), None, None)
def makeVarDecl(decl, init): global var newDecl = c_ast.Decl('____' + str(var), decl.quals, decl.storage, decl.funcspec, copy.deepcopy(decl.type), init, decl.bitsize) node = newDecl.type while nodeType(node) == 'PtrDecl': node = node.type node.declname = '____' + str(var) var = var + 1 return newDecl
def global_log(ast_tree): global_log = c_ast.Decl( 'global_log', [], [], [], c_ast.TypeDecl('global_log', [], c_ast.Struct('Global_Log', None)), None, None) temp_ls1 = [] temp_ls1.append(global_log) temp_ls2 = [] temp_ls2 = copy.deepcopy(ast_tree.ext) global_log = c_ast.FileAST(temp_ls1 + temp_ls2) return global_log
def getFunctionReturnType(node): assert(nodeType(node) == 'FuncDef') return c_ast.Decl( node.decl.name, node.decl.quals, node.decl.storage, node.decl.funcspec, node.decl.type.type, None, node.decl.bitsize, node.decl.coord)
def make_extra_decl(name, t): idtype = c_ast.IdentifierType([t]) td = c_ast.TypeDecl(name, [], idtype) return c_ast.Decl( name, [], # quals [], # storage [], # funcspec td, # type None, # init None, # bitsize )
def __init__(self, decl, typedefs): self.return_interface = _type_to_interface(decl.type, typedefs) self.name = decl.type.declname self.docstring = _get_docstring(decl.coord) self.arg_interfaces = [] self.args = [] self.blocks = False self.coord = decl.coord block_contents = [] post_block_contents = [] func_args = [] if decl.args: for i, arg in enumerate(decl.args.params): if type(arg) is c_ast.EllipsisParam: raise RuntimeError("vararg functions not supported") interface = _type_to_interface(arg.type, typedefs) if type(interface) is VoidWrapper: continue block_contents.extend(interface.pre_argument('arg' + str(i))) post_block_contents.extend( interface.post_argument('arg' + str(i))) func_args.append(c_ast.ID('arg' + str(i))) self.arg_interfaces.append(interface) self.blocks = self.blocks | interface.blocks if arg.name: self.args.append(arg.name) else: self.args.append(f'arg{len(self.args)}') function_call = c_ast.FuncCall(c_ast.ID(self.name), c_ast.ExprList(func_args)) self.returns = type(self.return_interface) is not VoidWrapper if self.returns: ret_assign = c_ast.Decl('ret', [], [], [], c_ast.TypeDecl('ret', [], decl.type.type), function_call, []) block_contents.append(ret_assign) block_contents.append(_generate_write('return_command')) block_contents.extend(post_block_contents) block_contents.append(_generate_write('ret')) self.blocks = True else: block_contents.append(function_call) if self.blocks: block_contents.append(_generate_write('return_command')) else: block_contents.append(_generate_write('void_command')) block_contents.extend(post_block_contents) self.call_ast = c_ast.Compound(block_contents) self.filename = decl.coord.file
def XXX_STACKVAR_HACK(): # XXX FIXME this will be going away once we've added elision of unnecessary # stack variables (probably will just stick declarations into the AST) regs = list( c_ast.Decl(x, [], [], [], c_ast.TypeDecl(x, [], c_ast.IdentifierType(['EPANOS_REG'])), None, None) for x in list('t%s' % str(n) for n in range(4, 8)) + list('s%s' % str(n) for n in range(0, 8)) + ['at', 't8', 't9', 'gp', 'sp', 'ra', 'fp', 'f1'] + list('f%s' % str(n) for n in range(3, 12)) + list('f%s' % str(n) for n in range(20, 32))) regs += [ c_ast.Decl( 'EPANOS_fp_cond', [], [], [], c_ast.TypeDecl('EPANOS_fp_cond', [], c_ast.IdentifierType(['int'])), None, None) ] return regs
def replace_call(self): raw = self.template_data placeholder = b"___FFFC_CALL___" if type(self.func.return_type) != dwarf_to_c.DwarfVoidType: tdecl = self.func.return_type.get_reference()("retval") init = self.func.call("FFFC_target") decl = c_ast.Decl("retval", [], [], [], tdecl, init, None) func_call = self.generator.visit(decl) else: func_call = self.generator.visit(self.func.call("FFFC_target")) raw = raw.replace(placeholder, bytes(func_call + ";", "utf-8")) self.template_data = raw