Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
    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 "..."
Esempio n. 5
0
def MakeSimpleTypeDecl(name, type_names):
    return c_ast.TypeDecl(name, [],
                          common.GetCanonicalIdentifierType(type_names))