00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "c_breeze.h"
00039 #include <stdarg.h>
00040
00041
00042
00043
00044
00045
00046
00047 unit_list CBZ::Program;
00048
00049
00050
00051 str_vec CBZ::Files;
00052
00053
00054 string CBZ::input_suffix = ".c";
00055 string CBZ::output_suffix = ".p.c";
00056
00057
00058 string CBZ::preproc;
00059
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
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
00068
00069
00070
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
00083
00084 float CBZ::VersionNumber ;
00085 string CBZ::VersionDate ;
00086 string CBZ::Executable;
00087 arch_info CBZ::ArchInfo;
00088
00089
00090 int CBZ::WarningLevel = 4;
00091
00092
00093 str_list * CBZ::cpp_flags;
00094
00095
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
00104
00105 string CBZ::PhaseName;
00106
00107 bool CBZ::OldStyleFunctionDefinition;
00108
00109
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
00123 bool CBZ::Preprocess = false;
00124 #else
00125 bool CBZ::Preprocess = true;
00126 #endif
00127 bool CBZ::ShowPreprocess = false;
00128
00129
00130
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
00139
00140 for (i=0; i < (int)Files.size(); ++i)
00141 if (Files[i] == nm)
00142 break;
00143
00144
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
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
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 {
00182 sprintf(array, "0x%x", value);
00183 }
00184 }
00185
00186
00187
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
00254
00255
00256 unsigned int CBZ::next_temp_id_seed = 0;
00257
00258 string CBZ::get_temp_id_str()
00259 {
00260
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
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
00281 idNode * pId = get_temp_id();
00282 pId->type( type );
00283
00284
00285 declNode * pDecl = new declNode( pId, declNode::AUTO, type, NULL, NULL );
00286 pDecl->decl_location( declNode::BLOCK );
00287 pId->decl( pDecl );
00288
00289
00290 containing_block->decls().push_back( pDecl );
00291
00292 return pId;
00293 }
00294