Skip to content

Commit

Permalink
[master] rvalue reference dispatch (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomhrr committed Mar 8, 2016
1 parent 824be32 commit e091022
Show file tree
Hide file tree
Showing 16 changed files with 162 additions and 59 deletions.
22 changes: 8 additions & 14 deletions src/dale/Context/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,29 +456,31 @@ getFunction_(Namespace *ns,
const char *name,
std::vector<Type *> *types,
Function **closest_fn,
bool is_macro)
bool is_macro,
std::vector<bool> *lvalues)
{
Function *fn =
ns->getFunction(name, types, closest_fn, is_macro, false);
ns->getFunction(name, types, closest_fn, is_macro, false, lvalues);
if (fn) {
return fn;
}
return ns->getFunction(name, types, closest_fn, is_macro, true);
return ns->getFunction(name, types, closest_fn, is_macro, true, lvalues);
}

Function *
Context::getFunction(const char *name,
std::vector<Type *> *types,
Function **closest_fn,
bool is_macro)
bool is_macro,
std::vector<bool> *lvalues)
{
if (strchr(name, '.')) {
Namespace *ns = getNamespace(name, true);
if (!ns) {
return NULL;
}
const char *fn_name = strrchr(name, '.') + 1;
return getFunction_(ns, fn_name, types, closest_fn, is_macro);
return getFunction_(ns, fn_name, types, closest_fn, is_macro, lvalues);
}

for (std::vector<NSNode *>::reverse_iterator
Expand All @@ -487,7 +489,7 @@ Context::getFunction(const char *name,
rb != re;
++rb) {
Function *fn =
getFunction_((*rb)->ns, name, types, closest_fn, is_macro);
getFunction_((*rb)->ns, name, types, closest_fn, is_macro, lvalues);
if (fn) {
return fn;
}
Expand All @@ -496,14 +498,6 @@ Context::getFunction(const char *name,
return NULL;
}

Function *
Context::getFunction(const char *name,
std::vector<Type *> *types,
bool is_macro)
{
return getFunction(name, types, NULL, is_macro);
}

Variable *
Context::getVariable(const char *name)
{
Expand Down
15 changes: 4 additions & 11 deletions src/dale/Context/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,10 @@ class Context
* method.
*/
Function *getFunction(const char *name,
std::vector<Type *> *types,
Function **closest_fn,
bool is_macro);
/*! Get the function with the given name and arguments.
*
* This is an overloaded version of getFunction, omitting
* closest_fn.
*/
Function *getFunction(const char *name,
std::vector<Type *> *types,
bool is_macro);
std::vector<Type *> *types,
Function **closest_fn,
bool is_macro,
std::vector<bool> *lvalues = NULL);
/*! Get the variable with the given name.
*
* See Namespace::getVariable. As per getFunction, this iterates
Expand Down
10 changes: 9 additions & 1 deletion src/dale/Form/Function/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,18 @@ isValidDeclaration(Context *ctx, Node *node, const char *name,
std::vector<Type*> types;
parametersToTypes(&fn->parameters, &types);
Function *closest_fn = NULL;
std::vector<bool> lvalues;
for (std::vector<Type *>::iterator b = types.begin(),
e = types.end();
b != e;
++b) {
lvalues.push_back((*b)->is_reference);
}
Function *matching_fn =
(linkage == Linkage::Extern_C)
? current_ns->getFunction(name, NULL, NULL, false)
: current_ns->getFunction(name, &types, &closest_fn, false);
: current_ns->getFunction(name, &types, &closest_fn,
false, true, &lvalues);
if (matching_fn) {
if (!matching_fn->isEqualTo(fn)) {
Error *e = new Error(RedeclarationOfFunctionOrMacro,
Expand Down
10 changes: 9 additions & 1 deletion src/dale/FunctionProcessor/FunctionProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,9 +585,17 @@ FunctionProcessor::parseFunctionCall(Function *dfn, llvm::BasicBlock *block,
/* Retrieve the function (if present) from the context, based on
* the argument types. */

std::vector<bool> lvalues;
for (std::vector<ParseResult>::iterator b = call_arg_prs.begin(),
e = call_arg_prs.end();
b != e;
++b) {
lvalues.push_back((*b).value_is_lvalue);
}

Function *closest_fn = NULL;
Function *fn = ctx->getFunction(proc_name, &call_arg_types,
&closest_fn, 0);
&closest_fn, false, &lvalues);

/* If the function is a macro, set macro_to_call and return false.
* (It's the caller's responsibility to handle processing of
Expand Down
10 changes: 5 additions & 5 deletions src/dale/Introspection/Introspection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ exists_2D_fn(MContext *mc, DNode *form)
Function *fn =
units->top()->ctx->getFunction(
node_function_name->token->str_value.c_str(),
&parameter_types, NULL, 0
&parameter_types, NULL, NULL, 0
);

units->top()->ctx->er->popErrors(error_count_begin);
Expand Down Expand Up @@ -444,7 +444,7 @@ fn_2D_by_2D_args_2D_count(MContext *mc, DNode *form, const char *prefix)
b != e;
++b) {
Function *fn = units->top()->ctx->getFunction(b->c_str(), &parameter_types,
NULL, 0);
NULL, NULL, 0);
if (fn && !fn->is_macro) {
fn_by_args_list->push_back(*b);
}
Expand Down Expand Up @@ -672,7 +672,7 @@ arity(MContext *mc, DNode *name)

const char *fn_name = fn_node->token->str_value.c_str();

Function *fn = units->top()->ctx->getFunction(fn_name, NULL, NULL, 0);
Function *fn = units->top()->ctx->getFunction(fn_name, NULL, NULL, NULL, 0);
if (!fn) {
return -1;
}
Expand Down Expand Up @@ -721,7 +721,7 @@ DNode *codomain(MContext *mc, DNode *form)

Function *fn =
units->top()->ctx->getFunction(function_name->token->str_value.c_str(),
&parameter_types, NULL, 0);
&parameter_types, NULL, NULL, 0);

units->top()->ctx->er->popErrors(error_count_begin);
if (fn && !fn->is_macro) {
Expand All @@ -743,7 +743,7 @@ input_2D_type(MContext *mc, DNode *fn_name_nd, int index)
}
const char *fn_name = fn_node->token->str_value.c_str();

Function *fn = units->top()->ctx->getFunction(fn_name, NULL, NULL, 0);
Function *fn = units->top()->ctx->getFunction(fn_name, NULL, NULL, NULL, 0);
if (!fn) {
return NULL;
}
Expand Down
6 changes: 3 additions & 3 deletions src/dale/MacroProcessor/MacroProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void
MacroProcessor::setPoolfree()
{
if (!pool_free_fptr) {
pool_free_fn = ctx->getFunction("pool-free", NULL, 0)->llvm_function;
pool_free_fn = ctx->getFunction("pool-free", NULL, NULL, 0)->llvm_function;
pool_free_fptr =
(void (*)(MContext *mcp))
ee->getPointerToFunction(pool_free_fn);
Expand Down Expand Up @@ -231,7 +231,7 @@ MacroProcessor::parsePotentialMacroCall(Node *n)
return core_mac(ctx, n);
}

Function *ffn = ctx->getFunction(macro_name, NULL, 1);
Function *ffn = ctx->getFunction(macro_name, NULL, NULL, 1);
if (!ffn) {
return n;
}
Expand Down Expand Up @@ -272,7 +272,7 @@ MacroProcessor::parsePotentialMacroCall(Node *n)
units->top()->removeTemporaryGlobalFunction();
}

ffn = ctx->getFunction(macro_name, &types, 1);
ffn = ctx->getFunction(macro_name, &types, NULL, 1);
if (!ffn) {
return n;
}
Expand Down
24 changes: 23 additions & 1 deletion src/dale/Namespace/Namespace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ Namespace::getFunction(const char *name,
std::vector<Type *> *types,
Function **pclosest_fn,
bool is_macro,
bool ignore_arg_constness)
bool ignore_arg_constness,
std::vector<bool> *lvalues)
{
std::string ss_name(name);

Expand Down Expand Up @@ -288,6 +289,7 @@ Namespace::getFunction(const char *name,
std::vector<Function *>::iterator fn_iter;
std::vector<Type *>::iterator arg_type_iter;
std::vector<Variable *>::iterator fn_arg_type_iter;
std::vector<bool>::iterator lvalue_iter;

fn_iter = function_list->begin();

Expand All @@ -307,6 +309,10 @@ Namespace::getFunction(const char *name,

fn_arg_type_iter = current->parameters.begin();
arg_type_iter = types->begin();
if (lvalues) {
lvalue_iter = lvalues->begin();
}

int matched_arg_count = 0;
bool broke_on_va = false;
bool broke_on_failure = false;
Expand Down Expand Up @@ -341,6 +347,19 @@ Namespace::getFunction(const char *name,
break;
}

if (lvalues && (lvalue_iter != lvalues->end())) {
Type *type = (*fn_arg_type_iter)->type;
bool is_lvalue = *lvalue_iter;

if ((!type->is_const && type->is_reference) && !is_lvalue) {
broke_on_failure = true;
break;
} else if (type->is_rvalue_reference && is_lvalue) {
broke_on_failure = true;
break;
}
}

bool result =
(*fn_arg_type_iter)->type->canBePassedFrom(
(*arg_type_iter),
Expand All @@ -351,6 +370,9 @@ Namespace::getFunction(const char *name,
++arg_type_iter;
++fn_arg_type_iter;
++matched_arg_count;
if (lvalues && (lvalue_iter != lvalues->end())) {
++lvalue_iter;
}
continue;
} else {
broke_on_failure = true;
Expand Down
5 changes: 4 additions & 1 deletion src/dale/Namespace/Namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class Namespace
* @param types The parameter types for the function.
* @param pclosest_fn A pointer for setting the closest candidate.
* @param is_macro Whether to limit searching to macros only.
* @param ignore_arg_constness Ignore argument type constness.
* @param lvalues A vector for type lvalue status.
*
* pclosest_fn may be NULL. If it is provided, and a function
* matching the types cannot be found, then it will be set to a
Expand All @@ -151,7 +153,8 @@ class Namespace
std::vector<Type *> *types,
Function **pclosest_fn,
bool is_macro,
bool ignore_arg_constness = true);
bool ignore_arg_constness = true,
std::vector<bool> *lvalues = NULL);
/*! Get a variable from this namespace.
* @param name The variable name. */
Variable *getVariable(const char *name);
Expand Down
26 changes: 17 additions & 9 deletions src/dale/Type/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ bool
Type::isEqualTo(Type *other_type,
bool ignore_arg_constness)
{
if (is_reference && other_type->is_rvalue_reference) {
return false;
}

if (is_rvalue_reference && other_type->is_reference) {
return false;
}

if (base_type != other_type->base_type) {
return false;
}
Expand Down Expand Up @@ -262,15 +270,6 @@ Type::toNode()

void Type::toString(std::string *str)
{
if (is_const) {
str->append("(const ");
is_const = false;
toString(str);
str->append(")");
is_const = true;
return;
}

if (is_reference) {
str->append("(ref ");
is_reference = false;
Expand All @@ -289,6 +288,15 @@ void Type::toString(std::string *str)
return;
}

if (is_const) {
str->append("(const ");
is_const = false;
toString(str);
str->append(")");
is_const = true;
return;
}

if (struct_name.size()) {
std::string name;
if (namespaces.size()) {
Expand Down
22 changes: 11 additions & 11 deletions src/dale/TypeRegister/TypeRegister.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ TypeRegister::getArrayType(Type *type, size_t size)
return ab->second;
} else {
Type *array_type = new Type();
array_type->is_array = 1;
array_type->is_array = true;
array_type->array_type = type;
array_type->array_size = size;
b->second.insert(
Expand Down Expand Up @@ -172,7 +172,7 @@ TypeRegister::getConstType(Type *type)
}

Type *const_type = type->makeCopy();
const_type->is_const = 1;
const_type->is_const = true;
const_types.insert(
std::pair<Type*, Type*>(type, const_type)
);
Expand All @@ -189,7 +189,7 @@ TypeRegister::getReferenceType(Type *type)
}

Type *reference_type = type->makeCopy();
reference_type->is_reference = 1;
reference_type->is_reference = true;
reference_types.insert(
std::pair<Type*, Type*>(type, reference_type)
);
Expand All @@ -206,7 +206,7 @@ TypeRegister::getRvalueReferenceType(Type *type)
}

Type *rvalue_reference_type = type->makeCopy();
rvalue_reference_type->is_rvalue_reference = 1;
rvalue_reference_type->is_rvalue_reference = true;
rvalue_reference_types.insert(
std::pair<Type*, Type*>(type, rvalue_reference_type)
);
Expand All @@ -223,7 +223,7 @@ TypeRegister::getRetvalType(Type *type)
}

Type *retval_type = type->makeCopy();
retval_type->is_retval = 1;
retval_type->is_retval = true;
retval_types.insert(
std::pair<Type*, Type*>(type, retval_type)
);
Expand Down Expand Up @@ -260,17 +260,17 @@ TypeRegister::getType(Type *type)
Type *final = NULL;

if (type->is_const) {
type->is_const = 0;
type->is_const = false;
final = getConstType(getType(type));
type->is_const = 1;
type->is_const = true;
} else if (type->is_reference) {
type->is_reference = 0;
type->is_reference = false;
final = getReferenceType(getType(type));
type->is_reference = 1;
type->is_reference = true;
} else if (type->is_rvalue_reference) {
type->is_rvalue_reference = 0;
type->is_rvalue_reference = false;
final = getRvalueReferenceType(getType(type));
type->is_rvalue_reference = 1;
type->is_rvalue_reference = true;
} else if (type->is_array) {
final = getArrayType(getType(type->array_type), type->array_size);
} else if (type->points_to) {
Expand Down
Loading

0 comments on commit e091022

Please sign in to comment.