00001
00002
00003 #include "stefan.h"
00004 #include "stefan_i.h"
00005
00006
00007 #line 43 "stefan.cpp"
00008 static bool
00009 change_alloc(char*& buffer, std::size_t olds, std::size_t news);
00010
00011 #line 103 "stefan.cpp"
00012 static bool
00013 process( char* file_name);
00014
00015 #line 157 "stefan.cpp"
00016 static void
00017 init_default_symbols(Abstract_scope* s);
00018 #line 29 "stefan.cpp"
00019 #ifdef USE_BACKTRACER
00020 #line 31 "stefan.cpp"
00021 #endif
00022 #line 32 "stefan.cpp"
00023
00024 #undef USE_REALLOC
00025 #line 34 "stefan.cpp"
00026
00027 static char cpp_name[] = "cpp";
00028 #line 36 "stefan.cpp"
00029
00030 static std::vector<char*> prepro_args;
00031 #line 38 "stefan.cpp"
00032 static std::vector<char*> input_files;
00033
00034 #line 42 "stefan.cpp"
00035
00036 static bool
00037 change_alloc(char*& buffer, std::size_t olds, std::size_t news)
00038 {
00039 using namespace std;
00040 char* p = new char[news];
00041 if (!p)
00042 return false;
00043 memcpy(p, buffer, olds > news ? news : olds);
00044 delete[] buffer;
00045 buffer = p;
00046 return true;
00047 }
00048
00049 #line 55 "stefan.cpp"
00050
00051
00052 Program_from_fd::Program_from_fd( char* filename, int fd)
00053 : Program(filename)
00054 {
00055 std::size_t buf_size = 10240;
00056 std::size_t amount_read = 0;
00057 bool verbose = Symbol_table::has_dump_flag('V');
00058
00059 #ifdef USE_REALLOC
00060 buf = static_cast<char*>(std::malloc(buf_size));
00061 #else
00062 buf = new char[buf_size];
00063 #endif
00064 if (verbose)
00065 std::cout << " allocated " << buf_size << " bytes at " << (void*)buf << "\n";
00066
00067 ssize_t n;
00068 while ((n = read(fd, buf + amount_read, buf_size - amount_read)) > 0) {
00069 amount_read += n;
00070 if (amount_read >= buf_size) {
00071
00072 #ifdef USE_REALLOC
00073 buf_size *= 2;
00074 char* p = static_cast<char*>(realloc(buf, buf_size));
00075 if (!p)
00076 compile_error("out of memory");
00077 #else
00078 std::size_t old_size = buf_size;
00079 buf_size *= 2;
00080 if (!change_alloc(buf, old_size, buf_size))
00081 compile_error("out of memory");
00082 #endif
00083
00084 if (verbose)
00085 std::cout << " allocated " << buf_size << " bytes at " << (void*)buf << "\n";
00086 }
00087 }
00088 if (n < 0)
00089 std::perror("read");
00090 }
00091
00092 #line 96 "stefan.cpp"
00093
00094
00095 Program_from_fd::~Program_from_fd()
00096 {
00097 std::free(buf);
00098 }
00099
00100 #line 102 "stefan.cpp"
00101
00102 static bool
00103 process( char* file_name)
00104 {
00105 std::size_t len = std::strlen(file_name);
00106 if (len >= 3 && (std::memcmp(file_name + len - 3, ".ii", 3) == 0
00107 || std::memcmp(file_name + len - 2, ".i", 2) == 0))
00108 {
00109 if (Symbol_table::has_dump_flag('v'))
00110 std::cout << "Parsing...\n";
00111 Source::instance().parse(file_name);
00112 return true;
00113 } else {
00114 int pipe_fd[2];
00115 if (pipe(pipe_fd) < 0) {
00116 std::perror("pipe");
00117 return false;
00118 }
00119
00120 int pid = fork();
00121 if (pid < 0) {
00122 std::perror("fork");
00123 return false;
00124 }
00125
00126 if (pid == 0) {
00127
00128 std::vector<char*> exec_args;
00129 exec_args.push_back(cpp_name);
00130 for (std::size_t i = 0; i < prepro_args.size(); ++i)
00131 exec_args.push_back(prepro_args[i]);
00132 exec_args.push_back(file_name);
00133 exec_args.push_back(0);
00134
00135 dup2(pipe_fd[1], 1);
00136 close(pipe_fd[1]);
00137
00138 execvp(cpp_name, &exec_args[0]);
00139 std::perror(cpp_name);
00140 std::exit(255);
00141 }
00142
00143
00144 close(pipe_fd[1]);
00145 Program* prog = new Program_from_fd(file_name, pipe_fd[0]);
00146 close(pipe_fd[0]);
00147 wait(0);
00148
00149 if (Symbol_table::has_dump_flag('v'))
00150 std::cout << "Parsing...\n";
00151 Source::instance().parse(file_name, prog);
00152 return true;
00153 }
00154 }
00155
00156 #line 156 "stefan.cpp"
00157
00158 static void
00159 init_default_symbols(Abstract_scope* s)
00160 {
00161 s->add_function_decl(s_Extern, 0, make_unary_function_type(size_type, void_type.make_pointer_type()),
00162 Symbol_name(Symbol_name::NEW_OPERATOR_NAME, s, Symbol_name::k_Alloc));
00163 s->add_function_decl(s_Extern, 0, make_unary_function_type(size_type, void_type.make_pointer_type()),
00164 Symbol_name(Symbol_name::ANEW_OPERATOR_NAME, s, Symbol_name::k_Alloc));
00165 s->add_function_decl(s_Extern, 0, make_unary_function_type(void_type.make_pointer_type(), void_type),
00166 Symbol_name(Symbol_name::DELETE_OPERATOR_NAME, s, Symbol_name::k_Alloc));
00167 s->add_function_decl(s_Extern, 0, make_unary_function_type(void_type.make_pointer_type(), void_type),
00168 Symbol_name(Symbol_name::ADELETE_OPERATOR_NAME, s, Symbol_name::k_Alloc));
00169 }
00170
00171 #line 169 "stefan.cpp"
00172
00173 int main(int argc, char** argv)
00174 {
00175 #ifdef USE_BACKTRACER
00176 initDebug();
00177 #endif
00178 try {
00179
00180 bool reading = true;
00181 while (*++argv) {
00182 char* p = *argv;
00183 if (reading && *p == '-') {
00184 if (p[1] == 0) {
00185 input_files.push_back("-");
00186 } else if (p[1] == '-' && p[2] == 0) {
00187 reading = false;
00188 } else {
00189 switch(p[1]) {
00190 case 'd':
00191 Symbol_table::dump_flags = &p[1];
00192 break;
00193 case 'D':
00194 case 'I':
00195 case 'U':
00196 prepro_args.push_back(p);
00197 break;
00198 default:
00199 std::cerr << "unrecognized option: " << p << "\n";
00200 return 1;
00201 }
00202 }
00203 } else {
00204 input_files.push_back(p);
00205 }
00206 }
00207
00208 if (input_files.empty()) {
00209 std::cerr << "No input files.\n";
00210 return 1;
00211 }
00212
00213
00214 Namespace_scope* nss = new Namespace_scope(0, std::string());
00215 init_default_symbols(nss);
00216 for (unsigned i = 0; i < input_files.size(); ++i) {
00217 if (Symbol_table::has_dump_flag('v'))
00218 std::cout << "Reading " << input_files[i] << "...\n";
00219 if (! process(input_files[i]))
00220 continue;
00221
00222 if (Symbol_table::has_dump_flag('v'))
00223 std::cout << "Starting annotator run...\n";
00224 Annotator reader(&Source::instance(), nss);
00225 reader.visit();
00226
00227 if (Symbol_table::has_dump_flag('v'))
00228 std::cout << "Filling in symbol names...\n";
00229 for (Symbol_table::Sym_it i = Symbol_table::get_instance().begin(); i != Symbol_table::get_instance().end(); ++i)
00230 if (Function_symbol* fsym = dynamic_cast<Function_symbol*>(i->second.untag))
00231 fsym->fill_in_mangled_names(false);
00232
00233 if (Symbol_table::has_dump_flag('t')) {
00234 Symbol_table::get_instance().dump(std::cout);
00235 }
00236 if (Symbol_table::has_dump_flag('s')) {
00237 std::cout << "Semantics of translation unit:\n";
00238 print_annotated_tree(std::cout, "# ", reader.get_output(), Symbol_table::has_dump_flag('c'));
00239 std::cout << "\n";
00240 }
00241 }
00242 }
00243 catch(std::exception& e) {
00244 std::cerr << "error[E]: " << e.what() << "\n";
00245 return 1;
00246 }
00247 catch(std::string& s) {
00248 std::cerr << "error[S]: " << s << "\n";
00249 return 1;
00250 }
00251 catch(const char* c) {
00252 std::cerr << "error[PC]: " << c << "\n";
00253 return 1;
00254 }
00255 catch(...) {
00256 std::cerr << "unknown flying object.\n";
00257 return 1;
00258 }
00259 if (Compile_error::had_errors) {
00260 std::cerr << "compilation had errors.\n";
00261 return 1;
00262 }
00263 }