C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

typenode.cc

Go to the documentation of this file.
00001 // $Id: typenode.cc,v 1.6 2003/08/11 17:18:27 abrown Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2000 University of Texas at Austin
00008 // 
00009 //  Samuel Z. Guyer
00010 //  Daniel A. Jimenez
00011 //  Calvin Lin
00012 // 
00013 //  Permission is hereby granted, free of charge, to any person
00014 //  obtaining a copy of this software and associated documentation
00015 //  files (the "Software"), to deal in the Software without
00016 //  restriction, including without limitation the rights to use, copy,
00017 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00018 //  of the Software, and to permit persons to whom the Software is
00019 //  furnished to do so, subject to the following conditions:
00020 //  
00021 //  The above copyright notice and this permission notice shall be
00022 //  included in all copies or substantial portions of the Software.
00023 //  
00024 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00028 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00029 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00030 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00031 //  THE SOFTWARE.
00032 //
00033 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00034 //  Computer Science for inspiring parts of the C-Breeze design.
00035 //
00036 // ----------------------------------------------------------------------
00037 
00038 #include "c_breeze.h"
00039 #include "sue_complete_walker.h"
00040 
00041 // --------------------------------------------------------------------
00042 // Constructors
00043 // --------------------------------------------------------------------
00044 typeNode::typeNode(NodeType typ, Type_qualifiers tq, typeNode * subtype,
00045                    const Coord coord)
00046   : Node(typ, coord),
00047     _type(subtype),
00048     _type_qualifiers(tq),
00049     _alloc_size(-1),
00050     _alloc_align(-1)
00051 {}
00052 
00053 // ------------------------------------------------------------
00054 //   deep_base_type
00055 // ------------------------------------------------------------
00056 
00057 typeNode * typeNode::deep_base_type()
00058 {
00059   typeNode * chain = this;
00060 
00061   while (chain->is_derived())
00062     chain = chain->type();
00063 
00064   return chain;
00065 }
00066 
00067 // ------------------------------------------------------------
00068 // SetBaseType from complex-types.c
00069 // ------------------------------------------------------------
00070 
00071 // SetBaseType:
00072 //   Follow chain of pointers, arrays, and functions to bottom,
00073 //   then set the base type, which should be NULL coming in.
00074 //
00075 //   Example:
00076 //         In: base=int, complex=(Ptr (Array NULL))
00077 //                               [pointer to an array of ???]
00078 //       Out:  (Ptr (Array int))
00079 //               [pointer to an array of int]
00080 //       In: base=void, complex=(Ptr (Func (int) NULL))
00081 //                              [pointer to a function from int to ???]
00082 //       Out:  (Ptr (Func (int) void))
00083 //             [pointer to a function from int to void]
00084 //
00085 
00086 void typeNode::set_base_type(typeNode * base)
00087 {
00088   typeNode * cur_type = this;
00089 
00090   // -- Traverse down the derived types Ptr, Array, Func...
00091 
00092   while ( cur_type->is_derived() && cur_type->type() )
00093     cur_type = cur_type->type();
00094 
00095   if (cur_type->is_derived())
00096     cur_type->type(base);
00097 }
00098 
00099 typeNode * typeNode::set_base_type_and(typeNode * base)
00100 {
00101   set_base_type(base);
00102   return this;
00103 }
00104 
00105 // ------------------------------------------------------------
00106 // FinishType from complex-types.c
00107 // ------------------------------------------------------------
00108 //   FinishType performs consistency checks that can't be conveniently 
00109 //   expressed in the grammar, some time after the type has been
00110 //   constructed.  It is called for both declarations and type names
00111 //   (such as in a cast or sizeof expression). 
00112 
00113 //   WARNING:  FinishType may be run more than once on a type, so it
00114 //   should not blindly make unnecessary changes.
00115 
00116 void typeNode::finish()
00117 {
00118   typeNode * deepbasetype = deep_base_type();
00119   Type_qualifiers basetq = deepbasetype->type_qualifiers();
00120 
00121   if (basetq & INLINE) {
00122     if (CBZ::ANSIOnly)
00123       CBZ::SyntaxError("inline keyword not allowed with -ansi switch");
00124     else
00125       if (typ() != Func)
00126         CBZ::Warning(1, coord(),
00127                      "inline qualifier applies only to functions");
00128       else
00129         // -- If the basetype has inline, add it to the current type...
00130         add_type_qualifiers(INLINE);
00131 
00132     // -- Remove it from the base type
00133     deepbasetype->remove_type_qualifiers(INLINE);
00134   }
00135 }
00136 
00137 typeNode * typeNode::finish_and()
00138 {
00139   finish();
00140   return this;
00141 }
00142 
00143 // ------------------------------------------------------------
00144 //   verify_sue_complete
00145 // ------------------------------------------------------------
00146 
00147 void typeNode::verify_sue_complete()
00148 {
00149   sue_complete_walker::check(this);
00150 }
00151 
00152 // ------------------------------------------------------------
00153 // Handle typedefs
00154 // ------------------------------------------------------------
00155 
00156 typeNode * typeNode::no_tdef_type()
00157 {
00158   typeNode * out = this;
00159 
00160   out = out->type();
00161   if (out)
00162     out = out->follow_tdefs();
00163 
00164   return out;
00165 }
00166 
00167 typeNode * typeNode::follow_tdefs()
00168 {
00169   typeNode * out = this;
00170 
00171   while (out && out->typ() == Tdef) {
00172     tdefNode * td = (tdefNode *) out;
00173     out = td->def();
00174   }
00175 
00176   return out;
00177 }
00178 // ----------------------------------------------------------------------
00179 //
00180 //  TypeEqual -- implements type equivalence according to K&R2 section
00181 //               A8.10 (fix: what section in ANSI standard?)
00182 //
00183 //     strict_toplevel and strict_recursive control whether 
00184 //        const and volatile (and other type qualifiers specified
00185 //      in TQ_COMPATIBLE) are ignored:
00186 //
00187 //      !strict_toplevel ==> type quals are ignored when comparing
00188 //                           roots of type1 and type2
00189 //        !strict_recursive => type quals are ignored when comparing
00190 //                           children of type1 and type2
00191 //      
00192 // ----------------------------------------------------------------------
00193 
00194 typeNode * typeNode::unwind_tdefs(Type_qualifiers & the_tq)
00195 {
00196   typeNode * cur = this;
00197   tdefNode * tdef;
00198 
00199   // -- Traverse typedef chain collecting type qualifiers
00200   the_tq = type_qualifiers();
00201 
00202   while (cur->typ() == Tdef) {
00203     tdef = (tdefNode *) cur;
00204     cur = tdef->def();
00205     the_tq = Type_qualifiers(the_tq | cur->type_qualifiers());
00206   }
00207 
00208   return cur;
00209 }
00210 
00211 // -- equal_to provides more control: the two booleans control whether or
00212 //    not certain qualifiers are taken into account when comparing the
00213 //    current node (strict_toplevel) and sub-nodes (strict_recursive).
00214 
00215 bool typeNode::equal_to(typeNode * node1, typeNode * node2,
00216                         bool strict_toplevel, bool strict_recursive)
00217 {
00218   Type_qualifiers tq1 = NONE;
00219   Type_qualifiers tq2 = NONE;
00220 
00221   assert(node1 && node2);
00222 
00223   node1 = node1->unwind_tdefs(tq1);
00224   node2 = node2->unwind_tdefs(tq2);
00225 
00226   if (!strict_toplevel) {
00227     // -- Remove any qualifiers that do not affect type compatibility...
00228     tq1 = Type_qualifiers(tq1 & COMPATIBLE);
00229     tq2 = Type_qualifiers(tq2 & COMPATIBLE);
00230   }
00231   if (tq1 != tq2)
00232     return false;
00233   if (node1->typ() != node2->typ())
00234     // pnav 
00235     // check if comparing an array to a pointer
00236     // if so, fall through to the virtual type comparison call
00237     if ((node1->typ() != Ptr && node1->typ() != Array)
00238         || (node2->typ() != Array && node2->typ() != Ptr))
00239       return false;
00240 
00241   // -- Virtual: call the appropriate type comparison...
00242   return node1->qualified_equal_to(node2, strict_toplevel, strict_recursive);
00243 }
00244 
00245 // --- Default case: fail
00246 
00247 bool typeNode::qualified_equal_to(typeNode * node2, bool strict_toplevel, bool strict_recursive)
00248 {
00249   CBZ::Fail(__FILE__, __LINE__, "type_equal(): Unrecognized type.");
00250   return false;
00251 }
00252 
00253 // ------------------------------------------------------------
00254 //  Type qualifier
00255 // ------------------------------------------------------------
00256 
00257 string typeNode::type_qualifiers_name(Type_qualifiers the_tq)
00258 {
00259   string out;
00260   bool not_empty = false;
00261 
00262   if (the_tq & CONST) {
00263     out += "const";
00264     not_empty = true;
00265   }
00266 
00267   if (the_tq & VOLATILE) {
00268     if (not_empty)
00269       out += " ";
00270     out += "volatile";
00271     not_empty = true;
00272   }
00273 
00274   if (the_tq & INLINE) {
00275     if (not_empty)
00276       out += " ";
00277     out += "inline";
00278     not_empty = true;
00279   }
00280 
00281   return out;
00282 }
00283 
00284 // ------------------------------------------------------------
00285 // Type conversions
00286 // ------------------------------------------------------------
00287 
00288 typeNode * typeNode::integral_promotions(typeNode * old_type)
00289 {
00290   if (old_type->typ() == Prim) {
00291     primNode * p = (primNode *) old_type;
00292 
00293     basic_type & b = p->basic();
00294 
00295     if (b.is_char()) {
00296       if (b.is_unsigned())
00297         return (typeNode *) new primNode(basic_type::UInt);
00298       else
00299         return (typeNode *) new primNode(basic_type::SInt);
00300     }
00301 
00302     if (b.is_int() && b.is_short()) {
00303       if (b.is_unsigned())
00304         return (typeNode *) new primNode(basic_type::UInt);
00305       else
00306         return (typeNode *) new primNode(basic_type::SInt);
00307     }
00308 
00309     // This is added in only for convenience
00310 
00311     if (b.is_float())
00312       return (typeNode *) new primNode(basic_type::Double);
00313   }
00314 
00315   return 0;
00316 }
00317 
00318 pair<typeNode *, typeNode *>
00319 typeNode::usual_arithmetic_conversions(typeNode * left,
00320                                        typeNode * right)
00321 {
00322   pair<typeNode *, typeNode *> out;
00323   basic_type lbasic;
00324   basic_type rbasic;
00325 
00326   out.first = 0;
00327   out.second = 0;
00328 
00329   // -- Get the basic types, if possible
00330 
00331   if (left->typ() == Prim)
00332     lbasic = ((primNode *)left)->basic();
00333 
00334   if (right->typ() == Prim)
00335     rbasic = ((primNode *)right)->basic();
00336 
00337   // -- Apply the rules...
00338 
00339   // -- If either type is long double, the other is converted to long double
00340 
00341   if (lbasic == basic_type::LongDouble) {
00342     out.second = new primNode(basic_type::LongDouble);
00343     return out;
00344   }
00345 
00346   if (rbasic == basic_type::LongDouble) {
00347     out.first = new primNode(basic_type::LongDouble);
00348     return out;
00349   }
00350 
00351   // -- If either type is double, the other is converted to double
00352 
00353   if (lbasic == basic_type::Double) {
00354     out.second = new primNode(basic_type::Double);
00355     return out;
00356   }
00357 
00358   if (rbasic == basic_type::Double) {
00359     out.first = new primNode(basic_type::Double);
00360     return out;
00361   }
00362 
00363   // -- If either type is float, the other is converted to float
00364 
00365   if (lbasic == basic_type::Float) {
00366     out.second = new primNode(basic_type::Float);
00367     return out;
00368   }
00369 
00370   if (rbasic == basic_type::Float) {
00371     out.first = new primNode(basic_type::Float);
00372     return out;
00373   }
00374 
00375   // -- Perform the integral promotions...
00376 
00377   out.first  = integral_promotions(left);
00378   out.second = integral_promotions(right);
00379 
00380   if (out.first)
00381     lbasic = ((primNode *)left)->basic();
00382 
00383   if (out.second)
00384     rbasic = ((primNode *)right)->basic();
00385 
00386   // -- The integral rules...
00387 
00388   // -- If either type is unsigned long, the other is converted to unsigned long
00389 
00390   if (lbasic == basic_type::ULong) {
00391     out.second = new primNode(basic_type::ULong);
00392     return out;
00393   }
00394 
00395   if (rbasic == basic_type::ULong) {
00396     out.first = new primNode(basic_type::ULong);
00397     return out;
00398   }
00399 
00400   // -- If one type is unsigned int and the other is long int,
00401   //    convert both to unsigned long (to be safe)
00402 
00403   if (((lbasic == basic_type::SLong) &&
00404        (rbasic == basic_type::UInt)) ||
00405       ((lbasic == basic_type::UInt) &&
00406        (rbasic == basic_type::SLong)))
00407     {
00408       out.first  = new primNode(basic_type::ULong);
00409       out.second = new primNode(basic_type::ULong);
00410       return out;
00411     }
00412 
00413   // -- If either type is long, the other is converted to long
00414 
00415   if (rbasic == basic_type::SLong) {
00416     out.first = new primNode(basic_type::SLong);
00417     return out;
00418   }
00419 
00420   if (lbasic == basic_type::SLong) {
00421     out.second = new primNode(basic_type::SLong);
00422     return out;
00423   }
00424 
00425   // -- If either type is unsigned int, the other is converted to unsigned int
00426 
00427   if (rbasic == basic_type::UInt) {
00428     out.first = new primNode(basic_type::UInt);
00429     return out;
00430   }
00431 
00432   if (lbasic == basic_type::UInt) {
00433     out.second = new primNode(basic_type::UInt);
00434     return out;
00435   }
00436 
00437   return out;
00438 }
00439 
00440 // ------------------------------------------------------------
00441 // Output
00442 // ------------------------------------------------------------
00443 
00444 void typeNode::output(output_context & ct, Node * parent)
00445 {
00446   output_type(ct, parent, Left, type_qualifiers());
00447   output_type(ct, parent, Right, type_qualifiers());
00448 }
00449 
00450 // ------------------------------------------------------------
00451 // Destructor
00452 // ------------------------------------------------------------
00453 
00454 typeNode::~typeNode()
00455 {
00456 }

Generated on August 27, 2003
Back to the C-Breeze home page