void AST_t::prepend_to_translation_unit(AST_t tree)
    {
        if (tree._ast == NULL)
        {
            return;
        }

        AST this_translation_unit = get_translation_unit(this->_ast);

        AST this_declaration_seq = ASTSon0(this_translation_unit);

        // Go to the very first one!
        while (ASTSon0(this_declaration_seq) != NULL)
        {
            this_declaration_seq = ASTSon0(this_declaration_seq);
        }

        AST tree_declaration_seq = tree._ast;

        if (this_declaration_seq == NULL)
        {
            ast_set_child(this_translation_unit, 0, tree_declaration_seq);
        }
        else
        {
            prepend_list(this_declaration_seq, tree_declaration_seq);
        }
    }
 void ASTIterator::previous()
 {
     if (_current != NULL)
     {
         _current = ASTSon0(_current);
     }
 }
    void AST_t::remove_in_list()
    {
        AST list = this->_ast;
        // Look for the enclosing list
        while (list != NULL &&
                ASTType(list) != AST_NODE_LIST)
        {
            list = ASTParent(list);
        }

        if (list == NULL)
        {
            std::cerr << "A suitable list has not been found" << std::endl;
            return;
        }

        AST parent = ASTParent(list);
        AST previous = ASTSon0(list);

        if (previous != NULL)
        {
            ast_set_parent(previous, parent);
        }

        int i;
        for (i = 0; i < ASTNumChildren(parent); i++)
        {
            if (ASTChild(parent, i) == list)
            {
                ast_set_child(parent, i, previous);
                break;
            }
        }
    }
    void AST_t::replace(AST_t ast)
    {
        if (ast._ast == NULL)
        {
            internal_error("Trying to replace a tree with an empty tree", 0);
        }

        if (this->_ast == NULL)
        {
            internal_error("Trying to replace an empty tree with another tree", 0);
        }

        if (ASTType(ast._ast) == AST_NODE_LIST)
        {
            // If the replacement is a list but the original is not, let's check two cases
            // maybe this list is a one-element list or not.
            if (ASTType(this->_ast) != AST_NODE_LIST)
            {
                // If it is a one element list
                if (ASTSon0(ast._ast) == NULL)
                {
                    // then replace the whole thing with the list information
                    AST_t repl_tree(ASTSon1(ast._ast));
                    replace_with(repl_tree);
                }
                // If this is not a one-element list then try to replace using
                // a typical replace_in_list but this may fail sometimes
                // because we'll look for the first enclosing list
                else 
                {
                    // Maybe we should yield a message here
                    // std::cerr << "Warning: Replacing a non-list tree at '" 
                    //     << this->get_locus() 
                    //     << "' with a list tree of more than one element" << std::endl;
                    replace_in_list(ast);
                }
            }
            // If both are lists is easy
            else
            {
                replace_in_list(ast);
            }
        }
        // If the thing being replaced is a list, but the replacement
        // is not, then convert the latter into a list
        else if (ASTType(_ast) == AST_NODE_LIST
                && ASTType(_ast) != AST_NODE_LIST)
        {
            // Create a single element list
            AST single(ASTListLeaf(ast._ast));
            replace_in_list(single);
        }
        // Otherwise replace directly. Neither the replaced nor the replacement
        // are lists in this case.
        else
        {
            replace_with(ast);
        }
    }
    bool ASTIterator::is_first()
    {
        if (_current == NULL)
        {
            return true;
        }

        return (ASTSon0(_current) == NULL);
    }
    ObjectList<AST_t> AST_t::children() const
    {
        ObjectList<AST_t> result;

        result.append(AST_t(ASTSon0(_ast)));
        result.append(AST_t(ASTSon1(_ast)));
        result.append(AST_t(ASTSon2(_ast)));
        result.append(AST_t(ASTSon3(_ast)));

        return result;
    }
Beispiel #7
0
 void Source::fortran_check_expression_adapter(AST a, const decl_context_t* decl_context, nodecl_t* nodecl_output)
 {
     if (ASTKind(a) == AST_COMMON_NAME)
     {
         // We allow common names in expressions
         scope_entry_t* entry = ::query_common_name(decl_context, ASTText(ASTSon0(a)),
                 ast_get_locus(ASTSon0(a)));
         if (entry != NULL)
         {
             *nodecl_output = ::nodecl_make_symbol(entry, ast_get_locus(a));
         }
         else
         {
             *nodecl_output = ::nodecl_make_err_expr(ast_get_locus(a));
         }
     }
     else
     {
         ::fortran_check_expression(a, decl_context, nodecl_output);
     }
 }
    void AST_t::replace_in_list(AST_t ast)
    {
        if (ast._ast == NULL)
        {
            std::cerr << "Cannot replace a list using an empty tree" << std::endl;
            return;
        }
        if (this->_ast == NULL)
        {
            std::cerr << "This tree is empty" << std::endl;
            return;
        }

        if (ASTType(ast._ast) != AST_NODE_LIST)
        {
            std::cerr << "The replacement tree is not a list. No replacement performed" << std::endl;
            return;
        }

        AST list = get_enclosing_list(this->_ast);

        if (list == NULL)
        {
            std::cerr << "A suitable list has not been found" << std::endl;
            return;
        }

        AST previous = ASTSon0(list);

        AST_t replaced(list);
        replaced.replace_with(ast);

        while (ASTSon0(list) != NULL)
        {
            list = ASTSon0(list);
        }

        ast_set_child(list, 0, previous);
    }
    // XXX - Fixme, implement it using ast_list_concat
    void AST_t::prepend_list(AST orig_list, AST prepended_list)
    {
        if (ASTType(orig_list) != AST_NODE_LIST
                || ASTType(prepended_list) != AST_NODE_LIST)
        {
            std::cerr << "You tried to prepend two lists that are not " 
                << "orig_list=" << ast_print_node_type(ASTType(orig_list)) << " "
                << "prepend_list=" << ast_print_node_type(ASTType(prepended_list)) << std::endl;
            return;
        }

        // Relink the parent, first remove pointer to the prepended_list
        if (ASTParent(prepended_list) != NULL)
        {
            AST parent = ASTParent(prepended_list);
            for (int i = 0; i < ASTNumChildren(parent); i++)
            {
                if (ASTChild(parent, i) == prepended_list)
                {
                    ast_set_child(parent, i, NULL);
                    break;
                }
            }
        }

        // Now make the prepended_list as the son
        AST original_previous = ASTSon0(orig_list);

        ast_set_child(orig_list, 0, prepended_list);

        // Go to the deeper node of prepended_list
        AST iter = prepended_list;
        while (ASTSon0(iter) != NULL)
        {
            iter = ASTSon0(iter);
        }

        ast_set_child(iter, 0, original_previous);
    }
 AST AST_t::get_list_of_extensible_block(AST node)
 {
     switch ((int)ASTType(node))
     {
         case AST_COMPOUND_STATEMENT :
             {
                 // This can be null
                 return ASTSon0(node);
                 break;
             }
         case AST_CLASS_SPECIFIER :
             {
                 // This can be null
                 return ASTSon1(node);
                 break;
             }
         case AST_TRANSLATION_UNIT :
             {
                 // This can be null
                 return ASTSon0(node);
                 break;
             }
         case AST_NAMESPACE_DEFINITION :
             {
                 // This can be null
                 return ASTSon1(node);
                 break;
             }
         case AST_NODE_LIST :
             {
                 return node;
                 break;
             }
     }
     return NULL;
 }
    // XXX - Fixme, implement it using ast_list_concat
    void AST_t::append_list(AST orig_list, AST appended_list)
    {
        if (ASTType(orig_list) != AST_NODE_LIST
                || ASTType(appended_list) != AST_NODE_LIST)
        {
            std::cerr << "You tried to append two lists that are not" << std::endl;
            return;
        }

        // Appending one list to another is as easy as making the deeper node
        // "appended_list" to point to the top node of "orig_list"

        // First replace appended_list as the new child of the parent of orig_list
        relink_parent(orig_list, appended_list);

        // Now link the deeper node of the list to the top node of "orig_list"
        AST iter = appended_list;
        while (ASTSon0(iter) != NULL)
        {
            iter = ASTSon0(iter);
        }

        ast_set_child(iter, 0, orig_list);
    }
    bool ASTIterator::is_last()
    {
        if (_current == NULL)
            return true;

        AST _possible_next = ASTParent(_current);
        if (_possible_next == NULL
                || ASTType(_possible_next) != AST_NODE_LIST)
        {
            return true;
        }
        else if (ASTType(_possible_next) == AST_NODE_LIST
                && ASTSon0(_possible_next) != _current)
        {
            return true;
        }
        return false;
    }
Beispiel #13
0
    static void compute_nodecl_parse_c_type(AST type_id, const decl_context_t* decl_context, nodecl_t* nodecl_output)
    {
        nodecl_t nodecl_out_type = nodecl_null();

        type_t* type_info = NULL;
        gather_decl_spec_t gather_info;
        memset(&gather_info, 0, sizeof(gather_info));

        AST type_specifier_seq = ASTSon0(type_id);
        AST abstract_decl = ASTSon1(type_id);

        build_scope_decl_specifier_seq(type_specifier_seq, &gather_info, &type_info,
                decl_context, &nodecl_out_type);

        type_t* declarator_type = type_info;
        compute_declarator_type(abstract_decl, &gather_info, type_info,
                &declarator_type, decl_context, &nodecl_out_type);

        *nodecl_output = nodecl_make_type(declarator_type, ast_get_locus(type_id));
    }
    void AST_t::append_to_translation_unit(AST_t tree)
    {
        if (tree._ast == NULL)
        {
            return;
        }

        AST this_translation_unit = get_translation_unit(this->_ast);

        AST this_declaration_seq = ASTSon0(this_translation_unit);
        AST tree_declaration_seq = tree._ast;

        if (this_declaration_seq == NULL)
        {
            ast_set_child(this_translation_unit, 0, tree_declaration_seq);
        }
        else
        {
            append_list(this_declaration_seq, tree_declaration_seq);
        }
    }
Beispiel #15
0
static void gather_ms_declspec_item(AST a,
        gather_decl_spec_t* gather_info,
        const decl_context_t* decl_context)
{
    ERROR_CONDITION(ASTKind(a) != AST_MS_DECLSPEC_ITEM, "Invalid node", 0);

    const char* declspec_name = ASTText(a);
    ERROR_CONDITION(declspec_name == NULL, "Invalide node", 0);

    if (strcmp(declspec_name, "align") == 0)
    {
        AST expr_list = ASTSon0(a);
        int num_items = 0;
        if (expr_list != NULL)
        {
            AST it = NULL;
            for_each_element(expr_list, it)
            {
                num_items++;
            }
        }
static void fortran_simplify_tree_stmt(AST a, AST *out)
{
    // FIXME: Think ways of improving this
    switch (ASTType(a))
    {
        case AST_ALLOCATE_STATEMENT:
        case AST_ARITHMETIC_IF_STATEMENT:
        case AST_ASSIGNED_GOTO_STATEMENT:
        case AST_BREAK_STATEMENT:
        case AST_CLOSE_STATEMENT:
        case AST_COMPUTED_GOTO_STATEMENT:
        case AST_CONTINUE_STATEMENT:
        case AST_DEALLOCATE_STATEMENT:
        case AST_EMPTY_STATEMENT:
        case AST_EXPRESSION_STATEMENT:
        case AST_GOTO_STATEMENT:
        case AST_IO_STATEMENT:
        case AST_LABEL_ASSIGN_STATEMENT:
        case AST_NULLIFY_STATEMENT:
        case AST_OPEN_STATEMENT:
        case AST_PRINT_STATEMENT:
        case AST_READ_STATEMENT:
        case AST_RETURN_STATEMENT:
        case AST_STOP_STATEMENT:
        case AST_PAUSE_STATEMENT:
        case AST_WRITE_STATEMENT:
        case AST_PRAGMA_CUSTOM_DIRECTIVE:
            {
                // Simple copy
                *out = ast_copy_with_scope_link(a, CURRENT_COMPILED_FILE->scope_link);
                break;
            }
        case AST_BLOCK_CONSTRUCT:
            {
                AST block = ASTSon1(a);
                AST new_block = NULL;
                AST it;
                for_each_element(block, it)
                {
                    AST stmt = ASTSon1(it);
                    AST new_stmt = NULL;

                    fortran_simplify_tree_stmt(stmt, &new_stmt);

                    if (new_stmt != NULL)
                    {
                        new_block = ASTList(new_block, new_stmt);
                    }
                }
                *out = ASTMake1(AST_COMPOUND_STATEMENT, new_block, ASTFileName(a), ASTLine(a), NULL);
                break;
            }
        case AST_COMPOUND_STATEMENT:
            {
                AST list = ASTSon0(a);
                AST new_list = NULL;
                AST it;
                for_each_element(list, it)
                {
                    AST stmt = ASTSon1(it);
                    AST new_stmt = NULL;

                    fortran_simplify_tree_stmt(stmt, &new_stmt);

                    if (new_stmt != NULL)
                    {
                        new_list = ASTList(new_list, new_stmt);
                    }
                }
                *out = ASTMake1(AST_COMPOUND_STATEMENT, new_list, ASTFileName(a), ASTLine(a), NULL);
                break;
            }