Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

enum.cc

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #include "enum.h"
00004 #include "enum_i.h"
00005 
00006 
00007 #line 28 "enum.cpp"
00008 
00019 Enum_symbol::Enum_symbol()
00020 {
00021     set_status(st_Declared);    // enums can't be referenced
00022 }
00023 
00024 #line 43 "enum.cpp"
00025 
00026 
00027 Enum_symbol::~Enum_symbol()
00028 { }
00029 
00030 #line 47 "enum.cpp"
00031 
00032 Symbol::Kind
00033 Enum_symbol::get_kind() const
00034 {
00035     return k_Enum;
00036 }
00037 
00038 #line 53 "enum.cpp"
00039 
00044 Ptree*
00045 Enum_symbol::process_value(Ptree* tree, Ptree* previous, Abstract_scope* scope)
00046 {
00047     /* split tree into symbol and value */
00048     Ptree *name, *init;
00049     if (tree->IsLeaf()) {
00050         name = tree;
00051         if (!previous)
00052             init = new Leaf("0", 1);
00053         else
00054             init = new PtreeInfixExpr(previous, Ptree::List(new Leaf("+", 1), new Leaf("1", 1)));
00055     } else {
00056         expect_ptree(tree->Second(), '=');
00057         name = tree->First();
00058         init = tree->Third();
00059     }
00060 
00061     assert(name->IsLeaf());
00062 
00063     /* annotate the initializer. This will always find a builtin
00064        operator. There cannot be any user-defined operator+ which
00065        takes a enum type on the lhs, because we're just defining the
00066        enum and the operator must be defined after the enum
00067        definition. There's no way to forward-declare an enum in ISO
00068        C++. */
00069     Expr_result res = Expr_annotator(scope, &Source::instance()).visit(init);
00070     res.do_integral_promotions();
00071 
00072     if (!res.get_type().is_int())
00073         compile_error("enum initializer must be integer or enum");
00074 
00075     Variable_symbol* vsym = new Variable_symbol(get_type(),       // type
00076                                                 s_None,           // storage class
00077                                                 res.get_tree(),   // initializer
00078                                                 0,                // bitsize
00079                                                 false);           // has no address
00080     scope->add_symbol(std::string(name->ToString()), vsym);
00081     values.push_back(vsym);
00082 
00083     Token t = { name->GetPosition(), name->GetLength(), ntName };
00084     return new LeafName(t);
00085 }
00086 
00087 #line 100 "enum.cpp"
00088 
00091 Type
00092 parse_enum(Ptree* tree, Abstract_scope* scope, Ptree* name_for_anon)
00093 {
00094     expect_ptree(tree->First(), "enum");
00095 
00096     Ptree* nametree = tree->Second();
00097     Ptree* content  = tree->Third();
00098 
00099     /* if there's no definition, it is a reference to an
00100      * already-defined enum */
00101     if (!content) {
00102         if (!nametree)
00103             compile_error("stray `enum' in program");
00104 
00105         Symbol_pair sym = Symbol_name(nametree, scope, false).lookup_for_use(false);
00106         if (!sym.tag || sym.tag->get_kind() != Symbol::k_Enum)
00107             compile_error("`enum " + std::string(nametree->ToString()) + "' not defined");
00108         return downcast<Enum_symbol*>(sym.tag)->get_type();
00109     }
00110 
00111     /* It is a definition. Figure out name. */
00112     std::string name;
00113     if (!nametree)
00114         nametree = name_for_anon;
00115 
00116     Symbol_name sname(nametree, scope, false);
00117     if (sname.is_qualified())
00118         compile_error("qualified name not allowed in definition");
00119     if (sname.is_template())
00120         compile_error("template enum");
00121     name = sname.get_name();
00122 
00123     Enum_symbol* sym;
00124     Symbol_pair pair;
00125     if ((pair = scope->lookup_here(name, true)) && pair.tag) {
00126         if (pair.tag->get_kind() != Symbol::k_Enum)
00127             compile_error("`" + name + "' already defined");
00128         sym = downcast<Enum_symbol*>(pair.tag);
00129     } else {
00130         sym = new Enum_symbol();
00131         scope->add_symbol(name, sym);
00132     }
00133 
00134     if (sym->is_defined())
00135         compile_error("`enum " + name + "' already defined");
00136 
00137     /* now parse content */
00138     assert(!content->IsLeaf());
00139     expect_ptree(content->First(), '{');
00140     expect_ptree(content->Third(), '}');
00141 
00142     Ptree* previous = 0;    
00143     for (Ptree* p = content->Second(); p; (p = p->Cdr()) && (p = p->Cdr())) {
00144         previous = sym->process_value(p->Car(), previous, scope);
00145     }
00146 
00147     sym->set_defined();
00148     return sym->get_type();
00149 }

Generated on Mon Feb 10 17:32:46 2003 for VFiasco Semantics Compiler by doxygen1.2.15