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  

c_breeze.cc

Go to the documentation of this file.
00001 // $Id: c_breeze.cc,v 1.14 2003/08/11 17:19:28 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 <stdarg.h>
00040 
00041 // ------------------------------------------------------------
00042 //  Static configuration
00043 // ------------------------------------------------------------
00044 
00045 // -- The parsed program
00046 
00047 unit_list CBZ::Program;
00048 
00049 // -- Global list of all files
00050 
00051 str_vec CBZ::Files;
00052 
00053 // -- expected suffixes for input and output files 
00054 string CBZ::input_suffix            = ".c";
00055 string CBZ::output_suffix           = ".p.c";
00056 
00057   // -- preprocessor command lines
00058 string CBZ::preproc; // Set to either of these, or by -P 
00059 //string CBZ::default_preproc         = "gcc -E -x c -U__USE_POSIX199309 ";
00060 #ifdef sun
00061 string CBZ::default_preproc         = "gcc -nostdinc -I/lusr/gnu/lib/gcc-lib/sparc-sun-solaris2.7/2.95.2/include -x c -E -D__C_BREEZE__ -U__GNUC__ ";
00062 #else
00063 // hack to work around idiotic decision to upgrade to gcc 3.0.3
00064 string CBZ::default_preproc         = "/usr/bin/gcc-2.95 -x c -E -D__C_BREEZE__ -U__GNUC__ ";
00065 #endif
00066 string CBZ::gcc_preproc
00067         // djimenez
00068         // this is a hack.  gcc headers recognize these attributes,
00069         // but C-Breeze gets confused and thinks they're undeclared
00070         // variables.  By making them constants, everyone is happy.
00071 #ifdef sun
00072 = "gcc -nostdinc -I/lusr/gnu/lib/gcc-lib/sparc-sun-solaris2.7/2.95.2/include -x c -E -D__C_BREEZE__ -D__QI__=1 -D__HI__=1 -D__SI__=1 -D__DI__=1  -D__word__=1 -D__extension__='' -D__const='' -D__restrict='' -D__printf__='' -D__builtin_va_list='long int'";
00073 #else
00074 = "/usr/bin/gcc -x c -E -D__C_BREEZE__ -D__QI__=1 -D__HI__=1 -D__SI__=1 -D__DI__=1  -D__word__=1 -D__extension__='' -D__const='' -D__restrict='' -D__printf__='' -D__builtin_va_list='long int'";
00075 #endif
00076 #ifdef sun
00077 string CBZ::ansi_preproc            = "gcc -nostdinc -I/lusr/gnu/lib/gcc-lib/sparc-sun-solaris2.7/2.95.2/include -E -ansi -x c";
00078 #else
00079 string CBZ::ansi_preproc            = "/usr/bin/gcc -E -ansi -x c";
00080 #endif
00081 
00082 // -- Basic Global Variables 
00083 
00084 float CBZ::VersionNumber ;
00085 string CBZ::VersionDate ;
00086 string CBZ::Executable;
00087 arch_info CBZ::ArchInfo;
00088 
00089 // -- default warning level 
00090 int CBZ::WarningLevel               = 4;
00091 
00092 // -- CPP flags
00093 str_list * CBZ::cpp_flags;
00094 
00095 // -- Current status in parsing
00096 
00097 unitNode * CBZ::current_unit;
00098 int CBZ::current_file;
00099 int CBZ::current_line;
00100 int CBZ::current_offset;
00101 text_list CBZ::pragmas;
00102 
00103 // -- Current phase in processing
00104 
00105 string CBZ::PhaseName;
00106 
00107 bool CBZ::OldStyleFunctionDefinition;
00108 
00109 // -- Command Line Flags
00110 
00111 bool CBZ::QuietlyIgnore     = false;
00112 bool CBZ::DebugLex          = false;
00113 bool CBZ::PrintSymTables    = false;
00114 bool CBZ::TrackInsertSymbol = false;
00115 bool CBZ::PrintLineOffset   = false;
00116 bool CBZ::IgnoreLineDirectives = false;
00117 bool CBZ::ANSIOnly          = false;
00118 bool CBZ::GCCisms          = false;
00119 bool CBZ::NoRegAlloc            = false;
00120 bool CBZ::FormatReadably    = false;
00121 #if (defined _WIN32) && ! (defined _MSC_VER)
00122 // no popen support on Windows
00123 bool CBZ::Preprocess        = false;
00124 #else
00125 bool CBZ::Preprocess        = true;
00126 #endif
00127 bool CBZ::ShowPreprocess    = false;
00128 
00129 // ------------------------------------------------------------
00130 // -- Was SetFile in c4.l
00131 // ------------------------------------------------------------
00132 
00133 void CBZ::set_file(const char *name, int line, bool is_new_file)
00134 {
00135   int i;
00136   string nm(name);
00137 
00138   // -- Look for this file in the list..
00139 
00140   for (i=0; i < (int)Files.size(); ++i)
00141     if (Files[i] == nm)
00142       break;
00143 
00144   // -- If not there, add it...
00145 
00146   if (i == Files.size())
00147     Files.push_back(nm);
00148   else
00149     if (is_new_file)
00150       Warning(5, string("Header file `") + nm + 
00151               string("' included more than once."));
00152 
00153   current_file = i;
00154 }
00155 
00156 // -- Returns true is the current file was included...
00157 
00158 bool CBZ::is_file_included()
00159 {
00160   if (Files.size() == 0)
00161     return false;
00162   else
00163     return (Files[current_file] != current_unit->input_file());
00164 }
00165 
00166 // -- Was CharToText in print-ast.c
00167 
00168 void CBZ::char_to_text(char *array, unsigned char value)
00169 {
00170   if (value < ' ') {
00171     static const char *names[32] = {
00172       "nul","soh","stx","etx","eot","enq","ack","bel",
00173       "\\b", "\\t", "\\n", "\\v", "ff", "cr", "so", "si",
00174       "dle","dc1","dc2","dc3","dc4","nak","syn","etb",
00175       "can","em", "sub","esc","fs", "gs", "rs", "us" };
00176     sprintf(array, "0x%02x (%s)", value, names[value]);
00177   } else if (value < 0x7f) {
00178     sprintf(array, "'%c'", value);
00179   } else if (value == 0x7f) {
00180     strcpy(array, "0x7f (del)");
00181   } else { /* value >= 0x80 */
00182     sprintf(array, "0x%x", value);
00183   }
00184 }
00185 
00186 // ------------------------------------------------------------
00187 //  Errors and warnings
00188 // ------------------------------------------------------------
00189 
00190 void CBZ::Fail(const string file, int line, const string msg)
00191 {
00192   cerr << "Assertion failed in " << file << ", line " << line << endl;
00193   cerr << "    " << msg << endl;
00194 
00195   if (PhaseName == "Parsing")
00196     cerr << "Input: " << CBZ::Files[CBZ::current_file] << ", line " << current_line << endl;
00197 
00198   abort();
00199 }
00200 
00201 void CBZ::SyntaxError(string s)
00202 {
00203   CBZ::current_unit->inc_errors();
00204   cerr << CBZ::Files[CBZ::current_file] << ":" << current_line << ": Error: " << s << endl;
00205 }
00206 
00207 void CBZ::Warning(int level, string s)
00208 {
00209   if (level <= WarningLevel) {
00210     CBZ::current_unit->inc_warnings();
00211     cerr << CBZ::Files[CBZ::current_file] << ":" << current_line << ": Warning: " << s << endl;
00212   }
00213 }
00214 
00215 void CBZ::SyntaxError(Coord c, string s)
00216 {
00217   CBZ::current_unit->inc_errors();
00218   cerr << c << ": Error: " << s << endl;
00219 }
00220 
00221 void CBZ::Warning(int level, Coord c, string s)
00222 {
00223   if (level <= WarningLevel) {
00224     CBZ::current_unit->inc_warnings();
00225     cerr << c << ": Warning: " << s << endl;
00226   }
00227 }
00228 
00229 void CBZ::WarnAboutPrecedence(unsigned int op_id, exprNode * the_expr)
00230 {
00231   if (the_expr->typ() == Binary && ! the_expr->parenthesized()) {
00232     unsigned int subop_id = ((binaryNode *)the_expr)->op()->id();
00233 
00234     if (op_id == Operator::OROR && subop_id == Operator::ANDAND)
00235       CBZ::Warning(4, the_expr->coord(),
00236                    string("suggest parentheses around && in operand of ||"));
00237     else if ((op_id == '|' || op_id == '^') && 
00238              (subop_id == '+' || subop_id == '-' || subop_id == '&' || subop_id == '^') &&
00239              op_id != subop_id)
00240       CBZ::Warning(4, the_expr->coord(),
00241                    string("suggest parentheses around arithmetic in operand of ") + 
00242                    string(1,(char)op_id));
00243   }
00244 }
00245 
00246 void CBZ::Error(Coord c, string s)
00247 {
00248   CBZ::current_unit->inc_errors();
00249   cerr << c << ": Error: " << s << endl;
00250 }
00251 
00252 // ---------------------------------------------------------
00253 // temporary name stuff
00254 // ---------------------------------------------------------
00255 
00256 unsigned int CBZ::next_temp_id_seed = 0;
00257 
00258 string CBZ::get_temp_id_str()
00259 {
00260         // make a string with the next temp id
00261         const int bufsize = 20;
00262         char buf[ bufsize ];
00263 #ifdef _WIN32
00264         _snprintf( buf, bufsize, "T%d", next_temp_id_seed++ );
00265 #else
00266         snprintf( buf, bufsize, "T%d", next_temp_id_seed++ );
00267 #endif
00268         buf[bufsize-1] = 0;
00269         return string( buf );
00270 }
00271 
00272 idNode * CBZ::get_temp_id()
00273 {
00274         // make a new id node
00275         return new idNode( get_temp_id_str().c_str() );
00276 }
00277 
00278 idNode * CBZ::get_temp_var( blockNode * containing_block, typeNode * type )
00279 {
00280         // make a temp id
00281         idNode * pId = get_temp_id();
00282         pId->type( type );
00283 
00284         // a declaration for it
00285         declNode * pDecl = new declNode( pId, declNode::AUTO, type, NULL, NULL );
00286         pDecl->decl_location( declNode::BLOCK );
00287         pId->decl( pDecl );
00288 
00289         // add this to the block
00290         containing_block->decls().push_back( pDecl );
00291 
00292         return pId;
00293 }
00294 

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