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 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 _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 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 requires_tranform_init(self, rules_set, c_type, node): """ - Change type init to fln_type """ rules = [] read = rules_set.get(capability=READ_NAME) write = rules_set.get(capability=WRITE_NAME) if len(read) > 1 or len(write) > 1: raise Exception("Redefined read or write found") rules.extend(read) rules.extend(write) fln_type = None tag_stmt = None tag_type = None members = None is_ptr = False if read: tag_stmt = read[0].tag_statement tag_type = self.gen.tag_type(read[0].tag_statement) members = read[0].struct_members is_ptr = read[0].is_ptr projection = 0 elif write: tag_stmt = write[0].tag_statement tag_type = self.gen.tag_type(write[0].tag_statement) members = write[0].struct_members is_ptr = write[0].is_ptr projection = 1 elif read and write: raise Exception("Two requires rules defined") fln_type = self.gen.fln_type(tag_type, c_type, projection) if isinstance(node.type, c_ast.TypeDecl): if isinstance(node.type.type, c_ast.IdentifierType): node.type.type.names = [fln_type] elif isinstance(node.type.type, c_ast.Struct): node.type.type = c_ast.IdentifierType([fln_type]) else: raise Exception("Unhandled node init type: " + node.type.type.__class__.__name__) elif isinstance(node.type, c_ast.PtrDecl): if isinstance(node.type.type.type, c_ast.IdentifierType): node.type.type.type.names = [fln_type] elif isinstance(node.type.type.type, c_ast.Struct): node.type.type.type = c_ast.IdentifierType([fln_type]) else: raise Exception("Unhandled node type: " + node.type.__class__.__name__) return (node.name, (fln_type, bool(read), bool(write), tag_stmt, members, c_type, is_ptr, FlnRuleSet(rules)))
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 reorganize_decl(n): """ Turns nested declarations into anonymous declarations. """ if isinstance(n, (c_ast.Union, c_ast.Struct)): name = n.name if not name: name = anonymous(n) if n.decls: generate_decl(n, '', name) return c_ast.IdentifierType(names=[name]) for name, child in n.children(): new_child = reorganize_decl(child) if new_child is not child: if "[" in name: field, _, num = name[:-1].partition("[") getattr(n, field)[int(num)] = new_child else: setattr(n, name, new_child) return n
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 inner2(param, tag, name, ptrs): if isinstance(param.type, c_ast.TypeDecl): quals = param.type.quals param.type.quals = [] if isinstance(param.type.type, c_ast.IdentifierType): new_type = [] new_type.extend(quals) new_type.extend(param.type.type.names) c_type = " ".join(new_type) + "*" * ptrs uncast[name] = (c_type, tag, False if ptrs == 0 else True) param.type.type.names = [tag] elif isinstance(param.type.type, c_ast.Struct): new_type = [] new_type.extend(quals) new_type.append("struct") new_type.append(param.type.type.name) c_type = " ".join(new_type) + "*" * ptrs uncast[name] = (c_type, tag, False if ptrs == 0 else True) param.type.type = c_ast.IdentifierType([tag]) else: raise Exception("Param c_type not found 3: " + str(type(param.type.type))) elif isinstance(param.type, c_ast.PtrDecl): return inner2(param.type, tag, name, ptrs + 1) else: raise Exception("Param c_type not found 4: " + str(type(param.type)))
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 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 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 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 visit_Decl(self, node): if not isinstance(node.type, c_ast.FuncDecl): return func_decl = node.type if not isinstance(func_decl.type, c_ast.TypeDecl) or not isinstance(func_decl.type.type, c_ast.IdentifierType) or func_decl.type.type.names != ['void']: self.functions[node.name] = node return_type=func_decl.type #node.return_type = return_type set_extra_attr(node, 'return_type', func_decl.type) #update declname it=return_type while it is not None: if isinstance(it, c_ast.TypeDecl): it.declname = 'return_of_the_jedi' it = None else: if hasattr(it, 'type'): it = it.type else: it = None func_decl.type = c_ast.TypeDecl(node.name, [], c_ast.IdentifierType(['void'])) result_type=deepcopy(return_type) result_type.type.names += '&' decl = create_simple_var(result_type, 'return_of_the_jedi', None) if func_decl.args is None: func_decl.args = c_ast.ParamList([]) #Handle the int f(void) case if len(func_decl.args.params) == 1 \ and isinstance(func_decl.args.params[0], c_ast.Typename) \ and isinstance(func_decl.args.params[0].type.type, c_ast.IdentifierType) \ and func_decl.args.params[0].type.type.names[0] == 'void': func_decl.args.params.pop() func_decl.args.params.append(decl)
def create_mock_params(self): mock_params = [] for param, expanded_param in self.params: if is_char_pointer(expanded_param.type): mock_params.append(param) elif is_pointer_or_array(expanded_param.type): pass elif is_va_list(expanded_param.type): pass elif is_struct_or_union(expanded_param.type): pass else: mock_params.append(param) if not self.is_void(self.return_value_decl): mock_params.append(self.return_value_decl) if self.is_variadic_func: mock_params.append( decl( None, c_ast.PtrDecl([], c_ast.TypeDecl( 'vafmt_p', ['const'], c_ast.IdentifierType(['char']))))) mock_params.append(decl(None, c_ast.EllipsisParam())) return mock_params
def check_value(ast_tree, ext_index, bock_item_index, var_name, func_name): Cast = c_ast.Cast( c_ast.Typename( None, [], c_ast.PtrDecl([], c_ast.TypeDecl(None, [], c_ast.IdentifierType(['void'])))), c_ast.ID(var_name)) func_call = c_ast.FuncCall( c_ast.ID('check_value'), c_ast.ExprList([ c_ast.UnaryOp('&', c_ast.ID('global_log')), Cast, c_ast.Constant('string', '"' + var_name + '"'), c_ast.Constant('string', '"' + func_name + '"'), c_ast.Constant('int', str(len(var_name))), c_ast.Constant('int', str(len(func_name))) ])) new_node = c_ast.If( c_ast.BinaryOp('==', func_call, c_ast.Constant('int', '0')), c_ast.Compound([ c_ast.FuncCall( c_ast.ID('printf'), c_ast.ExprList([ c_ast.Constant('string', '"%s\\n"'), c_ast.Constant('string', '"Attack Detected"') ])), c_ast.FuncCall(c_ast.ID('exit'), c_ast.ExprList([c_ast.Constant('int', '1')])) ]), None) return merge_ast_tree(ast_tree, ext_index, bock_item_index, new_node, "insert_before")
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 out_copy_member(name, param_dst, param_src): name = f'{name}_out_copy' return function_ptr_decl(name, void_type(name), [ param_dst, param_src, decl('size', c_ast.TypeDecl('size', [], c_ast.IdentifierType(['size_t']))) ])
def in_assert_member(name, param_actual, param_expected): name = f'{name}_in_assert' return function_ptr_decl(name, void_type(name), [ param_actual, param_expected, decl('size', c_ast.TypeDecl('size', [], c_ast.IdentifierType(['size_t']))) ])
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 create_svcomp_function_declaration(self, name: str): """ Creates a declaration for the given SV comp function name, e.g. "__VERIFIER_nondet_int". :param name: The SV comp function name. :return: c_ast.Decl """ return_type = self.get_c_type(name.replace("__VERIFIER_nondet_", "")) # Need to handle pointers separately. if "*" in return_type: return_type.remove("*") return_code = c_ast.PtrDecl( [], c_ast.TypeDecl(name, [], c_ast.IdentifierType(list(return_type)))) else: return_code = c_ast.TypeDecl(name, [], c_ast.IdentifierType(return_type)) return c_ast.Decl(name, [], ["extern"], [], c_ast.FuncDecl(None, return_code), None, None)
def visit_ParamList(self, node): for i, p in enumerate(node.params): if self._instrument[i][0]: p.storage.append(self._instrument[i][0]) if self._instrument[i][1]: p.type.quals.append(self._instrument[i][1]) self.visit(p) for cst in self._constants: if cst._is_scalar: t = c_ast.TypeDecl(cst._name, [], c_ast.IdentifierType([cst._cl_type])) else: t = c_ast.PtrDecl( [], c_ast.TypeDecl(cst._name, ["__constant"], c_ast.IdentifierType([cst._cl_type]))) decl = c_ast.Decl(cst._name, [], [], [], t, None, 0) node.params.append(decl)
def state_function(self, name, parameters): return function_ptr_decl( name, node.PtrDecl( [], node.TypeDecl(name, ["const"], node.IdentifierType([self.state_type])), ), parameters, )
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 create(self, mem_name, mem_type, mem_size, mem_init): if not mem_size: raise Exception("Could not find size of %d" % mem_name) stream_address_size = get_bit_width(mem_size) if self.debug: print "Found array %s" % mem_name decl_get_name = mem_name + '_get' decl_set_name = mem_name + '_set' out_type = c_ast.IdentifierType(deepcopy(mem_type.type.names)) out_type.names += '&' data_size = get_bus_size(mem_type) data_sign = get_bus_sign(mem_type) if not mem_init: out_type = c_ast.IdentifierType(deepcopy(mem_type.type.names)) dummy_name = 'dummy_' + mem_name array_type = ' '.join(mem_type.type.names) if mem_init: self.registry.addTemplateToRegistry( BromTemplate(mem_name, array_type, mem_size, data_size, mem_init, True, self.mems_map, self.platform, self.debug)) self.registry.addTemplateToRegistry( InternalArrayWrapperTemplate(decl_get_name, array_type, mem_size, stream_address_size, data_size, data_sign, mem_name, self.registry, self.debug)) else: internal = False self.registry.addTemplateToRegistry( BramTemplate(mem_name, array_type, mem_size, data_size, self.mems_map, self.platform, self.debug)) self.registry.addTemplateToRegistry( ExternalArrayWrapperTemplate(decl_get_name, array_type, mem_size, stream_address_size, data_size, data_sign, mem_name, self.streams_map, self.debug)) self.registry.addTemplateToRegistry( ExternalArrayWrapperTemplate(decl_set_name, array_type, mem_size, stream_address_size, data_size, data_sign, mem_name, self.streams_map, self.debug))
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 pre_argument(self, name): commands = [] commands.append( _generate_decl( name + '_len', c_ast.TypeDecl(name + '_len', [], c_ast.IdentifierType(['unsigned', 'short'])))) commands.append(_generate_read(name + '_len')) commands.append( _generate_arraydecl(name, self._type, c_ast.ID(name + '_len'))) commands.append(_generate_read(name, address=False)) return commands
def randomize_type(type: SimpleType, typemap: TypeMap, random: Random) -> SimpleType: if not allowed_simple_type( type, typemap, ["int", "char", "long", "short", "signed", "unsigned"]): return type new_names: List[str] = [] if random.choice([True, False]): new_names.append("unsigned") new_names.append(random.choice(["char", "short", "int", "int"])) idtype = ca.IdentifierType(names=new_names) return ca.TypeDecl(declname=None, quals=[], type=idtype)