00001
00002
00003 #include "namespace.h"
00004 #include "namespace_i.h"
00005
00006
00007 #line 38 "namespace.cpp"
00008
00009
00010
00011
00012 Namespace_symbol::Namespace_symbol()
00013 : Symbol()
00014 {
00015 set_status(st_Defined);
00016 }
00017
00018 #line 47 "namespace.cpp"
00019
00020 Symbol::Kind
00021 Namespace_symbol::get_kind() const
00022 {
00023 return k_Namespace;
00024 }
00025
00026 #line 53 "namespace.cpp"
00027
00028 Namespace_scope*
00029 Namespace_symbol::get_scope()
00030 {
00031 return new Namespace_scope(0, this);
00032 }
00033
00034 #line 59 "namespace.cpp"
00035
00036
00037
00038
00039 Namespace_scope::Namespace_scope(Namespace_scope* parent, std::string prefix)
00040 : Abstract_scope(parent), prefix(prefix), sym(new Namespace_symbol()),
00041 fbqueue(0)
00042 { }
00043
00044 #line 67 "namespace.cpp"
00045
00046
00047 Namespace_scope::Namespace_scope(Namespace_scope* parent,
00048 Namespace_symbol* sym)
00049 : Abstract_scope(parent),
00050 prefix(Symbol_name::get_mangled_scope_from_symbol(sym->get_name())),
00051 sym(sym),
00052 fbqueue(0)
00053 { }
00054
00055 #line 76 "namespace.cpp"
00056
00057 std::string
00058 Namespace_scope::get_unique_name(std::string name)
00059 {
00060 return Symbol_name::get_mangled_symbol_name(prefix, name);
00061 }
00062
00063 #line 82 "namespace.cpp"
00064
00065 Type
00066 Namespace_scope::get_this_type() const
00067 {
00068 return Type();
00069 }
00070
00071 #line 88 "namespace.cpp"
00072
00074 Symbol_pair
00075 Namespace_scope::lookup_here(std::string name, bool for_decl)
00076 {
00077
00078 return Symbol_table::get_instance().get_symbol(get_unique_name(name));
00079 }
00080
00081 #line 96 "namespace.cpp"
00082
00083 void
00084 Namespace_scope::add_symbol(std::string name, Symbol* sym)
00085 {
00086 Symbol_table::get_instance().add_symbol(get_unique_name(name), name.length(), sym);
00087 }
00088
00089 #line 102 "namespace.cpp"
00090
00092 Variable_symbol*
00093 Namespace_scope::add_variable(Storage_class_specifier storage,
00094 Type type, Ptree* name, Ptree* init, Ptree* bitsize)
00095 {
00096 Storage_class_specifier orig_storage = storage;
00097
00098
00099 assert(type.get_kind() != Type::k_Function);
00100
00101 if (!name)
00102 compile_error("unnamed objects are not allowed at namespace scope");
00103 if (bitsize)
00104 compile_error("objects with bitsize are not allowed at namespace scope");
00105
00106
00107
00108 const bool is_declaration = (storage == s_Extern && !init);
00109
00110 if (storage == s_None) {
00111
00112 if (type.is_qualified(Type::q_Const))
00113 storage = s_Static;
00114 else
00115 storage = s_Extern;
00116 }
00117
00118 if (storage == s_Mutable || storage == s_Auto || storage == s_Register)
00119
00120 compile_error("mutable/auto/register variables not allowed at namespace scope");
00121
00122 Symbol_name sname(name, this, false);
00123 Symbol_pair pair = sname.lookup_for_decl();
00124 Variable_symbol* vsym;
00125 if (pair && pair.tag != pair.untag) {
00126
00127 vsym = dynamic_cast<Variable_symbol*>(pair.untag);
00128 if (!vsym)
00129 compile_error("`" + pair.untag->get_name() + "' already defined as a different kind of symbol");
00130 } else {
00131 if (sname.is_qualified())
00132 compile_error("can't declare qualified names");
00133 if (sname.is_template())
00134 compile_error("can't declare template vars");
00135
00136
00137 vsym = new Variable_symbol(type, storage, 0, 0, Symbol::st_Declared);
00138 add_symbol(sname.get_name(), vsym);
00139 }
00140
00141 if (vsym->get_type() != type)
00142 compile_error("inconsistent types for `" + vsym->get_name() + "'");
00143
00144 if (is_declaration) {
00145
00146 assert(!init);
00147 if (!vsym->is_declared())
00148 vsym->set_status(Symbol::st_Declared);
00149 return 0;
00150 } else {
00151
00152 if (vsym->is_defined())
00153 compile_error("duplicate definition of `" + vsym->get_name() + "'");
00154 if (vsym->is_member_variable())
00155 compile_error("can't initialize member variable at namespace scope");
00156 if (orig_storage != s_None && vsym->get_storage_class() != storage)
00157 compile_error("inconsistent storage class for `" + vsym->get_name() + "'");
00158
00159 if (init)
00160 init = Init_handler(sname.get_scope(), init, true).process_initializer(type.get_unqualified_type());
00161
00162 vsym->define_variable(storage, init, bitsize, Symbol::st_Defined);
00163 return vsym;
00164 }
00165 }
00166
00167 #line 178 "namespace.cpp"
00168
00169 Function_signature*
00170 Namespace_scope::add_function_decl(Storage_class_specifier storage,
00171 Function_specifier_set fspec,
00172 Type type,
00173 const Symbol_name& sym_name)
00174 {
00175 Function_symbol* fsym;
00176 Type this_type;
00177
00178 if (sym_name.is_template())
00179 compile_error("function template specialisation not supported");
00180 if (!sym_name.is_qualified()) {
00181
00182 Symbol_pair pair = lookup_here(sym_name.get_name(), true);
00183 if (!pair || pair.tag == pair.untag) {
00184 fsym = new Function_symbol(this, sym_name.get_kind());
00185 add_symbol(sym_name.get_name(), fsym);
00186 } else {
00187 fsym = dynamic_cast<Function_symbol*>(pair.untag);
00188 if (!fsym)
00189 compile_error("`" + sym_name.get_name() + "' is not a function");
00190 }
00191 } else {
00192
00193 Abstract_scope* scope = sym_name.get_scope();
00194 fsym = dynamic_cast<Function_symbol*>(scope->lookup_here(sym_name.get_name(), true).untag);
00195 if (!fsym)
00196 compile_error("`" + sym_name.get_name() + "' has not been declared");
00197
00198
00199 if (Class_scope* cs = dynamic_cast<Class_scope*>(scope))
00200 this_type = cs->get_class_symbol()->get_type();
00201 }
00202
00203 if (storage == s_None || storage == s_Static || storage == s_Extern)
00204 ;
00205 else
00206 compile_error("invalid storage class for top-level function");
00207
00208 Function_signature* sig =
00209 fsym->add_signature(type, this_type, storage, fspec,
00210 (sym_name.is_qualified()
00211 ? Function_symbol::must_be_declared
00212 : Function_symbol::may_be_anything));
00213
00214 if (!sig->is_declared())
00215 sig->set_status(Symbol::st_Declared);
00216
00217 return sig;
00218 }
00219
00220 #line 229 "namespace.cpp"
00221
00222 void
00223 Namespace_scope::add_function_implementation(Function_signature* fsig,
00224 Block_scope* scope,
00225 Ptree* tree,
00226 Ptree* initializer)
00227 {
00228 if (!fbqueue)
00229 fbqueue = new Function_body_queue();
00230 fbqueue->add_function(fsig, scope, tree, initializer);
00231 }
00232
00233 #line 240 "namespace.cpp"
00234
00235 void
00236 Namespace_scope::process_pending()
00237 {
00238 if (fbqueue)
00239 fbqueue->process();
00240 }