Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/main.cc

    r74330e7 re0bd0f9  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb  8 08:33:50 2020
    13 // Update Count     : 633
     12// Last Modified On : Thu Aug 22 13:06:18 2019
     13// Update Count     : 605
    1414//
    1515
     
    1717#include <execinfo.h>                       // for backtrace, backtrace_symbols
    1818#include <getopt.h>                         // for no_argument, optind, geto...
     19#include <signal.h>                         // for signal, SIGABRT, SIGSEGV
    1920#include <cassert>                          // for assertf
    2021#include <cstdio>                           // for fopen, FILE, fclose, stdin
    2122#include <cstdlib>                          // for exit, free, abort, EXIT_F...
    22 #include <csignal>                          // for signal, SIGABRT, SIGSEGV
    2323#include <cstring>                          // for index
    2424#include <fstream>                          // for ofstream
     
    2828#include <list>                             // for list
    2929#include <string>                           // for char_traits, operator<<
    30 
    31 using namespace std;
    32 
    3330
    3431#include "CompilationState.h"
     
    5653#include "InitTweak/GenInit.h"              // for genInit
    5754#include "MakeLibCfa.h"                     // for makeLibCfa
     55#include "Parser/LinkageSpec.h"             // for Spec, Cforall, Intrinsic
    5856#include "Parser/ParseNode.h"               // for DeclarationNode, buildList
    5957#include "Parser/TypedefTable.h"            // for TypedefTable
     
    6159#include "ResolvExpr/Resolver.h"            // for resolve
    6260#include "SymTab/Validate.h"                // for validate
    63 #include "SynTree/LinkageSpec.h"            // for Spec, Cforall, Intrinsic
     61#include "SynTree/TopLvalue.h"              // for assertTopLvalue, clearInn...
    6462#include "SynTree/Declaration.h"            // for Declaration
    6563#include "SynTree/Visitor.h"                // for acceptAll
     
    6765#include "Virtual/ExpandCasts.h"            // for expandCasts
    6866
     67
     68using namespace std;
    6969
    7070static void NewPass( const char * const name ) {
     
    9696DeclarationNode * parseTree = nullptr;                                  // program parse tree
    9797
    98 static bool waiting_for_gdb = false;                                    // flag to set cfa-cpp to wait for gdb on start
    99 
    100 static string PreludeDirector = "";
     98static std::string PreludeDirector = "";
    10199
    102100static void parse_cmdline( int argc, char *argv[] );
     
    105103
    106104static void backtrace( int start ) {                                    // skip first N stack frames
    107         enum { Frames = 50, };                                                          // maximum number of stack frames
     105        enum { Frames = 50 };
    108106        void * array[Frames];
    109         size_t size = ::backtrace( array, Frames );
     107        int size = ::backtrace( array, Frames );
    110108        char ** messages = ::backtrace_symbols( array, size ); // does not demangle names
    111109
     
    114112
    115113        // skip last 2 stack frames after main
    116         for ( unsigned int i = start; i < size - 2 && messages != nullptr; i += 1 ) {
     114        for ( int i = start; i < size - 2 && messages != nullptr; i += 1 ) {
    117115                char * mangled_name = nullptr, * offset_begin = nullptr, * offset_end = nullptr;
    118 
    119                 for ( char * p = messages[i]; *p; p += 1 ) {    // find parantheses and +offset
     116                for ( char *p = messages[i]; *p; ++p ) {        // find parantheses and +offset
    120117                        if ( *p == '(' ) {
    121118                                mangled_name = p;
     
    155152} // backtrace
    156153
    157 #define SIGPARMS int sig __attribute__(( unused )), siginfo_t * sfp __attribute__(( unused )), ucontext_t * cxt __attribute__(( unused ))
    158 
    159 static void Signal( int sig, void (*handler)(SIGPARMS), int flags ) {
    160         struct sigaction act;
    161 
    162         act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
    163         act.sa_flags = flags;
    164 
    165         if ( sigaction( sig, &act, nullptr ) == -1 ) {
    166             cerr << "*CFA runtime error* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl;
    167             _exit( EXIT_FAILURE );
    168         } // if
    169 } // Signal
    170 
    171 static void sigSegvBusHandler( SIGPARMS ) {
    172         if ( sfp->si_addr == nullptr ) {
    173                 cerr << "Null pointer (nullptr) dereference." << endl;
    174         } else {
    175                 cerr << (sig == SIGSEGV ? "Segment fault" : "Bus error") << " at memory location " << sfp->si_addr << "." << endl
    176                          << "Possible cause is reading outside the address space or writing to a protected area within the address space with an invalid pointer or subscript." << endl;
    177         } // if
     154static void sigSegvBusHandler( int sig_num ) {
     155        cerr << "*CFA runtime error* program cfa-cpp terminated with "
     156                 <<     (sig_num == SIGSEGV ? "segment fault" : "bus error")
     157                 << "." << endl;
    178158        backtrace( 2 );                                                                         // skip first 2 stack frames
     159        //_exit( EXIT_FAILURE );
    179160        abort();                                                                                        // cause core dump for debugging
    180161} // sigSegvBusHandler
    181162
    182 static void sigFpeHandler( SIGPARMS ) {
    183         const char * msg;
    184 
    185         switch ( sfp->si_code ) {
    186           case FPE_INTDIV: case FPE_FLTDIV: msg = "divide by zero"; break;
    187           case FPE_FLTOVF: msg = "overflow"; break;
    188           case FPE_FLTUND: msg = "underflow"; break;
    189           case FPE_FLTRES: msg = "inexact result"; break;
    190           case FPE_FLTINV: msg = "invalid operation"; break;
    191           default: msg = "unknown";
    192         } // choose
    193         cerr << "Computation error " << msg << " at location " << sfp->si_addr << endl
    194                  << "Possible cause is constant-expression evaluation invalid." << endl;
    195         backtrace( 2 );                                                                         // skip first 2 stack frames
    196         abort();                                                                                        // cause core dump for debugging
    197 } // sigFpeHandler
    198 
    199 static void sigAbortHandler( SIGPARMS ) {
     163static void sigAbortHandler( __attribute__((unused)) int sig_num ) {
    200164        backtrace( 6 );                                                                         // skip first 6 stack frames
    201         Signal( SIGABRT, (void (*)(SIGPARMS))SIG_DFL, SA_SIGINFO );     // reset default signal handler
     165        signal( SIGABRT, SIG_DFL);                                                      // reset default signal handler
    202166        raise( SIGABRT );                                                                       // reraise SIGABRT
    203167} // sigAbortHandler
     168
    204169
    205170int main( int argc, char * argv[] ) {
     
    208173        list< Declaration * > translationUnit;
    209174
    210         Signal( SIGSEGV, sigSegvBusHandler, SA_SIGINFO );
    211         Signal( SIGBUS, sigSegvBusHandler, SA_SIGINFO );
    212         Signal( SIGFPE, sigFpeHandler, SA_SIGINFO );
    213         Signal( SIGABRT, sigAbortHandler, SA_SIGINFO );
    214 
    215         // cout << "main" << endl;
     175        signal( SIGSEGV, sigSegvBusHandler );
     176        signal( SIGBUS, sigSegvBusHandler );
     177        signal( SIGABRT, sigAbortHandler );
     178
     179        // std::cout << "main" << std::endl;
    216180        // for ( int i = 0; i < argc; i += 1 ) {
    217         //      cout << '\t' << argv[i] << endl;
     181        //      std::cout << '\t' << argv[i] << std::endl;
    218182        // } // for
    219183
    220184        parse_cmdline( argc, argv );                                            // process command-line arguments
    221185        CodeGen::FixMain::setReplaceMain( !nomainp );
    222 
    223         if ( waiting_for_gdb ) {
    224                 cerr << "Waiting for gdb" << endl;
    225                 cerr << "run :" << endl;
    226                 cerr << "  gdb attach " << getpid() << endl;
    227                 raise(SIGSTOP);
    228         } // if
    229186
    230187        try {
     
    294251                Stats::Time::StopBlock();
    295252
     253                //std::cerr << "Post-Parse Check" << std::endl;
     254                clearInnerLvalue( translationUnit );
     255                assertTopLvalue( translationUnit );
     256
    296257                // add the assignment statement after the initialization of a type parameter
    297258                PASS( "Validate", SymTab::validate( translationUnit, symtabp ) );
     
    312273                } // if
    313274
     275                assertTopLvalue( translationUnit );
    314276                PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) );
     277                assertTopLvalue( translationUnit );
    315278                PASS( "Fix Names", CodeGen::fixNames( translationUnit ) );
     279                assertTopLvalue( translationUnit );
    316280                PASS( "Gen Init", InitTweak::genInit( translationUnit ) );
     281                assertTopLvalue( translationUnit );
    317282                PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( translationUnit ) );
     283                assertTopLvalue( translationUnit );
    318284                if ( libcfap ) {
    319285                        // generate the bodies of cfa library functions
     
    339305                } // if
    340306
     307                assertTopLvalue( translationUnit );
     308
    341309                PASS( "Resolve", ResolvExpr::resolve( translationUnit ) );
    342310                if ( exprp ) {
     
    345313                } // if
    346314
     315                clearInnerLvalue( translationUnit );
     316                assertTopLvalue( translationUnit );
     317
    347318                // fix ObjectDecl - replaces ConstructorInit nodes
    348319                PASS( "Fix Init", InitTweak::fix( translationUnit, buildingLibrary() ) );
     320                clearInnerLvalue( translationUnit );
     321                assertTopLvalue( translationUnit );
    349322                if ( ctorinitp ) {
    350323                        dump ( translationUnit );
     
    353326
    354327                PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused
     328                assertTopLvalue( translationUnit );
    355329
    356330                PASS( "Translate EHM" , ControlStruct::translateEHM( translationUnit ) );
     331                assertTopLvalue( translationUnit );
    357332
    358333                PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) );
     334                clearInnerLvalue( translationUnit );
     335                assertTopLvalue( translationUnit );
    359336
    360337                PASS( "Convert Specializations",  GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded
     338                clearInnerLvalue( translationUnit );
     339                assertTopLvalue( translationUnit );
    361340
    362341                PASS( "Expand Tuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this?
     342                assertTopLvalue( translationUnit );
    363343
    364344                if ( tuplep ) {
     
    368348
    369349                PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM
     350                assertTopLvalue( translationUnit );
    370351
    371352                PASS( "Instantiate Generics", GenPoly::instantiateGeneric( translationUnit ) );
     
    374355                        return EXIT_SUCCESS;
    375356                } // if
    376 
     357                clearInnerLvalue( translationUnit );
     358                assertTopLvalue( translationUnit );
    377359                PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) );
     360                clearInnerLvalue( translationUnit );
     361                assertTopLvalue( translationUnit );
    378362
    379363                if ( bboxp ) {
     
    382366                } // if
    383367                PASS( "Box", GenPoly::box( translationUnit ) );
     368                clearInnerLvalue( translationUnit );
     369                assertTopLvalue( translationUnit );
    384370
    385371                if ( bcodegenp ) {
     
    393379
    394380                CodeTools::fillLocations( translationUnit );
     381                assertTopLvalue( translationUnit );
    395382                PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) );
    396383
     
    424411                return EXIT_FAILURE;
    425412        } catch ( ... ) {
    426                 exception_ptr eptr = current_exception();
     413                std::exception_ptr eptr = std::current_exception();
    427414                try {
    428415                        if (eptr) {
    429                                 rethrow_exception(eptr);
     416                                std::rethrow_exception(eptr);
    430417                        } else {
    431                                 cerr << "Exception Uncaught and Unknown" << endl;
    432                         } // if
    433                 } catch(const exception& e) {
    434                         cerr << "Uncaught Exception \"" << e.what() << "\"\n";
     418                                std::cerr << "Exception Uncaught and Unknown" << std::endl;
     419                        } // if
     420                } catch(const std::exception& e) {
     421                        std::cerr << "Uncaught Exception \"" << e.what() << "\"\n";
    435422                } // try
    436423                return EXIT_FAILURE;
     
    443430
    444431
    445 static const char optstring[] = ":c:ghlLmNnpP:S:twW:D:";
     432static const char optstring[] = ":hlLmNnpP:S:twW:D:";
    446433
    447434enum { PreludeDir = 128 };
    448435static struct option long_opts[] = {
    449         { "colors", required_argument, nullptr, 'c' },
    450         { "gdb", no_argument, nullptr, 'g' },
    451436        { "help", no_argument, nullptr, 'h' },
    452437        { "libcfa", no_argument, nullptr, 'l' },
     
    467452
    468453static const char * description[] = {
    469         "diagnostic color: never, always, or auto.",          // -c
    470         "wait for gdb to attach",                             // -g
    471         "print help message",                                 // -h
    472         "generate libcfa.c",                                  // -l
    473         "generate line marks",                                // -L
    474         "do not replace main",                                // -m
    475         "do not generate line marks",                         // -N
    476         "do not read prelude",                                // -n
     454        "print help message",                                                           // -h
     455        "generate libcfa.c",                                                            // -l
     456        "generate line marks",                                                          // -L
     457        "do not replace main",                                                          // -m
     458        "do not generate line marks",                                           // -N
     459        "do not read prelude",                                                          // -n
    477460        "generate prototypes for prelude functions",            // -p
    478         "print",                                              // -P
     461        "print",                                                                                        // -P
    479462        "<directory> prelude directory for debug/nodebug",      // no flag
    480463        "<option-list> enable profiling information:\n          counters,heap,time,all,none", // -S
    481         "building cfa standard lib",                          // -t
    482         "",                                                   // -w
    483         "",                                                   // -W
    484         "",                                                   // -D
     464        "build in tree",                                                                        // -t
     465        "",                                                                                                     // -w
     466        "",                                                                                                     // -W
     467        "",                                                                                                     // -D
    485468}; // description
    486469
     
    550533        while ( (c = getopt_long( argc, argv, optstring, long_opts, nullptr )) != -1 ) {
    551534                switch ( c ) {
    552                   case 'c':                                                                             // diagnostic colors
    553                         if ( strcmp( optarg, "always" ) == 0 ) {
    554                                 ErrorHelpers::colors = ErrorHelpers::Colors::Always;
    555                         } else if ( strcmp( optarg, "never" ) == 0 ) {
    556                                 ErrorHelpers::colors = ErrorHelpers::Colors::Never;
    557                         } else if ( strcmp( optarg, "auto" ) == 0 ) {
    558                                 ErrorHelpers::colors = ErrorHelpers::Colors::Auto;
    559                         } // if
    560                         break;
    561535                  case 'h':                                                                             // help message
    562536                        usage( argv );                                                          // no return
     
    598572                        Stats::parse_params( optarg );
    599573                        break;
    600                   case 't':                                                                             // building cfa stdlib
     574                  case 't':                                                                             // build in tree
    601575                        treep = true;
    602                         break;
    603                   case 'g':                                                                             // wait for gdb
    604                         waiting_for_gdb = true;
    605576                        break;
    606577                  case 'w':                                                                             // suppress all warnings, hidden
Note: See TracChangeset for help on using the changeset viewer.