Changes in src/main.cc [35f9114:e6955b1]
- File:
-
- 1 edited
-
src/main.cc (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/main.cc
r35f9114 re6955b1 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 6 16:17:41201613 // Update Count : 21012 // Last Modified On : Sat Aug 20 12:52:22 2016 13 // Update Count : 403 14 14 // 15 15 16 16 #include <iostream> 17 17 #include <fstream> 18 #include <cstdlib> 19 #include <cstdio> 20 #include <getopt.h> 21 #include "Parser/Parser.h" 22 #include "Parser/ParseNode.h" 23 #include "Parser/LinkageSpec.h" 24 #include "SynTree/Declaration.h" 25 #include "SynTree/Visitor.h" 18 #include <signal.h> // signal 19 #include <getopt.h> // getopt 20 #include <execinfo.h> // backtrace, backtrace_symbols_fd 21 #include <cxxabi.h> // __cxa_demangle 22 23 using namespace std; 24 25 #include "Parser/lex.h" 26 #include "Parser/parser.h" 27 #include "Parser/TypedefTable.h" 26 28 #include "GenPoly/Lvalue.h" 27 29 #include "GenPoly/Specialize.h" … … 32 34 #include "CodeGen/FixNames.h" 33 35 #include "ControlStruct/Mutate.h" 34 #include "Tuples/Mutate.h"35 #include "Tuples/FunctionChecker.h"36 #include "SymTab/Mangler.h"37 #include "SymTab/Indexer.h"38 36 #include "SymTab/Validate.h" 39 37 #include "ResolvExpr/AlternativePrinter.h" 40 38 #include "ResolvExpr/Resolver.h" 41 39 #include "MakeLibCfa.h" 42 #include "InitTweak/Mutate.h"43 40 #include "InitTweak/GenInit.h" 44 41 #include "InitTweak/FixInit.h" 45 //#include "Explain/GenProlog.h"46 //#include "Try/Visit.h"47 48 #include "Common/SemanticError.h"49 42 #include "Common/UnimplementedError.h" 50 51 43 #include "../config.h" 52 44 53 45 using namespace std; 54 46 55 #define OPTPRINT(x) \ 56 if ( errorp ) std::cerr << x << std::endl; 57 58 static void parse( FILE * input, LinkageSpec::Type t, bool shouldExit = false ); 59 static void dump( std::list< Declaration * > & translationUnit, std::ostream & out = std::cout ); 60 47 #define OPTPRINT(x) if ( errorp ) cerr << x << endl; 48 49 50 LinkageSpec::Spec linkage = LinkageSpec::Cforall; 51 TypedefTable typedefTable; 52 DeclarationNode * parseTree = nullptr; // program parse tree 53 54 extern int yydebug; // set for -g flag (Grammar) 61 55 bool 62 56 astp = false, … … 66 60 exprp = false, 67 61 expraltp = false, 68 grammarp = false,69 62 libcfap = false, 70 63 nopreludep = false, … … 78 71 codegenp = false; 79 72 80 enum { Ast, Bbox, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, }; 81 82 static struct option long_opts[] = { 83 { "ast", no_argument, 0, Ast }, 84 { "before-box", no_argument, 0, Bbox }, 85 { "before-resolver", no_argument, 0, Bresolver }, 86 { "ctorinitfix", no_argument, 0, CtorInitFix }, 87 { "expr", no_argument, 0, Expr }, 88 { "expralt", no_argument, 0, ExprAlt }, 89 { "grammar", no_argument, 0, Grammar }, 90 { "libcfa", no_argument, 0, LibCFA }, 91 { "no-preamble", no_argument, 0, Nopreamble }, 92 { "parse", no_argument, 0, Parse }, 93 { "no-prototypes", no_argument, 0, Prototypes }, 94 { "resolver", no_argument, 0, Resolver }, 95 { "symbol", no_argument, 0, Symbol }, 96 { "tree", no_argument, 0, Tree }, 97 { "validate", no_argument, 0, Validate }, 98 { 0, 0, 0, 0 } 99 }; 100 101 int main( int argc, char *argv[] ) { 102 FILE *input; 103 std::ostream *output = &std::cout; 104 int long_index; 105 std::list< Declaration * > translationUnit; 106 const char *filename = NULL; 107 108 opterr = 0; // prevent getopt from printing error messages 109 110 int c; 111 while ( (c = getopt_long( argc, argv, "abBcefglnpqrstvyzD:F:", long_opts, &long_index )) != -1 ) { 112 switch ( c ) { 113 case Ast: 114 case 'a': // dump AST 115 astp = true; 116 break; 117 case Bresolver: 118 case 'b': // print before resolver steps 119 bresolvep = true; 120 break; 121 case 'B': // print before resolver steps 122 bboxp = true; 123 break; 124 case CtorInitFix: 125 case 'c': 126 ctorinitp = true; 127 break; 128 case Expr: 129 case 'e': // dump AST after expression analysis 130 exprp = true; 131 break; 132 case ExprAlt: 133 case 'f': // print alternatives for expressions 134 expraltp = true; 135 break; 136 case Grammar: 137 case 'g': // bison debugging info (grammar rules) 138 grammarp = true; 139 break; 140 case LibCFA: 141 case 'l': // generate libcfa.c 142 libcfap = true; 143 break; 144 case Nopreamble: 145 case 'n': // do not read preamble 146 nopreludep = true; 147 break; 148 case Prototypes: 149 case 'p': // generate prototypes for preamble functions 150 noprotop = true; 151 break; 152 case Parse: 153 case 'q': // dump parse tree 154 parsep = true; 155 break; 156 case Resolver: 157 case 'r': // print resolver steps 158 resolvep = true; 159 break; 160 case Symbol: 161 case 's': // print symbol table events 162 symtabp = true; 163 break; 164 case Tree: 165 case 't': // build in tree 166 treep = true; 167 break; 168 case 'v': // dump AST after decl validation pass 169 validp = true; 170 break; 171 case 'y': 172 errorp = true; 173 break; 174 case 'z': 175 codegenp = true; 176 break; 177 case 'D': // ignore -Dxxx 178 break; 179 case 'F': // source file-name without suffix 180 filename = optarg; 181 break; 182 case '?': 183 cout << "Unknown option: '" << (char)optopt << "'" << endl; 184 exit( EXIT_FAILURE ); 185 default: 186 abort(); 187 } // switch 188 } // while 73 static void parse_cmdline( int argc, char *argv[], const char *& filename ); 74 static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false ); 75 static void dump( list< Declaration * > & translationUnit, ostream & out = cout ); 76 77 void sigSegvBusHandler( int sig_num ) { 78 enum { Frames = 50 }; 79 void * array[Frames]; 80 int size = backtrace( array, Frames ); 81 82 cerr << "*CFA runtime error* program cfa-cpp terminated with " 83 << (sig_num == SIGSEGV ? "segment fault" : "bus error") 84 << " backtrace:" << endl; 85 86 char ** messages = backtrace_symbols( array, size ); 87 88 // skip first stack frame (points here) 89 for ( int i = 2; i < size - 2 && messages != nullptr; i += 1 ) { 90 char * mangled_name = nullptr, * offset_begin = nullptr, * offset_end = nullptr; 91 for ( char *p = messages[i]; *p; ++p ) { // find parantheses and +offset 92 if (*p == '(') { 93 mangled_name = p; 94 } else if (*p == '+') { 95 offset_begin = p; 96 } else if (*p == ')') { 97 offset_end = p; 98 break; 99 } // if 100 } // for 101 102 // if line contains symbol, attempt to demangle 103 if ( mangled_name && offset_begin && offset_end && mangled_name < offset_begin ) { 104 *mangled_name++ = '\0'; 105 *offset_begin++ = '\0'; 106 *offset_end++ = '\0'; 107 108 int status; 109 char * real_name = __cxxabiv1::__cxa_demangle( mangled_name, 0, 0, &status ); 110 if ( status == 0 ) { // demangling successful ? 111 cerr << "(" << i - 2 << ") " << messages[i] << " : " 112 << real_name << "+" << offset_begin << offset_end << endl; 113 114 } else { // otherwise, output mangled name 115 cerr << "(" << i - 2 << ") " << messages[i] << " : " 116 << mangled_name << "+" << offset_begin << offset_end << endl; 117 } // if 118 free( real_name ); 119 } else { // otherwise, print the whole line 120 cerr << "(" << i - 2 << ") " << messages[i] << endl; 121 } // if 122 } // for 123 free( messages ); 124 exit( EXIT_FAILURE ); 125 } // sigSegvBusHandler 126 127 int main( int argc, char * argv[] ) { 128 FILE * input; // use FILE rather than istream because yyin is FILE 129 ostream *output = & cout; 130 const char *filename = nullptr; 131 list< Declaration * > translationUnit; 132 133 signal( SIGSEGV, sigSegvBusHandler ); 134 signal( SIGBUS, sigSegvBusHandler ); 135 136 parse_cmdline( argc, argv, filename ); // process command-line arguments 189 137 190 138 try { 191 139 // choose to read the program from a file or stdin 192 if ( optind < argc ) { 140 if ( optind < argc ) { // any commands after the flags ? => input file name 193 141 input = fopen( argv[ optind ], "r" ); 194 if ( ! input ) { 195 std::cout << "Error: cannot open " << argv[ optind ] << std::endl; 196 exit( EXIT_FAILURE ); 197 } // if 142 assertf( input, "cannot open %s\n", argv[ optind ] ); 198 143 // if running cfa-cpp directly, might forget to pass -F option (and really shouldn't have to) 199 if ( filename == NULL) filename = argv[ optind ];144 if ( filename == nullptr ) filename = argv[ optind ]; 200 145 // prelude filename comes in differently 201 146 if ( libcfap ) filename = "prelude.cf"; 202 147 optind += 1; 203 } else { 148 } else { // no input file name 204 149 input = stdin; 205 150 // if running cfa-cpp directly, might forget to pass -F option. Since this takes from stdin, pass 206 151 // a fake name along 207 if ( filename == NULL) filename = "stdin";208 } // if 209 210 if ( optind < argc ) { 152 if ( filename == nullptr ) filename = "stdin"; 153 } // if 154 155 if ( optind < argc ) { // any commands after the flags and input file ? => output file name 211 156 output = new ofstream( argv[ optind ] ); 212 157 } // if 213 214 Parser::get_parser().set_debug( grammarp );215 158 216 159 // read in the builtins, extras, and the prelude … … 218 161 // -l is for initial build ONLY and builtins.cf is not in the lib directory so access it here. 219 162 FILE * builtins = fopen( libcfap | treep ? "builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" ); 220 if ( builtins == NULL ) { 221 std::cerr << "Error: cannot open builtins.cf" << std::endl; 222 exit( EXIT_FAILURE ); 223 } // if 163 assertf( builtins, "cannot open builtins.cf\n" ); 224 164 parse( builtins, LinkageSpec::Compiler ); 225 165 226 166 // read the extra prelude in, if not generating the cfa library 227 167 FILE * extras = fopen( libcfap | treep ? "extras.cf" : CFA_LIBDIR "/extras.cf", "r" ); 228 if ( extras == NULL ) { 229 std::cerr << "Error: cannot open extras.cf" << std::endl; 230 exit( EXIT_FAILURE ); 231 } // if 168 assertf( extras, "cannot open extras.cf\n" ); 232 169 parse( extras, LinkageSpec::C ); 233 170 … … 235 172 // read the prelude in, if not generating the cfa library 236 173 FILE * prelude = fopen( treep ? "prelude.cf" : CFA_LIBDIR "/prelude.cf", "r" ); 237 if ( prelude == NULL ) { 238 std::cerr << "Error: cannot open prelude.cf" << std::endl; 239 exit( EXIT_FAILURE ); 240 } // if 241 174 assertf( prelude, "cannot open prelude.cf\n" ); 242 175 parse( prelude, LinkageSpec::Intrinsic ); 243 176 } // if 244 177 } // if 245 178 246 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp);179 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, yydebug ); 247 180 248 181 if ( parsep ) { 249 Parser::get_parser().get_parseTree()->printList( std::cout ); 250 Parser::get_parser().freeTree(); 251 return 0; 252 } // if 253 254 buildList( Parser::get_parser().get_parseTree(), translationUnit ); 255 256 Parser::get_parser().freeTree(); 182 parseTree->printList( cout ); 183 delete parseTree; 184 return 0; 185 } // if 186 187 buildList( parseTree, translationUnit ); 188 delete parseTree; 189 parseTree = nullptr; 190 257 191 if ( astp ) { 258 192 dump( translationUnit ); … … 268 202 269 203 if ( expraltp ) { 270 ResolvExpr::AlternativePrinter printer( std::cout );204 ResolvExpr::AlternativePrinter printer( cout ); 271 205 acceptAll( translationUnit, printer ); 272 206 return 0; … … 300 234 dump( translationUnit ); 301 235 return 0; 302 } 236 } // if 303 237 304 238 // fix ObjectDecl - replaces ConstructorInit nodes … … 308 242 dump ( translationUnit ); 309 243 return 0; 310 } 244 } // if 311 245 312 246 OPTPRINT("instantiateGenerics") … … 322 256 dump( translationUnit ); 323 257 return 0; 324 } 258 } // if 325 259 OPTPRINT( "box" ) 326 260 GenPoly::box( translationUnit ); … … 334 268 CodeGen::generate( translationUnit, *output, ! noprotop ); 335 269 336 if ( output != & std::cout ) {270 if ( output != &cout ) { 337 271 delete output; 338 272 } // if 339 273 } catch ( SemanticError &e ) { 340 274 if ( errorp ) { 341 std::cerr << "---AST at error:---" << std::endl;342 dump( translationUnit, std::cerr );343 std::cerr << std::endl << "---End of AST, begin error message:---\n" << std::endl;344 } 345 e.print( std::cerr );346 if ( output != & std::cout ) {275 cerr << "---AST at error:---" << endl; 276 dump( translationUnit, cerr ); 277 cerr << endl << "---End of AST, begin error message:---\n" << endl; 278 } // if 279 e.print( cerr ); 280 if ( output != &cout ) { 347 281 delete output; 348 282 } // if 349 283 return 1; 350 284 } catch ( UnimplementedError &e ) { 351 std::cout << "Sorry, " << e.get_what() << " is not currently implemented" << std::endl;352 if ( output != & std::cout ) {285 cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl; 286 if ( output != &cout ) { 353 287 delete output; 354 288 } // if 355 289 return 1; 356 290 } catch ( CompilerError &e ) { 357 std::cerr << "Compiler Error: " << e.get_what() << std::endl;358 std::cerr << "(please report bugs to " << std::endl;359 if ( output != & std::cout ) {291 cerr << "Compiler Error: " << e.get_what() << endl; 292 cerr << "(please report bugs to " << endl; 293 if ( output != &cout ) { 360 294 delete output; 361 295 } // if … … 367 301 } // main 368 302 369 static void parse( FILE * input, LinkageSpec::Type linkage, bool shouldExit ) { 370 Parser::get_parser().set_linkage( linkage ); 371 Parser::get_parser().parse( input ); 303 void parse_cmdline( int argc, char * argv[], const char *& filename ) { 304 enum { Ast, Bbox, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, }; 305 306 static struct option long_opts[] = { 307 { "ast", no_argument, 0, Ast }, 308 { "before-box", no_argument, 0, Bbox }, 309 { "before-resolver", no_argument, 0, Bresolver }, 310 { "ctorinitfix", no_argument, 0, CtorInitFix }, 311 { "expr", no_argument, 0, Expr }, 312 { "expralt", no_argument, 0, ExprAlt }, 313 { "grammar", no_argument, 0, Grammar }, 314 { "libcfa", no_argument, 0, LibCFA }, 315 { "no-preamble", no_argument, 0, Nopreamble }, 316 { "parse", no_argument, 0, Parse }, 317 { "no-prototypes", no_argument, 0, Prototypes }, 318 { "resolver", no_argument, 0, Resolver }, 319 { "symbol", no_argument, 0, Symbol }, 320 { "tree", no_argument, 0, Tree }, 321 { "validate", no_argument, 0, Validate }, 322 { 0, 0, 0, 0 } 323 }; // long_opts 324 int long_index; 325 326 opterr = 0; // (global) prevent getopt from printing error messages 327 328 int c; 329 while ( (c = getopt_long( argc, argv, "abBcefglnpqrstvyzD:F:", long_opts, &long_index )) != -1 ) { 330 switch ( c ) { 331 case Ast: 332 case 'a': // dump AST 333 astp = true; 334 break; 335 case Bresolver: 336 case 'b': // print before resolver steps 337 bresolvep = true; 338 break; 339 case 'B': // print before resolver steps 340 bboxp = true; 341 break; 342 case CtorInitFix: 343 case 'c': 344 ctorinitp = true; 345 break; 346 case Expr: 347 case 'e': // dump AST after expression analysis 348 exprp = true; 349 break; 350 case ExprAlt: 351 case 'f': // print alternatives for expressions 352 expraltp = true; 353 break; 354 case Grammar: 355 case 'g': // bison debugging info (grammar rules) 356 yydebug = true; 357 break; 358 case LibCFA: 359 case 'l': // generate libcfa.c 360 libcfap = true; 361 break; 362 case Nopreamble: 363 case 'n': // do not read preamble 364 nopreludep = true; 365 break; 366 case Prototypes: 367 case 'p': // generate prototypes for preamble functions 368 noprotop = true; 369 break; 370 case Parse: 371 case 'q': // dump parse tree 372 parsep = true; 373 break; 374 case Resolver: 375 case 'r': // print resolver steps 376 resolvep = true; 377 break; 378 case Symbol: 379 case 's': // print symbol table events 380 symtabp = true; 381 break; 382 case Tree: 383 case 't': // build in tree 384 treep = true; 385 break; 386 case 'v': // dump AST after decl validation pass 387 validp = true; 388 break; 389 case 'y': 390 errorp = true; 391 break; 392 case 'z': 393 codegenp = true; 394 break; 395 case 'D': // ignore -Dxxx 396 break; 397 case 'F': // source file-name without suffix 398 filename = optarg; 399 break; 400 case '?': 401 assertf( false, "Unknown option: '%c'\n", (char)optopt ); 402 default: 403 abort(); 404 } // switch 405 } // while 406 } // parse_cmdline 407 408 static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit ) { 409 extern int yyparse( void ); 410 extern FILE * yyin; 411 extern int yylineno; 412 413 ::linkage = linkage; // set globals 414 yyin = input; 415 yylineno = 1; 416 typedefTable.enterScope(); 417 int parseStatus = yyparse(); 372 418 373 419 fclose( input ); 374 if ( shouldExit || Parser::get_parser().get_parseStatus()!= 0 ) {375 exit( Parser::get_parser().get_parseStatus());420 if ( shouldExit || parseStatus != 0 ) { 421 exit( parseStatus ); 376 422 } // if 377 } 423 } // parse 378 424 379 425 static bool notPrelude( Declaration * decl ) { 380 426 return ! LinkageSpec::isBuiltin( decl->get_linkage() ); 381 } 382 383 static void dump( std::list< Declaration * > & translationUnit, std::ostream & out ) { 384 std::list< Declaration * > decls; 427 } // notPrelude 428 429 static void dump( list< Declaration * > & translationUnit, ostream & out ) { 430 list< Declaration * > decls; 431 385 432 if ( noprotop ) { 386 filter( translationUnit.begin(), translationUnit.end(), 387 std::back_inserter( decls ), notPrelude ); 433 filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), notPrelude ); 388 434 } else { 389 435 decls = translationUnit; 390 } 436 } // if 391 437 392 438 printAll( decls, out ); 393 439 deleteAll( translationUnit ); 394 } 395 440 } // dump 396 441 397 442 // Local Variables: //
Note:
See TracChangeset
for help on using the changeset viewer.