zeek/tools/binpac/src/pac_field.cc

125 lines
3.3 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#include "pac_field.h"
#include "pac_attr.h"
#include "pac_common.h"
#include "pac_exception.h"
#include "pac_id.h"
#include "pac_type.h"
Field::Field(FieldType tof, int flags, ID* id, Type* type)
: DataDepElement(DataDepElement::FIELD), tof_(tof), flags_(flags), id_(id), type_(type) {
decl_id_ = current_decl_id;
field_id_str_ = strfmt("%s:%s", decl_id()->Name(), id_->Name());
attrs_ = nullptr;
}
Field::~Field() {
delete id_;
delete type_;
delete_list(AttrList, attrs_);
}
void Field::AddAttr(AttrList* attrs) {
bool delete_attrs = false;
if ( ! attrs_ ) {
attrs_ = attrs;
}
else {
attrs_->insert(attrs_->end(), attrs->begin(), attrs->end());
delete_attrs = true;
}
foreach (i, AttrList, attrs)
ProcessAttr(*i);
if ( delete_attrs )
delete attrs;
}
void Field::ProcessAttr(Attr* a) {
switch ( a->type() ) {
case ATTR_IF:
if ( tof() != LET_FIELD && tof() != WITHINPUT_FIELD ) {
throw Exception(a,
"&if can only be applied to a "
"let field");
}
break;
default: break;
}
if ( type_ )
type_->ProcessAttr(a);
}
bool Field::anonymous_field() const { return type_ && type_->anonymous_value_var(); }
int Field::ValueVarType() const {
if ( flags_ & CLASS_MEMBER )
return (flags_ & PUBLIC_READABLE) ? MEMBER_VAR : PRIV_MEMBER_VAR;
else
return TEMP_VAR;
}
void Field::Prepare(Env* env) {
if ( type_ ) {
if ( anonymous_field() )
flags_ &= ~(CLASS_MEMBER | PUBLIC_READABLE);
if ( ! type_->persistent() )
flags_ &= (~PUBLIC_READABLE);
type_->set_value_var(id(), ValueVarType());
type_->Prepare(env, flags_ & TYPE_TO_BE_PARSED ? Type::TO_BE_PARSED : 0);
env->SetField(id(), this);
}
}
void Field::GenPubDecls(Output* out_h, Env* env) {
if ( type_ && (flags_ & PUBLIC_READABLE) && (flags_ & CLASS_MEMBER) )
type_->GenPubDecls(out_h, env);
}
void Field::GenPrivDecls(Output* out_h, Env* env) {
// Generate private declaration only if it is a class member
if ( type_ && (flags_ & CLASS_MEMBER) )
type_->GenPrivDecls(out_h, env);
}
void Field::GenTempDecls(Output* out_h, Env* env) {
// Generate temp field
if ( type_ && ! (flags_ & CLASS_MEMBER) )
type_->GenPrivDecls(out_h, env);
}
void Field::GenInitCode(Output* out_cc, Env* env) {
if ( type_ && ! anonymous_field() )
type_->GenInitCode(out_cc, env);
}
void Field::GenCleanUpCode(Output* out_cc, Env* env) {
if ( type_ && ! anonymous_field() )
type_->GenCleanUpCode(out_cc, env);
}
bool Field::DoTraverse(DataDepVisitor* visitor) {
// Check parameterized type
if ( type_ && ! type_->Traverse(visitor) )
return false;
foreach (i, AttrList, attrs_)
if ( ! (*i)->Traverse(visitor) )
return false;
return true;
}
bool Field::RequiresAnalyzerContext() const {
// Check parameterized type
if ( type_ && type_->RequiresAnalyzerContext() )
return true;
foreach (i, AttrList, attrs_)
if ( (*i)->RequiresAnalyzerContext() )
return true;
return false;
}