-
Elemer Lelik authoredElemer Lelik authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CompField.cc 5.22 KiB
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2000-2014 Ericsson Telecom AB
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
///////////////////////////////////////////////////////////////////////////////
#include "CompField.hh"
#include "Type.hh"
#include "Value.hh"
#include "CompilerError.hh"
namespace Common {
// =================================
// ===== CompField
// =================================
CompField::CompField(Identifier *p_name, Type *p_type, bool p_is_optional,
Value *p_defval)
: Node(), Location(), name(p_name), type(p_type),
is_optional(p_is_optional), defval(p_defval), rawattrib(0)
{
if(!p_name || !p_type)
FATAL_ERROR("NULL parameter: Common::CompField::CompField()");
type->set_ownertype(Type::OT_COMP_FIELD, this);
}
CompField::CompField(const CompField& p)
: Node(p), Location(p), is_optional(p.is_optional), rawattrib(0)
{
name=p.name->clone();
type=p.type->clone();
type->set_ownertype(Type::OT_COMP_FIELD, this);
defval=p.defval?p.defval->clone():0;
}
CompField::~CompField()
{
delete name;
delete type;
delete defval;
delete rawattrib;
}
CompField *CompField::clone() const
{
return new CompField(*this);
}
void CompField::set_fullname(const string& p_fullname)
{
string base_name(p_fullname + "." + name->get_dispname());
Node::set_fullname(base_name);
type->set_fullname(base_name);
if (defval) defval->set_fullname(base_name + ".<defval>");
}
void CompField::set_my_scope(Scope *p_scope)
{
type->set_my_scope(p_scope);
if (defval) defval->set_my_scope(p_scope);
}
void CompField::set_raw_attrib(RawAST* r_attr)
{
delete rawattrib;
rawattrib=r_attr;
}
void CompField::dump(unsigned level) const
{
name->dump(level);
type->dump(level + 1);
if(is_optional)
DEBUG(level + 1, "optional");
if(defval) {
DEBUG(level + 1, "with default value");
defval->dump(level + 2);
}
}
// =================================
// ===== CompFieldMap
// =================================
CompFieldMap::CompFieldMap(const CompFieldMap& p)
: Node(p), my_type(0), checked(false)
{
size_t nof_comps = p.v.size();
for (size_t i = 0; i < nof_comps; i++) v.add(p.v[i]->clone());
}
CompFieldMap::~CompFieldMap()
{
size_t nof_comps = v.size();
for (size_t i = 0; i < nof_comps; i++) delete v[i];
v.clear();
m.clear();
}
CompFieldMap *CompFieldMap::clone() const
{
return new CompFieldMap(*this);
}
void CompFieldMap::set_fullname(const string& p_fullname)
{
Node::set_fullname(p_fullname);
size_t nof_comps = v.size();
for (size_t i = 0; i < nof_comps; i++) v[i]->set_fullname(p_fullname);
}
void CompFieldMap::set_my_scope(Scope *p_scope)
{
size_t nof_comps = v.size();
for (size_t i = 0; i < nof_comps; i++) v[i]->set_my_scope(p_scope);
}
void CompFieldMap::add_comp(CompField *comp)
{
v.add(comp);
if (checked) {
const string& name = comp->get_name().get_name();
if (m.has_key(name)) FATAL_ERROR("CompFieldMap::add_comp(%s)", name.c_str());
m.add(name, comp);
}
}
bool CompFieldMap::has_comp_withName(const Identifier& p_name)
{
if (!checked) chk_uniq();
return m.has_key(p_name.get_name());
}
CompField* CompFieldMap::get_comp_byName(const Identifier& p_name)
{
if (!checked) chk_uniq();
return m[p_name.get_name()];
}
const char *CompFieldMap::get_typetype_name() const
{
if (!my_type) FATAL_ERROR("CompFieldMap::get_typetype_name()");
switch (my_type->get_typetype()) {
case Type::T_ANYTYPE:
return "anytype";
case Type::T_CHOICE_T:
return "union";
case Type::T_SEQ_T:
return "record";
case Type::T_SET_T:
return "set";
case Type::T_OPENTYPE:
return "open type";
default:
return "<unknown>";
}
}
void CompFieldMap::chk_uniq()
{
if (checked) return;
const char *typetype_name = get_typetype_name();
size_t nof_comps = v.size();
for (size_t i = 0; i < nof_comps; i++) {
CompField *comp = v[i];
const Identifier& id = comp->get_name();
const string& name = id.get_name();
if (m.has_key(name)) {
const char *dispname = id.get_dispname().c_str();
comp->error("Duplicate %s field name `%s'", typetype_name, dispname);
m[name]->note("Field `%s' is already defined here", dispname);
} else m.add(name, comp);
}
checked = true;
}
void CompFieldMap::chk()
{
if (!checked) chk_uniq();
const char *typetype_name = get_typetype_name();
size_t nof_comps = v.size();
for (size_t i = 0; i < nof_comps; i++) {
CompField *comp = v[i];
const Identifier& id = comp->get_name();
Error_Context cntxt(comp, "In %s field `%s'", typetype_name,
id.get_dispname().c_str());
Type *t = comp->get_type();
t->set_genname(my_type->get_genname_own(), id.get_name());
t->set_parent_type(my_type);
t->chk();
t->chk_embedded(true, "embedded into another type");
}
}
void CompFieldMap::dump(unsigned level) const
{
size_t nof_comps = v.size();
DEBUG(level, "component fields: (%lu pcs.) @ %p",
(unsigned long) nof_comps, (const void*)this);
for (size_t i = 0; i < nof_comps; i++) v[i]->dump(level + 1);
}
} /* namespace Common */