00001
00002
00003 #include "type_rep.h"
00004 #include "type_rep_i.h"
00005
00006
00007 #line 139 "type_rep.cpp"
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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;
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
00261 ++n;
00262 break;
00263 case 'M':
00264
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
00278 while (++n < s.length() && isdigit(s[n]))
00279 ++n;
00280 return s.substr(n);
00281 case 'F':
00282
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':
00290 case 'h':
00291 case 'l':
00292 case 'j':
00293 case 'c':
00294 case 'f':
00295 case 'd':
00296 case 'e':
00297 case 'b':
00298 case 'w':
00299 case 'v':
00300 case 'E':
00301 case 'O':
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
00519
00520
00521
00522
00523
00524 if (code == "c" || code == "sc" || code == "uc" || code == "h" || code == "uh")
00525 return int_type;
00526
00527
00528
00529
00530
00531
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
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
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
00571
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
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
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
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;
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
00616 if (!t2.is_qualified(q_Const))
00617 had_const = false;
00618 } else if (t1.is_more_qualified_than(t2)) {
00619
00620 return false;
00621 } else if (!had_const) {
00622
00623 return false;
00624 }
00625 }
00626
00627
00628
00629 return t1.is_same_unqualified_type(t2);
00630 }
00631 #line 767 "type_rep.cpp"
00632
00633
00634
00635 #define DECLARE_FUNDAMENTAL(name,type,encoding) Type name(encoding)
00636 #line 771 "type_rep.cpp"
00637
00638
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
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
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
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
00825 int kind = tree->What();
00826
00827 if (kind == ntClassSpec) {
00828
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
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
00845
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
00854
00855
00856
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
00864 return tree;
00865 }
00866 }
00867 return ptr;
00868 } else {
00869 if (parse_qualifier(tree, qualifiers)) {
00870
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
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
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
00961
00962 t = t.get_unqualified_type().make_pointer_type();
00963 else if (t.get_kind() == Type::k_Array)
00964
00965
00966 t = t.get_unqualified_type().get_basis_type().make_pointer_type();
00967 else
00968
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
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
01009
01010
01011
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
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
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 }