#include <list>
#include <map>
#include <vector>
+#include <cstring>
#include "compileddef.h"
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.
class Symbol : public RefCountable<Symbol> {
NameSpace *ns;
+ void init()
+ {
+ ns = NULL;
+ external = false;
+ priv = false;
+ lang_priv = NULL;
+ }
+
public:
StringRef name;
bool priv;
- // This is set to ::traversal when this symbol is visited along a chain.
- // If a target needs more than 8 simultaneous chains, increase the size
- // of the array. These traversals are reserved for language binding use.
-
- int traversed[8];
+ // Reserved for language binding use.
+ Releasable *lang_priv;
Symbol()
{
- ns = NULL;
- external = false;
- priv = false;
-
- memset(traversed, 0, sizeof(traversed));
+ init();
}
Symbol(const String *_name) : name(_name)
{
- if (_name)
- name->retain();
-
- ns = NULL;
- external = false;
- priv = false;
-
- memset(traversed, 0, sizeof(traversed));
+ init();
}
virtual ~Symbol();
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:
CompiledDefHeader hdr;
// sym is the symbol from which to get the path/name, and
- // dir is true if it should be "name/.self" rather than
+ // is_dir is true if it should be "name/.self" rather than
// "name".
- void output_self(const char *dir, Symbol *sym, bool dir);
+ void output_self(const char *dir, Symbol *sym, bool is_dir);
public:
Def(const char *self, int self_len, CompiledDefHeader::Type type) :
// lower is [0], upper is [1]
StrListRef dcons[2];
- Con cons[2];
// Strings for error reporting on each constant. If the constant
// is symbolic, then this is the fully qualified symbol name.
StringRef strs[2];
public:
+ Con cons[2];
+
// ca is not valid until after final_analysis() is called.
CompiledArray ca;
bool const_init; // Datum's constant has been initialized; this is
// true after a successful verify_const().
CompiledBasicType *cbt;
-
- ArrayRef array;
int chain_traversed;
}
public:
+ ArrayRef array;
CompiledDatum def;
TypeRef type;
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 {
SymbolRef supersym;
StrListRef supername;
bool attrs_resolved;
+
+ // 0 = unknown, 1 = yes, 2 = no
+ int plain_data;
void add_elem(Datum *d);
def.guid[0] = guid[0];
def.guid[1] = guid[1];
}
+
+ // A struct is "plain data" if it contains no object references,
+ // no non-inline arrays or structs, and no inline non-plain structs.
+ bool is_plain_data();
};
class Param : public Symbol, 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 {