mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
no semantic changes: factored some of the complexity of begin_func() into a pair of static functions for clarity
This commit is contained in:
parent
9cb506ad97
commit
98529ae4ec
1 changed files with 116 additions and 100 deletions
152
src/Var.cc
152
src/Var.cc
|
@ -486,43 +486,27 @@ static bool canonical_arg_types_match(const FuncType* decl, const FuncType* impl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void begin_func(IDPtr id, const char* module_name,
|
static auto get_prototype(IDPtr id, FuncTypePtr t)
|
||||||
FunctionFlavor flavor, bool is_redef,
|
|
||||||
FuncTypePtr t,
|
|
||||||
std::unique_ptr<std::vector<AttrPtr>> attrs)
|
|
||||||
{
|
|
||||||
if ( flavor == FUNC_FLAVOR_EVENT )
|
|
||||||
{
|
|
||||||
const auto& yt = t->Yield();
|
|
||||||
|
|
||||||
if ( yt && yt->Tag() != TYPE_VOID )
|
|
||||||
id->Error("event cannot yield a value", t.get());
|
|
||||||
|
|
||||||
t->ClearYieldType(flavor);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<FuncType::Prototype> prototype;
|
|
||||||
|
|
||||||
if ( id->GetType() )
|
|
||||||
{
|
{
|
||||||
auto decl = id->GetType()->AsFuncType();
|
auto decl = id->GetType()->AsFuncType();
|
||||||
prototype = func_type_check(decl, t.get());
|
auto prototype = func_type_check(decl, t.get());
|
||||||
|
|
||||||
if ( prototype )
|
if ( prototype )
|
||||||
{
|
{
|
||||||
if ( decl->Flavor() == FUNC_FLAVOR_FUNCTION )
|
if ( decl->Flavor() == FUNC_FLAVOR_FUNCTION )
|
||||||
{
|
{
|
||||||
// If a previous declaration of the function had &default
|
// If a previous declaration of the function had
|
||||||
// params, automatically transfer any that are missing
|
// &default params, automatically transfer any that
|
||||||
// (convenience so that implementations don't need to specify
|
// are missing (convenience so that implementations
|
||||||
// the &default expression again).
|
// don't need to specify the &default expression again).
|
||||||
transfer_arg_defaults(prototype->args.get(), t->Params().get());
|
transfer_arg_defaults(prototype->args.get(), t->Params().get());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Warn for trying to use &default parameters in hook/event
|
// Warn for trying to use &default parameters in
|
||||||
// handler body when it already has a declaration since only
|
// hook/event handler body when it already has a
|
||||||
// &default in the declaration has any effect.
|
// declaration since only &default in the declaration
|
||||||
|
// has any effect.
|
||||||
const auto& args = t->Params();
|
const auto& args = t->Params();
|
||||||
|
|
||||||
for ( int i = 0; i < args->NumFields(); ++i )
|
for ( int i = 0; i < args->NumFields(); ++i )
|
||||||
|
@ -551,6 +535,7 @@ void begin_func(IDPtr id, const char* module_name,
|
||||||
prototype->args.get(), true);
|
prototype->args.get(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Allow renaming arguments, but only for the canonical
|
// Allow renaming arguments, but only for the canonical
|
||||||
|
@ -560,8 +545,80 @@ void begin_func(IDPtr id, const char* module_name,
|
||||||
else
|
else
|
||||||
t->Error("use of undeclared alternate prototype", id.get());
|
t->Error("use of undeclared alternate prototype", id.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return prototype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool check_params(int i, std::optional<FuncType::Prototype> prototype,
|
||||||
|
const RecordTypePtr& args,
|
||||||
|
const RecordTypePtr& canon_args,
|
||||||
|
const char* module_name)
|
||||||
|
{
|
||||||
|
TypeDecl* arg_i;
|
||||||
|
bool hide = false;
|
||||||
|
|
||||||
|
if ( prototype )
|
||||||
|
{
|
||||||
|
auto it = prototype->offsets.find(i);
|
||||||
|
|
||||||
|
if ( it == prototype->offsets.end() )
|
||||||
|
{
|
||||||
|
// Alternate prototype hides this param
|
||||||
|
hide = true;
|
||||||
|
arg_i = canon_args->FieldDecl(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Alternate prototype maps this param to another index
|
||||||
|
arg_i = args->FieldDecl(it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( i < args->NumFields() )
|
||||||
|
arg_i = args->FieldDecl(i);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto arg_id = lookup_ID(arg_i->id, module_name);
|
||||||
|
|
||||||
|
if ( arg_id && ! arg_id->IsGlobal() )
|
||||||
|
arg_id->Error("argument name used twice");
|
||||||
|
|
||||||
|
const char* local_name = arg_i->id;
|
||||||
|
|
||||||
|
if ( hide )
|
||||||
|
// Note the illegal '-' in hidden name implies we haven't
|
||||||
|
// clobbered any local variable names.
|
||||||
|
local_name = util::fmt("%s-hidden", local_name);
|
||||||
|
|
||||||
|
arg_id = install_ID(local_name, module_name, false, false);
|
||||||
|
arg_id->SetType(arg_i->type);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void begin_func(IDPtr id, const char* module_name,
|
||||||
|
FunctionFlavor flavor, bool is_redef,
|
||||||
|
FuncTypePtr t,
|
||||||
|
std::unique_ptr<std::vector<AttrPtr>> attrs)
|
||||||
|
{
|
||||||
|
if ( flavor == FUNC_FLAVOR_EVENT )
|
||||||
|
{
|
||||||
|
const auto& yt = t->Yield();
|
||||||
|
|
||||||
|
if ( yt && yt->Tag() != TYPE_VOID )
|
||||||
|
id->Error("event cannot yield a value", t.get());
|
||||||
|
|
||||||
|
t->ClearYieldType(flavor);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FuncType::Prototype> prototype;
|
||||||
|
|
||||||
|
if ( id->GetType() )
|
||||||
|
prototype = get_prototype(id, t);
|
||||||
|
|
||||||
else if ( is_redef )
|
else if ( is_redef )
|
||||||
id->Error("redef of not-previously-declared value");
|
id->Error("redef of not-previously-declared value");
|
||||||
|
|
||||||
|
@ -604,49 +661,8 @@ void begin_func(IDPtr id, const char* module_name,
|
||||||
push_scope(std::move(id), std::move(attrs));
|
push_scope(std::move(id), std::move(attrs));
|
||||||
|
|
||||||
for ( int i = 0; i < canon_args->NumFields(); ++i )
|
for ( int i = 0; i < canon_args->NumFields(); ++i )
|
||||||
{
|
if ( ! check_params(i, prototype, args, canon_args, module_name) )
|
||||||
TypeDecl* arg_i;
|
|
||||||
bool hide = false;
|
|
||||||
|
|
||||||
if ( prototype )
|
|
||||||
{
|
|
||||||
auto it = prototype->offsets.find(i);
|
|
||||||
|
|
||||||
if ( it == prototype->offsets.end() )
|
|
||||||
{
|
|
||||||
// Alternate prototype hides this param
|
|
||||||
hide = true;
|
|
||||||
arg_i = canon_args->FieldDecl(i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Alternate prototype maps this param to another index
|
|
||||||
arg_i = args->FieldDecl(it->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( i < args->NumFields() )
|
|
||||||
arg_i = args->FieldDecl(i);
|
|
||||||
else
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
auto arg_id = lookup_ID(arg_i->id, module_name);
|
|
||||||
|
|
||||||
if ( arg_id && ! arg_id->IsGlobal() )
|
|
||||||
arg_id->Error("argument name used twice");
|
|
||||||
|
|
||||||
const char* local_name = arg_i->id;
|
|
||||||
|
|
||||||
if ( hide )
|
|
||||||
// Note the illegal '-' in hidden name implies we haven't
|
|
||||||
// clobbered any local variable names.
|
|
||||||
local_name = util::fmt("%s-hidden", local_name);
|
|
||||||
|
|
||||||
arg_id = install_ID(local_name, module_name, false, false);
|
|
||||||
arg_id->SetType(arg_i->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( Attr* depr_attr = find_attr(current_scope()->Attrs().get(), ATTR_DEPRECATED) )
|
if ( Attr* depr_attr = find_attr(current_scope()->Attrs().get(), ATTR_DEPRECATED) )
|
||||||
current_scope()->GetID()->MakeDeprecated(depr_attr->GetExpr());
|
current_scope()->GetID()->MakeDeprecated(depr_attr->GetExpr());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue