Example #1
0
def type_to_ehlit(typ: Type) -> ast.Node:
    res: Optional[ast.Node] = None
    if typ.kind in uint_types:
        res = ast.CompoundIdentifier(
            [ast.Identifier(0, '@uint' + str(typ.get_size() * 8))])
    elif typ.kind in int_types:
        res = ast.CompoundIdentifier(
            [ast.Identifier(0, '@int' + str(typ.get_size() * 8))])
    elif typ.kind in decimal_types:
        res = ast.CompoundIdentifier(
            [ast.Identifier(0, decimal_types[typ.kind])])
    else:
        try:
            res = globals()['type_' + typ.kind.name](typ)
        except KeyError:
            logging.debug('c_compat: unimplemented: type_%s' % typ.kind.name)
    if res is None:
        return ast.CompoundIdentifier([ast.Identifier(0, '@any')])
    elif not isinstance(res, ast.Symbol):
        return res
    if typ.is_const_qualified():
        res.qualifiers = res.qualifiers | ast.Qualifier.CONST
    if typ.is_volatile_qualified():
        res.qualifiers = res.qualifiers | ast.Qualifier.VOLATILE
    if typ.is_restrict_qualified():
        res.qualifiers = res.qualifiers | ast.Qualifier.RESTRICT
    return res
Example #2
0
def _macro_var_type(tokens: List[Token]) -> ast.Symbol:
    for tok in tokens:
        if tok.kind == TokenKind.LITERAL:
            if tok.spelling[0] == '"':
                return ast.CompoundIdentifier([ast.Identifier(0, '@str')])
            if all(x in '0123456789' for x in tok.spelling):
                return ast.CompoundIdentifier([ast.Identifier(0, '@int32')])
            if all(x in '0123456789.' for x in tok.spelling):
                return ast.CompoundIdentifier([ast.Identifier(0, '@float')])
    return CAnyType.make_symbol()
Example #3
0
def type_POINTER(typ: Type) -> ast.Node:
    subtype: Type = typ.get_pointee()
    builtin_type: Optional[ast.Symbol] = {
        TypeKind.CHAR_S: ast.CompoundIdentifier([ast.Identifier(0, '@str')]),
        TypeKind.SCHAR: ast.CompoundIdentifier([ast.Identifier(0, '@str')]),
        TypeKind.VOID: ast.CompoundIdentifier([ast.Identifier(0, '@any')])
    }.get(subtype.kind)
    if builtin_type is not None:
        return builtin_type
    res = type_to_ehlit(subtype)
    if isinstance(res, ast.TemplatedIdentifier) and res.name == '@func':
        return res
    assert isinstance(res, ast.Symbol)
    return ast.Reference(res)
Example #4
0
def type_RECORD(typ: Type) -> ast.Node:
    decl: Cursor = typ.get_declaration()
    # If the type do not have a name, it may not be referenced. In the case, we have to embed
    # the type definition in its usage. Otherwise, we reference it with its identifier.
    if decl.spelling == '':
        res: Optional[ast.Node] = cursor_to_ehlit(decl)
        if res is None:
            # The underlying type is not handled, so make this elaborated type unhandled too
            raise KeyError
        return res
    return ast.CompoundIdentifier([ast.Identifier(0, decl.spelling)])
Example #5
0
def _macro_alias_value(tokens: List[Token]) -> Optional[ast.Symbol]:
    name: str = tokens[0].spelling
    tokens = tokens[2:] if tokens[1].spelling == '(' else tokens[1:]
    if tokens[0].kind == TokenKind.KEYWORD:
        typ: Optional[ast.Symbol] = _macro_alias_type(tokens)
        if type is not None:
            return typ
    elif len(tokens) == 1 or (len(tokens) == 2 and tokens[1].spelling == ')'):
        return ast.CompoundIdentifier([ast.Identifier(0, tokens[0].spelling)])
    logging.debug('c_parser: failed to parse macro: {}'.format(name))
    return None
Example #6
0
 def visit_function_arguments(self, node: ParseTreeNode,
                              children: Tuple[ast.VariableDeclaration]
                              ) -> Tuple[List[ast.VariableDeclaration], Optional[ast.Symbol]]:
     args: List[ast.VariableDeclaration] = []
     variadic_type: Optional[ast.Symbol] = None
     for child in children[::2]:
         arg = child
         if isinstance(arg, ast.VariableDeclaration):
             args.append(arg)
         else:
             if arg == '...':
                 variadic_type = ast.CompoundIdentifier([ast.Identifier(0, '@any')])
             else:
                 assert isinstance(arg, ast.Symbol)
                 variadic_type = arg
     return args, variadic_type
Example #7
0
 def visit_destructor(self, node: ParseTreeNode, children: Tuple[str, ast.UnparsedContents]
                      ) -> ast.Dtor:
     qualifiers: ast.Qualifier = ast.Qualifier.NONE
     i: int = 0
     while isinstance(children[i], str):
         if children[i] == 'inline':
             qualifiers |= ast.Qualifier.INLINE
         elif children[i] == 'priv':
             qualifiers |= ast.Qualifier.PRIVATE
         elif children[i] == 'dtor':
             break
         i += 1
     i += 1
     body = None
     if len(children) > i:
         body = children[i]
     typ = ast.TemplatedIdentifier(node.position, '@func', [ast.FunctionType(
         ast.CompoundIdentifier([ast.Identifier(node.position, '@void')]),
         []
     )])
     assert(body is None or isinstance(body, ast.UnparsedContents))
     return ast.Dtor(node.position, qualifiers, typ, body)
Example #8
0
 def visit_constructor(self, node: ParseTreeNode,
                       children: Tuple[str, Tuple[List[ast.VariableDeclaration],
                                                  Optional[ast.Symbol]],
                                       ast.UnparsedContents]
                       ) -> ast.Ctor:
     qualifiers: ast.Qualifier = ast.Qualifier.NONE
     i: int = 0
     while isinstance(children[i], str):
         if children[i] == 'inline':
             qualifiers |= ast.Qualifier.INLINE
         elif children[i] == 'priv':
             qualifiers |= ast.Qualifier.PRIVATE
         elif children[i] == 'ctor':
             break
         i += 1
     i += 1
     args: List[ast.VariableDeclaration]
     variadic_type: Optional[ast.Symbol]
     body = None
     if len(children) < i or isinstance(children[i], ast.UnparsedContents):
         args = []
         variadic_type = None
         if len(children) > i:
             body = children[i]
     else:
         child_i = children[i]
         assert(isinstance(child_i, tuple))
         args, variadic_type = child_i
         if len(children) > i + 1:
             body = children[i + 1]
     typ = ast.TemplatedIdentifier(node.position, '@func', [ast.FunctionType(
         ast.CompoundIdentifier([ast.Identifier(node.position, '@void')]),
         args,
         variadic_type is not None,
         variadic_type
     )])
     assert(body is None or isinstance(body, ast.UnparsedContents))
     return ast.Ctor(node.position, qualifiers, typ, body)
Example #9
0
 def visit_function_type(self, node: ParseTreeNode,
                         children: Tuple[StrMatch, ast.Symbol, Tuple[ast.Symbol, ...]]
                         ) -> ast.TemplatedIdentifier:
     args: List[ast.VariableDeclaration] = []
     variadic: bool = False
     variadic_type: Optional[ast.Symbol] = ast.CompoundIdentifier([ast.Identifier(0, '@any')])
     if len(children) > 2:
         i = 0
         while i < len(children[2]):
             arg = children[2][i]
             if arg == '...':
                 variadic = True
             elif len(children[2]) > i + 1 and children[2][i + 1] == '...':
                 assert isinstance(arg, ast.Symbol)
                 variadic_type = arg
                 variadic = True
             else:
                 args.append(ast.VariableDeclaration(arg, None))
             i += 2
     return ast.TemplatedIdentifier(
         node.position,
         '@func',
         [ast.FunctionType(children[1], args, variadic, variadic_type)]
     )
Example #10
0
def type_TYPEDEF(typ: Type) -> ast.Node:
    return ast.CompoundIdentifier(
        [ast.Identifier(0,
                        typ.get_declaration().spelling)])
Example #11
0
def type_VOID(typ: Type) -> ast.Symbol:
    return ast.CompoundIdentifier([ast.Identifier(0, '@void')])
Example #12
0
 def make_symbol() -> ast.Symbol:
     return ast.CompoundIdentifier([ast.Identifier(0, '@c_any')])
Example #13
0
 def __init__(self, sym: ast.Identifier) -> None:
     super().__init__(0, ast.CompoundIdentifier([ast.Identifier(0,
                                                                '@any')]),
                      sym, ast.Qualifier.NONE)
     self.declaration_type = ast.DeclarationType.C
Example #14
0
 def visit_compound_identifier(self, node: ParseTreeNode, children: List[ast.Identifier]
                               ) -> ast.CompoundIdentifier:
     return ast.CompoundIdentifier(children)