def TypeForNode(node, parent, sym_links, struct_links, type_tab, child_types, fundef): if isinstance(node, c_ast.Constant): m = _RE_NUMBER_SUFFIX.search(node.value) if m: kinds = [_SUFFIX_MAP[c] for c in m.group().lower()] return common.GetCanonicalIdentifierType(kinds) return common.GetCanonicalIdentifierType(node.type.split()) elif isinstance(node, c_ast.ID): if isinstance(parent, c_ast.StructRef) and parent.field == node: return _GetFieldRefTypeAndUpdateSymbolLink(parent, sym_links, struct_links, type_tab) else: decl = sym_links[node].type if isinstance(decl, c_ast.FuncDecl): return decl return GetTypeForDecl(decl) elif isinstance(node, c_ast.BinaryOp): return GetBinopType(node, child_types[0], child_types[1]) elif isinstance(node, c_ast.UnaryOp): return GetUnaryType(node, child_types[0]) elif isinstance(node, c_ast.FuncCall): return GetFunReturnType(child_types[0]) elif isinstance(node, c_ast.ArrayRef): a = child_types[0] assert isinstance(a, (c_ast.ArrayDecl, c_ast.PtrDecl)), f"{node} - {a.__class__.__name__}" # TODO: check that child_types[1] is integer return GetTypeForDecl(a.type) elif isinstance(node, c_ast.Return): return GetTypeForDecl(fundef.decl.type.type) elif isinstance(node, c_ast.Assignment): return child_types[0] elif isinstance(node, c_ast.ExprList): # unfortunately ExprList have multiple uses which we need to disambiguate if isinstance(parent, c_ast.FuncCall): args = sym_links[parent.name].type.args assert isinstance(args, c_ast.ParamList) return args else: return child_types[-1] elif isinstance(node, c_ast.TernaryOp): return common.MaxType(child_types[1], child_types[2]) elif isinstance(node, c_ast.StructRef): # This was computed by _GetFieldRefTypeAndUpdateSymbolLink return child_types[1] elif isinstance(node, c_ast.Cast): return GetTypeForDecl(node.to_type.type) else: assert False, "unsupported expression node %s" % node
def GetTypeForDecl(decl: Union[c_ast.TypeDecl, c_ast.FuncDecl, c_ast.ArrayDecl]): if isinstance(decl, c_ast.TypeDecl): # for simple decl extract the type if isinstance(decl.type, c_ast.IdentifierType): return common.GetCanonicalIdentifierType(decl.type.names) else: assert isinstance(decl.type, _STRUCT_OR_UNION) return decl.type elif isinstance(decl, c_ast.FuncDecl): # for function get the return type return GetTypeForDecl(decl.type) elif isinstance(decl, (c_ast.ArrayDecl, c_ast.PtrDecl)): # for the rest do nothing return decl else: assert False, decl
def MakeCombinedSubscript(chain_head, meta_info): """ Return the node reflecting the name computation and the combined offset """ # print ("INPUT", chain_head) assert isinstance(chain_head, c_ast.ArrayRef) subscripts = [] node = chain_head while isinstance(node, c_ast.ArrayRef): old_subscript = node.subscript assert meta_info.type_links[old_subscript] in common.ALLOWED_IDENTIFIER_TYPES multiplier = GetArrayRefMultiplier(node, meta_info.type_links[node]) if common.IsZeroConstant(old_subscript): pass elif multiplier == 1: subscripts.append(old_subscript) else: new_subscript = c_ast.BinaryOp("*", old_subscript, c_ast.Constant("int", str(multiplier))) subscripts.append(new_subscript) meta_info.type_links[new_subscript] = meta_info.type_links[old_subscript] meta_info.type_links[new_subscript.right] = common.GetCanonicalIdentifierType(["int"]) node = node.name if not isinstance(meta_info.type_links[node], c_ast.ArrayDecl): break if not subscripts: return node, None s = subscripts[0] for x in subscripts[1:]: s = c_ast.BinaryOp("+", s, x) # TODO: compute the max type meta_info.type_links[s] = meta_info.type_links[x] # print ("OUTPUT-NAME", node) # print ("OUTPUT-SUBS", s) return node, s
else: assert False, decl def GetTypeForFunArg(arg: c_ast.Node): if isinstance(arg, c_ast.Decl): return arg.type elif isinstance(arg, c_ast.Typename): return arg.type elif isinstance(arg, c_ast.EllipsisParam): return arg else: assert False, arg SIZE_T_IDENTIFIER_TYPE = common.GetCanonicalIdentifierType(["int", "unsigned"]) INT_IDENTIFIER_TYPE = common.GetCanonicalIdentifierType(["int"]) STRING_IDENTIFIER_TYPE = common.GetCanonicalIdentifierType(["string"]) def TypePrettyPrint(decl): if decl is None: return "none" elif isinstance(decl, str): return decl elif isinstance(decl, c_ast.TypeDecl): return TypePrettyPrint(decl.type) elif isinstance(decl, c_ast.EllipsisParam): return "..."
def MakeSimpleTypeDecl(name, type_names): return c_ast.TypeDecl(name, [], common.GetCanonicalIdentifierType(type_names))