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

decl_read.cc

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #include "decl_read.h"
00004 #include "decl_read_i.h"
00005 
00006 
00007 #line 54 "decl_read.cpp"
00008 
00009 /*************************** Declaration_reader **************************/
00010 
00014 Declaration_reader::Declaration_reader(Abstract_scope* scope)
00015     : current_scope(scope), function_args(0)
00016 {
00017     assert(current_scope);
00018 }
00019 
00020 #line 65 "decl_read.cpp"
00021 
00029 Declaration_reader::Declaration_reader(Abstract_scope* scope, Arg_vec* args)
00030     : current_scope(scope), function_args(args)
00031 {
00032     assert(current_scope);
00033     assert(function_args);
00034 }
00035 
00036 #line 79 "decl_read.cpp"
00037 
00038 
00039 Declaration_reader::~Declaration_reader()
00040 { }
00041 
00042 #line 83 "decl_read.cpp"
00043 
00088 void
00089 Declaration_reader::parse_declarator(Type type, Ptree* tree)
00090 {
00091     parse_declarator_internal(type, tree, 0, 0, current_scope);
00092 }
00093 
00094 #line 133 "decl_read.cpp"
00095 
00096 void
00097 Declaration_reader::parse_declarator_internal(Type type, Ptree* tree,
00098                                               Ptree* initializer,
00099                                               Ptree* bitsize,
00100                                               Abstract_scope* scope)
00101 {
00102     // declarators: [dcl.decl]
00103     if (tree->IsLeaf())
00104         bogus_ptree_error("expected a list in parse_declarator", tree);
00105 
00106     while (tree) {
00107         Ptree* f = tree->Car();
00108         if (!f) {
00109             tree = tree->Cdr();
00110             break;
00111         } else if (parse_qualifier(f, type)) {
00112             /* const, volatile or restrict */
00113             if (type.get_kind() == Type::k_Reference)
00114                 compile_error("references may not be cv-qualified");
00115             tree = tree->Cdr();
00116         } else if (f->Eq('*')) {
00117             if (type.get_kind() == Type::k_Reference)
00118                 compile_error("pointers to references are not allowed");
00119             type = type.make_pointer_type();
00120             tree = tree->Cdr();
00121         } else if (f->Eq('&')) {
00122             if (type.get_kind() == Type::k_Reference)
00123                 compile_error("references to references are not allowed");
00124             type = type.make_reference_type();
00125             tree = tree->Cdr();
00126         } else if (!f->IsLeaf()) {
00127             /* ARGH! */
00128             int len = f->Length();
00129             if (len > 2 && f->Nth(len-2)->Eq("::") && f->Nth(len-1)->Eq("*")) {
00130                 /* member pointer. Class name is f->Car() .. f->Nth(len-3).
00131                    Parsed as a symbol name, this appears as a symbol with
00132                    basename "*". */
00133                 Symbol_name name(f, scope, false);
00134                 assert(name.get_name() == "*");
00135                 assert(!name.is_template());  // that'd be "class::*<T>"
00136                 Class_scope* class_scope = dynamic_cast<Class_scope*>(name.get_scope());
00137                 if (!class_scope)
00138                     compile_error("invalid class type in member pointer declaration");
00139                 type = class_scope->get_class_symbol()->get_type().make_member_type(type);
00140 
00141                 tree = tree->Cdr();
00142             } else {
00143                 break;
00144             }
00145         } else {
00146             break;
00147         }
00148     }
00149 
00150     /* isn't there a simpler way to do this? */
00151     Ptree* name_ptr = 0;
00152     if (tree && tree->Car()) {
00153         name_ptr = tree->Car();
00154         if (name_ptr->Eq('(') || name_ptr->Eq('[') || name_ptr->Eq(':') || name_ptr->Eq('=') || name_ptr->Eq('*') || name_ptr->Eq(')'))
00155             name_ptr = 0;
00156     }
00157 
00158     bool do_function_args = false;
00159     if (name_ptr) {
00160         tree = tree->Cdr();     // skip over name
00161 
00162         /* Function args are parsed within the symbol name's scope. In
00163            "void a::foo(p x)", p is looked up in scope a. */
00164         // FIXME: this parses the symbol name twice. I'm unsure whether
00165         // the interface of declare_variable should accept a Symbol_name
00166         // instead? That'd waste an anonymous variable per abstract
00167         // declarator, though.
00168         if (name_ptr->IsLeaf() || !name_ptr->Car() || !name_ptr->Car()->Eq('(')) {
00169             scope = Symbol_name(name_ptr, scope, true).get_scope();
00170             assert(scope);
00171             do_function_args = true;
00172         }
00173     }
00174 
00175     Ptree* p = tree;
00176     while (p) {
00177         // FIXME: this parses () and [] combinations wrong!!!1
00178         if (p->Car()->Eq('(')) {
00179             /* Function header */
00180             // Note that we parse the function args while we are in
00181             // the function's enclosing scope. This should satisfy
00182             // 3.3.1p5.2. The only difference I see would be a type
00183             // definition inside a parameter list (whose scope would
00184             // be inside the prototype only) which isn't allowed in
00185             // C++.
00186             Function_declaration_reader reader(scope, do_function_args ? function_args : 0);
00187             do_function_args = false;
00188             Ptree* arg = p->Second();
00189             while (arg) {
00190                 if (arg->Car()->Eq("...")) {
00191                     reader.add_ellipsis();
00192                     arg = arg->Cdr();
00193                     break;
00194                 }
00195 
00196                 Ptree* item = arg->Car();
00197                 Type t = parse_type(item->First(), scope, 0, false);
00198                 reader.parse_declarator(t, item->Second());
00199                 arg = arg->Cdr();
00200                 if (!arg)
00201                     break;
00202                 arg = arg->Cdr();
00203             }
00204             type = reader.get_maker().make_function_type(type);
00205             p = p->Cdr()->Cdr()->Cdr();
00206             /* parse function's cv-qualifiers, as in `void (Foo::*x)() const'
00207                for a pointer to a const member function */
00208             while (p && p->Car() && parse_qualifier(p->Car(), type))
00209                 p = p->Cdr();
00210             // FIXME: exception-specification
00211         } else if (p->Car()->Eq('[')) {
00212             /* Array */
00213             type = type.make_array_type(p->Cdr()->Car());
00214             p = p->Cdr()->Cdr()->Cdr();
00215         } else if (p->Car()->Eq('=')) {
00216             /* initializer */
00217             assert(!initializer);
00218             initializer = p;
00219             p = p->Cdr()->Cdr();
00220             break;
00221         } else if (p->Car()->Eq(':')) {
00222             assert(!bitsize);
00223             bitsize = p->Cdr();
00224             p = p->Cdr()->Cdr();
00225             break;
00226         } else if (!p->Car()->IsLeaf()) {
00227             /* initializer */
00228             assert(!initializer);
00229             initializer = p->Car();
00230             p = p->Cdr();
00231             break;
00232         } else {
00233             bogus_ptree_error("expected '[' or '('", p);
00234         }
00235     }
00236 
00237     if (p)
00238         bogus_ptree_error("declaration not terminated yet?", p);
00239 
00240     if (name_ptr && !name_ptr->IsLeaf() && name_ptr->Car() && name_ptr->Car()->Eq('('))
00241         parse_declarator_internal(type, name_ptr->Cdr()->Car(), initializer, bitsize, scope);
00242     else
00243         declare_variable(type, name_ptr, initializer, bitsize);
00244 }
00245 
00246 #line 283 "decl_read.cpp"
00247 
00252 void
00253 Declaration_reader::parse_declarator_list(Type type, Ptree* list)
00254 {
00255     assert(!function_args);
00256     while (list) {
00257         parse_declarator(type, list->Car());        
00258         list = list->Cdr();
00259         if (!list)
00260             break;
00261 
00262         expect_ptree(list->Car(), ',');
00263         list = list->Cdr();
00264     }
00265 }
00266 
00267 #line 302 "decl_read.cpp"
00268 
00271 Ptree*
00272 Declaration_reader::parse_declarator_get_name(Ptree* tree)
00273 {
00274     if (tree->IsLeaf())
00275         bogus_ptree_error("expected a list in parse_declarator", tree);
00276 
00277     Type dummy;
00278     while (tree) {
00279         Ptree* f = tree->Car();
00280         if (!f) {
00281             tree = tree->Cdr();
00282             break;
00283         }
00284         
00285         if (parse_qualifier(f, dummy) || f->Eq('*') || f->Eq('&')) {
00286             tree = tree->Cdr();
00287         } else if (!f->IsLeaf()) {
00288             /* ARGH! */
00289             int len = f->Length();
00290             if (len > 2 && f->Nth(len-2)->Eq("::") && f->Nth(len-1)->Eq("*")) {
00291                 tree = tree->Cdr();
00292             } else {
00293                 break;
00294             }
00295         } else {
00296             break;
00297         }
00298     }
00299 
00300     Ptree* name_ptr = 0;
00301     if (tree && tree->Car()) {
00302         name_ptr = tree->Car();
00303         if (name_ptr->Eq('(') || name_ptr->Eq('[') || name_ptr->Eq(':') || name_ptr->Eq('=') || name_ptr->Eq('*') || name_ptr->Eq(')'))
00304             name_ptr = 0;
00305     }
00306 
00307     if (name_ptr && !name_ptr->IsLeaf() && name_ptr->Car() && name_ptr->Car()->Eq('('))
00308         return parse_declarator_get_name(tree);
00309     else
00310         return name_ptr;
00311 }
00312 
00313 #line 346 "decl_read.cpp"
00314 
00315 /********************** Function_declaration_reader **********************/
00316 
00325 Function_declaration_reader::Function_declaration_reader(Abstract_scope* s,
00326                                                          Arg_vec* args)
00327     : Declaration_reader(s), had_void_arg(false), had_parameter(false),
00328       args(args)
00329 { }
00330 
00331 #line 362 "decl_read.cpp"
00332 
00333 void
00334 Function_declaration_reader::declare_variable(Type type, Ptree* name,
00335                                               Ptree* initializer,
00336                                               Ptree* bitsize)
00337 {
00338     if (bitsize)
00339         compile_error("function arguments must not have bitsizes");
00340     if (initializer)
00341         compile_error("FIXME: function default args not supported");
00342     if (had_void_arg)
00343         compile_error("`void' argument must be the only one");
00344     if (type == void_type)
00345         if (had_parameter)
00346             compile_error("`void' argument must be the only one");
00347         else if (name)
00348             compile_error("`void' argument with a name? you're kidding.");
00349         else
00350             had_void_arg = true;
00351     else if (type.get_unqualified_type() == void_type)
00352         compile_error("qualified void as a type is bullshit");
00353     else {
00354         maker.add_parameter(type), had_parameter = true;
00355         if (args)
00356             args->push_back(std::make_pair(type, name));
00357     }
00358 }
00359 
00360 #line 389 "decl_read.cpp"
00361 
00362 void
00363 Function_declaration_reader::add_ellipsis()
00364 {
00365     if (had_void_arg)
00366         compile_error("`void' argument must be the only one");
00367     maker.add_ellipsis();
00368 }
00369 
00370 #line 412 "decl_read.cpp"
00371 
00377 bool
00378 parse_abstract_declarator(Ptree* tree, Abstract_scope* scope, Type* t)
00379 {
00380     Ad_reader r(scope);
00381     r.parse_declarator(*t, tree);
00382     if (!r.t.is_valid())
00383         return false;
00384     *t = r.t;
00385     return true;
00386 }
00387 
00388 #line 437 "decl_read.cpp"
00389 
00392 Ptree*
00393 get_name_from_declarator(Ptree* tree, Abstract_scope* scope)
00394 {
00395     return Name_decl_reader(scope).parse_declarator_get_name(tree);
00396 }

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