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

type_rep.cc

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #include "type_rep.h"
00004 #include "type_rep_i.h"
00005 
00006 
00007 #line 139 "type_rep.cpp"
00008 
00009 /* 3.9.2 [basic.compound]
00010    - array of TYPE
00011    - function
00012    - pointers [dcl.ptr]
00013    - references [dcl.ref]
00014    - class [class]
00015    - union [class.union]
00016    - enum [dcl.enum]
00017    - member pointer [dcl.mptr] */
00018 
00022 Type::Type()
00023     : code(), qualifiers(0)
00024 { }
00025 
00026 #line 156 "type_rep.cpp"
00027 
00032 Type::Type(std::string encoded)
00033     : code(encoded), qualifiers(0)
00034 {
00035     while (code.length()) {
00036         if (code[0] == 'C') {
00037             add_qualifier(q_Const);
00038             code.erase(0, 1);
00039         } else if (code[0] == 'V') {
00040             add_qualifier(q_Volatile);
00041             code.erase(0, 1);
00042         } else if (code[0] == 'N') {
00043             add_qualifier(q_Restrict);
00044             code.erase(0, 1);
00045         } else
00046             break;
00047     }
00048 }
00049 
00050 #line 178 "type_rep.cpp"
00051 
00052 
00053 Type::Type(std::string code, int qualifiers)
00054     : code(code), qualifiers(qualifiers)
00055 { }
00056 
00057 #line 183 "type_rep.cpp"
00058 
00060 Type
00061 Type::get_named_type(std::string name)
00062 {
00063     std::ostringstream s;
00064     s << name.length();
00065     return Type("Q" + s.str() + name);
00066 }
00067 
00068 #line 192 "type_rep.cpp"
00069 
00071 Type::Kind
00072 Type::get_kind() const
00073 {
00074     using namespace std;
00075     if (code.length() && isupper(code[0]))
00076         return Kind(code[0]);
00077     else
00078         return k_Fundamental;
00079 }
00080 
00081 #line 203 "type_rep.cpp"
00082 
00085 std::string
00086 Type::encode_qualifiers(std::string prefix) const
00087 {
00088     if (is_qualified(q_Const))
00089         prefix.append("C");
00090     if (is_qualified(q_Volatile))
00091         prefix.append("V");
00092     if (is_qualified(q_Restrict))
00093         prefix.append("N");
00094     return prefix + code;
00095 }
00096 
00097 #line 231 "type_rep.cpp"
00098 
00100 Type
00101 Type::make_array_type(Ptree* dimension) const
00102 {
00103     /* FIXME: we currently ignore dimensions */
00104     return Type(encode_qualifiers("A"));
00105 }
00106 
00107 #line 239 "type_rep.cpp"
00108 
00113 Type
00114 Type::make_member_type(Type membertype) const
00115 {
00116     return Type(membertype.encode_qualifiers(encode_qualifiers("M")));
00117 }
00118 
00119 #line 249 "type_rep.cpp"
00120 
00123 Type
00124 Type::get_basis_type() const
00125 {
00126     assert(get_kind() == k_Reference || get_kind() == k_Pointer || get_kind() == k_Array);
00127     return Type(code.substr(1));
00128 }
00129 
00130 #line 258 "type_rep.cpp"
00131 
00134 Type
00135 Type::sans_reference() const
00136 {
00137     if (get_kind() == k_Reference)
00138         return get_basis_type();
00139     else
00140         return *this;
00141 }
00142 
00143 #line 269 "type_rep.cpp"
00144 
00145 Type
00146 Type::sans_array() const
00147 {
00148     if (get_kind() == k_Array)
00149         return get_basis_type().sans_array();
00150     else
00151         return *this;
00152 }
00153 
00154 #line 278 "type_rep.cpp"
00155 
00157 Type
00158 Type::get_class_type() const
00159 {
00160     assert(get_kind() == k_Member);
00161     std::string mem_type = eat_type(code.substr(1));
00162     return Type(code.substr(1, code.length() - 1 - mem_type.length()));
00163 }
00164 
00165 #line 287 "type_rep.cpp"
00166 
00168 Type
00169 Type::get_member_type() const
00170 {
00171     assert(get_kind() == k_Member);
00172     return Type(eat_type(code.substr(1)));
00173 }
00174 
00175 #line 295 "type_rep.cpp"
00176 
00178 Type
00179 Type::get_return_type() const
00180 {
00181     assert(get_kind() == k_Function);
00182     std::string r = code.substr(1);
00183     while (r.length() && r[0] != '_')
00184         r = eat_type(r);
00185     return Type(r.substr(1));
00186 }
00187 
00188 #line 306 "type_rep.cpp"
00189 
00192 std::string
00193 Type::get_function_signature() const
00194 {
00195     assert(get_kind() == k_Function);
00196     std::string r = code.substr(1);
00197     while (r.length() && r[0] != '_')
00198         r = eat_type(r);
00199     return code.substr(0, code.length() - r.length());
00200 }
00201 
00202 #line 318 "type_rep.cpp"
00203 
00205 Type
00206 Type::get_function_arg(int n) const
00207 {
00208     assert(get_kind() == k_Function);
00209     std::string r = code.substr(1);
00210     while (n--)
00211         r = eat_type(r);
00212     return Type(r.substr(0, r.length() - eat_type(r).length()));
00213 }
00214 
00215 #line 329 "type_rep.cpp"
00216 
00218 int
00219 Type::get_num_function_args() const
00220 {
00221     assert(get_kind() == k_Function);
00222     std::string r = code.substr(1);
00223     int n = 0;
00224     while (r.length() && r[0] != '_')
00225         r = eat_type(r), ++n;
00226     return n;
00227 }
00228 
00229 #line 341 "type_rep.cpp"
00230 
00232 int
00233 Type::get_template_argindex() const
00234 {
00235     assert(get_kind() == Type::k_Template);
00236     int n = 0;
00237     for (std::string::size_type i = 1; i < code.length(); ++i)
00238         n = 10*n + code[i]-'0';
00239     return n;
00240 }
00241 
00242 #line 352 "type_rep.cpp"
00243 
00245 std::string
00246 Type::eat_type(std::string s)
00247 {
00248     using namespace std;        // for ctype macros
00249     std::string::size_type n = 0;
00250     while (n < s.length()) {
00251         switch(s[n]) {
00252          case 'C':
00253          case 'V':
00254          case 'N':
00255          case 'P':
00256          case 'R':
00257          case 'A':
00258          case 's':
00259          case 'u':
00260             /* these all have syntax "<char><rest-of-type>" */
00261             ++n;
00262             break;
00263          case 'M':
00264             /* M<TM><T> */
00265             return eat_type(eat_type(s.substr(n+1)));
00266          case 'Q':
00267             {
00268                 int add = 0;
00269                 ++n;
00270                 while (n < s.length() && isdigit(s[n]))
00271                     add = 10*add + s[n++] - '0';
00272                 n += add;
00273                 assert(n < s.length());
00274                 return s.substr(n);
00275             }
00276          case 'T':
00277             /* T<n> */
00278             while (++n < s.length() && isdigit(s[n]))
00279                 ++n;
00280             return s.substr(n);
00281          case 'F':
00282             /* F<T>..._<TR> */
00283             {
00284                 std::string r = s.substr(n+1);
00285                 while (r.length() && r[0] != '_')
00286                     r = eat_type(r);
00287                 return eat_type(r.substr(1));
00288             }
00289          case 'i':              // int
00290          case 'h':              // half == short
00291          case 'l':              // long
00292          case 'j':              // long long
00293          case 'c':              // char
00294          case 'f':              // float
00295          case 'd':              // double
00296          case 'e':              // extended == long double
00297          case 'b':              // bool
00298          case 'w':              // wchar_t
00299          case 'v':              // void
00300          case 'E':              // ...
00301          case 'O':              // ctor return type
00302             return s.substr(n+1);
00303          default:
00304             goto exit_loop;
00305         }
00306     }
00307  exit_loop:
00308     compile_error("internal error: got an invalid type");
00309 }
00310 
00311 #line 419 "type_rep.cpp"
00312 
00314 std::string
00315 Type::get_human_readable_type() const
00316 {
00317     std::string text;
00318     if (is_qualified(q_Const))
00319         text += "const ";
00320     if (is_qualified(q_Volatile))
00321         text += "volatile ";
00322     if (is_qualified(q_Restrict))
00323         text += "restrict ";
00324     switch (get_kind()) {
00325      case k_Fundamental:
00326         return text + "fundamental type " + code;
00327      case k_Pointer:
00328         return text + "pointer to " + get_basis_type().get_human_readable_type();
00329      case k_Reference:
00330         return text + "reference to " + get_basis_type().get_human_readable_type();
00331      case k_Function:
00332         {
00333             int n = get_num_function_args();
00334             if (n) {
00335                 text += "function taking (";
00336                 for (int i = 0; i < n; ++i) {
00337                     if (i)
00338                         text += ", ";
00339                     text += get_function_arg(i).get_human_readable_type();
00340                 }
00341                 text += ")";
00342             } else {
00343                 text += "function without args";
00344             }
00345             return text + " returning " + get_return_type().get_human_readable_type();
00346         }
00347      case k_Array:
00348         return text + "array of " + get_basis_type().get_human_readable_type();
00349      case k_Member:
00350         return text + "pointer to member of " + get_class_type().get_human_readable_type()
00351             + " of type " + get_member_type().get_human_readable_type();
00352      case k_Userdef:
00353         return text + "user-defined " + code.substr(1);
00354      case k_Ellipsis:
00355         return text + "ellipsis";
00356      case k_Nothing:
00357         return text + "nothing";
00358      case k_Template:
00359         return text + "template arg " + code;
00360      default:
00361         assert(0);
00362     }
00363 }
00364 
00365 #line 487 "type_rep.cpp"
00366 
00368 bool
00369 Type::is_int() const
00370 {
00371     return code.length() && get_kind() == k_Fundamental && !is_float() && !is_void();
00372 }
00373 
00374 #line 494 "type_rep.cpp"
00375 
00377 bool
00378 Type::is_complete() const
00379 {
00380     if (is_void())
00381         return false;
00382     if (get_kind() == k_Userdef)
00383         return get_type_symbol()->get_status() == Symbol::st_Defined;
00384     return true;
00385 }
00386 
00387 #line 505 "type_rep.cpp"
00388 
00391 bool
00392 Type::is_object_type() const
00393 {
00394     if (is_void() || get_kind() == k_Function || get_kind() == k_Reference)
00395         return false;
00396     return true;
00397 }
00398 
00399 #line 515 "type_rep.cpp"
00400 
00403 bool
00404 Type::is_arithmetic_type() const
00405 {
00406     return is_float() || is_int();
00407 }
00408 
00409 #line 523 "type_rep.cpp"
00410 
00414 bool
00415 Type::is_scalar_type() const
00416 {
00417     switch (get_kind()) {
00418      case k_Userdef:
00419         return is_enum_type();
00420      case k_Pointer:
00421      case k_Member:
00422         return true;
00423      case k_Fundamental:
00424         return is_arithmetic_type();
00425      default:
00426         return false;
00427     }
00428 }
00429 
00430 #line 542 "type_rep.cpp"
00431 
00433 bool
00434 Type::is_pod() const
00435 {
00436     if (!is_valid())
00437         return false;
00438     switch (get_kind()) {
00439      case k_Userdef:
00440         if (Class_symbol* cs = dynamic_cast<Class_symbol*>(get_type_symbol()))
00441             return cs->is_pod();
00442         else
00443             return true;
00444      case k_Pointer:
00445      case k_Member:
00446         return true;
00447      case k_Fundamental:
00448         return is_arithmetic_type();
00449      case k_Array:
00450         return get_basis_type().is_pod();
00451      default:
00452         return false;
00453     }
00454 }
00455 
00456 #line 566 "type_rep.cpp"
00457 
00458 bool
00459 Type::is_aggregate() const
00460 {
00461     if (!is_valid())
00462         return false;
00463     switch (get_kind()) {
00464      case k_Array:
00465         return true;
00466      case k_Userdef:
00467         if (Class_symbol* cs = dynamic_cast<Class_symbol*>(get_type_symbol()))
00468             return cs->is_aggregate();
00469         else
00470             return true;
00471      default:
00472         return false;
00473     }
00474 }
00475 
00476 #line 595 "type_rep.cpp"
00477 
00478 bool
00479 Type::is_enum_type() const
00480 {
00481     return (get_kind() == k_Userdef && get_type_symbol()->get_kind() == Symbol::k_Enum);
00482 }
00483 
00484 #line 601 "type_rep.cpp"
00485 
00486 bool
00487 Type::is_class_type() const
00488 {
00489     return (get_kind() == k_Userdef && get_type_symbol()->get_kind() != Symbol::k_Enum);
00490 }
00491 
00492 #line 607 "type_rep.cpp"
00493 
00495 Type_symbol*
00496 Type::get_type_symbol() const
00497 {
00498     assert(get_kind() == k_Userdef);
00499 
00500     std::string::size_type s = code.find_first_not_of("0123456789", 1);
00501     Type_symbol* sym = dynamic_cast<Type_symbol*>(Symbol_table::get_instance().get_symbol(code.substr(s)).tag);
00502     assert(sym);
00503 
00504     return sym;
00505 }
00506 
00507 #line 646 "type_rep.cpp"
00508 
00512 Type
00513 Type::get_promoted_integer() const
00514 {
00515     if (!code.length())
00516         return Type();
00517 
00518     /* An rvalue of type char, signed char, unsigned char, short int,
00519      * or unsigned short int can be converted to an rvalue of type int
00520      * if int can represent all the values of the source type;
00521      * other-wise, the source rvalue can be converted to an rvalue of
00522      * type unsigned int. */
00523     // MACHINE: I assume they all fit into an int
00524     if (code == "c" || code == "sc" || code == "uc" || code == "h" || code == "uh")
00525         return int_type;
00526 
00527     /* An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2)
00528      * can be converted to an rvalue of the first of the following
00529      * types that can represent all the values of its underlying type:
00530      * int, unsigned int, long, or unsigned long. */
00531     // MACHINE: I assume that wchar_t is uint, and that all enums fit into int
00532     if (code == "w")
00533         return uint_type;
00534 
00535     if (code[0] == 'Q') {
00536         Type_symbol* sym = get_type_symbol();
00537         if (sym->get_kind() == Symbol::k_Enum)
00538             return int_type;
00539     }
00540 
00541     /* An rvalue for an integral bit-field (9.6) can be converted to
00542      * an rvalue of type int if int can represent all the values of
00543      * the bit-field; otherwise, it can be converted to unsigned int
00544      * if unsigned int can rep-resent all the values of the
00545      * bit-field. If the bit-field is larger yet, no integral
00546      * promotion applies to it. If the bit-field has an enumerated
00547      * type, it is treated as any other value of that type for
00548      * promotion purposes. */
00549     // we better do that when really reading the bitfield
00550 
00551     /* An rvalue of type bool can be converted to an rvalue of type
00552      * int, with false becoming zero and true becoming one. */
00553     if (code == "b")
00554         return int_type;
00555 
00556     return *this;
00557 }
00558 
00559 #line 696 "type_rep.cpp"
00560 
00562 bool
00563 Type::is_qualification_convertible_to(Type t) const
00564 {
00565     Kind k = get_kind();
00566     if ((k != k_Pointer && k != k_Member && k != k_Reference) || k != t.get_kind())
00567         return false;
00568 
00569     if (k != k_Member) {
00570         /* 4.4p1: T cv1* => T cv2* if cv1 < cv2
00571                   T cv1& => T cv2& */
00572         if (t.get_basis_type().is_more_qualified_than(get_basis_type())
00573             && t.get_basis_type().is_same_unqualified_type(get_basis_type()))
00574             return true;
00575     } else {
00576         /* 4.4p2: T X::* cv1 => T X::* cv2 if cv1 < cv2 */
00577         if (t.get_class_type() == get_class_type()
00578             && t.get_member_type().is_more_qualified_than(get_member_type())
00579             && t.get_member_type().is_same_unqualified_type(get_member_type()))
00580             return true;
00581     }
00582 
00583     /* might be similar:
00584          *this is  cv1,0 P0 to cv1,1 P1 to ... cv1,n T
00585          t     is  cv2,0 P0 to cv2,1 P1 to ... cv2,n T
00586 
00587          Pi is either "pointer" or "pointer to member of X"
00588 
00589          cvi,0 are the cv-qualifiers of *this resp. t and can be
00590          ignored
00591 
00592          \forall j>0: cv1,j <= cv2,j                      [0]
00593 
00594          \forall j>0: cv1,j == cv2,j                      [1]
00595                    || \forall 0<k<j: const \in cv2,k      [2] */
00596 
00597     bool had_const = true;
00598     Type t1 = *this, t2 = t;
00599     while (1) {
00600         Kind k1 = t1.get_kind(), k2 = t2.get_kind();
00601         if (k1 != k2)
00602             return false;       // types are dissimilar
00603         if (k1 == k_Member) {
00604             if (t1.get_class_type() != t2.get_class_type())
00605                 return false;
00606             t1 = t1.get_member_type();
00607             t2 = t2.get_member_type();
00608         } else if (k1 == k_Pointer || k1 == k_Reference) {
00609             t1 = t1.get_basis_type();
00610             t2 = t2.get_basis_type();
00611         } else {
00612             break;
00613         }
00614         if (t1.is_same_qualified_as(t2)) {
00615             /* same qualifiers */
00616             if (!t2.is_qualified(q_Const))
00617                 had_const = false;           // [2] can't be true any longer
00618         } else if (t1.is_more_qualified_than(t2)) {
00619             /* [0] is false, removing qualifiers won't work */
00620             return false;
00621         } else if (!had_const) {
00622             /* [1] is false, and [2] too -> can't work */
00623             return false;
00624         }
00625     }
00626 
00627     /* when we're here, the types are similar so far, we just have to
00628        check the basis type. */
00629     return t1.is_same_unqualified_type(t2);
00630 }
00631 #line 767 "type_rep.cpp"
00632 
00633 /*************************** Fundamental Types ***************************/
00634 
00635 #define DECLARE_FUNDAMENTAL(name,type,encoding) Type name(encoding)
00636 #line 771 "type_rep.cpp"
00637 
00638 // 3.9.1 [basic.fundamental]
00639 DECLARE_FUNDAMENTAL(int_type, int, "i");
00640 #line 774 "type_rep.cpp"
00641 DECLARE_FUNDAMENTAL(uint_type, unsigned int, "ui");
00642 #line 775 "type_rep.cpp"
00643 DECLARE_FUNDAMENTAL(short_type, short, "h");
00644 #line 776 "type_rep.cpp"
00645 DECLARE_FUNDAMENTAL(ushort_type, unsigned short, "uh");
00646 #line 777 "type_rep.cpp"
00647 DECLARE_FUNDAMENTAL(long_type, long, "l");
00648 #line 778 "type_rep.cpp"
00649 DECLARE_FUNDAMENTAL(ulong_type, unsigned long, "ul");
00650 #line 779 "type_rep.cpp"
00651 DECLARE_FUNDAMENTAL(llong_type, long long, "j");
00652 #line 780 "type_rep.cpp"
00653 DECLARE_FUNDAMENTAL(ullong_type, unsigned long long, "uj");
00654 #line 781 "type_rep.cpp"
00655 DECLARE_FUNDAMENTAL(char_type, char, "c");
00656 #line 782 "type_rep.cpp"
00657 DECLARE_FUNDAMENTAL(schar_type, signed char, "sc");
00658 #line 783 "type_rep.cpp"
00659 DECLARE_FUNDAMENTAL(uchar_type, unsigned char, "uc");
00660 #line 784 "type_rep.cpp"
00661 DECLARE_FUNDAMENTAL(float_type, float, "f");
00662 #line 785 "type_rep.cpp"
00663 DECLARE_FUNDAMENTAL(double_type, double, "d");
00664 #line 786 "type_rep.cpp"
00665 DECLARE_FUNDAMENTAL(ldouble_type, long double, "e");
00666 #line 787 "type_rep.cpp"
00667 DECLARE_FUNDAMENTAL(bool_type, bool, "b");
00668 #line 788 "type_rep.cpp"
00669 DECLARE_FUNDAMENTAL(wchar_type, wchar_t, "w");
00670 #line 789 "type_rep.cpp"
00671 DECLARE_FUNDAMENTAL(void_type, void, "v");
00672 #line 790 "type_rep.cpp"
00673 DECLARE_FUNDAMENTAL(ctor_type, _, "O");
00674 #line 791 "type_rep.cpp"
00675 
00676 Type size_type = uint_type, ptrdiff_type = int_type;
00677 
00678 #line 793 "type_rep.cpp"
00679 
00682 bool
00683 parse_qualifier(Ptree* tree, Type& type)
00684 {
00685     switch (tree->What()) {
00686      case CONST:
00687         if (type.is_qualified(Type::q_Const))
00688             compile_error("multiple `const' not allowed [dcl.type p1]");
00689         type.add_qualifier(Type::q_Const);
00690         return true;
00691      case VOLATILE:
00692         if (type.is_qualified(Type::q_Volatile))
00693             compile_error("multiple `volatile' not allowed [dcl.type p1]");
00694         type.add_qualifier(Type::q_Volatile);
00695         return true;
00696      case RESTRICT:
00697         /* C99 allows this, 6.7.3p4 */
00698         type.add_qualifier(Type::q_Restrict);
00699         return true;
00700      default:
00701         return false;
00702     }
00703 }
00704 
00705 #line 853 "type_rep.cpp"
00706 
00707 
00708 Type_reader::Type_reader(Abstract_scope* scope, Ptree* tree,
00709                          bool is_type_declaration,
00710                          Ptree* name_for_anon)
00711     : mask(0), builtin(0), user_id(0), scope(scope),
00712       is_type_declaration(is_type_declaration),
00713       name_for_anon(name_for_anon)
00714 {
00715     user_id = read_type(tree);
00716     if (user_id) {
00717         if (builtin)
00718             compile_error("malformed type: identifier + built-in type");
00719 
00720         Symbol_name sym_name(user_id, scope, false);
00721         if (Symbol_pair p = sym_name.lookup_for_use(false)) {
00722             if (p.untag->get_kind() == Symbol::k_Typedef) {
00723                 user_type = dynamic_cast<Typedef_symbol*>(p.untag)->get_type();
00724                 builtin = &user_type;
00725             } else if (Type_symbol* ts = dynamic_cast<Type_symbol*>(p.untag)) {
00726                 user_type = ts->get_type();
00727                 builtin = &user_type;
00728             } else
00729                 compile_error("name `" + std::string(tree->ToString()) + "' is not a type");
00730         } else {
00731             compile_error("name `" + std::string(tree->ToString()) + "' is not defined");
00732         }
00733     }
00734 
00735     if (mask && builtin)
00736         compile_error("Invalid combination of type names");
00737 
00738     /* mask now contains all encountered words. */
00739     switch (mask) {
00740      case 0:
00741         if (builtin)
00742             result = *builtin;
00743         else
00744             compile_error("Missing type name");
00745         break;
00746      case iInt:
00747      case iSigned + iInt:
00748      case iSigned:
00749         result = int_type;
00750         break;
00751      case iUnsigned:
00752      case iUnsigned + iInt:
00753         result = uint_type;
00754         break;
00755      case iShort:
00756      case iShort + iInt:
00757      case iSigned + iShort:
00758      case iShort + iShort + iInt:
00759         result = short_type;
00760         break;
00761      case iUnsigned + iShort:
00762      case iUnsigned + iShort + iInt:
00763         result = ushort_type;
00764         break;
00765      case iLong:
00766      case iLong + iInt:
00767      case iSigned + iLong:
00768      case iSigned + iLong + iInt:
00769         result = long_type;
00770         break;
00771      case iUnsigned + iLong:
00772      case iUnsigned + iLong + iInt:
00773         result = ulong_type;
00774         break;
00775      case iLong + iLong:
00776      case iLong + iLong + iInt:
00777      case iSigned + iLong + iLong:
00778      case iSigned + iLong + iLong + iInt:
00779         result = llong_type;
00780         break;
00781      case iUnsigned + iLong + iLong:
00782      case iUnsigned + iLong + iLong + iInt:
00783         result = ullong_type;
00784         break;
00785      case iChar:
00786         result = char_type;
00787         break;
00788      case iUnsigned + iChar:
00789         result = uchar_type;
00790         break;
00791      case iSigned + iChar:
00792         result = schar_type;
00793         break;
00794      case iFloat:
00795         result = float_type;
00796         break;
00797      case iDouble:
00798         result = double_type;
00799         break;
00800      case iLong + iDouble:
00801         result = ldouble_type;
00802         break;
00803      default:
00804         compile_error("invalid combination of type names");
00805     }
00806 
00807     /* this happens for `typedef T& x; const x i;', 8.3.2p1 */
00808     if (result.get_kind() != Type::k_Reference)
00809         result.copy_qualifiers(qualifiers);
00810 }
00811 
00812 #line 958 "type_rep.cpp"
00813 
00821 Ptree*
00822 Type_reader::read_type(Ptree*const tree)
00823 {
00824     /* This sucks donkeyballs. */
00825     int kind = tree->What();
00826 
00827     if (kind == ntClassSpec) {
00828         /* class [name] [body] */
00829         if (builtin)
00830             compile_error("class-spec not allowed here");
00831 
00832         Default_class_adder adder;
00833         user_type = parse_class(tree, scope, name_for_anon, is_type_declaration, adder)->get_type();
00834         builtin = &user_type;
00835         return 0;
00836     } else if (kind == ntEnumSpec) {
00837         /* enum [name] [body] */
00838         if (builtin)
00839             compile_error("enum-spec not allowed here");
00840         user_type = parse_enum(tree, scope, name_for_anon);
00841         builtin = &user_type;
00842         return 0;
00843     } else if (!tree->IsLeaf()) {
00844         /* it is a list. Either it contains reserved words plus one
00845            user-defined identifier, or it is itself a user-defined id. */
00846         bool had_rw = false;
00847         Ptree* ptr = 0;
00848         for (Ptree* p = tree; p; p = p->Cdr()) {
00849             Ptree* r = read_type(p->Car());
00850             if (!r) {
00851                 had_rw = true;
00852             } else if (ptr) {
00853                 /* more than one non-reserved word. The whole thing
00854                    must be a name */
00855                 // don't assert here in case this is in a sizeof or operator
00856                 // assert(!had_rw);
00857                 if (had_rw)
00858                     compile_error("a weird type you gave me here");
00859                 return tree;
00860             } else {
00861                 ptr = r;
00862                 if (p->Cdr() && !p->Second()->IsLeaf() && p->Second()->Car()->Eq('<'))
00863                     /* template */
00864                     return tree;
00865             }
00866         }
00867         return ptr;
00868     } else {
00869         if (parse_qualifier(tree, qualifiers)) {
00870             /* nothing */
00871         } else if (kind == VOID) {
00872             if (builtin)
00873                 compile_error("`void' not allowed here");
00874             builtin = &void_type;
00875         } else if (kind == BOOLEAN) {
00876             if (builtin)
00877                 compile_error("`bool' not allowed here");
00878             builtin = &bool_type;
00879         } else if (kind == WCHAR_T) {
00880             if (builtin)
00881                 compile_error("`wchar_t' not allowed here");
00882             builtin = &wchar_type;
00883         } else {
00884             unsigned long now = 0;
00885             switch (tree->What()) {
00886              case INT:      now = iInt;      break;
00887              case UNSIGNED: now = iUnsigned; break;
00888              case SHORT:    now = iShort;    break;
00889              case LONG:     now = iLong;     break;
00890              case SIGNED:   now = iSigned;   break;
00891              case FLOAT:    now = iFloat;    break;
00892              case DOUBLE:   now = iDouble;   break;
00893              case CHAR:     now = iChar;     break;
00894              default:
00895                 return tree;
00896             }
00897             /* no word may appear more than twice */
00898             if (now && (mask & (7*now)) == 2*now)
00899                 compile_error(std::string("`") + tree->ToString() + "' not allowed here");
00900             mask += now;
00901         }
00902         return 0;
00903     }
00904 }
00905 
00906 #line 1050 "type_rep.cpp"
00907 
00926 Type
00927 parse_type(Ptree* tree, Abstract_scope* scope,
00928            Ptree* name_for_anon,
00929            bool is_type_declaration)
00930 {
00931     if (!tree) {
00932         return ctor_type;
00933     } else {
00934         Type_reader r(scope, tree, is_type_declaration, name_for_anon);
00935         return r.get_result();
00936     }
00937 }
00938 
00939 #line 1081 "type_rep.cpp"
00940 
00941 /*************************** Function_type_maker ***************************/
00942 
00948 Function_type_maker::Function_type_maker()
00949     : types("F")
00950 {
00951 }
00952 
00953 #line 1093 "type_rep.cpp"
00954 
00956 void
00957 Function_type_maker::add_parameter(Type t)
00958 {
00959     if (t.get_kind() == Type::k_Function)
00960         /* 13p3.3: function arguments of type "function" are actually
00961            "pointer to function" */
00962         t = t.get_unqualified_type().make_pointer_type();
00963     else if (t.get_kind() == Type::k_Array)
00964         /* 13p3.4: function arguments of type "array of X" are actually
00965            "pointer to X" */
00966         t = t.get_unqualified_type().get_basis_type().make_pointer_type();
00967     else
00968         /* 13p3.5: qualifiers don't matter */
00969         t = t.get_unqualified_type();
00970 
00971     types = t.encode_qualifiers(types);
00972 }
00973 
00974 #line 1112 "type_rep.cpp"
00975 
00977 void
00978 Function_type_maker::add_ellipsis()
00979 {
00980     types.append("E");
00981 }
00982 
00983 #line 1119 "type_rep.cpp"
00984 
00986 Type
00987 Function_type_maker::make_function_type(Type return_type) const
00988 {
00989     return return_type.encode_qualifiers(types + "_");
00990 }
00991 
00992 #line 1126 "type_rep.cpp"
00993 
00994 /****************** Function / Storage Class Specifiers ******************/
00995 
01002 bool
01003 parse_specifier(Ptree* tree, Storage_class_specifier* scs, Function_specifier_set* fs)
01004 {
01005     Storage_class_specifier this_scs = s_None;
01006     Function_specifier      this_fs  = f_None;
01007 
01008     /* 7.1.1p1: At most one storage-class-specifier shall appear in a given
01009        decl-specifier-seq. */
01010     /* no similar requirement exists for function specifiers; function
01011        specifiers can also be combined ("inline virtual" etc.) */
01012     switch(tree->What()) {
01013      case STATIC:
01014         this_scs = s_Static;
01015         break;
01016      case AUTO:
01017         this_scs = s_Auto;
01018         break;
01019      case REGISTER:
01020         this_scs = s_Register;
01021         break;
01022      case EXTERN:
01023         this_scs = s_Extern;
01024         break;
01025      case MUTABLE:
01026         this_scs = s_Mutable;
01027         break;
01028      case INLINE:
01029         this_fs = f_Inline;
01030         break;
01031      case VIRTUAL:
01032         this_fs = f_Virtual;
01033         break;
01034      case EXPLICIT:
01035         this_fs = f_Explicit;
01036         break;
01037      default:
01038         // HACK, because OpenC++ doesn't do it
01039         if (tree->Eq("explicit")) {
01040             this_fs = f_Explicit;
01041             break;
01042         }
01043         return false;
01044     }
01045     if (this_scs) {
01046         if (*scs != s_None)
01047             compile_error("Multiple storage class specifiers in one declaration not allowed, 7.1.1p1");
01048         *scs = this_scs;
01049     } else {
01050         *fs |= this_fs;
01051     }
01052     return true;
01053 }
01054 
01055 #line 1187 "type_rep.cpp"
01056 
01062 void
01063 parse_specifiers(Ptree* tree,
01064                  Storage_class_specifier* scs,
01065                  Function_specifier_set* fs)
01066 {
01067     if (!tree) {
01068         /* empty */
01069     } else if (tree->IsLeaf()) {
01070         if (!parse_specifier(tree, scs, fs))
01071             compile_error(std::string("Unknown function/storage class specifier `") + tree->ToString() + "'");
01072     } else {
01073         for (Ptree* p = tree; p; p = p->Cdr())
01074             parse_specifiers(p->Car(), scs, fs);
01075     }
01076 }
01077 
01078 #line 1208 "type_rep.cpp"
01079 
01081 const char*
01082 get_storage_specifier_name(Storage_class_specifier x)
01083 {
01084     static const char*const data[] = {
01085         "none",
01086         "auto",
01087         "parameter",
01088         "register",
01089         "static",
01090         "extern",
01091         "mutable",
01092         "member"
01093     };
01094     return data[x];
01095 }
01096 
01097 #line 1225 "type_rep.cpp"
01098 
01100 std::string
01101 get_function_specifier_name(Function_specifier_set s)
01102 {
01103     std::string data;
01104     if (s & f_Inline)
01105         data += " inline";
01106     if (s & f_Virtual)
01107         data += " virtual";
01108     if (s & f_Explicit)
01109         data += " explicit";
01110     if (s & f_Abstract)
01111         data += " abstract";
01112     if (data.length())
01113         return data.substr(1);
01114     else
01115         return std::string("none");
01116 }
01117 
01118 #line 1244 "type_rep.cpp"
01119 
01122 Type
01123 make_unary_function_type(Type arg, Type ret)
01124 {
01125     Function_type_maker ftm;
01126     ftm.add_parameter(arg);
01127     return ftm.make_function_type(ret);
01128 }
01129 
01130 #line 1254 "type_rep.cpp"
01131 
01132 Type
01133 make_binary_function_type(Type arg, Type brg, Type ret)
01134 {
01135     Function_type_maker ftm;
01136     ftm.add_parameter(arg);
01137     ftm.add_parameter(brg);
01138     return ftm.make_function_type(ret);
01139 }

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