/** * \file scope.cpp */ INTERFACE: #include #include #include #include "symbol_table.h" #include "type_rep.h" #include "garbage.h" class Symbol_name; class Class_symbol; class Function_signature; class Block_scope; class Variable_symbol; class Abstract_scope : public virtual G_light { Abstract_scope* parent; public: Abstract_scope(Abstract_scope* parent) : parent(parent) { } virtual ~Abstract_scope() {} /** Look up a symbol in this scope. \param for_decl=true this is a declaration, don't scan bases or using */ virtual Symbol_pair lookup_here(std::string name, bool for_decl) = 0; /** Add a variable. Returns variable symbol if this is a definition of a variable which must appear in output. */ virtual Variable_symbol* add_variable(Storage_class_specifier storage, Type type, Ptree* name, Ptree* init, Ptree* bitsize) = 0; /** Declare a function. Returns the declared signature. */ virtual Function_signature* add_function_decl(Storage_class_specifier storage, Function_specifier_set fspec, Type type, const Symbol_name& sym_name) = 0; /** Add function implementation. */ virtual void add_function_implementation(Function_signature*, Block_scope*, Ptree*, Ptree*) = 0; /** Add another symbol (nested type, ...). */ virtual void add_symbol(std::string name, Symbol*) = 0; /** Get unique naming prefix. I hope to never need this function */ virtual std::string get_unique_name(std::string name) = 0; /** Get type of "*this". */ virtual Type get_this_type() const = 0; Abstract_scope* get_parent() const { return parent; } void set_parent(Abstract_scope* p) { parent = p; } }; IMPLEMENTATION: #include "ptree_util.h" #include "except.h" #include "symbol_name.h" /** Look up an unqualified symbol. That is, look up the symbol in this scope and all containing scopes. */ PUBLIC virtual Symbol_pair Abstract_scope::lookup_unqualified(std::string name) { Symbol_pair rv = lookup_here(name, false); if (rv) return rv; Abstract_scope* p = this; while ((p = p->get_parent())) if ((rv = p->lookup_here(name, false))) return rv; return Symbol_pair(); } /** Check whether /tree/ names a constructor. This is used by Symbol_name when parsing apart a name. Only Class_scope needs to override this. */ PUBLIC virtual bool Abstract_scope::is_constructor(Ptree* tree) { return false; } /** Process pending tasks. This is called periodically by the main annotator code. This is needed to process definition of functions inside classes. */ PUBLIC virtual void Abstract_scope::process_pending() { } /** Get global scope. That is the scope without a parent. */ PUBLIC Abstract_scope* Abstract_scope::get_global_scope() { Abstract_scope* p = this; while (p->get_parent()) p = p->get_parent(); return p; }