class NameSpace;
class LangCallback;
+typedef Ref<NameSpace> NameSpaceRef;
+
// This is incremented when a chain of symbols is traversed to reset
// detection of already-visited symbols. It is assumed that this
// will not have to happen billions of times.
Symbol(const String *_name) : name(_name)
{
- if (_name)
- name->retain();
-
init();
}
struct UserError {
};
-typedef Ref<NameSpace> NameSpaceRef;
-
class NameSpace : public virtual Symbol {
protected:
// Filesystem path to the external symbol storage, or NULL
list<NameSpaceRef> imports;
public:
- // This is set in the destructor, so the contents of the namespace
- // don't try to remove themselves from the namespace when destructed
- // due to the destruction of map.
- int dying;
-
// This is a counter for generating unique names for anonymous
// members of the namespace.
int anon;
- NameSpace() : dying(0), anon(0)
+ NameSpace() : anon(0)
{
}
- virtual ~NameSpace()
- {
- dying = 1;
- }
+ virtual ~NameSpace();
// Return a description of the type of namespace, for
// error messages.
// SymbolNotFound is thrown if sym is not in this namespace.
virtual void del(Symbol *sym)
{
- fprintf(stderr, "Removing symbol %s\n",
- sym->get_fq_name()->flatten()->c_str());
-
- if (tbl.erase(sym->name) == 0)
+ if (sym->ns != this)
throw SymbolNotFound();
-
+
sym->ns = NULL;
+ int ret = tbl.erase(sym->name);
+ assert(ret != 0);
}
private:
class Struct;
typedef Ref<Struct> StructRef;
-extern Struct *System_VStruct;
+extern StructRef System_VStruct;
// FIXME: typedefed superstructs
class Struct : public NameSpace, public Type, public Def {
class Interface;
typedef Ref<Interface> InterfaceRef;
-extern Interface *System_Object;
+extern InterfaceRef System_Object;
// FIXME: typedefed superinterfaces
class Interface : public NameSpace, public Type, public Def {
list<const char *> inputs;
list<NameSpaceRef> nspace_stack;
Language *first_lang, *output_lang;
-Interface *System_Object;
-Struct *System_VStruct;
+InterfaceRef System_Object;
+StructRef System_VStruct;
AutoReleasePool autorelease_pool;
void print_usage()
{
int ret = run_idlc(argc, argv);
autorelease_pool.clean();
+
return ret;
}
if (lang_priv)
lang_priv->release();
- if (ns && !ns->dying) {
+ if (ns) {
try {
ns->del(this);
}
}
}
+NameSpace::~NameSpace()
+{
+ tbl_type::iterator i = tbl.begin();
+ while (i != tbl.end()) {
+ Symbol *sym = (*i).second;
+ ++i;
+
+ try {
+ del(sym);
+ }
+
+ catch (SymbolNotFound) {
+ fprintf(stderr, "SymbolNotFound in NameSpace::~NameSpace(), cannot propagate\n");
+ }
+
+ catch (InternalError &e) {
+ fprintf(stderr, "InternalError %s:%d in NameSpace::~NameSpace(), cannot propagate\n", e.file, e.line);
+ }
+ }
+
+ assert(tbl.empty());
+}
+
StrList *Symbol::get_fq_name(const char *append, bool not_last) const
{
StrList *ret;