Пример #1
0
Файл: Do.cpp Проект: tomhrr/dale
bool FormProcDoParse(Units *units, Function *fn,
                     llvm::BasicBlock *block, Node *node,
                     bool get_address, bool prefixed_with_core,
                     ParseResult *pr) {
    Context *ctx = units->top()->ctx;

    if (node->list->size() == 1) {
        pr->set(block, ctx->tr->type_void, NULL);
        return true;
    }

    for (std::vector<Node *>::iterator b = (node->list->begin() + 1),
                                       e = (node->list->end() - 1);
         b != e; ++b) {
        ParseResult local_pr;
        bool res = FormProcInstParse(units, fn, block, *b, get_address,
                                     false, NULL, &local_pr);
        if (!res) {
            return false;
        }

        ParseResult destruct_pr;
        res = Operation::Destruct(ctx, &local_pr, &destruct_pr);
        if (!res) {
            return false;
        }
        block = destruct_pr.block;
    }

    return FormProcInstParse(units, fn, block, *(node->list->end() - 1),
                             get_address, false, NULL, pr);
}
Пример #2
0
bool
FormProcFuncallParse(Units *units, Function *fn, llvm::BasicBlock *block,
                     Node *node, bool get_address, bool prefixed_with_core,
                     ParseResult *pr)
{
    Context *ctx = units->top()->ctx;

    if (!ctx->er->assertArgNums("funcall", node, 1, -1)) {
        return false;
    }

    std::vector<Node *> *lst = node->list;
    Node *fp_node = (*lst)[1];

    ParseResult fp_pr;
    bool res = FormProcInstParse(units, fn, block, fp_node, get_address,
                                 false, NULL, &fp_pr);
    if (!res) {
        return false;
    }

    if (!fp_pr.type->points_to || !fp_pr.type->points_to->is_function) {
        std::string type_str;
        fp_pr.type->toString(&type_str);
        Error *e = new Error(IncorrectArgType, fp_node, "funcall",
                             "function pointer", "1", type_str.c_str());
        ctx->er->addError(e);
        return false;
    }

    return units->top()->fp->parseFunctionPointerCall(fn, node, &fp_pr,
                                                      2, NULL, pr);
}
Пример #3
0
bool FormProcVaArgParse(Units *units, Function *fn,
                        llvm::BasicBlock *block, Node *node,
                        bool get_address, bool prefixed_with_core,
                        ParseResult *pr) {
    Context *ctx = units->top()->ctx;

    if (!ctx->er->assertArgNums("va-arg", node, 2, 2)) {
        return false;
    }

    std::vector<Node *> *lst = node->list;

    ParseResult arglist_pr;
    bool res = FormProcInstParse(units, fn, block, (*lst)[1], false,
                                 false, NULL, &arglist_pr);
    if (!res) {
        return false;
    }

    Type *type = FormTypeParse(units, (*lst)[2], false, false);
    if (!type) {
        return false;
    }

    llvm::Type *llvm_type = ctx->toLLVMType(type, NULL, false, false);
    if (!llvm_type) {
        return false;
    }

    if (!units->top()->is_x86_64) {
        /* Use the default va-arg intrinsic implementation. */
        llvm::IRBuilder<> builder(block);
        llvm::Value *res =
            builder.CreateVAArg(arglist_pr.getValue(ctx), llvm_type);
        pr->set(arglist_pr.block, type, res);
        return true;
    } else {
        return parseVaArg64(units, fn, type, llvm_type, &arglist_pr,
                            pr);
    }
}
Пример #4
0
bool
FormProcMoveParse(Units *units, Function *fn, llvm::BasicBlock *block,
                  Node *node, bool get_address, bool prefixed_with_core,
                  ParseResult *pr)
{
    Context *ctx = units->top()->ctx;

    if (!ctx->er->assertArgNums("cast", node, 1, 1)) {
        return false;
    }

    std::vector<Node *> *lst = node->list;
    Node *value_node = (*lst)[1];

    ParseResult value_pr;
    bool res = FormProcInstParse(units, fn, block, value_node, false,
                                 false, NULL, &value_pr, true);
    if (!res) {
        return false;
    }

    res = Operation::Move(ctx, fn, &value_pr, pr);
    return res;
}
Пример #5
0
Node *
MacroProcessor::parsePotentialMacroCall(Node *n)
{
    if (n->is_token || !n->is_list) {
        return n;
    }

    std::vector<Node *> *lst = n->list;
    if (lst->size() == 0) {
        return n;
    }

    Node *macro_name_node = (*lst)[0];
    if (!macro_name_node->is_token) {
        return n;
    }

    const char *macro_name = macro_name_node->token->str_value.c_str();

    Node *(*core_mac)(Context *ctx, Node *n);

    core_mac =   (eq("setv")) ? &FormMacroSetvParse
               : (eq("@$"))   ? &FormMacroArrayDerefParse
               : (eq(":@"))   ? &FormMacroDerefStructParse
               : (eq("@:"))   ? &FormMacroStructDerefParse
               : (eq("@:@"))  ? &FormMacroDerefStructDerefParse
               : NULL;

    if (core_mac) {
        return core_mac(ctx, n);
    }

    Function *ffn = ctx->getFunction(macro_name, NULL, 1);
    if (!ffn) {
        return n;
    }

    bool made_temp = false;
    Function *global_fn = units->top()->getGlobalFunction();
    if (!global_fn) {
        units->top()->makeTemporaryGlobalFunction();
        global_fn = units->top()->getGlobalFunction();
        made_temp = true;
    }

    std::vector<Type *> types;
    llvm::BasicBlock *block = &(global_fn->llvm_function->front());

    int error_count = ctx->er->getErrorTypeCount(ErrorType::Error);
    for (std::vector<Node *>::iterator b = lst->begin() + 1,
                                       e = lst->end();
            b != e;
            ++b) {
        ParseResult arg_pr;
        bool res =
            FormProcInstParse(units, global_fn, block, *b, false, false, NULL,
                              &arg_pr);
        if (res) {
            /* Add the type. */
            types.push_back(arg_pr.type);
            block = arg_pr.block;
        }
        else {
            /* Add a (p DNode) to types. */
            types.push_back(ctx->tr->type_pdnode);
        }
    }
    ctx->er->popErrors(error_count);

    if (made_temp) {
        units->top()->removeTemporaryGlobalFunction();
    }

    ffn = ctx->getFunction(macro_name, &types, 1);
    if (!ffn) {
        return n;
    }

    Node *mac_node = parseMacroCall(n, ffn);
    if (!mac_node) {
        return NULL;
    }

    /* If a macro node was got, and it's a list containing two
     * elements, and the first element is 'do', then just return the
     * second element. */

    if ((!mac_node->is_token)
            && (mac_node->list->size() == 2)
            && ((*mac_node->list)[0]->is_token)
            && ((*mac_node->list)[0]
                ->token->str_value.compare("do") == 0)) {
        return parsePotentialMacroCall((*mac_node->list)[1]);
    } else {
        return parsePotentialMacroCall(mac_node);
    }
}
Пример #6
0
bool FormProcArefParse(Units *units, Function *fn,
                       llvm::BasicBlock *block, Node *node,
                       bool get_address, bool prefixed_with_core,
                       ParseResult *pr) {
    Context *ctx = units->top()->ctx;

    if (!ctx->er->assertArgNums("$", node, 2, 2)) {
        return false;
    }

    std::vector<Node *> *lst = node->list;
    Node *array_node = (*lst)[1];
    Node *index_node = (*lst)[2];

    ParseResult initial_array_pr;
    bool res = FormProcInstParse(units, fn, block, array_node, false,
                                 false, NULL, &initial_array_pr);
    if (!res) {
        return false;
    }

    if (!(initial_array_pr.type->array_type ||
          initial_array_pr.type->points_to)) {
        std::string type_str;
        initial_array_pr.type->toString(&type_str);
        Error *e =
            new Error(IncorrectArgType, array_node, "$",
                      "a pointer or array", "1", type_str.c_str());
        ctx->er->addError(e);
        return false;
    }

    ParseResult array_pr;
    bool is_array;
    if (initial_array_pr.type->array_type) {
        initial_array_pr.getAddressOfValue(ctx, &array_pr);
        array_pr.type =
            ctx->tr->getPointerType(initial_array_pr.type->array_type);
        is_array = true;
    } else {
        initial_array_pr.copyTo(&array_pr);
        is_array = false;
    }

    ParseResult index_pr;
    res = FormProcInstParse(units, fn, array_pr.block, index_node,
                            false, false, NULL, &index_pr);
    if (!res) {
        return false;
    }
    if (!index_pr.type->isIntegerType()) {
        std::string type_str;
        index_pr.type->toString(&type_str);
        Error *e = new Error(IncorrectType, index_node, "integer",
                             type_str.c_str());
        ctx->er->addError(e);
        return false;
    }

    llvm::IRBuilder<> builder(index_pr.block);
    std::vector<llvm::Value *> indices;
    if (!is_array) {
        indices.push_back(
            llvm::cast<llvm::Value>(index_pr.getValue(ctx)));
    } else {
        STL::push_back2(
            &indices, ctx->nt->getLLVMZero(),
            llvm::cast<llvm::Value>(index_pr.getValue(ctx)));
    }
    llvm::Value *array_value = array_pr.getValue(ctx);
    if (array_pr.type->is_array) {
        pr->type = ctx->tr->getPointerType(array_pr.type->array_type);
    } else {
        pr->type = array_pr.type;
    }

    llvm::Value *index_ptr =
        builder.Insert(createGEP(array_value, indices));

    pr->block = index_pr.block;

    pr->set(pr->block, pr->type, index_ptr);
    array_pr.block = index_pr.block;
    ParseResult destruct_pr;
    res = Operation::Destruct(ctx, &array_pr, &destruct_pr);
    if (!res) {
        return false;
    }
    index_pr.block = destruct_pr.block;
    res = Operation::Destruct(ctx, &index_pr, &destruct_pr);
    if (!res) {
        return false;
    }
    pr->block = destruct_pr.block;

    return true;
}
Пример #7
0
bool
FormLiteralStructParse(Units *units, Function *fn, llvm::BasicBlock *block,
                       Node *node, const char *struct_name, Struct *st,
                       Type *st_type, bool get_address, ParseResult *pr)
{
    Context *ctx = units->top()->ctx;

    if (!node->is_list) {
        Error *e = new Error(UnexpectedElement, node,
                             "list", "struct initialisers", "atom");
        ctx->er->addError(e);
        return false;
    }

    std::vector<Node *> *lst = node->list;

    llvm::IRBuilder<> builder(block);

    llvm::Value *storage =
        llvm::cast<llvm::Value>(builder.CreateAlloca(st->type));

    for (std::vector<Node *>::iterator b = lst->begin(),
                                       e = lst->end();
            b != e;
            ++b) {
        Node *member_node = (*b);
        if (!member_node->is_list) {
            Error *e = new Error(UnexpectedElement, member_node,
                                 "list", "struct initialiser", "atom");
            ctx->er->addError(e);
            return false;
        }
        std::vector<Node *> *member_lst = member_node->list;
        if (member_lst->size() != 2) {
            Error *e = new Error(UnexpectedElement, member_node,
                                 "list", "struct initialiser", "atom");
            ctx->er->addError(e);
            return false;
        }
        Node *name_node  = (*member_lst)[0];
        Node *value_node = (*member_lst)[1];

        if (!name_node->is_token) {
            Error *e = new Error(UnexpectedElement, name_node,
                                 "atom", "struct field name", "list");
            ctx->er->addError(e);
            return false;
        }

        const char *name = name_node->token->str_value.c_str();
        Type *type = st->nameToType(name);
        if (!type) {
            Error *e = new Error(FieldDoesNotExistInStruct,
                                 name_node, name, struct_name);
            ctx->er->addError(e);
            return false;
        }

        int index = st->nameToIndex(name);

        std::vector<llvm::Value *> indices;
        STL::push_back2(&indices, ctx->nt->getLLVMZero(),
                        ctx->nt->getNativeInt(index));

        llvm::Value *storage_ptr =
            builder.CreateGEP(storage,
                              llvm::ArrayRef<llvm::Value*>(indices));

        ParseResult value_pr;
        bool res = FormProcInstParse(units, fn, block, value_node, false,
                                      false, NULL, &value_pr);
        if (!res) {
            return false;
        }

        if (!value_pr.type->isEqualTo(type, 1)) {
            if ((type->isIntegerType()
                    && value_pr.type->isIntegerType())
                    || (type->isFloatingPointType()
                        && value_pr.type->isFloatingPointType())) {
                ParseResult cast_pr;
                res = Operation::Cast(ctx, value_pr.block,
                                      value_pr.value, value_pr.type,
                                      type, member_node, 0, &cast_pr);
                if (!res) {
                    return false;
                }
                cast_pr.copyTo(&value_pr);
            } else {
                std::string wanted;
                std::string got;
                type->toString(&wanted);
                value_pr.type->toString(&got);
                Error *e = new Error(IncorrectType, name_node,
                                     wanted.c_str(), got.c_str());
                ctx->er->addError(e);
                return false;
            }
        }

        block = value_pr.block;
        builder.SetInsertPoint(block);
        builder.CreateStore(value_pr.value, storage_ptr);
    }

    if (get_address) {
        pr->set(block, ctx->tr->getPointerType(st_type), storage);
    } else {
        llvm::Value *final_value = builder.CreateLoad(storage);
        pr->set(block, st_type, final_value);
        pr->address_of_value = storage;
        pr->value_is_lvalue = true;
    }
    return true;
}