Changeset b87a5ed


Ignore:
Timestamp:
May 16, 2015, 3:36:19 PM (8 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
a32b204
Parents:
b8508a2
Message:

licencing: first groups of files

Files:
2 deleted
38 edited

Legend:

Unmodified
Added
Removed
  • INSTALL

    rb8508a2 rb87a5ed  
    22======================================
    33
    4 Cforall is built using GNU Make and the GNU Autoconf system.  It also
    5 requires g++ version 3, bison and flex.  On systems where GNU Make is
    6 the default make it may suffice to build the system by entering the
    7 commands
     4Cforall is built using GNU Make and the GNU Autoconf system.  It also requires
     5g++ version 3, bison and flex.  On systems where GNU Make is the default make
     6it may suffice to build the system by entering the commands
    87
    98        ./configure
     
    1312Options for 'configure'
    1413-----------------------
    15 The script 'configure' accepts many command line arguments.  Run
    16 './configure --help' to see a list of all of them.  This document
    17 attempts to summarize the most useful arguments.
     14The script 'configure' accepts many command line arguments.  Run './configure
     15--help' to see a list of all of them.  This document attempts to summarize the
     16most useful arguments.
    1817
    19 --prefix=/some/directory controls the path prefix common to all
    20 installed cfa-cc components.  Some components will be installed in
    21 /some/directory/bin, others in /some/directory/lib.  If unspecified,
    22 this defaults to /usr/local.
     18--prefix=/some/directory controls the path prefix common to all installed
     19cfa-cc components.  Some components will be installed in /some/directory/bin,
     20others in /some/directory/lib.  If unspecified, this defaults to /usr/local.
    2321
    24 --with-backend-compiler=PROGRAM specifies the installed path of gcc
    25 3.2.  It defaults to the first command named 'gcc' in the current
    26 PATH.
     22--with-backend-compiler=PROGRAM specifies the installed path of gcc 3.2.  It
     23defaults to the first command named 'gcc' in the current PATH.
    2724
    28 cfa-cc itself is built with the version of g++ specified by the
    29 environment variable CXX.  If CXX is unset, cfa-cc is built using the
    30 first command named 'g++' in the current PATH.
     25cfa-cc itself is built with the version of g++ specified by the environment
     26variable CXX.  If CXX is unset, cfa-cc is built using the first command named
     27'g++' in the current PATH.
  • Makefile.in

    rb8508a2 rb87a5ed  
    3838        $(top_srcdir)/libcfa/Makefile.in \
    3939        $(top_srcdir)/translator/Makefile.in \
    40         $(top_srcdir)/translator/examples/Makefile.in AUTHORS COPYING \
    41         ChangeLog INSTALL NEWS install-sh missing mkinstalldirs
     40        $(top_srcdir)/translator/examples/Makefile.in AUTHORS INSTALL \
     41        TODO install-sh missing mkinstalldirs
    4242ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    4343am__aclocal_m4_deps = $(top_srcdir)/configure.in
     
    225225          case '$(am__configure_deps)' in \
    226226            *$$dep*) \
    227               echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
    228               $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
     227              echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
     228              $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
    229229                && exit 0; \
    230230              exit 1;; \
    231231          esac; \
    232232        done; \
    233         echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
     233        echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
    234234        $(am__cd) $(top_srcdir) && \
    235           $(AUTOMAKE) --gnu Makefile
     235          $(AUTOMAKE) --foreign Makefile
    236236.PRECIOUS: Makefile
    237237Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
  • configure

    rb8508a2 rb87a5ed  
    25932593
    25942594# Define the identity of the package.
    2595  PACKAGE=cfa
    2596  VERSION=1.0
     2595 PACKAGE='cfa-cc'
     2596 VERSION='1.0'
    25972597
    25982598
     
    26332633
    26342634
    2635 
     2635                # do not follow GNU standard
    26362636ac_config_headers="$ac_config_headers config.h"
    26372637
     
    64726472
    64736473
    6474 { $as_echo "$as_me:${as_lineno-$LINENO}: result: The Cforall translator is now configured for your system" >&5
    6475 $as_echo "The Cforall translator is now configured for your system" >&6; }
     6474{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Cforall configuraton completed. Type \"make install\"." >&5
     6475$as_echo "Cforall configuraton completed. Type \"make install\"." >&6; }
  • configure.in

    rb8508a2 rb87a5ed  
    22AC_CONFIG_SRCDIR([translator/main.cc])
    33
    4 AM_INIT_AUTOMAKE(cfa, 1.0)
     4AM_INIT_AUTOMAKE([foreign])             # do not follow GNU standard
    55AM_CONFIG_HEADER(config.h)
    66
     
    105105dnl Final text
    106106
    107 AC_MSG_RESULT(The Cforall translator is now configured for your system)
    108 dnl AC_MSG_RESULT()
    109 dnl AC_MSG_RESULT(Perhaps you'd like to inspect the created Makefiles)
     107AC_MSG_RESULT(Cforall configuraton completed. Type "make install".)
  • driver/Makefile.in

    rb8508a2 rb87a5ed  
    1 ###
    2 ### This file is part of the Cforall project
    3 ###
    4 ### $Id: Makefile.in,v 1.5 2005/08/26 19:16:54 rcbilson Exp $
    5 ###
     1######################### -*- Mode: Makefile-Gmake -*- ########################$
     2##
     3## Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     4##
     5## The contents of this file are covered under the licence agreement in the
     6## file "LICENCE" distributed with Cforall.
     7##
     8## Makefile.in --
     9##
     10## Author           : Peter A. Buhr
     11## Created On       : Sat May 16 07:50:15 2015
     12## Last Modified By : Peter A. Buhr
     13## Last Modified On : Sat May 16 08:34:55 2015
     14## Update Count     : 4
     15###############################################################################
    616
    717CXX=@CXX@
     
    1121
    1222SRCS:=cfa.cc cc1.cc
    13 OBJECTS:=$(SRCS:.cc=.o)
    14 DEPS:=$(SRCS:.cc=.d)
     23OBJECTS:=${SRCS:.cc=.o}
     24DEPS:=${SRCS:.cc=.d}
    1525
    1626all: cfa cc1
    1727
    1828cfa: cfa.o
    19         $(CXX) $< -o $@
     29        ${CXX} $< -o $@
    2030
    2131cc1 : cc1.o
    22         $(CXX) $< -o $@
     32        ${CXX} $< -o $@
    2333
    2434install: cfa cc1
    25         $(INSTALL) -d @CFA_BINDIR@
    26         $(INSTALL) -d @CFA_LIBDIR@
    27         $(INSTALL) cc1 @CFA_LIBDIR@
    28         $(INSTALL) cfa @CFA_BINDIR@
     35        ${INSTALL} -d @CFA_BINDIR@
     36        ${INSTALL} -d @CFA_LIBDIR@
     37        ${INSTALL} cc1 @CFA_LIBDIR@
     38        ${INSTALL} cfa @CFA_BINDIR@
    2939
    3040clean:
    31         rm -f cfa cc1 $(OBJECTS) $(DEPS) core
     41        rm -f cfa cc1 ${OBJECTS} ${DEPS} core
  • driver/cc1.cc

    rb8508a2 rb87a5ed  
    1 //                              -*- Mode: C++ -*-
    2 //
    3 // CForall Version 1.0, Copyright (C) Peter A. Buhr 2005
    4 //
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
    57// cc1.cc --
    6 // 
    7 // Author           : Richard C. Bilson
     8//
     9// Author           : Peter A. Buhr
    810// Created On       : Fri Aug 26 14:23:51 2005
    911// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Thu May 14 13:24:45 2015
    11 // Update Count     : 43
     12// Last Modified On : Sat May 16 07:42:14 2015
     13// Update Count     : 49
    1214//
    13 
    1415
    1516#include <iostream>
     
    1819#include <string>
    1920using std::string;
    20 #include <cstdio>                                       // stderr, stdout, perror, fprintf
    21 #include <cstdlib>                                      // getenv, exit, mkstemp
    22 #include <unistd.h>                                     // execvp, fork, unlink
    23 #include <sys/wait.h>                                   // wait
    24 
    25 #include "config.h"                                     // configure info
     21#include <cstdio>                                                                               // stderr, stdout, perror, fprintf
     22#include <cstdlib>                                                                              // getenv, exit, mkstemp
     23#include <unistd.h>                                                                             // execvp, fork, unlink
     24#include <sys/wait.h>                                                                   // wait
     25
     26#include "config.h"                                                                             // configure info
    2627
    2728
     
    2930
    3031
    31 string compiler_name( GCC_PATH );                       // path/name of C compiler
     32string compiler_name( GCC_PATH );                                               // path/name of C compiler
    3233
    3334string D__GCC_BPREFIX__( "-D__GCC_BPREFIX__=" );
     
    3940
    4041bool prefix( string arg, string pre ) {
    41     return arg.substr( 0, pre.size() ) == pre;
     42        return arg.substr( 0, pre.size() ) == pre;
    4243} // prefix
    4344
    4445
    4546void checkEnv( const char *args[], int &nargs ) {
    46     char *value;
    47 
    48     value = getenv( "__COMPILER__" );
    49     if ( value != NULL ) {
    50         compiler_name = value;
    51 #ifdef __DEBUG_H__
    52         cerr << "env arg:\"" << compiler_name << "\"" << endl;
    53 #endif // __DEBUG_H__
    54     } // if
    55 
    56     value = getenv( "__GCC_MACHINE__" );
    57     if ( value != NULL ) {
    58         args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along
    59 #ifdef __DEBUG_H__
    60         cerr << "env arg:\"" << args[nargs] << "\"" << endl;
    61 #endif // __DEBUG_H__
     47        char *value;
     48
     49        value = getenv( "__COMPILER__" );
     50        if ( value != NULL ) {
     51                compiler_name = value;
     52#ifdef __DEBUG_H__
     53                cerr << "env arg:\"" << compiler_name << "\"" << endl;
     54#endif // __DEBUG_H__
     55        } // if
     56
     57        value = getenv( "__GCC_MACHINE__" );
     58        if ( value != NULL ) {
     59                args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along
     60#ifdef __DEBUG_H__
     61                cerr << "env arg:\"" << args[nargs] << "\"" << endl;
     62#endif // __DEBUG_H__
     63                nargs += 1;
     64        } // if
     65
     66        value = getenv( "__GCC_VERSION__" );
     67        if ( value != NULL ) {
     68                args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along
     69#ifdef __DEBUG_H__
     70                cerr << "env arg:\"" << args[nargs] << "\"" << endl;
     71#endif // __DEBUG_H__
     72                nargs += 1;
     73        } // if
     74} // checkEnv
     75
     76
     77void rmtmpfile() {
     78        if ( unlink( tmpname ) == -1 ) {                                        // remove tmpname
     79                perror ( "CFA Translator error: cpp failed" );
     80                exit( EXIT_FAILURE );
     81        } // if
     82        tmpfilefd = -1;                                                                         // mark closed
     83} // rmtmpfile
     84
     85
     86void sigTermHandler( int signal ) {
     87        if ( tmpfilefd != -1 ) {                                                        // RACE, file created ?
     88                rmtmpfile();                                                                    // remove
     89                exit( EXIT_FAILURE );                                                   // terminate
     90        } // if
     91} // sigTermHandler
     92
     93
     94void Stage1( const int argc, const char * const argv[] ) {
     95        int code;
     96        int i;
     97
     98        string arg;
     99        string bprefix;
     100
     101        const char *cpp_in = NULL;
     102        const char *cpp_out = NULL;
     103
     104        bool CFA_flag = false;
     105        bool cpp_flag = false;
     106        const char *o_name = NULL;
     107
     108        const char *args[argc + 100];                                           // leave space for 100 additional cpp command line values
     109        int nargs = 1;                                                                          // number of arguments in args list; 0 => command name
     110        const char *uargs[20];                                                          // leave space for 20 additional cfa-cpp command line values
     111        int nuargs = 1;                                                                         // 0 => command name
     112
     113        signal( SIGINT,  sigTermHandler );
     114        signal( SIGTERM, sigTermHandler );
     115
     116        // process all the arguments
     117
     118        checkEnv( args, nargs );                                                        // arguments passed via environment variables
     119
     120        for ( i = 1; i < argc; i += 1 ) {
     121#ifdef __DEBUG_H__
     122                cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
     123#endif // __DEBUG_H__
     124                arg = argv[i];
     125#ifdef __DEBUG_H__
     126                cerr << "arg:\"" << arg << "\"" << endl;
     127#endif // __DEBUG_H__
     128                if ( prefix( arg, "-" ) ) {
     129                        // strip g++ flags that are inappropriate or cause duplicates in subsequent passes
     130
     131                        if ( arg == "-quiet" ) {
     132                        } else if ( arg == "-imultilib" || arg == "-imultiarch" ) {
     133                                i += 1;                                                                 // and the argument
     134                        } else if ( prefix( arg, "-A" ) ) {
     135                        } else if ( prefix( arg, "-D__GNU" ) ) {
     136                                //********
     137                                // GCC 5.6.0 SEPARATED THE -D FROM THE ARGUMENT!
     138                                //********
     139                        } else if ( arg == "-D" && prefix( argv[i + 1], "__GNU" ) ) {
     140                                i += 1;                                                                 // and the argument
     141
     142                                // strip flags controlling cpp step
     143
     144                        } else if ( arg == "-D__CPP__" ) {
     145                                cpp_flag = true;
     146                        } else if ( arg == "-D" && string( argv[i + 1] ) == "__CPP__" ) {
     147                                i += 1;                                                                 // and the argument
     148                                cpp_flag = true;
     149                        } else if ( arg == "-D__CFA__" ) {
     150                                CFA_flag = true;
     151                        } else if ( arg == "-D" && string( argv[i + 1] ) == "__CFA__" ) {
     152                                i += 1;                                                                 // and the argument
     153                                CFA_flag = true;
     154                        } else if ( prefix( arg, D__CFA_FLAGPREFIX__ ) ) {
     155                                uargs[nuargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str();
     156                                nuargs += 1;
     157                        } else if ( arg == "-D" && prefix( argv[i + 1], D__CFA_FLAGPREFIX__.substr(2) ) ) {
     158                                uargs[nuargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str();
     159                                nuargs += 1;
     160                                i += 1;                                                                 // and the argument
     161                        } else if ( prefix( arg, D__GCC_BPREFIX__ ) ) {
     162                                bprefix = arg.substr( D__GCC_BPREFIX__.size() );
     163                        } else if ( arg == "-D" && prefix( argv[i + 1], D__GCC_BPREFIX__.substr(2) ) ) {
     164                                bprefix = string( argv[i + 1] ).substr( D__GCC_BPREFIX__.size() - 2 );
     165                                i += 1;                                                                 // and the argument
     166
     167                                // all other flags
     168
     169                        } else if ( arg == "-o" ) {
     170                                i += 1;
     171                                o_name = argv[i];
     172                        } else {
     173                                args[nargs] = argv[i];                                  // pass the flag along
     174                                nargs += 1;
     175                                // CPP flags with an argument
     176                                if ( arg == "-D" || arg == "-I" || arg == "-MF" || arg == "-MT" || arg == "-MQ" ||
     177                                         arg == "-include" || arg == "-imacros" || arg == "-idirafter" || arg == "-iprefix" ||
     178                                         arg == "-iwithprefix" || arg == "-iwithprefixbefore" || arg == "-isystem" || arg == "-isysroot" ) {
     179                                        i += 1;
     180                                        args[nargs] = argv[i];                          // pass the argument along
     181                                        nargs += 1;
     182#ifdef __DEBUG_H__
     183                                        cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
     184#endif // __DEBUG_H__
     185                                } else if ( arg == "-MD" || arg == "-MMD" ) {
     186                                        args[nargs] = "-MF";                            // insert before file
     187                                        nargs += 1;
     188                                        i += 1;
     189                                        args[nargs] = argv[i];                          // pass the argument along
     190                                        nargs += 1;
     191#ifdef __DEBUG_H__
     192                                        cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
     193#endif // __DEBUG_H__
     194                                } // if
     195                        } // if
     196                } else {                                                                                // obtain input and possibly output files
     197                        if ( cpp_in == NULL ) {
     198                                cpp_in = argv[i];
     199#ifdef __DEBUG_H__
     200                                cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
     201#endif // __DEBUG_H__
     202                        } else if ( cpp_out == NULL ) {
     203                                cpp_out = argv[i];
     204#ifdef __DEBUG_H__
     205                                cerr << "cpp_out:\"" << cpp_out << "\""<< endl;
     206#endif // __DEBUG_H__
     207                        } else {
     208                                cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
     209                                exit( EXIT_FAILURE );
     210                        } // if
     211                } // if
     212        } // for
     213
     214#ifdef __DEBUG_H__
     215        cerr << "args:";
     216        for ( i = 1; i < nargs; i += 1 ) {
     217                cerr << " " << args[i];
     218        } // for
     219        if ( cpp_in != NULL ) cerr << " " << cpp_in;
     220        if ( cpp_out != NULL ) cerr << " " << cpp_out;
     221        cerr << endl;
     222#endif // __DEBUG_H__
     223
     224        if ( cpp_in == NULL ) {
     225                cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
     226                exit( EXIT_FAILURE );
     227        } // if
     228
     229        if ( cpp_flag ) {
     230                // The -E flag is specified on the cfa command so only run the preprocessor and output is written to standard
     231                // output or -o. The call to cfa has a -E so it does not have to be added to the argument list.
     232
     233                args[0] = compiler_name.c_str();
     234                args[nargs] = cpp_in;
     235                nargs += 1;
     236                if ( o_name != NULL ) {                                                 // location for output
     237                        args[nargs] = "-o";
     238                        nargs += 1;
     239                        args[nargs] = o_name;
     240                        nargs += 1;
     241                } // if
     242                args[nargs] = NULL;                                                             // terminate argument list
     243
     244#ifdef __DEBUG_H__
     245                cerr << "nargs: " << nargs << endl;
     246                for ( i = 0; args[i] != NULL; i += 1 ) {
     247                        cerr << args[i] << " ";
     248                } // for
     249                cerr << endl;
     250#endif // __DEBUG_H__
     251
     252                execvp( args[0], (char *const *)args );                 // should not return
     253                perror( "CFA Translator error: cpp level, execvp" );
     254                exit( EXIT_FAILURE );
     255        } // if
     256
     257        // Create a temporary file to store output of the C preprocessor.
     258
     259        tmpfilefd = mkstemp( tmpname );
     260        if ( tmpfilefd == -1 ) {
     261                perror( "CFA Translator error: cpp level, mkstemp" );
     262                exit( EXIT_FAILURE );
     263        } // if
     264
     265#ifdef __DEBUG_H__
     266        cerr << "tmpname:" << tmpname << " tmpfilefd:" << tmpfilefd << endl;
     267#endif // __DEBUG_H__
     268
     269        // Run the C preprocessor and save the output in tmpfile.
     270
     271        if ( fork() == 0 ) {                                                             // child process ?
     272                // -o xxx.ii cannot be used to write the output file from cpp because no output file is created if cpp detects
     273                // an error (e.g., cannot find include file). Whereas, output is always generated, even when there is an error,
     274                // when cpp writes to stdout. Hence, stdout is redirected into the temporary file.
     275                if ( freopen( tmpname, "w", stdout ) == NULL ) { // redirect stdout to tmpname
     276                        perror( "CFA Translator error: cpp level, freopen" );
     277                        exit( EXIT_FAILURE );
     278                } // if
     279
     280                args[0] = compiler_name.c_str();
     281                args[nargs] = cpp_in;                                                   // input to cpp
     282                nargs += 1;
     283                args[nargs] = NULL;                                                             // terminate argument list
     284
     285#ifdef __DEBUG_H__
     286                cerr << "cpp nargs: " << nargs << endl;
     287                for ( i = 0; args[i] != NULL; i += 1 ) {
     288                        cerr << args[i] << " ";
     289                } // for
     290                cerr << endl;
     291#endif // __DEBUG_H__
     292
     293                execvp( args[0], (char *const *)args );                 // should not return
     294                perror( "CFA Translator error: cpp level, execvp" );
     295                exit( EXIT_FAILURE );
     296        } // if
     297
     298        wait( &code );                                                                          // wait for child to finish
     299
     300#ifdef __DEBUG_H__
     301        cerr << "return code from cpp:" << WEXITSTATUS(code) << endl;
     302#endif // __DEBUG_H__
     303
     304        if ( WIFSIGNALED(code) != 0 ) {                                         // child failed ?
     305                rmtmpfile();                                                                    // remove tmpname
     306                cerr << "CFA Translator error: cpp failed with signal " << WTERMSIG(code) << endl;
     307                exit( EXIT_FAILURE );
     308        } // if
     309
     310        if ( WEXITSTATUS(code) != 0 ) {                                         // child error ?
     311                rmtmpfile();                                                                    // remove tmpname
     312                exit( WEXITSTATUS( code ) );                                    // do not continue
     313        } // if
     314
     315        // If -CFA flag specified, run the cfa-cpp preprocessor on the temporary file, and output is written to standard
     316        // output.  Otherwise, run the cfa-cpp preprocessor on the temporary file and save the result into the output file.
     317
     318        if ( fork() == 0 ) {                                                            // child runs CFA
     319                uargs[0] = ( *new string( bprefix + "/cfa-cpp" ) ).c_str();
     320
     321                uargs[nuargs] = "-p";
     322                nuargs += 1;
     323
     324                uargs[nuargs] = tmpname;
     325                nuargs += 1;
     326                if ( o_name != NULL ) {
     327                        uargs[nuargs] = o_name;
     328                        nuargs += 1;
     329                } else if ( ! CFA_flag ) {                                              // run cfa-cpp ?
     330                        uargs[nuargs] = cpp_out;
     331                        nuargs += 1;
     332                } // if
     333                uargs[nuargs] = NULL;                                                   // terminate argument list
     334
     335#ifdef __DEBUG_H__
     336                cerr << "cfa-cpp nuargs: " << o_name << " " << CFA_flag << " " << nuargs << endl;
     337                for ( i = 0; uargs[i] != NULL; i += 1 ) {
     338                        cerr << uargs[i] << " ";
     339                } // for
     340                cerr << endl;
     341#endif // __DEBUG_H__
     342
     343                execvp( uargs[0], (char * const *)uargs );              // should not return
     344                perror( "CFA Translator error: cpp level, execvp" );
     345                exit( EXIT_FAILURE );
     346        } // if
     347
     348        wait( &code );                                                                          // wait for child to finish
     349
     350#ifdef __DEBUG_H__
     351        cerr << "return code from cfa-cpp:" << WEXITSTATUS(code) << endl;
     352#endif // __DEBUG_H__
     353
     354        // Must unlink here because file must exist across execvp.
     355        rmtmpfile();                                                                            // remove tmpname
     356
     357        if ( WIFSIGNALED(code) ) {                                                      // child failed ?
     358                cerr << "CFA Translator error: cfa-cpp failed with signal " << WTERMSIG(code) << endl;
     359                exit( EXIT_FAILURE );
     360        } // if
     361
     362        exit( WEXITSTATUS(code) );
     363} // Stage1
     364
     365
     366void Stage2( const int argc, const char * const * argv ) {
     367        int i;
     368
     369        string arg;
     370
     371        const char *cpp_in = NULL;
     372
     373        const char *args[argc + 100];                                           // leave space for 100 additional cfa command line values
     374        int nargs = 1;                                                                          // number of arguments in args list; 0 => command name
     375
     376        // process all the arguments
     377
     378        checkEnv( args, nargs );                                                        // arguments passed via environment variables
     379
     380        for ( i = 1; i < argc; i += 1 ) {
     381#ifdef __DEBUG_H__
     382                cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
     383#endif // __DEBUG_H__
     384                arg = argv[i];
     385#ifdef __DEBUG_H__
     386                cerr << "arg:\"" << arg << "\"" << endl;
     387#endif // __DEBUG_H__
     388                if ( prefix( arg, "-" ) ) {
     389                        // strip inappropriate flags
     390
     391                        if ( arg == "-quiet" || arg == "-version" || arg == "-fpreprocessed" ||
     392                                 // Currently CFA does not suppose precompiled .h files.
     393                                 prefix( arg, "--output-pch" ) ) {
     394
     395                                // strip inappropriate flags with an argument
     396
     397                        } else if ( arg == "-auxbase" || arg == "-auxbase-strip" || arg == "-dumpbase" ) {
     398                                i += 1;
     399#ifdef __DEBUG_H__
     400                                cerr << "arg:\"" << argv[i] << "\"" << endl;
     401#endif // __DEBUG_H__
     402
     403                                // all other flags
     404
     405                        } else {
     406                                args[nargs] = argv[i];                                  // pass the flag along
     407                                nargs += 1;
     408                                if ( arg == "-o" ) {
     409                                        i += 1;
     410                                        args[nargs] = argv[i];                          // pass the argument along
     411                                        nargs += 1;
     412#ifdef __DEBUG_H__
     413                                        cerr << "arg:\"" << argv[i] << "\"" << endl;
     414#endif // __DEBUG_H__
     415                                } // if
     416                        } // if
     417                } else {                                                                                // obtain input and possibly output files
     418                        if ( cpp_in == NULL ) {
     419                                cpp_in = argv[i];
     420#ifdef __DEBUG_H__
     421                                cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
     422#endif // __DEBUG_H__
     423                        } else {
     424                                cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
     425                                exit( EXIT_FAILURE );
     426                        } // if
     427                } // if
     428        } // for
     429
     430#ifdef __DEBUG_H__
     431        cerr << "args:";
     432        for ( i = 1; i < nargs; i += 1 ) {
     433                cerr << " " << args[i];
     434        } // for
     435        cerr << endl;
     436        if ( cpp_in != NULL ) cerr << " " << cpp_in;
     437#endif // __DEBUG_H__
     438
     439        args[0] = compiler_name.c_str();
     440        args[nargs] = "-S";                                                                     // only compile and put assembler output in specified file
    62441        nargs += 1;
    63     } // if
    64 
    65     value = getenv( "__GCC_VERSION__" );
    66     if ( value != NULL ) {
    67         args[nargs] = ( *new string( value ) ).c_str(); // pass the argument along
    68 #ifdef __DEBUG_H__
    69         cerr << "env arg:\"" << args[nargs] << "\"" << endl;
    70 #endif // __DEBUG_H__
    71         nargs += 1;
    72     } // if
    73 } // checkEnv
    74 
    75 
    76 void rmtmpfile() {
    77     if ( unlink( tmpname ) == -1 ) {                    // remove tmpname
    78         perror ( "CFA Translator error: cpp failed" );
    79         exit( EXIT_FAILURE );
    80     } // if
    81     tmpfilefd = -1;                                     // mark closed
    82 } // rmtmpfile
    83 
    84 
    85 void sigTermHandler( int signal ) {
    86     if ( tmpfilefd != -1 ) {                            // RACE, file created ?
    87         rmtmpfile();                                    // remove
    88         exit( EXIT_FAILURE );                           // terminate
    89     } // if
    90 } // sigTermHandler
    91 
    92 
    93 void Stage1( const int argc, const char * const argv[] ) {
    94     int code;
    95     int i;
    96 
    97     string arg;
    98     string bprefix;
    99 
    100     const char *cpp_in = NULL;
    101     const char *cpp_out = NULL;
    102 
    103     bool CFA_flag = false;
    104     bool cpp_flag = false;
    105     const char *o_name = NULL;
    106 
    107     const char *args[argc + 100];                       // leave space for 100 additional cpp command line values
    108     int nargs = 1;                                      // number of arguments in args list; 0 => command name
    109     const char *uargs[20];                              // leave space for 20 additional cfa-cpp command line values
    110     int nuargs = 1;                                     // 0 => command name
    111 
    112     signal( SIGINT,  sigTermHandler );
    113     signal( SIGTERM, sigTermHandler );
    114 
    115     // process all the arguments
    116 
    117     checkEnv( args, nargs );                            // arguments passed via environment variables
    118 
    119     for ( i = 1; i < argc; i += 1 ) {
    120 #ifdef __DEBUG_H__
    121         cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
    122 #endif // __DEBUG_H__
    123         arg = argv[i];
    124 #ifdef __DEBUG_H__
    125         cerr << "arg:\"" << arg << "\"" << endl;
    126 #endif // __DEBUG_H__
    127         if ( prefix( arg, "-" ) ) {
    128             // strip g++ flags that are inappropriate or cause duplicates in subsequent passes
    129 
    130             if ( arg == "-quiet" ) {
    131             } else if ( arg == "-imultilib" || arg == "-imultiarch" ) {
    132                 i += 1;                                 // and the argument
    133             } else if ( prefix( arg, "-A" ) ) {
    134             } else if ( prefix( arg, "-D__GNU" ) ) {
    135             //********
    136             // GCC 5.6.0 SEPARATED THE -D FROM THE ARGUMENT!
    137             //********
    138             } else if ( arg == "-D" && prefix( argv[i + 1], "__GNU" ) ) {
    139                 i += 1;                                 // and the argument
    140 
    141             // strip flags controlling cpp step
    142 
    143             } else if ( arg == "-D__CPP__" ) {
    144                 cpp_flag = true;
    145             } else if ( arg == "-D" && string( argv[i + 1] ) == "__CPP__" ) {
    146                 i += 1;                                 // and the argument
    147                 cpp_flag = true;
    148             } else if ( arg == "-D__CFA__" ) {
    149                 CFA_flag = true;
    150             } else if ( arg == "-D" && string( argv[i + 1] ) == "__CFA__" ) {
    151                 i += 1;                                 // and the argument
    152                 CFA_flag = true;
    153             } else if ( prefix( arg, D__CFA_FLAGPREFIX__ ) ) {
    154                 uargs[nuargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str();
    155                 nuargs += 1;
    156             } else if ( arg == "-D" && prefix( argv[i + 1], D__CFA_FLAGPREFIX__.substr(2) ) ) {
    157                 uargs[nuargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str();
    158                 nuargs += 1;
    159                 i += 1;                                 // and the argument
    160             } else if ( prefix( arg, D__GCC_BPREFIX__ ) ) {
    161                 bprefix = arg.substr( D__GCC_BPREFIX__.size() );
    162             } else if ( arg == "-D" && prefix( argv[i + 1], D__GCC_BPREFIX__.substr(2) ) ) {
    163                 bprefix = string( argv[i + 1] ).substr( D__GCC_BPREFIX__.size() - 2 );
    164                 i += 1;                                 // and the argument
    165 
    166             // all other flags
    167 
    168             } else if ( arg == "-o" ) {
    169                 i += 1;
    170                 o_name = argv[i];
    171             } else {
    172                 args[nargs] = argv[i];                  // pass the flag along
    173                 nargs += 1;
    174                 // CPP flags with an argument
    175                 if ( arg == "-D" || arg == "-I" || arg == "-MF" || arg == "-MT" || arg == "-MQ" ||
    176                      arg == "-include" || arg == "-imacros" || arg == "-idirafter" || arg == "-iprefix" ||
    177                      arg == "-iwithprefix" || arg == "-iwithprefixbefore" || arg == "-isystem" || arg == "-isysroot" ) {
    178                     i += 1;
    179                     args[nargs] = argv[i];              // pass the argument along
    180                     nargs += 1;
    181 #ifdef __DEBUG_H__
    182                     cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
    183 #endif // __DEBUG_H__
    184                 } else if ( arg == "-MD" || arg == "-MMD" ) {
    185                     args[nargs] = "-MF";                // insert before file
    186                     nargs += 1;
    187                     i += 1;
    188                     args[nargs] = argv[i];              // pass the argument along
    189                     nargs += 1;
    190 #ifdef __DEBUG_H__
    191                     cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
    192 #endif // __DEBUG_H__
    193                 } // if
    194             } // if
    195         } else {                                        // obtain input and possibly output files
    196             if ( cpp_in == NULL ) {
    197                 cpp_in = argv[i];
    198 #ifdef __DEBUG_H__
    199                 cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
    200 #endif // __DEBUG_H__
    201             } else if ( cpp_out == NULL ) {
    202                 cpp_out = argv[i];
    203 #ifdef __DEBUG_H__
    204                 cerr << "cpp_out:\"" << cpp_out << "\""<< endl;
    205 #endif // __DEBUG_H__
    206             } else {
    207                 cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
    208                 exit( EXIT_FAILURE );
    209             } // if
    210         } // if
    211     } // for
    212 
    213 #ifdef __DEBUG_H__
    214     cerr << "args:";
    215     for ( i = 1; i < nargs; i += 1 ) {
    216         cerr << " " << args[i];
    217     } // for
    218     if ( cpp_in != NULL ) cerr << " " << cpp_in;
    219     if ( cpp_out != NULL ) cerr << " " << cpp_out;
    220     cerr << endl;
    221 #endif // __DEBUG_H__
    222 
    223     if ( cpp_in == NULL ) {
    224         cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
    225         exit( EXIT_FAILURE );
    226     } // if
    227 
    228     if ( cpp_flag ) {
    229         // The -E flag is specified on the cfa command so only run the preprocessor and output is written to standard
    230         // output or -o. The call to cfa has a -E so it does not have to be added to the argument list.
    231 
    232         args[0] = compiler_name.c_str();
    233442        args[nargs] = cpp_in;
    234443        nargs += 1;
    235         if ( o_name != NULL ) {                         // location for output
    236             args[nargs] = "-o";
    237             nargs += 1;
    238             args[nargs] = o_name;
    239             nargs += 1;
    240         } // if
    241         args[nargs] = NULL;                             // terminate argument list
    242 
    243 #ifdef __DEBUG_H__
    244         cerr << "nargs: " << nargs << endl;
     444        args[nargs] = NULL;                                                                     // terminate argument list
     445
     446#ifdef __DEBUG_H__
     447        cerr << "stage2 nargs: " << nargs << endl;
    245448        for ( i = 0; args[i] != NULL; i += 1 ) {
    246             cerr << args[i] << " ";
     449                cerr << args[i] << " ";
    247450        } // for
    248451        cerr << endl;
    249452#endif // __DEBUG_H__
    250453
    251         execvp( args[0], (char *const *)args );         // should not return
     454        execvp( args[0], (char * const *)args );                        // should not return
    252455        perror( "CFA Translator error: cpp level, execvp" );
    253         exit( EXIT_FAILURE );
    254     } // if
    255 
    256     // Create a temporary file to store output of the C preprocessor.
    257 
    258     tmpfilefd = mkstemp( tmpname );
    259     if ( tmpfilefd == -1 ) {
    260         perror( "CFA Translator error: cpp level, mkstemp" );
    261         exit( EXIT_FAILURE );
    262     } // if
    263 
    264 #ifdef __DEBUG_H__
    265     cerr << "tmpname:" << tmpname << " tmpfilefd:" << tmpfilefd << endl;
    266 #endif // __DEBUG_H__
    267 
    268     // Run the C preprocessor and save the output in tmpfile.
    269 
    270     if ( fork() == 0 ) {                                // child process ?
    271         // -o xxx.ii cannot be used to write the output file from cpp because no output file is created if cpp detects
    272         // an error (e.g., cannot find include file). Whereas, output is always generated, even when there is an error,
    273         // when cpp writes to stdout. Hence, stdout is redirected into the temporary file.
    274         if ( freopen( tmpname, "w", stdout ) == NULL ) { // redirect stdout to tmpname
    275             perror( "CFA Translator error: cpp level, freopen" );
    276             exit( EXIT_FAILURE );
    277         } // if
    278 
    279         args[0] = compiler_name.c_str();
    280         args[nargs] = cpp_in;                           // input to cpp
    281         nargs += 1;
    282         args[nargs] = NULL;                             // terminate argument list
    283 
    284 #ifdef __DEBUG_H__
    285         cerr << "cpp nargs: " << nargs << endl;
    286         for ( i = 0; args[i] != NULL; i += 1 ) {
    287             cerr << args[i] << " ";
    288         } // for
    289         cerr << endl;
    290 #endif // __DEBUG_H__
    291 
    292         execvp( args[0], (char *const *)args );         // should not return
    293         perror( "CFA Translator error: cpp level, execvp" );
    294         exit( EXIT_FAILURE );
    295     } // if
    296 
    297     wait( &code );                                      // wait for child to finish
    298 
    299 #ifdef __DEBUG_H__
    300     cerr << "return code from cpp:" << WEXITSTATUS(code) << endl;
    301 #endif // __DEBUG_H__
    302 
    303     if ( WIFSIGNALED(code) != 0 ) {                     // child failed ?
    304         rmtmpfile();                                    // remove tmpname
    305         cerr << "CFA Translator error: cpp failed with signal " << WTERMSIG(code) << endl;
    306         exit( EXIT_FAILURE );
    307     } // if
    308 
    309     if ( WEXITSTATUS(code) != 0 ) {                     // child error ?
    310         rmtmpfile();                                    // remove tmpname
    311         exit( WEXITSTATUS( code ) );                    // do not continue
    312     } // if
    313 
    314     // If -CFA flag specified, run the cfa-cpp preprocessor on the temporary file, and output is written to standard
    315     // output.  Otherwise, run the cfa-cpp preprocessor on the temporary file and save the result into the output file.
    316 
    317     if ( fork() == 0 ) {                                // child runs CFA
    318         uargs[0] = ( *new string( bprefix + "/cfa-cpp" ) ).c_str();
    319 
    320         uargs[nuargs] = "-p";
    321         nuargs += 1;
    322 
    323         uargs[nuargs] = tmpname;
    324         nuargs += 1;
    325         if ( o_name != NULL ) {
    326             uargs[nuargs] = o_name;
    327             nuargs += 1;
    328         } else if ( ! CFA_flag ) {                      // run cfa-cpp ?
    329             uargs[nuargs] = cpp_out;
    330             nuargs += 1;
    331         } // if
    332         uargs[nuargs] = NULL;                           // terminate argument list
    333 
    334 #ifdef __DEBUG_H__
    335         cerr << "cfa-cpp nuargs: " << o_name << " " << CFA_flag << " " << nuargs << endl;
    336         for ( i = 0; uargs[i] != NULL; i += 1 ) {
    337             cerr << uargs[i] << " ";
    338         } // for
    339         cerr << endl;
    340 #endif // __DEBUG_H__
    341 
    342         execvp( uargs[0], (char * const *)uargs );      // should not return
    343         perror( "CFA Translator error: cpp level, execvp" );
    344         exit( EXIT_FAILURE );
    345     } // if
    346 
    347     wait( &code );                                      // wait for child to finish
    348 
    349 #ifdef __DEBUG_H__
    350     cerr << "return code from cfa-cpp:" << WEXITSTATUS(code) << endl;
    351 #endif // __DEBUG_H__
    352 
    353     // Must unlink here because file must exist across execvp.
    354     rmtmpfile();                                        // remove tmpname
    355 
    356     if ( WIFSIGNALED(code) ) {                          // child failed ?
    357         cerr << "CFA Translator error: cfa-cpp failed with signal " << WTERMSIG(code) << endl;
    358         exit( EXIT_FAILURE );
    359     } // if
    360 
    361     exit( WEXITSTATUS(code) );
    362 } // Stage1
    363 
    364 
    365 void Stage2( const int argc, const char * const * argv ) {
    366     int i;
    367 
    368     string arg;
    369 
    370     const char *cpp_in = NULL;
    371 
    372     const char *args[argc + 100];                       // leave space for 100 additional cfa command line values
    373     int nargs = 1;                                      // number of arguments in args list; 0 => command name
    374 
    375     // process all the arguments
    376 
    377     checkEnv( args, nargs );                            // arguments passed via environment variables
    378 
    379     for ( i = 1; i < argc; i += 1 ) {
    380 #ifdef __DEBUG_H__
    381         cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
    382 #endif // __DEBUG_H__
    383         arg = argv[i];
    384 #ifdef __DEBUG_H__
    385         cerr << "arg:\"" << arg << "\"" << endl;
    386 #endif // __DEBUG_H__
    387         if ( prefix( arg, "-" ) ) {
    388             // strip inappropriate flags
    389 
    390             if ( arg == "-quiet" || arg == "-version" || arg == "-fpreprocessed" ||
    391                  // Currently CFA does not suppose precompiled .h files.
    392                  prefix( arg, "--output-pch" ) ) {
    393 
    394             // strip inappropriate flags with an argument
    395 
    396             } else if ( arg == "-auxbase" || arg == "-auxbase-strip" || arg == "-dumpbase" ) {
    397                 i += 1;
    398 #ifdef __DEBUG_H__
    399                 cerr << "arg:\"" << argv[i] << "\"" << endl;
    400 #endif // __DEBUG_H__
    401 
    402             // all other flags
    403 
    404             } else {
    405                 args[nargs] = argv[i];                  // pass the flag along
    406                 nargs += 1;
    407                 if ( arg == "-o" ) {
    408                     i += 1;
    409                     args[nargs] = argv[i];              // pass the argument along
    410                     nargs += 1;
    411 #ifdef __DEBUG_H__
    412                     cerr << "arg:\"" << argv[i] << "\"" << endl;
    413 #endif // __DEBUG_H__
    414                 } // if
    415             } // if
    416         } else {                                        // obtain input and possibly output files
    417             if ( cpp_in == NULL ) {
    418                 cpp_in = argv[i];
    419 #ifdef __DEBUG_H__
    420                 cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
    421 #endif // __DEBUG_H__
    422             } else {
     456        exit( EXIT_FAILURE );                                                           // tell gcc not to go any further
     457} // Stage2
     458
     459
     460int main( const int argc, const char * const argv[], const char * const env[] ) {
     461#ifdef __DEBUG_H__
     462        for ( int i = 0; env[i] != NULL; i += 1 ) {
     463                cerr << env[i] << endl;
     464        } // for
     465#endif // __DEBUG_H__
     466
     467        string arg = argv[1];
     468
     469        // Currently, stage 1 starts with flag -E and stage 2 with flag -fpreprocessed.
     470
     471        if ( arg == "-E" ) {
     472#ifdef __DEBUG_H__
     473                cerr << "Stage1" << endl;
     474#endif // __DEBUG_H__
     475                Stage1( argc, argv );
     476        } else if ( arg == "-fpreprocessed" ) {
     477#ifdef __DEBUG_H__
     478                cerr << "Stage2" << endl;
     479#endif // __DEBUG_H__
     480                Stage2( argc, argv );
     481        } else {
    423482                cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
    424483                exit( EXIT_FAILURE );
    425             } // if
    426         } // if
    427     } // for
    428 
    429 #ifdef __DEBUG_H__
    430     cerr << "args:";
    431     for ( i = 1; i < nargs; i += 1 ) {
    432         cerr << " " << args[i];
    433     } // for
    434     cerr << endl;
    435     if ( cpp_in != NULL ) cerr << " " << cpp_in;
    436 #endif // __DEBUG_H__
    437 
    438     args[0] = compiler_name.c_str();
    439     args[nargs] = "-S";                                 // only compile and put assembler output in specified file
    440     nargs += 1;
    441     args[nargs] = cpp_in;
    442     nargs += 1;
    443     args[nargs] = NULL;                                 // terminate argument list
    444 
    445 #ifdef __DEBUG_H__
    446     cerr << "stage2 nargs: " << nargs << endl;
    447     for ( i = 0; args[i] != NULL; i += 1 ) {
    448         cerr << args[i] << " ";
    449     } // for
    450     cerr << endl;
    451 #endif // __DEBUG_H__
    452 
    453     execvp( args[0], (char * const *)args );            // should not return
    454     perror( "CFA Translator error: cpp level, execvp" );
    455     exit( EXIT_FAILURE );                               // tell gcc not to go any further
    456 } // Stage2
    457 
    458 
    459 int main( const int argc, const char * const argv[], const char * const env[] ) {
    460 #ifdef __DEBUG_H__
    461     for ( int i = 0; env[i] != NULL; i += 1 ) {
    462         cerr << env[i] << endl;
    463     } // for
    464 #endif // __DEBUG_H__
    465 
    466     string arg = argv[1];
    467 
    468     // Currently, stage 1 starts with flag -E and stage 2 with flag -fpreprocessed.
    469 
    470     if ( arg == "-E" ) {
    471 #ifdef __DEBUG_H__
    472         cerr << "Stage1" << endl;
    473 #endif // __DEBUG_H__
    474         Stage1( argc, argv );
    475     } else if ( arg == "-fpreprocessed" ) {
    476 #ifdef __DEBUG_H__
    477         cerr << "Stage2" << endl;
    478 #endif // __DEBUG_H__
    479         Stage2( argc, argv );
    480     } else {
    481         cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
    482         exit( EXIT_FAILURE );
    483     } // if
     484        } // if
    484485} // main
    485486
    486 
    487487// Local Variables: //
     488// tab-width: 4 //
     489// mode: c++ //
    488490// compile-command: "make install" //
    489491// End: //
  • driver/cfa.cc

    rb8508a2 rb87a5ed  
    1 //                              -*- Mode: C++ -*-
    2 //
    3 // CForall Version 1.0, Copyright (C) Peter A. Buhr 2002
    4 //
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
    57// cfa.cc --
    6 // 
     8//
    79// Author           : Peter A. Buhr
    810// Created On       : Tue Aug 20 13:44:49 2002
    911// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Fri May 15 15:01:26 2015
    11 // Update Count     : 108
    12 // 
     12// Last Modified On : Sat May 16 07:47:05 2015
     13// Update Count     : 111
     14//
    1315
    1416#include <iostream>
    15 #include <cstdio>                                       // perror
    16 #include <cstdlib>                                      // putenv, exit
    17 #include <unistd.h>                                     // execvp
    18 #include <string>                                       // STL version
    19 
    20 #include "config.h"                                     // configure info
     17#include <cstdio>                                                                               // perror
     18#include <cstdlib>                                                                              // putenv, exit
     19#include <unistd.h>                                                                             // execvp
     20#include <string>                                                                               // STL version
     21
     22#include "config.h"                                                                             // configure info
    2123
    2224using std::cerr;
     
    2931
    3032bool prefix( string arg, string pre ) {
    31     return arg.substr( 0, pre.size() ) == pre;
     33        return arg.substr( 0, pre.size() ) == pre;
    3234} // prefix
    3335
    3436
    3537void shuffle( const char *args[], int S, int E, int N ) {
    36     // S & E index 1 passed the end so adjust with -1
    37 #ifdef __DEBUG_H__
    38     cerr << "shuffle:" << S << " " << E << " " << N << endl;
    39 #endif // __DEBUG_H__
    40     for ( int j = E-1 + N; j > S-1 + N; j -=1 ) {
    41 #ifdef __DEBUG_H__
    42         cerr << "\t" << j << " " << j-N << endl;
    43 #endif // __DEBUG_H__
    44         args[j] = args[j-N];
    45     } // for
     38        // S & E index 1 passed the end so adjust with -1
     39#ifdef __DEBUG_H__
     40        cerr << "shuffle:" << S << " " << E << " " << N << endl;
     41#endif // __DEBUG_H__
     42        for ( int j = E-1 + N; j > S-1 + N; j -=1 ) {
     43#ifdef __DEBUG_H__
     44                cerr << "\t" << j << " " << j-N << endl;
     45#endif // __DEBUG_H__
     46                args[j] = args[j-N];
     47        } // for
    4648} // shuffle
    4749
    4850
    4951int main( int argc, char *argv[] ) {
    50     string Version( VERSION );                          // current version number from CONFIG
    51     string Major( "0" ), Minor( "0" ), Patch( "0" );    // default version numbers
    52     int posn1 = Version.find( "." );                    // find the divider between major and minor version numbers
    53     if ( posn1 == -1 ) {                                // not there ?
    54         Major = Version;
    55     } else {
    56         Major = Version.substr( 0, posn1 );
    57         int posn2 = Version.find( ".", posn1 + 1 );     // find the divider between minor and patch numbers
    58         if ( posn2 == -1 ) {                            // not there ?
    59             Minor = Version.substr( posn1 );
     52        string Version( VERSION );                                                      // current version number from CONFIG
     53        string Major( "0" ), Minor( "0" ), Patch( "0" );        // default version numbers
     54        int posn1 = Version.find( "." );                                        // find the divider between major and minor version numbers
     55        if ( posn1 == -1 ) {                                                            // not there ?
     56                Major = Version;
    6057        } else {
    61             Minor = Version.substr( posn1 + 1, posn2 - posn1 - 1 );
    62             Patch = Version.substr( posn2 + 1 );
    63         } // if
    64     } // if
    65 
    66     string installincdir( CFA_INCDIR );                 // fixed location of cc1 and cfa-cpp commands
    67     string installlibdir( CFA_LIBDIR );                 // fixed location of include files
    68 
    69     string heading;                                     // banner printed at start of cfa compilation
    70     string arg;                                         // current command-line argument during command-line parsing
    71     string Bprefix;                                     // path where gcc looks for compiler command steps
    72     string langstd;                                     // language standard
    73 
    74     string compiler_path( GCC_PATH );                   // path/name of C compiler
    75     string compiler_name;                               // name of C compiler
    76 
    77     bool nonoptarg = false;                             // indicates non-option argument specified
    78     bool link = true;                                   // linking as well as compiling
    79     bool verbose = false;                               // -v flag
    80     bool quiet = false;                                 // -quiet flag
    81     bool debug = true;                                  // -debug flag
    82     bool help = false;                                  // -help flag
    83     bool CFA_flag = false;                              // -CFA flag
    84     bool cpp_flag = false;                              // -E or -M flag, preprocessor only
    85     bool debugging = false;                             // -g flag
    86 
    87     const char *args[argc + 100];                       // cfa command line values, plus some space for additional flags
    88     int sargs = 1;                                      // starting location for arguments in args list
    89     int nargs = sargs;                                  // number of arguments in args list; 0 => command name
    90 
    91     const char *libs[argc + 20];                        // non-user libraries must come separately, plus some added libraries and flags
    92     int nlibs = 0;
    93 
    94 #ifdef __DEBUG_H__
    95     cerr << "CFA:" << endl;
    96 #endif // __DEBUG_H__
    97 
    98     // process command-line arguments
    99 
    100     for ( int i = 1; i < argc; i += 1 ) {
    101 #ifdef __DEBUG_H__
    102         cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
    103 #endif // __DEBUG_H__
    104         arg = argv[i];                                  // convert to string value
    105 #ifdef __DEBUG_H__
    106         cerr << "arg:\"" << arg << "\"" << endl;
    107 #endif // __DEBUG_H__
    108         if ( prefix( arg, "-" ) ) {
    109             // pass through arguments
    110 
    111             if ( arg == "-Xlinker" || arg == "-o" ) {
    112                 args[nargs] = argv[i];                  // pass the argument along
    113                 nargs += 1;
    114                 i += 1;
    115                 if ( i == argc ) continue;              // next argument available ?
    116                 args[nargs] = argv[i];                  // pass the argument along
    117                 nargs += 1;
    118             } else if ( arg == "-XCFA" ) {              // CFA pass through
    119                 i += 1;
    120                 args[nargs] = ( *new string( string("-D__CFA_FLAG__=") + argv[i] ) ).c_str();
    121                 nargs += 1;
    122 
    123             // CFA specific arguments
    124 
    125             } else if ( arg == "-CFA" ) {
    126                 CFA_flag = true;                        // strip the -CFA flag
    127                 link = false;
    128                 args[nargs] = "-E";                     // replace the argument with -E
    129                 nargs += 1;
    130             } else if ( arg == "-debug" ) {
    131                 debug = true;                           // strip the debug flag
    132             } else if ( arg == "-nodebug" ) {
    133                 debug = false;                          // strip the nodebug flag
    134             } else if ( arg == "-quiet" ) {
    135                 quiet = true;                           // strip the quiet flag
    136             } else if ( arg == "-noquiet" ) {
    137                 quiet = false;                          // strip the noquiet flag
    138             } else if ( arg == "-help" ) {
    139                 help = true;                            // strip the help flag
    140             } else if ( arg == "-nohelp" ) {
    141                 help = false;                           // strip the nohelp flag
    142             } else if ( arg == "-compiler" ) {
    143                 // use the user specified compiler
    144                 i += 1;
    145                 if ( i == argc ) continue;              // next argument available ?
    146                 compiler_path = argv[i];
    147                 if ( putenv( (char *)( *new string( string( "__U_COMPILER__=" ) + argv[i]) ).c_str() ) != 0 ) {
    148                     cerr << argv[0] << " error, cannot set environment variable." << endl;
    149                     exit( EXIT_FAILURE );
     58                Major = Version.substr( 0, posn1 );
     59                int posn2 = Version.find( ".", posn1 + 1 );             // find the divider between minor and patch numbers
     60                if ( posn2 == -1 ) {                                                    // not there ?
     61                        Minor = Version.substr( posn1 );
     62                } else {
     63                        Minor = Version.substr( posn1 + 1, posn2 - posn1 - 1 );
     64                        Patch = Version.substr( posn2 + 1 );
    15065                } // if
    151 
    152             // C++ specific arguments
    153 
    154             } else if ( arg == "-v" ) {
    155                 verbose = true;                         // verbosity required
    156                 args[nargs] = argv[i];                  // pass the argument along
    157                 nargs += 1;
    158             } else if ( arg == "-g" ) {
    159                 debugging = true;                       // symbolic debugging required
    160                 args[nargs] = argv[i];                  // pass the argument along
    161                 nargs += 1;
    162             } else if ( prefix( arg, "-B" ) ) {
    163                 Bprefix = arg.substr(2);                // strip the -B flag
     66        } // if
     67
     68        string installincdir( CFA_INCDIR );                                     // fixed location of cc1 and cfa-cpp commands
     69        string installlibdir( CFA_LIBDIR );                                     // fixed location of include files
     70
     71        string heading;                                                                         // banner printed at start of cfa compilation
     72        string arg;                                                                                     // current command-line argument during command-line parsing
     73        string Bprefix;                                                                         // path where gcc looks for compiler command steps
     74        string langstd;                                                                         // language standard
     75
     76        string compiler_path( GCC_PATH );                                       // path/name of C compiler
     77        string compiler_name;                                                           // name of C compiler
     78
     79        bool nonoptarg = false;                                                         // indicates non-option argument specified
     80        bool link = true;                                                                       // linking as well as compiling
     81        bool verbose = false;                                                           // -v flag
     82        bool quiet = false;                                                                     // -quiet flag
     83        bool debug = true;                                                                      // -debug flag
     84        bool help = false;                                                                      // -help flag
     85        bool CFA_flag = false;                                                          // -CFA flag
     86        bool cpp_flag = false;                                                          // -E or -M flag, preprocessor only
     87        bool debugging = false;                                                         // -g flag
     88
     89        const char *args[argc + 100];                                           // cfa command line values, plus some space for additional flags
     90        int sargs = 1;                                                                          // starting location for arguments in args list
     91        int nargs = sargs;                                                                      // number of arguments in args list; 0 => command name
     92
     93        const char *libs[argc + 20];                                            // non-user libraries must come separately, plus some added libraries and flags
     94        int nlibs = 0;
     95
     96#ifdef __DEBUG_H__
     97        cerr << "CFA:" << endl;
     98#endif // __DEBUG_H__
     99
     100        // process command-line arguments
     101
     102        for ( int i = 1; i < argc; i += 1 ) {
     103#ifdef __DEBUG_H__
     104                cerr << "argv[" << i << "]:\"" << argv[i] << "\"" << endl;
     105#endif // __DEBUG_H__
     106                arg = argv[i];                                                                  // convert to string value
     107#ifdef __DEBUG_H__
     108                cerr << "arg:\"" << arg << "\"" << endl;
     109#endif // __DEBUG_H__
     110                if ( prefix( arg, "-" ) ) {
     111                        // pass through arguments
     112
     113                        if ( arg == "-Xlinker" || arg == "-o" ) {
     114                                args[nargs] = argv[i];                                  // pass the argument along
     115                                nargs += 1;
     116                                i += 1;
     117                                if ( i == argc ) continue;                              // next argument available ?
     118                                args[nargs] = argv[i];                                  // pass the argument along
     119                                nargs += 1;
     120                        } else if ( arg == "-XCFA" ) {                          // CFA pass through
     121                                i += 1;
     122                                args[nargs] = ( *new string( string("-D__CFA_FLAG__=") + argv[i] ) ).c_str();
     123                                nargs += 1;
     124
     125                                // CFA specific arguments
     126
     127                        } else if ( arg == "-CFA" ) {
     128                                CFA_flag = true;                                                // strip the -CFA flag
     129                                link = false;
     130                                args[nargs] = "-E";                                             // replace the argument with -E
     131                                nargs += 1;
     132                        } else if ( arg == "-debug" ) {
     133                                debug = true;                                                   // strip the debug flag
     134                        } else if ( arg == "-nodebug" ) {
     135                                debug = false;                                                  // strip the nodebug flag
     136                        } else if ( arg == "-quiet" ) {
     137                                quiet = true;                                                   // strip the quiet flag
     138                        } else if ( arg == "-noquiet" ) {
     139                                quiet = false;                                                  // strip the noquiet flag
     140                        } else if ( arg == "-help" ) {
     141                                help = true;                                                    // strip the help flag
     142                        } else if ( arg == "-nohelp" ) {
     143                                help = false;                                                   // strip the nohelp flag
     144                        } else if ( arg == "-compiler" ) {
     145                                // use the user specified compiler
     146                                i += 1;
     147                                if ( i == argc ) continue;                              // next argument available ?
     148                                compiler_path = argv[i];
     149                                if ( putenv( (char *)( *new string( string( "__U_COMPILER__=" ) + argv[i]) ).c_str() ) != 0 ) {
     150                                        cerr << argv[0] << " error, cannot set environment variable." << endl;
     151                                        exit( EXIT_FAILURE );
     152                                } // if
     153
     154                                // C++ specific arguments
     155
     156                        } else if ( arg == "-v" ) {
     157                                verbose = true;                                                 // verbosity required
     158                                args[nargs] = argv[i];                                  // pass the argument along
     159                                nargs += 1;
     160                        } else if ( arg == "-g" ) {
     161                                debugging = true;                                               // symbolic debugging required
     162                                args[nargs] = argv[i];                                  // pass the argument along
     163                                nargs += 1;
     164                        } else if ( prefix( arg, "-B" ) ) {
     165                                Bprefix = arg.substr(2);                                // strip the -B flag
     166                                args[nargs] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
     167                                nargs += 1;
     168                        } else if ( prefix( arg, "-b" ) ) {
     169                                if ( arg.length() == 2 ) {                              // separate argument ?
     170                                        i += 1;
     171                                        if ( i == argc ) continue;                      // next argument available ?
     172                                        arg += argv[i];                                         // concatenate argument
     173                                } // if
     174                                // later versions of gcc require the -b option to appear at the start of the command line
     175                                shuffle( args, sargs, nargs, 1 );               // make room at front of argument list
     176                                args[sargs] = ( *new string( arg ) ).c_str(); // pass the argument along
     177                                if ( putenv( (char *)( *new string( string( "__GCC_MACHINE__=" ) + arg ) ).c_str() ) != 0 ) {
     178                                        cerr << argv[0] << " error, cannot set environment variable." << endl;
     179                                        exit( EXIT_FAILURE );
     180                                } // if
     181                                sargs += 1;
     182                                nargs += 1;
     183                        } else if ( prefix( arg, "-V" ) ) {
     184                                if ( arg.length() == 2 ) {                              // separate argument ?
     185                                        i += 1;
     186                                        if ( i == argc ) continue;                      // next argument available ?
     187                                        arg += argv[i];                                         // concatenate argument
     188                                } // if
     189                                // later versions of gcc require the -V option to appear at the start of the command line
     190                                shuffle( args, sargs, nargs, 1 );               // make room at front of argument list
     191                                args[sargs] = ( *new string( arg ) ).c_str(); // pass the argument along
     192                                if ( putenv( (char *)( *new string( string( "__GCC_VERSION__=" ) + arg ) ).c_str() ) != 0 ) {
     193                                        cerr << argv[0] << " error, cannot set environment variable." << endl;
     194                                        exit( EXIT_FAILURE );
     195                                } // if
     196                                sargs += 1;
     197                                nargs += 1;
     198                        } else if ( arg == "-c" || arg == "-S" || arg == "-E" || arg == "-M" || arg == "-MM" ) {
     199                                args[nargs] = argv[i];                                  // pass the argument along
     200                                nargs += 1;
     201                                if ( arg == "-E" || arg == "-M" || arg == "-MM" ) {
     202                                        cpp_flag = true;                                        // cpp only
     203                                } // if
     204                                link = false;                           // no linkage required
     205                        } else if ( arg[1] == 'l' ) {
     206                                // if the user specifies a library, load it after user code
     207                                libs[nlibs] = argv[i];
     208                                nlibs += 1;
     209                        } else {
     210                                // concatenate any other arguments
     211                                args[nargs] = argv[i];
     212                                nargs += 1;
     213                        } // if
     214                } else {
     215                        // concatenate other arguments
     216                        args[nargs] = argv[i];
     217                        nargs += 1;
     218                        nonoptarg = true;
     219                } // if
     220        } // for
     221
     222#ifdef __DEBUG_H__
     223        cerr << "args:";
     224        for ( int i = 1; i < nargs; i += 1 ) {
     225                cerr << " " << args[i];
     226        } // for
     227        cerr << endl;
     228#endif // __DEBUG_H__
     229
     230        if ( cpp_flag && CFA_flag ) {
     231                cerr << argv[0] << " error, cannot use -E and -CFA flags together." << endl;
     232                exit( EXIT_FAILURE );
     233        } // if
     234
     235        string d;
     236        if ( debug ) {
     237                d = "-d";
     238        } // if
     239
     240        args[nargs] = "-I" CFA_INCDIR;
     241        nargs += 1;
     242
     243        if ( link ) {
     244                // include the cfa library in case it's needed
     245                args[nargs] = "-L" CFA_LIBDIR;
     246                nargs += 1;
     247                args[nargs] = "-lcfa";
     248                nargs += 1;
     249        } // if
     250
     251        // add the correct set of flags based on the type of compile this is
     252
     253        args[nargs] = ( *new string( string("-D__CFA_MAJOR__=") + Major ) ).c_str();
     254        nargs += 1;
     255        args[nargs] = ( *new string( string("-D__CFA_MINOR__=") + Minor ) ).c_str();
     256        nargs += 1;
     257
     258        if ( cpp_flag ) {
     259                args[nargs] = "-D__CPP__";
     260                nargs += 1;
     261        } // if
     262
     263        if ( CFA_flag ) {
     264                args[nargs] = "-D__CFA__";
     265                nargs += 1;
     266        } // if
     267
     268        if ( debug ) {
     269                heading += " (debug)";
     270                args[nargs] = "-D__CFA_DEBUG__";
     271                nargs += 1;
     272        } else {
     273                heading += " (no debug)";
     274        } // if
     275
     276        if ( Bprefix.length() == 0 ) {
     277                Bprefix = installlibdir;
    164278                args[nargs] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
    165279                nargs += 1;
    166             } else if ( prefix( arg, "-b" ) ) {
    167                 if ( arg.length() == 2 ) {              // separate argument ?
    168                     i += 1;
    169                     if ( i == argc ) continue;          // next argument available ?
    170                     arg += argv[i];                     // concatenate argument
     280        } // if
     281
     282        // execute the compilation command
     283
     284        args[0] = compiler_path.c_str();                                        // set compiler command for exec
     285        // find actual name of the compiler independent of the path to it
     286        int p = compiler_path.find_last_of( '/' );                      // scan r -> l for first '/'
     287        if ( p == -1 ) {
     288                compiler_name = compiler_path;
     289        } else {
     290                compiler_name = *new string( compiler_path.substr( p + 1 ) );
     291        } // if
     292
     293        if ( prefix( compiler_name, "gcc" ) ) {                         // allow suffix on gcc name
     294                args[nargs] = "-no-integrated-cpp";
     295                nargs += 1;
     296                args[nargs] = "-Wno-deprecated";
     297                nargs += 1;
     298                args[nargs] = "-std=c99";
     299                nargs += 1;
     300                args[nargs] = ( *new string( string("-B") + Bprefix + "/" ) ).c_str();
     301                nargs += 1;
     302        } else {
     303                cerr << argv[0] << " error, compiler " << compiler_name << " not supported." << endl;
     304                exit( EXIT_FAILURE );
     305        } // if
     306
     307        for ( int i = 0; i < nlibs; i += 1 ) {                          // copy non-user libraries after all user libraries
     308                args[nargs] = libs[i];
     309                nargs += 1;
     310        } // for
     311
     312        args[nargs] = NULL;                                                                     // terminate with NULL
     313
     314#ifdef __DEBUG_H__
     315        cerr << "nargs: " << nargs << endl;
     316        cerr << "args:" << endl;
     317        for ( int i = 0; args[i] != NULL; i += 1 ) {
     318                cerr << " \"" << args[i] << "\"" << endl;
     319        } // for
     320#endif // __DEBUG_H__
     321
     322        if ( ! quiet ) {
     323                cerr << "CFA " << "Version " << Version << heading << endl;
     324
     325                if ( help ) {
     326                        cerr <<
     327                                "-debug\t\t\t: use cfa runtime with debug checking" << endl <<
     328                                "-help\t\t\t: print this help message" << endl <<
     329                                "-quiet\t\t\t: print no messages from the cfa command" << endl <<
     330                                "-CFA\t\t\t: run the cpp preprocessor and the cfa-cpp translator" << endl <<
     331                                "-XCFA -cfa-cpp-flag\t: pass next flag as-is to the cfa-cpp translator" << endl <<
     332                                "...\t\t\t: any other " << compiler_name << " flags" << endl;
    171333                } // if
    172                 // later versions of gcc require the -b option to appear at the start of the command line
    173                 shuffle( args, sargs, nargs, 1 );       // make room at front of argument list
    174                 args[sargs] = ( *new string( arg ) ).c_str(); // pass the argument along
    175                 if ( putenv( (char *)( *new string( string( "__GCC_MACHINE__=" ) + arg ) ).c_str() ) != 0 ) {
    176                     cerr << argv[0] << " error, cannot set environment variable." << endl;
    177                     exit( EXIT_FAILURE );
    178                 } // if
    179                 sargs += 1;
    180                 nargs += 1;
    181             } else if ( prefix( arg, "-V" ) ) {
    182                 if ( arg.length() == 2 ) {              // separate argument ?
    183                     i += 1;
    184                     if ( i == argc ) continue;          // next argument available ?
    185                     arg += argv[i];                     // concatenate argument
    186                 } // if
    187                 // later versions of gcc require the -V option to appear at the start of the command line
    188                 shuffle( args, sargs, nargs, 1 );       // make room at front of argument list
    189                 args[sargs] = ( *new string( arg ) ).c_str(); // pass the argument along
    190                 if ( putenv( (char *)( *new string( string( "__GCC_VERSION__=" ) + arg ) ).c_str() ) != 0 ) {
    191                     cerr << argv[0] << " error, cannot set environment variable." << endl;
    192                     exit( EXIT_FAILURE );
    193                 } // if
    194                 sargs += 1;
    195                 nargs += 1;
    196             } else if ( arg == "-c" || arg == "-S" || arg == "-E" || arg == "-M" || arg == "-MM" ) {
    197                 args[nargs] = argv[i];                  // pass the argument along
    198                 nargs += 1;
    199                 if ( arg == "-E" || arg == "-M" || arg == "-MM" ) {
    200                     cpp_flag = true;                    // cpp only
    201                 } // if
    202                 link = false;                           // no linkage required
    203             } else if ( arg[1] == 'l' ) {
    204                 // if the user specifies a library, load it after user code
    205                 libs[nlibs] = argv[i];
    206                 nlibs += 1;
    207             } else {
    208                 // concatenate any other arguments
    209                 args[nargs] = argv[i];
    210                 nargs += 1;
    211             } // if
    212         } else {
    213             // concatenate other arguments
    214             args[nargs] = argv[i];
    215             nargs += 1;
    216             nonoptarg = true;
    217         } // if
    218     } // for
    219 
    220 #ifdef __DEBUG_H__
    221     cerr << "args:";
    222     for ( int i = 1; i < nargs; i += 1 ) {
    223         cerr << " " << args[i];
    224     } // for
    225     cerr << endl;
    226 #endif // __DEBUG_H__
    227 
    228     if ( cpp_flag && CFA_flag ) {
    229         cerr << argv[0] << " error, cannot use -E and -CFA flags together." << endl;
     334        } // if
     335
     336        if ( verbose ) {
     337                if ( argc == 2 ) exit( EXIT_SUCCESS );                  // if only the -v flag is specified, do not invoke gcc
     338
     339                for ( int i = 0; args[i] != NULL; i += 1 ) {
     340                        cerr << args[i] << " ";
     341                } // for
     342                cerr << endl;
     343        } // if
     344
     345        if ( ! nonoptarg ) {
     346                cerr << argv[0] << " error, no input files" << endl;
     347                exit( EXIT_FAILURE );
     348        } // if
     349
     350        // execute the command and return the result
     351
     352        execvp( args[0], (char *const *)args );                         // should not return
     353        perror( "CFA Translator error: cfa level, execvp" );
    230354        exit( EXIT_FAILURE );
    231     } // if
    232 
    233     string d;
    234     if ( debug ) {
    235         d = "-d";
    236     } // if
    237 
    238     args[nargs] = "-I" CFA_INCDIR;
    239     nargs += 1;
    240 
    241     if ( link ) {
    242         // include the cfa library in case it's needed
    243         args[nargs] = "-L" CFA_LIBDIR;
    244         nargs += 1;
    245         args[nargs] = "-lcfa";
    246         nargs += 1;
    247     } // if
    248 
    249     // add the correct set of flags based on the type of compile this is
    250 
    251     args[nargs] = ( *new string( string("-D__CFA_MAJOR__=") + Major ) ).c_str();
    252     nargs += 1;
    253     args[nargs] = ( *new string( string("-D__CFA_MINOR__=") + Minor ) ).c_str();
    254     nargs += 1;
    255 
    256     if ( cpp_flag ) {
    257         args[nargs] = "-D__CPP__";
    258         nargs += 1;
    259     } // if
    260 
    261     if ( CFA_flag ) {
    262         args[nargs] = "-D__CFA__";
    263         nargs += 1;
    264     } // if
    265 
    266     if ( debug ) {
    267         heading += " (debug)";
    268         args[nargs] = "-D__CFA_DEBUG__";
    269         nargs += 1;
    270     } else {
    271         heading += " (no debug)";
    272     } // if
    273 
    274     if ( Bprefix.length() == 0 ) {
    275         Bprefix = installlibdir;
    276         args[nargs] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
    277         nargs += 1;
    278     } // if
    279 
    280     // execute the compilation command
    281 
    282     args[0] = compiler_path.c_str();                    // set compiler command for exec
    283     // find actual name of the compiler independent of the path to it
    284     int p = compiler_path.find_last_of( '/' );          // scan r -> l for first '/'
    285     if ( p == -1 ) {
    286         compiler_name = compiler_path;
    287     } else {
    288         compiler_name = *new string( compiler_path.substr( p + 1 ) );
    289     } // if
    290 
    291     if ( prefix( compiler_name, "gcc" ) ) {             // allow suffix on gcc name
    292         args[nargs] = "-no-integrated-cpp";
    293         nargs += 1;
    294         args[nargs] = "-Wno-deprecated";
    295         nargs += 1;
    296         args[nargs] = "-std=c99";
    297         nargs += 1;
    298         args[nargs] = ( *new string( string("-B") + Bprefix + "/" ) ).c_str();
    299         nargs += 1;
    300     } else {
    301         cerr << argv[0] << " error, compiler " << compiler_name << " not supported." << endl;
    302         exit( EXIT_FAILURE );
    303     } // if
    304 
    305     for ( int i = 0; i < nlibs; i += 1 ) {              // copy non-user libraries after all user libraries
    306         args[nargs] = libs[i];
    307         nargs += 1;
    308     } // for
    309 
    310     args[nargs] = NULL;                                 // terminate with NULL
    311 
    312 #ifdef __DEBUG_H__
    313     cerr << "nargs: " << nargs << endl;
    314     cerr << "args:" << endl;
    315     for ( int i = 0; args[i] != NULL; i += 1 ) {
    316         cerr << " \"" << args[i] << "\"" << endl;
    317     } // for
    318 #endif // __DEBUG_H__
    319 
    320     if ( ! quiet ) {
    321         cerr << "CFA " << "Version " << Version << heading << endl;
    322 
    323         if ( help ) {
    324             cerr <<
    325                 "-debug\t\t\t: use cfa runtime with debug checking" << endl <<
    326                 "-help\t\t\t: print this help message" << endl <<
    327                 "-quiet\t\t\t: print no messages from the cfa command" << endl <<
    328                 "-CFA\t\t\t: run the cpp preprocessor and the cfa-cpp translator" << endl <<
    329                 "-XCFA -cfa-cpp-flag\t: pass next flag as-is to the cfa-cpp translator" << endl <<
    330                 "...\t\t\t: any other " << compiler_name << " flags" << endl;
    331         } // if
    332     } // if
    333 
    334     if ( verbose ) {
    335         if ( argc == 2 ) exit( EXIT_SUCCESS );          // if only the -v flag is specified, do not invoke gcc
    336 
    337         for ( int i = 0; args[i] != NULL; i += 1 ) {
    338             cerr << args[i] << " ";
    339         } // for
    340         cerr << endl;
    341     } // if
    342 
    343     if ( ! nonoptarg ) {
    344         cerr << argv[0] << " error, no input files" << endl;
    345         exit( EXIT_FAILURE );
    346     } // if
    347 
    348     // execute the command and return the result
    349 
    350     execvp( args[0], (char *const *)args );             // should not return
    351     perror( "CFA Translator error: cfa level, execvp" );
    352     exit( EXIT_FAILURE );
    353355} // main
    354356
    355357// Local Variables: //
     358// tab-width: 4 //
     359// mode: c++ //
    356360// compile-command: "make install" //
    357361// End: //
  • include/bfd.h

    rb8508a2 rb87a5ed  
    1 //                              -*- Mode: C++ -*-
    2 //
    3 // Cforall Version 1.0.0, Copyright (C) Peter A. Buhr 2015
    4 //
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
    57// bfd.h --
    6 // 
     8//
    79// Author           : Peter A. Buhr
    810// Created On       : Thu Jan  8 15:50:56 2015
    911// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Sat Jan 10 14:12:35 2015
    11 // Update Count     : 3
     12// Last Modified On : Sat May 16 07:54:59 2015
     13// Update Count     : 5
    1214
    1315// This include file uses the CFA keyword "type" as a field name of a structure.
     
    1921
    2022// Local Variables: //
     23// tab-width: 4 //
     24// mode: c++ //
    2125// compile-command: "make install" //
    2226// End: //
  • include/math.h

    rb8508a2 rb87a5ed  
    1 //                              -*- Mode: C++ -*-
    2 //
    3 // Cforall Version 1.0.0, Copyright (C) Peter A. Buhr 2014
    4 //
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
    57// math.h --
    6 // 
     8//
    79// Author           : Peter A. Buhr
    810// Created On       : Mon Nov 10 23:41:29 2014
    911// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Sat Jan 10 14:12:21 2015
    11 // Update Count     : 2
     12// Last Modified On : Sat May 16 07:55:52 2015
     13// Update Count     : 3
    1214
    1315// This include file uses the CFA keyword "type" as a field name of a structure.
     
    1921
    2022// Local Variables: //
     23// tab-width: 4 //
     24// mode: c++ //
    2125// compile-command: "make install" //
    2226// End: //
  • libcfa/Makefile.in

    rb8508a2 rb87a5ed  
     1######################### -*- Mode: Makefile-Gmake -*- ########################
     2##
     3## Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     4##
     5## The contents of this file are covered under the licence agreement in the
     6## file "LICENCE" distributed with Cforall.
     7##
     8## Makefile.in --
     9##
     10## Author           : Peter A. Buhr
     11## Created On       : Sat May 16 08:05:18 2015
     12## Last Modified By : Peter A. Buhr
     13## Last Modified On : Sat May 16 08:06:05 2015
     14## Update Count     : 1
     15###############################################################################
     16
    117INSTALL=@INSTALL@
    218BACKEND_CC := @BACKEND_CC@
  • libcfa/prototypes.awk

    rb8508a2 rb87a5ed  
     1#
     2# Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3#
     4# The contents of this file are covered under the licence agreement in the
     5# file "LICENCE" distributed with Cforall.
     6#
     7# prototypes.awk --
     8#
     9# Author           : Peter A. Buhr
     10# Created On       : Sat May 16 07:57:37 2015
     11# Last Modified By : Peter A. Buhr
     12# Last Modified On : Sat May 16 08:02:10 2015
     13# Update Count     : 3
     14#
     15
    116# http://llvm.org/svn/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def
    217
     
    419    FS = "("
    520    # order so string search is longest string
    6     types[0]  = "UINTMAX";                      vtypes[0]  = "unsigned long int"
    7     types[1]  = "UINT16";                       vtypes[1]  = "short int"
    8     types[2]  = "UINT32";                       vtypes[2]  = "int"
    9     types[3]  = "UINT64";                       vtypes[3]  = "long long int"
    10     types[4]  = "UINT";                         vtypes[4]  = "unsigned int"
    11     types[5]  = "INTMAX";                       vtypes[5]  = "long int"
    12     types[6]  = "INTPTR";                       vtypes[6]  = "int *"
    13     types[7]  = "WINT";                         vtypes[7]  = "unsigned int"
    14     types[8]  = "INT";                          vtypes[8]  = "int"
    15     types[9]  = "ULONGLONG";                    vtypes[9]  = "unsigned long long"
    16     types[10] = "ULONG";                        vtypes[10] = "unsigned long"
    17     types[11] = "UNSIGNED";                     vtypes[11] = "unsigned"
     21    types[0]  = "UINTMAX";                                      vtypes[0]  = "unsigned long int"
     22    types[1]  = "UINT16";                                       vtypes[1]  = "short int"
     23    types[2]  = "UINT32";                                       vtypes[2]  = "int"
     24    types[3]  = "UINT64";                                       vtypes[3]  = "long long int"
     25    types[4]  = "UINT";                                         vtypes[4]  = "unsigned int"
     26    types[5]  = "INTMAX";                                       vtypes[5]  = "long int"
     27    types[6]  = "INTPTR";                                       vtypes[6]  = "int *"
     28    types[7]  = "WINT";                                         vtypes[7]  = "unsigned int"
     29    types[8]  = "INT";                                          vtypes[8]  = "int"
     30    types[9]  = "ULONGLONG";                            vtypes[9]  = "unsigned long long"
     31    types[10] = "ULONG";                                        vtypes[10] = "unsigned long"
     32    types[11] = "UNSIGNED";                                     vtypes[11] = "unsigned"
    1833    types[12] = "COMPLEX_LONGDOUBLE";           vtypes[12] = "_Complex long double"
    19     types[13] = "COMPLEX_DOUBLE";               vtypes[13] = "_Complex double"
    20     types[14] = "COMPLEX_FLOAT";                vtypes[14] = "_Complex float"
    21     types[15] = "LONGDOUBLEPTR";                vtypes[15] = "long double *"
    22     types[16] = "LONGDOUBLE";                   vtypes[16] = "long double"
    23     types[17] = "LONGLONG";                     vtypes[17] = "long long"
    24     types[18] = "LONG";                         vtypes[18] = "long"
    25     types[19] = "DFLOAT32";                     vtypes[19] = "_Decimal32"
    26     types[20] = "DFLOAT64";                     vtypes[20] = "_Decimal64"
    27     types[21] = "DFLOAT128";                    vtypes[21] = "_Decimal128"
    28     types[22] = "DOUBLEPTR";                    vtypes[22] = "double *"
    29     types[23] = "DOUBLE";                       vtypes[23] = "double"
    30     types[24] = "FLOATPTR";                     vtypes[24] = "float *"
    31     types[25] = "FLOAT";                        vtypes[25] = "float"
    32     types[26] = "CONST_PTR";                    vtypes[26] = "const void *"
    33     types[27] = "CONST_STRING";                 vtypes[27] = "const char *"
     34    types[13] = "COMPLEX_DOUBLE";                       vtypes[13] = "_Complex double"
     35    types[14] = "COMPLEX_FLOAT";                        vtypes[14] = "_Complex float"
     36    types[15] = "LONGDOUBLEPTR";                        vtypes[15] = "long double *"
     37    types[16] = "LONGDOUBLE";                           vtypes[16] = "long double"
     38    types[17] = "LONGLONG";                                     vtypes[17] = "long long"
     39    types[18] = "LONG";                                         vtypes[18] = "long"
     40    types[19] = "DFLOAT32";                                     vtypes[19] = "_Decimal32"
     41    types[20] = "DFLOAT64";                                     vtypes[20] = "_Decimal64"
     42    types[21] = "DFLOAT128";                            vtypes[21] = "_Decimal128"
     43    types[22] = "DOUBLEPTR";                            vtypes[22] = "double *"
     44    types[23] = "DOUBLE";                                       vtypes[23] = "double"
     45    types[24] = "FLOATPTR";                                     vtypes[24] = "float *"
     46    types[25] = "FLOAT";                                        vtypes[25] = "float"
     47    types[26] = "CONST_PTR";                            vtypes[26] = "const void *"
     48    types[27] = "CONST_STRING";                         vtypes[27] = "const char *"
    3449    types[28] = "PTR_FN_VOID_VAR_PTR_SIZE";     vtypes[28] = ""
    35     types[29] = "PTR_CONST_STRING";             vtypes[29] = "char *const"
    36     types[30] = "PTRMODE_PTR";                  vtypes[30] = ""
    37     types[31] = "PTRPTR";                       vtypes[31] = "void **"
    38     types[32] = "PTR";                          vtypes[32] = "void *"
    39     types[33] = "VOID";                         vtypes[33] = "void"
    40     types[34] = "STRING";                       vtypes[34] = "char *"
    41     types[35] = "FILEPTR";                      vtypes[35] = "struct _IO_FILE *"
    42     types[36] = "SIZE";                         vtypes[36] = "unsigned long"
    43     types[37] = "VAR";                          vtypes[37] = "..."
    44     types[38] = "VALIST_ARG";                   vtypes[38] = "void **"
    45     types[39] = "VALIST_REF";                   vtypes[39] = "void **"
    46     types[40] = "UNWINDWORD";                   vtypes[40] = "void *"
    47     types[41] = "WORD";                         vtypes[41] = ""
    48     types[42] = "SSIZE";                        vtypes[42] = "long int"
    49     types[43] = "PID";                          vtypes[43] = "int"
     50    types[29] = "PTR_CONST_STRING";                     vtypes[29] = "char *const"
     51    types[30] = "PTRMODE_PTR";                          vtypes[30] = ""
     52    types[31] = "PTRPTR";                                       vtypes[31] = "void **"
     53    types[32] = "PTR";                                          vtypes[32] = "void *"
     54    types[33] = "VOID";                                         vtypes[33] = "void"
     55    types[34] = "STRING";                                       vtypes[34] = "char *"
     56    types[35] = "FILEPTR";                                      vtypes[35] = "struct _IO_FILE *"
     57    types[36] = "SIZE";                                         vtypes[36] = "unsigned long"
     58    types[37] = "VAR";                                          vtypes[37] = "..."
     59    types[38] = "VALIST_ARG";                           vtypes[38] = "void **"
     60    types[39] = "VALIST_REF";                           vtypes[39] = "void **"
     61    types[40] = "UNWINDWORD";                           vtypes[40] = "void *"
     62    types[41] = "WORD";                                         vtypes[41] = ""
     63    types[42] = "SSIZE";                                        vtypes[42] = "long int"
     64    types[43] = "PID";                                          vtypes[43] = "int"
    5065    N = 44
    5166} # BEGIN
     
    6075    # generate C types for macros names
    6176    for ( i = 0; i < N; i += 1 ) {
    62         printf( "#define BT_%s %s\n", types[i], vtypes[i] )
     77                printf( "#define BT_%s %s\n", types[i], vtypes[i] )
    6378    } # for
    6479    printf( "\n" )
    6580
    6681    for ( prototype in prototypes ) {
    67         if ( index( "BT_LAST", prototype ) == 1 ) {
    68             continue
    69         } # if
     82                if ( index( "BT_LAST", prototype ) == 1 ) {
     83                        continue
     84                } # if
    7085
    71         printf( "#define %s(NAME) FUNC_SIMPLE(", prototype )
     86                printf( "#define %s(NAME) FUNC_SIMPLE(", prototype )
    7287
    73         if ( sub( "BT_FN_", "", prototype ) == 0 ) {
    74             printf( "\n********** BAD MACRO NAME \"%s\" **********\n", prototype )
    75             exit 0
    76         } # if
     88                if ( sub( "BT_FN_", "", prototype ) == 0 ) {
     89                        printf( "\n********** BAD MACRO NAME \"%s\" **********\n", prototype )
     90                        exit 0
     91                } # if
    7792
    78         # generate function return type as macro
    79         for ( t = 0; t < N; t += 1 ) {                  # find longest match
    80             type = types[t];
    81             if ( index( prototype, type ) == 1 ) {      # found match
    82                 printf( "BT_%s, NAME", type )
    83                 sub( type, "", prototype )
    84                 break;
    85             } # if
    86         } # for
     93                # generate function return type as macro
     94                for ( t = 0; t < N; t += 1 ) {                                  # find longest match
     95                        type = types[t];
     96                        if ( index( prototype, type ) == 1 ) {          # found match
     97                                printf( "BT_%s, NAME", type )
     98                                sub( type, "", prototype )
     99                                break;
     100                        } # if
     101                } # for
    87102
    88         # generate function parameter types as macro
    89         if ( index( prototype, "VAR" ) != 2 ) {         # C-style empty parameters ?
    90             for ( p = 0; length( prototype ) > 0; p += 1 ) { # until all parameters types are removed
    91                 sub( "_", "", prototype)                # remove "_"
    92                 printf( ", ", type )
    93                 temp = prototype
    94                 for ( t = 0; t < N; t += 1 ) {          # find longest match
    95                     type = types[t];
    96                     if ( index( prototype, type ) == 1 ) { # found match
    97                         printf( "BT_%s", type )
    98                         sub( type, "", prototype )
    99                         break;
    100                     } # if
    101                 } # for
    102                 if ( temp == prototype ) {              # no match found for parameter in macro table
    103                     printf( "\n********** MISSING TYPE \"%s\" **********\n", prototype )
    104                     exit 0
     103                # generate function parameter types as macro
     104                if ( index( prototype, "VAR" ) != 2 ) {                 # C-style empty parameters ?
     105                        for ( p = 0; length( prototype ) > 0; p += 1 ) { # until all parameters types are removed
     106                                sub( "_", "", prototype)                                # remove "_"
     107                                printf( ", ", type )
     108                                temp = prototype
     109                                for ( t = 0; t < N; t += 1 ) {                  # find longest match
     110                                        type = types[t];
     111                                        if ( index( prototype, type ) == 1 ) { # found match
     112                                                printf( "BT_%s", type )
     113                                                sub( type, "", prototype )
     114                                                break;
     115                                        } # if
     116                                } # for
     117                                if ( temp == prototype ) {                              # no match found for parameter in macro table
     118                                        printf( "\n********** MISSING TYPE \"%s\" **********\n", prototype )
     119                                        exit 0
     120                                } # if
     121                        } # for
    105122                } # if
    106             } # for
    107         } # if
    108         printf( ")\n" )
     123                printf( ")\n" )
    109124    } # for
    110125
     
    115130    printf( "typedef int wchar_t;\n" );
    116131} # END
     132
     133# Local Variables: #
     134# tab-width: 4 #
     135# mode: awk #
     136# compile-command: "make install" #
     137# End: #
  • translator/ArgTweak/FunctionFixer.cc

    rb8508a2 rb87a5ed  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// FunctionFixer.cc --
     8//
     9// Author           : Peter A. Buhr
     10// Created On       : Sat May 16 08:12:38 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat May 16 08:17:07 2015
     13// Update Count     : 5
     14//
     15
    116#include <list>
    217#include <vector>
     
    1025
    1126namespace ArgTweak {
     27        FunctionFixer::FunctionFixer( SymTab::Indexer *ind ) : index( ind ) {
     28                if ( index == 0 ) index = new SymTab::Indexer();
     29        }
    1230
     31        FunctionFixer::~FunctionFixer() {
     32                delete index;
     33        }
    1334
    14   FunctionFixer::FunctionFixer( SymTab::Indexer *ind ) : index( ind )
    15   {
    16     if ( index == 0 ) index = new SymTab::Indexer();
    17   }
     35        DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl ) {
     36                index->visit( functionDecl );
     37                /* check for duplicate named parameters here?  It might not be an error if they're never used, on the other hand, it
     38                   might be to costly to check for duplicates every time we try a match */
     39                return Parent::mutate( functionDecl );
     40        }
    1841
    19   FunctionFixer::~FunctionFixer()
    20   {
    21     delete index;
    22   }
     42        Expression *FunctionFixer::mutate( UntypedExpr *untypedExpr ) throw ( SemanticError ) {
     43                assert( untypedExpr != 0 );
     44                NameExpr *function;
    2345
    24   DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl )
    25   {
    26     index->visit( functionDecl );
    27     /* check for duplicate named parameters here?  It might not be an
    28     error if they're never used, on the other hand, it might be to
    29     costly to check for duplicates every time we try a match */
    30     return Parent::mutate( functionDecl );
    31   }
     46                if ( ( function = dynamic_cast< NameExpr *>(untypedExpr->get_function()) ) != 0 ) {
     47                        std::list < DeclarationWithType * > options;
     48                        index->lookupId ( function->get_name(), options );
     49                        for ( std::list < DeclarationWithType * >::iterator i = options.begin(); i != options.end(); i++ ) {
     50                                FunctionType *f;
     51                                if ( ( f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) ) != 0 ) {
     52                                        std::list < DeclarationWithType * > &pars = f->get_parameters();
    3253
    33   Expression *FunctionFixer::mutate( UntypedExpr *untypedExpr )
    34     throw ( SemanticError )
    35   {
    36     assert( untypedExpr != 0 );
    37     NameExpr *function;
     54                                        bool candidateExists ;
     55                                        for ( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ )
     56                                                if ( ( candidateExists = align( f->get_parameters(), untypedExpr->get_args(), Matcher() ) ) ) break;
    3857
    39     if ( ( function = dynamic_cast< NameExpr *>(untypedExpr->get_function()) ) != 0 )
    40       {
    41         std::list < DeclarationWithType * > options;
    42         index->lookupId ( function->get_name(), options );
    43         for ( std::list < DeclarationWithType * >::iterator i = options.begin(); i != options.end(); i++ )
    44           {
    45             FunctionType *f;
    46             if ( ( f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) ) != 0 )
    47               {
    48                 std::list < DeclarationWithType * > &pars = f->get_parameters();
     58                                        if ( !candidateExists ) throw SemanticError("Error in function call");
     59                                } // if
     60                        } // for
     61                } // if
     62                return untypedExpr;
     63        }
    4964
    50                 bool candidateExists ;
    51                 for( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ )
    52                   if ( ( candidateExists = align( f->get_parameters(), untypedExpr->get_args(), Matcher() ) ) ) break;
     65        template < class L1, class L2, class Helper >
     66        bool align( L1 &pattern, L2 &possible_permutation, Helper help ) {
     67                std::map < typename Helper::key, int > positions;
     68                int p = 0;
    5369
    54                 if ( !candidateExists ) throw SemanticError("Error in function call");
    55               }
    56           }
    57       }
    58     return untypedExpr;
    59   }
     70                for ( typename L1::iterator i = pattern.begin(); i != pattern.end(); i++, p++ )
     71                        if ( help.extract_key( *i ) != Helper::null_key )
     72                                positions[ help.extract_key( *i ) ] = p;
    6073
    61   template < class L1, class L2, class Helper >
    62   bool align( L1 &pattern, L2 &possible_permutation, Helper help )
    63   {
    64     std::map < typename Helper::key, int > positions;
    65     int p = 0;
     74                L2 copy_pp( possible_permutation );
    6675
    67     for ( typename L1::iterator i = pattern.begin(); i != pattern.end(); i++, p++ )
    68       if ( help.extract_key( *i ) != Helper::null_key )
    69         positions[ help.extract_key( *i ) ] = p;
     76                std::vector< typename L2::value_type > temp(copy_pp.size(), Helper::null_value );
     77                for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++ )
     78                        if ( positions.find( help.extract_key( *i ) ) != positions.end() ) {
     79                                temp [ positions [ help.extract_key( *i ) ] ] = *i;
     80                                *i = Helper::null_value;
     81                        } // if
    7082
    71     L2 copy_pp( possible_permutation );
     83                // rest of the arguments
     84                int a = 0;
     85                bool goAhead = true;                                                    // go ahead and change the list
     86                for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++, a++ ) {
     87                        if (  *i != Helper::null_value )
     88                                if ( temp[a] == Helper::null_value )
     89                                        temp[a] = *i;
     90                                else
     91                                        { goAhead = false; /* there's something there already */; break; }
     92                        else
     93                                if ( temp[a] == Helper::null_value )
     94                                        { goAhead = false; /* can't leave empty spaces */ break; }
     95                                else
     96                                        ;                                                                       // all good, this was filled during the first pass
     97                        assert ( temp[a] != Helper::null_value );
     98                } // for
    7299
    73     std::vector< typename L2::value_type > temp(copy_pp.size(), Helper::null_value );
    74     for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++ )
    75       if ( positions.find( help.extract_key( *i ) ) != positions.end() ) {
    76         temp [ positions [ help.extract_key( *i ) ] ] = *i;
    77         *i = Helper::null_value;
    78       }
     100                // Change the original list
     101                if ( goAhead ) std::copy( temp.begin(), temp.end(), possible_permutation.begin() );
    79102
    80     // rest of the arguments
    81     int a = 0;
    82     bool goAhead = true;  // go ahead and change the list
    83     for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++, a++ ) {
    84       if (  *i != Helper::null_value )
    85         if ( temp[a] == Helper::null_value )
    86           temp[a] = *i;
    87         else
    88           { goAhead = false; /* there's something there already */; break; }
    89       else
    90         if ( temp[a] == Helper::null_value )
    91           { goAhead = false; /* can't leave empty spaces */ break; }
    92         else
    93           ; // all good, this was filled during the first pass
    94       assert ( temp[a] != Helper::null_value );
    95     }
     103                return goAhead;
     104        }
    96105
    97     // Change the original list
    98     if ( goAhead ) std::copy( temp.begin(), temp.end(), possible_permutation.begin() );
     106        std::string FunctionFixer::Matcher::null_key("");
     107        Expression *FunctionFixer::Matcher::null_value = 0;
    99108
    100     return goAhead;
    101   }
     109        std::string FunctionFixer::Matcher::extract_key ( DeclarationWithType *decl ) {
     110                return decl->get_name();
     111        }
    102112
    103   std::string FunctionFixer::Matcher::null_key("");
    104   Expression *FunctionFixer::Matcher::null_value = 0;
     113        std::string FunctionFixer::Matcher::extract_key ( Expression *expression ) {
     114                if ( expression->get_argName() == 0 )
     115                        return std::string("");
     116                else
     117                        return *(expression->get_argName());
     118        }
     119} // namespace ArgTweak
    105120
    106   std::string FunctionFixer::Matcher::extract_key ( DeclarationWithType *decl ) {
    107     return decl->get_name();
    108   }
    109 
    110   std::string FunctionFixer::Matcher::extract_key ( Expression *expression ) {
    111     if ( expression->get_argName() == 0 )
    112       return std::string("");
    113     else
    114       return *(expression->get_argName());
    115   }
    116 
    117 } // namespace ArgTweak
     121// Local Variables: //
     122// tab-width: 4 //
     123// mode: c++ //
     124// compile-command: "make install" //
     125// End: //
  • translator/MakeLibCfa.cc

    rb8508a2 rb87a5ed  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: MakeLibCfa.cc,v 1.6 2005/08/29 20:14:14 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// MakeLibCfa.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sat May 16 10:33:33 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat May 16 10:40:44 2015
     13// Update Count     : 13
     14//
    715
    816#include "MakeLibCfa.h"
     17#include "SynTree/Visitor.h"
    918#include "SynTree/Declaration.h"
    1019#include "SynTree/Type.h"
     
    1221#include "SynTree/Statement.h"
    1322#include "SynTree/Initializer.h"
    14 #include "SynTree/Visitor.h"
    1523#include "CodeGen/OperatorTable.h"
    1624#include "UniqueName.h"
    1725
     26namespace LibCfa {
     27        class MakeLibCfa : public Visitor {
     28          public:
     29                void visit( FunctionDecl* funcDecl );
     30                void visit( ObjectDecl* objDecl );
     31 
     32                std::list< Declaration* > &get_newDecls() { return newDecls; }
     33          private:
     34                std::list< Declaration* > newDecls;
     35        };
    1836
    19 namespace LibCfa {
     37        void makeLibCfa( std::list< Declaration* > &prelude ) {
     38                MakeLibCfa maker;
     39                acceptAll( prelude, maker );
     40                prelude.splice( prelude.end(), maker.get_newDecls() );
     41        }
    2042
    21 class MakeLibCfa : public Visitor
    22 {
    23 public:
    24   void visit( FunctionDecl* funcDecl );
    25   void visit( ObjectDecl* objDecl );
     43        void MakeLibCfa::visit( FunctionDecl* origFuncDecl ) {
     44                if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
    2645 
    27   std::list< Declaration* > &get_newDecls() { return newDecls; }
     46                FunctionDecl *funcDecl = origFuncDecl->clone();
     47                CodeGen::OperatorInfo opInfo;
     48                bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo );
     49                assert( lookResult );
     50                assert( !funcDecl->get_statements() );
     51                UntypedExpr *newExpr = new UntypedExpr( new NameExpr( funcDecl->get_name() ) );
     52                UniqueName paramNamer( "_p" );
     53                std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin();
     54                assert( param != funcDecl->get_functionType()->get_parameters().end() );
     55
     56                if ( (*param)->get_name() == "" ) {
     57                        (*param)->set_name( paramNamer.newName() );
     58                        (*param)->set_linkage( LinkageSpec::C );
     59                } // if
     60
     61                switch( opInfo.type ) {
     62                  case CodeGen::OT_INDEX:
     63                  case CodeGen::OT_CALL:
     64                  case CodeGen::OT_PREFIX:
     65                  case CodeGen::OT_POSTFIX:
     66                  case CodeGen::OT_INFIX:
     67                        newExpr->get_args().push_back( new VariableExpr( *param ) );
     68                        break;
     69                  case CodeGen::OT_PREFIXASSIGN:
     70                  case CodeGen::OT_POSTFIXASSIGN:
     71                  case CodeGen::OT_INFIXASSIGN:
     72                        {
     73                                newExpr->get_args().push_back( new VariableExpr( *param ) );
     74                                // UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     75                                // deref->get_args().push_back( new VariableExpr( *param ) );
     76                                // newExpr->get_args().push_back( deref );
     77                                break;
     78                        }
     79                  case CodeGen::OT_CONSTANT:
     80                        assert( false );
     81                } // switch
     82
     83                for ( param++; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
     84                        if ( (*param)->get_name() == "" ) {
     85                                (*param)->set_name( paramNamer.newName() );
     86                                (*param)->set_linkage( LinkageSpec::C );
     87                        }
     88                        newExpr->get_args().push_back( new VariableExpr( *param ) );
     89                } // for
     90                funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
     91                funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
     92                newDecls.push_back( funcDecl );
     93        }
     94
     95        void MakeLibCfa::visit( ObjectDecl* origObjDecl ) {
     96                if ( origObjDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
    2897 
    29 private:
    30   std::list< Declaration* > newDecls;
    31 };
     98                ObjectDecl *objDecl = origObjDecl->clone();
     99                assert( !objDecl->get_init() );
     100                std::list< Expression* > noDesignators;
     101                objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators ) );
     102                newDecls.push_back( objDecl );
     103        }
     104} // namespace LibCfa
    32105
    33 void
    34 makeLibCfa( std::list< Declaration* > &prelude )
    35 {
    36   MakeLibCfa maker;
    37   acceptAll( prelude, maker );
    38   prelude.splice( prelude.end(), maker.get_newDecls() );
    39 }
    40 
    41 void
    42 MakeLibCfa::visit( FunctionDecl* origFuncDecl )
    43 {
    44   if( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
    45  
    46   FunctionDecl *funcDecl = origFuncDecl->clone();
    47   CodeGen::OperatorInfo opInfo;
    48   bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo );
    49   assert( lookResult );
    50   assert( !funcDecl->get_statements() );
    51   UntypedExpr *newExpr = new UntypedExpr( new NameExpr( funcDecl->get_name() ) );
    52   UniqueName paramNamer( "_p" );
    53   std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin();
    54   assert( param != funcDecl->get_functionType()->get_parameters().end() );
    55   if( (*param)->get_name() == "" ) {
    56     (*param)->set_name( paramNamer.newName() );
    57     (*param)->set_linkage( LinkageSpec::C );
    58   }
    59   switch( opInfo.type ) {
    60   case CodeGen::OT_INDEX:
    61   case CodeGen::OT_CALL:
    62   case CodeGen::OT_PREFIX:
    63   case CodeGen::OT_POSTFIX:
    64   case CodeGen::OT_INFIX:
    65     newExpr->get_args().push_back( new VariableExpr( *param ) );
    66     break;
    67    
    68   case CodeGen::OT_PREFIXASSIGN:
    69   case CodeGen::OT_POSTFIXASSIGN:
    70   case CodeGen::OT_INFIXASSIGN:
    71   {
    72     newExpr->get_args().push_back( new VariableExpr( *param ) );
    73 ///     UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    74 ///     deref->get_args().push_back( new VariableExpr( *param ) );
    75 ///     newExpr->get_args().push_back( deref );
    76     break;
    77   }
    78    
    79   case CodeGen::OT_CONSTANT:
    80     assert( false );
    81   }
    82   for( param++; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
    83     if( (*param)->get_name() == "" ) {
    84       (*param)->set_name( paramNamer.newName() );
    85       (*param)->set_linkage( LinkageSpec::C );
    86     }
    87     newExpr->get_args().push_back( new VariableExpr( *param ) );
    88   }
    89   funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
    90   funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
    91   newDecls.push_back( funcDecl );
    92 }
    93 
    94 void
    95 MakeLibCfa::visit( ObjectDecl* origObjDecl )
    96 {
    97   if( origObjDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
    98  
    99   ObjectDecl *objDecl = origObjDecl->clone();
    100   assert( !objDecl->get_init() );
    101   std::list< Expression* > noDesignators;
    102   objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators ) );
    103   newDecls.push_back( objDecl );
    104 }
    105 
    106 } // namespace LibCfa
     106// Local Variables: //
     107// tab-width: 4 //
     108// mode: c++ //
     109// compile-command: "make install" //
     110// End: //
  • translator/MakeLibCfa.h

    rb8508a2 rb87a5ed  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: MakeLibCfa.h,v 1.2 2005/08/29 20:14:14 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// MakeLibCfa.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sat May 16 10:42:14 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat May 16 10:43:29 2015
     13// Update Count     : 1
     14//
    715
    816#ifndef LIBCFA_MAKELIBCFA_H
     
    1321
    1422namespace LibCfa {
    15 
    16 void makeLibCfa( std::list< Declaration* > &prelude );
    17 
     23        void makeLibCfa( std::list< Declaration* > &prelude );
    1824} // namespace LibCfa
    1925
    20 #endif /* #ifndef LIBCFA_MAKELIBCFA_H */
     26#endif // LIBCFA_MAKELIBCFA_H
     27
     28// Local Variables: //
     29// tab-width: 4 //
     30// mode: c++ //
     31// compile-command: "make install" //
     32// End: //
  • translator/Makefile.in

    rb8508a2 rb87a5ed  
    1 # This makefile is adapted from Peter Miller's article
    2 # "Recursive Make Considered Harmful"
    3 #
    4 # http://www.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html
     1######################### -*- Mode: Makefile-Gmake -*- ########################
     2##
     3## Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     4##
     5## The contents of this file are covered under the licence agreement in the
     6## file "LICENCE" distributed with Cforall.
     7##
     8## Makefile.in --
     9##
     10## Author           : Peter A. Buhr
     11## Created On       : Sat May 16 08:37:37 2015
     12## Last Modified By : Peter A. Buhr
     13## Last Modified On : Sat May 16 08:38:52 2015
     14## Update Count     : 2
     15###############################################################################
    516
    6 MODULES := Common Parser SynTree SymTab ResolvExpr CodeGen ControlStruct GenPoly Tuples InitTweak Designators #Try ArgTweak Explain
     17# This makefile is adapted from Peter Miller's article "Recursive Make Considered Harmful"
     18
     19MODULES := Common Parser SynTree SymTab ResolvExpr CodeGen ControlStruct GenPoly Tuples InitTweak Designators # Try ArgTweak Explain
    720TARGET := cfa-cpp
    821
    9 all: $(TARGET)
     22all: ${TARGET}
    1023
    1124# look for include files in each of the modules
     
    1629# this is the back-end compiler, used to compile libcfa & builtins to link with user code
    1730BACKEND_CC := @BACKEND_CC@
    18 
    19 # uncomment the definition of this variable to enable purify
    20 #  (do a "purerun" first)
    21 #PURIFY := purify --cache-dir=$(HOME)/tmp
    2231
    2332# extra libraries if required
     
    3140
    3241# include the description for each module
    33 include $(patsubst %,%/module.mk,$(MODULES))
     42include ${patsubst %,%/module.mk,${MODULES}}
    3443
    3544# determine the object files
    36 OBJ := $(patsubst %.cc,%.o,$(filter %.cc,$(SRC))) \
    37        $(patsubst %.y,%.tab.o,$(filter %.y,$(SRC))) \
    38        $(patsubst %.l,%.yy.o,$(filter %.l,$(SRC)))
     45OBJ := ${patsubst %.cc,%.o,${filter %.cc,${SRC}}} \
     46       ${patsubst %.y,%.tab.o,${filter %.y,${SRC}}} \
     47       ${patsubst %.l,%.yy.o,${filter %.l,${SRC}}}
    3948
    4049# include the C include dependencies
    41 DEPS := $(OBJ:.o=.d)
    42 -include $(DEPS)
     50DEPS := ${OBJ:.o=.d}
     51-include ${DEPS}
    4352
    4453# link the program
    45 $(TARGET): $(OBJ)
    46         $(PURIFY) $(CXX) -o $@ $(OBJ) $(LIBS)
     54${TARGET}: ${OBJ}
     55        ${PURIFY} ${CXX} -o $@ ${OBJ} ${LIBS}
    4756
    4857#installing
    49 install: $(TARGET)
    50         $(INSTALL) -d @CFA_LIBDIR@
    51         $(INSTALL) $(TARGET) @CFA_LIBDIR@
     58install: ${TARGET}
     59        ${INSTALL} -d @CFA_LIBDIR@
     60        ${INSTALL} ${TARGET} @CFA_LIBDIR@
    5261
    5362# clean-up rule
    5463clean:
    55         rm -f $(OBJ) $(DEPS) $(TARGET) tags $(EXTRA_OUTPUT)
     64        rm -f ${OBJ} ${DEPS} ${TARGET} tags ${EXTRA_OUTPUT}
    5665        find . -name "Expected*" -prune -o \( -name "*.tst" -o -name "report" \) -print | xargs rm -f
    5766        find . -name "core*" -print | xargs rm -f
  • translator/Parser/DeclarationNode.cc

    rb8508a2 rb87a5ed  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// DeclarationNode.cc --
     8//
     9// Author           : Rodolfo G. Esteves
     10// Created On       : Sat May 16 12:34:05 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat May 16 12:38:20 2015
     13// Update Count     : 4
     14//
     15
    116#include <string>
    217#include <list>
     
    2338
    2439DeclarationNode *DeclarationNode::clone() const {
    25     DeclarationNode *newnode = new DeclarationNode;
    26     newnode->type = maybeClone( type );
    27     newnode->name = name;
    28     newnode->storageClasses = storageClasses;
    29     newnode->bitfieldWidth = maybeClone( bitfieldWidth );
    30     newnode->hasEllipsis = hasEllipsis;
    31     newnode->initializer = initializer;
    32     newnode->next = maybeClone( next );
    33     newnode->linkage = linkage;
    34     return newnode;
     40        DeclarationNode *newnode = new DeclarationNode;
     41        newnode->type = maybeClone( type );
     42        newnode->name = name;
     43        newnode->storageClasses = storageClasses;
     44        newnode->bitfieldWidth = maybeClone( bitfieldWidth );
     45        newnode->hasEllipsis = hasEllipsis;
     46        newnode->initializer = initializer;
     47        newnode->next = maybeClone( next );
     48        newnode->linkage = linkage;
     49        return newnode;
    3550}
    3651
     
    3954
    4055DeclarationNode::~DeclarationNode() {
    41     delete type;
    42     delete bitfieldWidth;
    43     delete initializer;
     56        delete type;
     57        delete bitfieldWidth;
     58        delete initializer;
    4459}
    4560
    4661bool DeclarationNode::get_hasEllipsis() const {
    47     return hasEllipsis;
     62        return hasEllipsis;
    4863}
    4964
    5065const char *storageClassName[] = {
    51     // order must correspond with DeclarationNode::StorageClass
    52     "extern",
    53     "static",
    54     "auto",
    55     "register",
    56     "inline",
    57     "fortran",
     66        // order must correspond with DeclarationNode::StorageClass
     67        "extern",
     68        "static",
     69        "auto",
     70        "register",
     71        "inline",
     72        "fortran",
    5873};
    5974
    6075void DeclarationNode::print( std::ostream &os, int indent ) const {
    61     os << string(indent, ' ' );
    62     if ( name == "" ) {
    63         os << "unnamed: ";
    64     } else {
    65         os << name << ": ";
    66     }
    67 
    68     if ( linkage != LinkageSpec::Cforall ) {
    69         os << LinkageSpec::toString( linkage ) << " ";
    70     }
    71 
    72     printEnums( storageClasses.begin(), storageClasses.end(), storageClassName, os );
    73     if ( type ) {
    74         type->print( os, indent );
    75     } else {
    76         os << "untyped entity ";
    77     }
    78 
    79     if ( bitfieldWidth ) {
    80         os << endl << string(indent+2,  ' ') << "with bitfield width ";
    81         bitfieldWidth->printOneLine( os );
    82     }
    83 
    84     if ( initializer != 0 ) {
    85         os << endl << string(indent+2,  ' ') << "with initializer ";
    86         initializer->printOneLine( os );
    87     }
    88 
    89     os << endl;
     76        os << string(indent, ' ' );
     77        if ( name == "" ) {
     78                os << "unnamed: ";
     79        } else {
     80                os << name << ": ";
     81        }
     82
     83        if ( linkage != LinkageSpec::Cforall ) {
     84                os << LinkageSpec::toString( linkage ) << " ";
     85        }
     86
     87        printEnums( storageClasses.begin(), storageClasses.end(), storageClassName, os );
     88        if ( type ) {
     89                type->print( os, indent );
     90        } else {
     91                os << "untyped entity ";
     92        }
     93
     94        if ( bitfieldWidth ) {
     95                os << endl << string(indent+2,  ' ') << "with bitfield width ";
     96                bitfieldWidth->printOneLine( os );
     97        }
     98
     99        if ( initializer != 0 ) {
     100                os << endl << string(indent+2,  ' ') << "with initializer ";
     101                initializer->printOneLine( os );
     102        }
     103
     104        os << endl;
    90105}
    91106
    92107void DeclarationNode::printList( std::ostream &os, int indent ) const {
    93     ParseNode::printList( os, indent );
    94     if ( hasEllipsis ) {
    95         os << string( indent, ' ' )  << "and a variable number of other arguments" << endl;
    96     }
     108        ParseNode::printList( os, indent );
     109        if ( hasEllipsis ) {
     110                os << string( indent, ' ' )  << "and a variable number of other arguments" << endl;
     111        }
    97112}
    98113
    99114DeclarationNode *DeclarationNode::newFunction( std::string *name, DeclarationNode *ret, DeclarationNode *param, StatementNode *body, bool newStyle ) {
    100     DeclarationNode *newnode = new DeclarationNode;
    101     newnode->name = assign_strptr( name );
    102 
    103     newnode->type = new TypeData( TypeData::Function );
    104     newnode->type->function->params = param;
    105     newnode->type->function->newStyle = newStyle;
    106     newnode->type->function->body = body;
    107 
    108     if ( body ) {
    109         newnode->type->function->hasBody = true;
    110     }
    111 
    112     if ( ret ) {
    113         newnode->type->base = ret->type;
    114         ret->type = 0;
    115         delete ret;
    116     }
    117 
    118     return newnode;
     115        DeclarationNode *newnode = new DeclarationNode;
     116        newnode->name = assign_strptr( name );
     117
     118        newnode->type = new TypeData( TypeData::Function );
     119        newnode->type->function->params = param;
     120        newnode->type->function->newStyle = newStyle;
     121        newnode->type->function->body = body;
     122
     123        if ( body ) {
     124                newnode->type->function->hasBody = true;
     125        }
     126
     127        if ( ret ) {
     128                newnode->type->base = ret->type;
     129                ret->type = 0;
     130                delete ret;
     131        }
     132
     133        return newnode;
    119134}
    120135
    121136DeclarationNode *DeclarationNode::newQualifier( Qualifier q ) {
    122     DeclarationNode *newnode = new DeclarationNode;
    123     newnode->type = new TypeData();
    124     newnode->type->qualifiers.push_back( q );
    125     return newnode;
     137        DeclarationNode *newnode = new DeclarationNode;
     138        newnode->type = new TypeData();
     139        newnode->type->qualifiers.push_back( q );
     140        return newnode;
    126141}
    127142
    128143DeclarationNode *DeclarationNode::newStorageClass( StorageClass sc ) {
    129     DeclarationNode *newnode = new DeclarationNode;
    130     newnode->storageClasses.push_back( sc );
    131     return newnode;
     144        DeclarationNode *newnode = new DeclarationNode;
     145        newnode->storageClasses.push_back( sc );
     146        return newnode;
    132147}
    133148
    134149DeclarationNode *DeclarationNode::newBasicType( BasicType bt ) {
    135     DeclarationNode *newnode = new DeclarationNode;
    136     newnode->type = new TypeData( TypeData::Basic );
    137     newnode->type->basic->typeSpec.push_back( bt );
    138     return newnode;
     150        DeclarationNode *newnode = new DeclarationNode;
     151        newnode->type = new TypeData( TypeData::Basic );
     152        newnode->type->basic->typeSpec.push_back( bt );
     153        return newnode;
    139154}
    140155
    141156DeclarationNode *DeclarationNode::newModifier( Modifier mod ) {
    142     DeclarationNode *newnode = new DeclarationNode;
    143     newnode->type = new TypeData( TypeData::Basic );
    144     newnode->type->basic->modifiers.push_back( mod );
    145     return newnode;
     157        DeclarationNode *newnode = new DeclarationNode;
     158        newnode->type = new TypeData( TypeData::Basic );
     159        newnode->type->basic->modifiers.push_back( mod );
     160        return newnode;
    146161}
    147162
    148163DeclarationNode *DeclarationNode::newForall( DeclarationNode* forall ) {
    149     DeclarationNode *newnode = new DeclarationNode;
    150     newnode->type = new TypeData( TypeData::Unknown );
    151     newnode->type->forall = forall;
    152     return newnode;
     164        DeclarationNode *newnode = new DeclarationNode;
     165        newnode->type = new TypeData( TypeData::Unknown );
     166        newnode->type->forall = forall;
     167        return newnode;
    153168}
    154169
    155170DeclarationNode *DeclarationNode::newFromTypedef( std::string* name ) {
    156     DeclarationNode *newnode = new DeclarationNode;
    157     newnode->type = new TypeData( TypeData::SymbolicInst );
    158     newnode->type->symbolic->name = assign_strptr( name );
    159     newnode->type->symbolic->isTypedef = true;
    160     newnode->type->symbolic->params = 0;
    161     return newnode;
     171        DeclarationNode *newnode = new DeclarationNode;
     172        newnode->type = new TypeData( TypeData::SymbolicInst );
     173        newnode->type->symbolic->name = assign_strptr( name );
     174        newnode->type->symbolic->isTypedef = true;
     175        newnode->type->symbolic->params = 0;
     176        return newnode;
    162177}
    163178
    164179DeclarationNode *DeclarationNode::newAggregate( TyCon kind, std::string* name, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields ) {
    165     DeclarationNode *newnode = new DeclarationNode;
    166     newnode->type = new TypeData( TypeData::Aggregate );
    167     newnode->type->aggregate->kind = kind;
    168     newnode->type->aggregate->name = assign_strptr( name );
    169     if ( newnode->type->aggregate->name == "" ) {
    170         newnode->type->aggregate->name = DeclarationNode::anonymous.newName();
    171     }
    172     newnode->type->aggregate->params = formals;
    173     newnode->type->aggregate->actuals = actuals;
    174     newnode->type->aggregate->members = fields;
    175     return newnode;
     180        DeclarationNode *newnode = new DeclarationNode;
     181        newnode->type = new TypeData( TypeData::Aggregate );
     182        newnode->type->aggregate->kind = kind;
     183        newnode->type->aggregate->name = assign_strptr( name );
     184        if ( newnode->type->aggregate->name == "" ) {
     185                newnode->type->aggregate->name = DeclarationNode::anonymous.newName();
     186        }
     187        newnode->type->aggregate->params = formals;
     188        newnode->type->aggregate->actuals = actuals;
     189        newnode->type->aggregate->members = fields;
     190        return newnode;
    176191}
    177192
    178193DeclarationNode *DeclarationNode::newEnum( std::string *name, DeclarationNode *constants ) {
    179     DeclarationNode *newnode = new DeclarationNode;
    180     newnode->name = assign_strptr( name );
    181     newnode->type = new TypeData( TypeData::Enum );
    182     newnode->type->enumeration->name = newnode->name;
    183     if ( newnode->type->enumeration->name == "" ) {
    184         newnode->type->enumeration->name = DeclarationNode::anonymous.newName();
    185     }
    186     newnode->type->enumeration->constants = constants;
    187     return newnode;
     194        DeclarationNode *newnode = new DeclarationNode;
     195        newnode->name = assign_strptr( name );
     196        newnode->type = new TypeData( TypeData::Enum );
     197        newnode->type->enumeration->name = newnode->name;
     198        if ( newnode->type->enumeration->name == "" ) {
     199                newnode->type->enumeration->name = DeclarationNode::anonymous.newName();
     200        }
     201        newnode->type->enumeration->constants = constants;
     202        return newnode;
    188203}
    189204
    190205DeclarationNode *DeclarationNode::newEnumConstant( std::string* name, ExpressionNode *constant ) {
    191     DeclarationNode *newnode = new DeclarationNode;
    192     newnode->name = assign_strptr( name );
    193     // do something with the constant
    194     return newnode;
     206        DeclarationNode *newnode = new DeclarationNode;
     207        newnode->name = assign_strptr( name );
     208        // do something with the constant
     209        return newnode;
    195210}
    196211
    197212DeclarationNode *DeclarationNode::newName( std::string* name ) {
    198     DeclarationNode *newnode = new DeclarationNode;
    199     newnode->name = assign_strptr( name );
    200     return newnode;
     213        DeclarationNode *newnode = new DeclarationNode;
     214        newnode->name = assign_strptr( name );
     215        return newnode;
    201216}
    202217
    203218DeclarationNode *DeclarationNode::newFromTypeGen( std::string* name, ExpressionNode *params ) {
    204     DeclarationNode *newnode = new DeclarationNode;
    205     newnode->type = new TypeData( TypeData::SymbolicInst );
    206     newnode->type->symbolic->name = assign_strptr( name );
    207     newnode->type->symbolic->isTypedef = false;
    208     newnode->type->symbolic->actuals = params;
    209     return newnode;
     219        DeclarationNode *newnode = new DeclarationNode;
     220        newnode->type = new TypeData( TypeData::SymbolicInst );
     221        newnode->type->symbolic->name = assign_strptr( name );
     222        newnode->type->symbolic->isTypedef = false;
     223        newnode->type->symbolic->actuals = params;
     224        return newnode;
    210225}
    211226
    212227DeclarationNode *DeclarationNode::newTypeParam( TypeClass tc, std::string* name ) {
    213     DeclarationNode *newnode = new DeclarationNode;
    214     newnode->name = assign_strptr( name );
    215     newnode->type = new TypeData( TypeData::Variable );
    216     newnode->type->variable->tyClass = tc;
    217     newnode->type->variable->name = newnode->name;
    218     return newnode;
     228        DeclarationNode *newnode = new DeclarationNode;
     229        newnode->name = assign_strptr( name );
     230        newnode->type = new TypeData( TypeData::Variable );
     231        newnode->type->variable->tyClass = tc;
     232        newnode->type->variable->name = newnode->name;
     233        return newnode;
    219234}
    220235
    221236DeclarationNode *DeclarationNode::newContext( std::string *name, DeclarationNode *params, DeclarationNode *asserts ) {
    222     DeclarationNode *newnode = new DeclarationNode;
    223     newnode->type = new TypeData( TypeData::Aggregate );
    224     newnode->type->aggregate->kind = Context;
    225     newnode->type->aggregate->params = params;
    226     newnode->type->aggregate->members = asserts;
    227     newnode->type->aggregate->name = assign_strptr( name );
    228     return newnode;
     237        DeclarationNode *newnode = new DeclarationNode;
     238        newnode->type = new TypeData( TypeData::Aggregate );
     239        newnode->type->aggregate->kind = Context;
     240        newnode->type->aggregate->params = params;
     241        newnode->type->aggregate->members = asserts;
     242        newnode->type->aggregate->name = assign_strptr( name );
     243        return newnode;
    229244}
    230245
    231246DeclarationNode *DeclarationNode::newContextUse( std::string *name, ExpressionNode *params ) {
    232     DeclarationNode *newnode = new DeclarationNode;
    233     newnode->type = new TypeData( TypeData::AggregateInst );
    234     newnode->type->aggInst->aggregate = new TypeData( TypeData::Aggregate );
    235     newnode->type->aggInst->aggregate->aggregate->kind = Context;
    236     newnode->type->aggInst->aggregate->aggregate->name = assign_strptr( name );
    237     newnode->type->aggInst->params = params;
    238     return newnode;
     247        DeclarationNode *newnode = new DeclarationNode;
     248        newnode->type = new TypeData( TypeData::AggregateInst );
     249        newnode->type->aggInst->aggregate = new TypeData( TypeData::Aggregate );
     250        newnode->type->aggInst->aggregate->aggregate->kind = Context;
     251        newnode->type->aggInst->aggregate->aggregate->name = assign_strptr( name );
     252        newnode->type->aggInst->params = params;
     253        return newnode;
    239254}
    240255
    241256DeclarationNode *DeclarationNode::newTypeDecl( std::string *name, DeclarationNode *typeParams ) {
    242     DeclarationNode *newnode = new DeclarationNode;
    243     newnode->name = assign_strptr( name );
    244     newnode->type = new TypeData( TypeData::Symbolic );
    245     newnode->type->symbolic->isTypedef = false;
    246     newnode->type->symbolic->params = typeParams;
    247     newnode->type->symbolic->name = newnode->name;
    248     return newnode;
     257        DeclarationNode *newnode = new DeclarationNode;
     258        newnode->name = assign_strptr( name );
     259        newnode->type = new TypeData( TypeData::Symbolic );
     260        newnode->type->symbolic->isTypedef = false;
     261        newnode->type->symbolic->params = typeParams;
     262        newnode->type->symbolic->name = newnode->name;
     263        return newnode;
    249264}
    250265
    251266DeclarationNode *DeclarationNode::newPointer( DeclarationNode *qualifiers ) {
    252     DeclarationNode *newnode = new DeclarationNode;
    253     newnode->type = new TypeData( TypeData::Pointer );
    254     return newnode->addQualifiers( qualifiers );
     267        DeclarationNode *newnode = new DeclarationNode;
     268        newnode->type = new TypeData( TypeData::Pointer );
     269        return newnode->addQualifiers( qualifiers );
    255270}
    256271
    257272DeclarationNode *DeclarationNode::newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic ) {
    258     DeclarationNode *newnode = new DeclarationNode;
    259     newnode->type = new TypeData( TypeData::Array );
    260     newnode->type->array->dimension = size;
    261     newnode->type->array->isStatic = isStatic;
    262     newnode->type->array->isVarLen = false;
    263     return newnode->addQualifiers( qualifiers );
     273        DeclarationNode *newnode = new DeclarationNode;
     274        newnode->type = new TypeData( TypeData::Array );
     275        newnode->type->array->dimension = size;
     276        newnode->type->array->isStatic = isStatic;
     277        newnode->type->array->isVarLen = false;
     278        return newnode->addQualifiers( qualifiers );
    264279}
    265280
    266281DeclarationNode *DeclarationNode::newVarArray( DeclarationNode *qualifiers ) {
    267     DeclarationNode *newnode = new DeclarationNode;
    268     newnode->type = new TypeData( TypeData::Array );
    269     newnode->type->array->dimension = 0;
    270     newnode->type->array->isStatic = false;
    271     newnode->type->array->isVarLen = true;
    272     return newnode->addQualifiers( qualifiers );
     282        DeclarationNode *newnode = new DeclarationNode;
     283        newnode->type = new TypeData( TypeData::Array );
     284        newnode->type->array->dimension = 0;
     285        newnode->type->array->isStatic = false;
     286        newnode->type->array->isVarLen = true;
     287        return newnode->addQualifiers( qualifiers );
    273288}
    274289
    275290DeclarationNode *DeclarationNode::newBitfield( ExpressionNode *size ) {
    276     DeclarationNode *newnode = new DeclarationNode;
    277     newnode->bitfieldWidth = size;
    278     return newnode;
     291        DeclarationNode *newnode = new DeclarationNode;
     292        newnode->bitfieldWidth = size;
     293        return newnode;
    279294}
    280295
    281296DeclarationNode *DeclarationNode::newTuple( DeclarationNode *members ) {
    282     DeclarationNode *newnode = new DeclarationNode;
    283     newnode->type = new TypeData( TypeData::Tuple );
    284     newnode->type->tuple->members = members;
    285     return newnode;
     297        DeclarationNode *newnode = new DeclarationNode;
     298        newnode->type = new TypeData( TypeData::Tuple );
     299        newnode->type->tuple->members = members;
     300        return newnode;
    286301}
    287302
    288303DeclarationNode *DeclarationNode::newTypeof( ExpressionNode *expr ) {
    289     DeclarationNode *newnode = new DeclarationNode;
    290     newnode->type = new TypeData( TypeData::Typeof );
    291     newnode->type->typeexpr->expr = expr;
    292     return newnode;
     304        DeclarationNode *newnode = new DeclarationNode;
     305        newnode->type = new TypeData( TypeData::Typeof );
     306        newnode->type->typeexpr->expr = expr;
     307        return newnode;
    293308}
    294309
    295310DeclarationNode *DeclarationNode::newAttr( std::string *name, ExpressionNode *expr ) {
    296     DeclarationNode *newnode = new DeclarationNode;
    297     newnode->type = new TypeData( TypeData::Attr );
    298     newnode->type->attr->name = assign_strptr( name );
    299     newnode->type->attr->expr = expr;
    300     return newnode;
     311        DeclarationNode *newnode = new DeclarationNode;
     312        newnode->type = new TypeData( TypeData::Attr );
     313        newnode->type->attr->name = assign_strptr( name );
     314        newnode->type->attr->expr = expr;
     315        return newnode;
    301316}
    302317
    303318DeclarationNode *DeclarationNode::newAttr( std::string *name, DeclarationNode *type ) {
    304     DeclarationNode *newnode = new DeclarationNode;
    305     newnode->type = new TypeData( TypeData::Attr );
    306     newnode->type->attr->name = assign_strptr( name );
    307     newnode->type->attr->type = type;
    308     return newnode;
     319        DeclarationNode *newnode = new DeclarationNode;
     320        newnode->type = new TypeData( TypeData::Attr );
     321        newnode->type->attr->name = assign_strptr( name );
     322        newnode->type->attr->type = type;
     323        return newnode;
    309324}
    310325
    311326static void addQualifiersToType( TypeData *&src, TypeData *dst ) {
    312     if ( src && dst ) {
    313         if ( src->forall && dst->kind == TypeData::Function ) {
    314             if ( dst->forall ) {
    315                 dst->forall->appendList( src->forall );
    316             } else {
    317                 dst->forall = src->forall;
    318             }
    319             src->forall = 0;
    320         }
    321         if ( dst->base ) {
    322             addQualifiersToType( src, dst->base );
    323         } else if ( dst->kind == TypeData::Function ) {
    324             dst->base = src;
    325             src = 0;
    326         } else {
    327             dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
    328         }
    329     }
    330 }
    331      
     327        if ( src && dst ) {
     328                if ( src->forall && dst->kind == TypeData::Function ) {
     329                        if ( dst->forall ) {
     330                                dst->forall->appendList( src->forall );
     331                        } else {
     332                                dst->forall = src->forall;
     333                        }
     334                        src->forall = 0;
     335                }
     336                if ( dst->base ) {
     337                        addQualifiersToType( src, dst->base );
     338                } else if ( dst->kind == TypeData::Function ) {
     339                        dst->base = src;
     340                        src = 0;
     341                } else {
     342                        dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
     343                }
     344        }
     345}
     346         
    332347DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
    333     if ( q ) {
    334         storageClasses.splice( storageClasses.end(), q->storageClasses );
    335         if ( q->type ) {
    336             if ( ! type ) {
    337                 type = new TypeData;
    338             }
    339             addQualifiersToType( q->type, type );
    340             if ( q->type && q->type->forall ) {
    341                 if ( type->forall ) {
    342                     type->forall->appendList( q->type->forall );
     348        if ( q ) {
     349                storageClasses.splice( storageClasses.end(), q->storageClasses );
     350                if ( q->type ) {
     351                        if ( ! type ) {
     352                                type = new TypeData;
     353                        }
     354                        addQualifiersToType( q->type, type );
     355                        if ( q->type && q->type->forall ) {
     356                                if ( type->forall ) {
     357                                        type->forall->appendList( q->type->forall );
     358                                } else {
     359                                        type->forall = q->type->forall;
     360                                }
     361                                q->type->forall = 0;
     362                        }
     363                }
     364        }
     365        delete q;
     366        return this;
     367}
     368
     369DeclarationNode *DeclarationNode::copyStorageClasses( DeclarationNode *q ) {
     370        storageClasses = q->storageClasses;
     371        return this;
     372}
     373
     374static void addTypeToType( TypeData *&src, TypeData *&dst ) {
     375        if ( src && dst ) {
     376                if ( src->forall && dst->kind == TypeData::Function ) {
     377                        if ( dst->forall ) {
     378                                dst->forall->appendList( src->forall );
     379                        } else {
     380                                dst->forall = src->forall;
     381                        }
     382                        src->forall = 0;
     383                }
     384                if ( dst->base ) {
     385                        addTypeToType( src, dst->base );
    343386                } else {
    344                     type->forall = q->type->forall;
    345                 }
    346                 q->type->forall = 0;
    347             }
    348         }
    349     }
    350     delete q;
    351     return this;
    352 }
    353 
    354 DeclarationNode *DeclarationNode::copyStorageClasses( DeclarationNode *q ) {
    355     storageClasses = q->storageClasses;
    356     return this;
    357 }
    358 
    359 static void addTypeToType( TypeData *&src, TypeData *&dst ) {
    360     if ( src && dst ) {
    361         if ( src->forall && dst->kind == TypeData::Function ) {
    362             if ( dst->forall ) {
    363                 dst->forall->appendList( src->forall );
    364             } else {
    365                 dst->forall = src->forall;
    366             }
    367             src->forall = 0;
    368         }
    369         if ( dst->base ) {
    370             addTypeToType( src, dst->base );
    371         } else {
    372             switch ( dst->kind ) {
    373               case TypeData::Unknown:
    374                 src->qualifiers.splice( src->qualifiers.end(), dst->qualifiers );
    375                 dst = src;
    376                 src = 0;
     387                        switch ( dst->kind ) {
     388                          case TypeData::Unknown:
     389                                src->qualifiers.splice( src->qualifiers.end(), dst->qualifiers );
     390                                dst = src;
     391                                src = 0;
     392                                break;
     393
     394                          case TypeData::Basic:
     395                                dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
     396                                if ( src->kind != TypeData::Unknown ) {
     397                                        assert( src->kind == TypeData::Basic );
     398                                        dst->basic->modifiers.splice( dst->basic->modifiers.end(), src->basic->modifiers );
     399                                        dst->basic->typeSpec.splice( dst->basic->typeSpec.end(), src->basic->typeSpec );
     400                                }
     401                                break;
     402
     403                          default:
     404                                switch ( src->kind ) {
     405                                  case TypeData::Aggregate:
     406                                  case TypeData::Enum:
     407                                        dst->base = new TypeData( TypeData::AggregateInst );
     408                                        dst->base->aggInst->aggregate = src;
     409                                        if ( src->kind == TypeData::Aggregate ) {
     410                                                dst->base->aggInst->params = maybeClone( src->aggregate->actuals );
     411                                        }
     412                                        dst->base->qualifiers.splice( dst->base->qualifiers.end(), src->qualifiers );
     413                                        src = 0;
     414                                        break;
     415
     416                                  default:
     417                                        if ( dst->forall ) {
     418                                                dst->forall->appendList( src->forall );
     419                                        } else {
     420                                                dst->forall = src->forall;
     421                                        }
     422                                        src->forall = 0;
     423                                        dst->base = src;
     424                                        src = 0;
     425                                }
     426                        }
     427                }
     428        }
     429}
     430
     431DeclarationNode *DeclarationNode::addType( DeclarationNode *o ) {
     432        if ( o ) {
     433                storageClasses.splice( storageClasses.end(), o->storageClasses );
     434                if ( o->type ) {
     435                        if ( ! type ) {
     436                                if ( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
     437                                        type = new TypeData( TypeData::AggregateInst );
     438                                        type->aggInst->aggregate = o->type;
     439                                        if ( o->type->kind == TypeData::Aggregate ) {
     440                                                type->aggInst->params = maybeClone( o->type->aggregate->actuals );
     441                                        }
     442                                        type->qualifiers.splice( type->qualifiers.end(), o->type->qualifiers );
     443                                } else {
     444                                        type = o->type;
     445                                }
     446                                o->type = 0;
     447                        } else {
     448                                addTypeToType( o->type, type );
     449                        }
     450                }
     451                if ( o->bitfieldWidth ) {
     452                        bitfieldWidth = o->bitfieldWidth;
     453                }
     454        }
     455        delete o;
     456        return this;
     457}
     458
     459DeclarationNode *DeclarationNode::addTypedef() {
     460        TypeData *newtype = new TypeData( TypeData::Symbolic );
     461        newtype->symbolic->params = 0;
     462        newtype->symbolic->isTypedef = true;
     463        newtype->symbolic->name = name;
     464        newtype->base = type;
     465        type = newtype;
     466        return this;
     467}
     468
     469DeclarationNode *DeclarationNode::addAssertions( DeclarationNode* assertions ) {
     470        assert( type );
     471        switch ( type->kind ) {
     472          case TypeData::Symbolic:
     473                if ( type->symbolic->assertions ) {
     474                        type->symbolic->assertions->appendList( assertions );
     475                } else {
     476                        type->symbolic->assertions = assertions;
     477                }
    377478                break;
    378 
    379               case TypeData::Basic:
    380                 dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
    381                 if ( src->kind != TypeData::Unknown ) {
    382                     assert( src->kind == TypeData::Basic );
    383                     dst->basic->modifiers.splice( dst->basic->modifiers.end(), src->basic->modifiers );
    384                     dst->basic->typeSpec.splice( dst->basic->typeSpec.end(), src->basic->typeSpec );
     479       
     480          case TypeData::Variable:
     481                if ( type->variable->assertions ) {
     482                        type->variable->assertions->appendList( assertions );
     483                } else {
     484                        type->variable->assertions = assertions;
    385485                }
    386486                break;
    387 
    388               default:
    389                 switch ( src->kind ) {
    390                   case TypeData::Aggregate:
    391                   case TypeData::Enum:
    392                     dst->base = new TypeData( TypeData::AggregateInst );
    393                     dst->base->aggInst->aggregate = src;
    394                     if ( src->kind == TypeData::Aggregate ) {
    395                         dst->base->aggInst->params = maybeClone( src->aggregate->actuals );
    396                     }
    397                     dst->base->qualifiers.splice( dst->base->qualifiers.end(), src->qualifiers );
    398                     src = 0;
    399                     break;
    400          
    401                   default:
    402                     if ( dst->forall ) {
    403                         dst->forall->appendList( src->forall );
    404                     } else {
    405                         dst->forall = src->forall;
    406                     }
    407                     src->forall = 0;
    408                     dst->base = src;
    409                     src = 0;
    410                 }
    411             }
    412         }
    413     }
    414 }
    415 
    416 DeclarationNode *DeclarationNode::addType( DeclarationNode *o ) {
    417     if ( o ) {
    418         storageClasses.splice( storageClasses.end(), o->storageClasses );
    419         if ( o->type ) {
    420             if ( ! type ) {
    421                 if ( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
    422                     type = new TypeData( TypeData::AggregateInst );
    423                     type->aggInst->aggregate = o->type;
    424                     if ( o->type->kind == TypeData::Aggregate ) {
    425                         type->aggInst->params = maybeClone( o->type->aggregate->actuals );
    426                     }
    427                     type->qualifiers.splice( type->qualifiers.end(), o->type->qualifiers );
    428                 } else {
    429                     type = o->type;
    430                 }
    431                 o->type = 0;
    432             } else {
    433                 addTypeToType( o->type, type );
    434             }
    435         }
    436         if ( o->bitfieldWidth ) {
    437             bitfieldWidth = o->bitfieldWidth;
    438         }
    439     }
    440     delete o;
    441     return this;
    442 }
    443 
    444 DeclarationNode *DeclarationNode::addTypedef() {
    445     TypeData *newtype = new TypeData( TypeData::Symbolic );
    446     newtype->symbolic->params = 0;
    447     newtype->symbolic->isTypedef = true;
    448     newtype->symbolic->name = name;
    449     newtype->base = type;
    450     type = newtype;
    451     return this;
    452 }
    453 
    454 DeclarationNode *DeclarationNode::addAssertions( DeclarationNode* assertions ) {
    455     assert( type );
    456     switch ( type->kind ) {
    457       case TypeData::Symbolic:
    458         if ( type->symbolic->assertions ) {
    459             type->symbolic->assertions->appendList( assertions );
    460         } else {
    461             type->symbolic->assertions = assertions;
    462         }
    463         break;
    464    
    465       case TypeData::Variable:
    466         if ( type->variable->assertions ) {
    467             type->variable->assertions->appendList( assertions );
    468         } else {
    469             type->variable->assertions = assertions;
    470         }
    471         break;
    472    
    473       default:
    474         assert( false );
    475     }
    476    
    477     return this;
     487       
     488          default:
     489                assert( false );
     490        }
     491       
     492        return this;
    478493}
    479494
    480495DeclarationNode *DeclarationNode::addName( std::string* newname ) {
    481     name = assign_strptr( newname );
    482     return this;
     496        name = assign_strptr( newname );
     497        return this;
    483498}
    484499
    485500DeclarationNode *DeclarationNode::addBitfield( ExpressionNode *size ) {
    486     bitfieldWidth = size;
    487     return this;
     501        bitfieldWidth = size;
     502        return this;
    488503}
    489504
    490505DeclarationNode *DeclarationNode::addVarArgs() {
    491     assert( type );
    492     hasEllipsis = true;
    493     return this;
     506        assert( type );
     507        hasEllipsis = true;
     508        return this;
    494509}
    495510
    496511DeclarationNode *DeclarationNode::addFunctionBody( StatementNode *body ) {
    497     assert( type );
    498     assert( type->kind == TypeData::Function );
    499     assert( type->function->body == 0 );
    500     type->function->body = body;
    501     type->function->hasBody = true;
    502     return this;
     512        assert( type );
     513        assert( type->kind == TypeData::Function );
     514        assert( type->function->body == 0 );
     515        type->function->body = body;
     516        type->function->hasBody = true;
     517        return this;
    503518}
    504519
    505520DeclarationNode *DeclarationNode::addOldDeclList( DeclarationNode *list ) {
    506     assert( type );
    507     assert( type->kind == TypeData::Function );
    508     assert( type->function->oldDeclList == 0 );
    509     type->function->oldDeclList = list;
    510     return this;
     521        assert( type );
     522        assert( type->kind == TypeData::Function );
     523        assert( type->function->oldDeclList == 0 );
     524        type->function->oldDeclList = list;
     525        return this;
    511526}
    512527
    513528static void
    514529setBase( TypeData *&type, TypeData *newType ) {
    515     if ( type ) {
    516         TypeData *prevBase = type;
    517         TypeData *curBase = type->base;
    518         while( curBase != 0 ) {
    519             prevBase = curBase;
    520             curBase = curBase->base;
    521         }
    522         prevBase->base = newType;
    523     } else {
    524         type = newType;
    525     }
     530        if ( type ) {
     531                TypeData *prevBase = type;
     532                TypeData *curBase = type->base;
     533                while( curBase != 0 ) {
     534                        prevBase = curBase;
     535                        curBase = curBase->base;
     536                }
     537                prevBase->base = newType;
     538        } else {
     539                type = newType;
     540        }
    526541}
    527542
    528543DeclarationNode *DeclarationNode::addPointer( DeclarationNode *p ) {
    529     if ( p ) {
    530         assert( p->type->kind == TypeData::Pointer );
    531         setBase( type, p->type );
    532         p->type = 0;
    533         delete p;
    534     }
    535     return this;
     544        if ( p ) {
     545                assert( p->type->kind == TypeData::Pointer );
     546                setBase( type, p->type );
     547                p->type = 0;
     548                delete p;
     549        }
     550        return this;
    536551}
    537552
    538553DeclarationNode *DeclarationNode::addArray( DeclarationNode *a ) {
    539     if ( a ) {
    540         assert( a->type->kind == TypeData::Array );
    541         setBase( type, a->type );
    542         a->type = 0;
    543         delete a;
    544     }
    545     return this;
     554        if ( a ) {
     555                assert( a->type->kind == TypeData::Array );
     556                setBase( type, a->type );
     557                a->type = 0;
     558                delete a;
     559        }
     560        return this;
    546561}
    547562
    548563DeclarationNode *DeclarationNode::addNewPointer( DeclarationNode *p ) {
    549     if ( p ) {
    550         assert( p->type->kind == TypeData::Pointer );
     564        if ( p ) {
     565                assert( p->type->kind == TypeData::Pointer );
     566                if ( type ) {
     567                        switch ( type->kind ) {
     568                          case TypeData::Aggregate:
     569                          case TypeData::Enum:
     570                                p->type->base = new TypeData( TypeData::AggregateInst );
     571                                p->type->base->aggInst->aggregate = type;
     572                                if ( type->kind == TypeData::Aggregate ) {
     573                                        p->type->base->aggInst->params = maybeClone( type->aggregate->actuals );
     574                                }
     575                                p->type->base->qualifiers.splice( p->type->base->qualifiers.end(), type->qualifiers );
     576                                break;
     577
     578                          default:
     579                                p->type->base = type;
     580                        }
     581                        type = 0;
     582                }
     583                delete this;
     584                return p;
     585        } else {
     586                return this;
     587        }
     588}
     589
     590static TypeData *findLast( TypeData *a ) {
     591        assert( a );
     592        TypeData *cur = a;
     593        while( cur->base ) {
     594                cur = cur->base;
     595        }
     596        return cur;
     597}
     598
     599DeclarationNode *DeclarationNode::addNewArray( DeclarationNode *a ) {
     600        if ( a ) {
     601                assert( a->type->kind == TypeData::Array );
     602                TypeData *lastArray = findLast( a->type );
     603                if ( type ) { 
     604                        switch ( type->kind ) {
     605                          case TypeData::Aggregate:
     606                          case TypeData::Enum:
     607                                lastArray->base = new TypeData( TypeData::AggregateInst );
     608                                lastArray->base->aggInst->aggregate = type;
     609                                if ( type->kind == TypeData::Aggregate ) {
     610                                        lastArray->base->aggInst->params = maybeClone( type->aggregate->actuals );
     611                                }
     612                                lastArray->base->qualifiers.splice( lastArray->base->qualifiers.end(), type->qualifiers );
     613                                break;
     614                          default:
     615                                lastArray->base = type;
     616                        }
     617                        type = 0;
     618                }
     619                delete this;
     620                return a;
     621        } else {
     622                return this;
     623        }
     624}
     625
     626DeclarationNode *DeclarationNode::addParamList( DeclarationNode *params ) {
     627        TypeData *ftype = new TypeData( TypeData::Function );
     628        ftype->function->params = params;
     629        setBase( type, ftype );
     630        return this;
     631}
     632
     633static TypeData *addIdListToType( TypeData *type, DeclarationNode *ids ) {
    551634        if ( type ) {
    552             switch ( type->kind ) {
    553               case TypeData::Aggregate:
    554               case TypeData::Enum:
    555                 p->type->base = new TypeData( TypeData::AggregateInst );
    556                 p->type->base->aggInst->aggregate = type;
    557                 if ( type->kind == TypeData::Aggregate ) {
    558                     p->type->base->aggInst->params = maybeClone( type->aggregate->actuals );
    559                 }
    560                 p->type->base->qualifiers.splice( p->type->base->qualifiers.end(), type->qualifiers );
    561                 break;
    562        
    563               default:
    564                 p->type->base = type;
    565             }
    566             type = 0;
    567         }
    568         delete this;
    569         return p;
    570     } else {
    571         return this;
    572     }
    573 }
    574 
    575 static TypeData *findLast( TypeData *a ) {
    576     assert( a );
    577     TypeData *cur = a;
    578     while( cur->base ) {
    579         cur = cur->base;
    580     }
    581     return cur;
    582 }
    583 
    584 DeclarationNode *DeclarationNode::addNewArray( DeclarationNode *a ) {
    585     if ( a ) {
    586         assert( a->type->kind == TypeData::Array );
    587         TypeData *lastArray = findLast( a->type );
    588         if ( type ) { 
    589             switch ( type->kind ) {
    590               case TypeData::Aggregate:
    591               case TypeData::Enum:
    592                 lastArray->base = new TypeData( TypeData::AggregateInst );
    593                 lastArray->base->aggInst->aggregate = type;
    594                 if ( type->kind == TypeData::Aggregate ) {
    595                     lastArray->base->aggInst->params = maybeClone( type->aggregate->actuals );
    596                 }
    597                 lastArray->base->qualifiers.splice( lastArray->base->qualifiers.end(), type->qualifiers );
    598                 break;
    599        
    600               default:
    601                 lastArray->base = type;
    602             }
    603             type = 0;
    604         }
    605         delete this;
    606         return a;
    607     } else {
    608         return this;
    609     }
    610 }
    611 
    612 DeclarationNode *DeclarationNode::addParamList( DeclarationNode *params ) {
    613     TypeData *ftype = new TypeData( TypeData::Function );
    614     ftype->function->params = params;
    615     setBase( type, ftype );
    616     return this;
    617 }
    618 
    619 static TypeData *addIdListToType( TypeData *type, DeclarationNode *ids ) {
    620     if ( type ) {
    621         if ( type->kind != TypeData::Function ) {
    622             type->base = addIdListToType( type->base, ids );
     635                if ( type->kind != TypeData::Function ) {
     636                        type->base = addIdListToType( type->base, ids );
     637                } else {
     638                        type->function->idList = ids;
     639                }
     640                return type;
    623641        } else {
    624             type->function->idList = ids;
    625         }
    626         return type;
    627     } else {
    628         TypeData *newtype = new TypeData( TypeData::Function );
    629         newtype->function->idList = ids;
    630         return newtype;
    631     }
    632 }
    633    
     642                TypeData *newtype = new TypeData( TypeData::Function );
     643                newtype->function->idList = ids;
     644                return newtype;
     645        }
     646}
     647       
    634648DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
    635     type = addIdListToType( type, ids );
    636     return this;
     649        type = addIdListToType( type, ids );
     650        return this;
    637651}
    638652
    639653DeclarationNode *DeclarationNode::addInitializer( InitializerNode *init ) {
    640     //assert
    641     initializer = init;
    642     return this;
     654        //assert
     655        initializer = init;
     656        return this;
    643657}
    644658
    645659DeclarationNode *DeclarationNode::cloneBaseType( string *newName ) {
    646     DeclarationNode *newnode = new DeclarationNode;
    647     TypeData *srcType = type;
    648     while( srcType->base ) {
    649         srcType = srcType->base;
    650     }
    651     newnode->type = maybeClone( srcType );
    652     if ( newnode->type->kind == TypeData::AggregateInst ) {
    653         // don't duplicate members
    654         if ( newnode->type->aggInst->aggregate->kind == TypeData::Enum ) {
    655             delete newnode->type->aggInst->aggregate->enumeration->constants;
    656             newnode->type->aggInst->aggregate->enumeration->constants = 0;
     660        DeclarationNode *newnode = new DeclarationNode;
     661        TypeData *srcType = type;
     662        while( srcType->base ) {
     663                srcType = srcType->base;
     664        }
     665        newnode->type = maybeClone( srcType );
     666        if ( newnode->type->kind == TypeData::AggregateInst ) {
     667                // don't duplicate members
     668                if ( newnode->type->aggInst->aggregate->kind == TypeData::Enum ) {
     669                        delete newnode->type->aggInst->aggregate->enumeration->constants;
     670                        newnode->type->aggInst->aggregate->enumeration->constants = 0;
     671                } else {
     672                        assert( newnode->type->aggInst->aggregate->kind == TypeData::Aggregate );
     673                        delete newnode->type->aggInst->aggregate->aggregate->members;
     674                        newnode->type->aggInst->aggregate->aggregate->members = 0;
     675                }
     676        }
     677        newnode->type->forall = maybeClone( type->forall );
     678        newnode->storageClasses = storageClasses;
     679        newnode->name = assign_strptr( newName );
     680        return newnode;
     681}
     682
     683DeclarationNode *DeclarationNode::cloneBaseType( DeclarationNode *o ) {
     684        if ( o ) {
     685                o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
     686                if ( type ) {
     687                        TypeData *srcType = type;
     688                        while( srcType->base ) {
     689                                srcType = srcType->base;
     690                        }
     691                        TypeData *newType = srcType->clone();
     692                        if ( newType->kind == TypeData::AggregateInst ) {
     693                                // don't duplicate members
     694                                if ( newType->aggInst->aggregate->kind == TypeData::Enum ) {
     695                                        delete newType->aggInst->aggregate->enumeration->constants;
     696                                        newType->aggInst->aggregate->enumeration->constants = 0;
     697                                } else {
     698                                        assert( newType->aggInst->aggregate->kind == TypeData::Aggregate );
     699                                        delete newType->aggInst->aggregate->aggregate->members;
     700                                        newType->aggInst->aggregate->aggregate->members = 0;
     701                                }
     702                        }
     703                        newType->forall = maybeClone( type->forall );
     704                        if ( ! o->type ) {
     705                                o->type = newType;
     706                        } else {
     707                                addTypeToType( newType, o->type );
     708                                delete newType;
     709                        }
     710                }
     711        }
     712        return o;
     713}
     714
     715DeclarationNode *DeclarationNode::cloneType( string *newName ) {
     716        DeclarationNode *newnode = new DeclarationNode;
     717        newnode->type = maybeClone( type );
     718        newnode->storageClasses = storageClasses;
     719        newnode->name = assign_strptr( newName );
     720        return newnode;
     721}
     722
     723DeclarationNode *DeclarationNode::cloneType( DeclarationNode *o ) {
     724        if ( o ) {
     725                o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
     726                if ( type ) {
     727                        TypeData *newType = type->clone();
     728                        if ( ! o->type ) {
     729                                o->type = newType;
     730                        } else {
     731                                addTypeToType( newType, o->type );
     732                                delete newType;
     733                        }
     734                }
     735        }
     736        return o;
     737}
     738
     739DeclarationNode *DeclarationNode::appendList( DeclarationNode *node ) {
     740        if ( node != 0 ) {
     741                set_link( node );
     742        }
     743        return this;
     744}
     745
     746DeclarationNode *DeclarationNode::extractAggregate() const {
     747        if ( type ) {
     748                TypeData *ret = type->extractAggregate();
     749                if ( ret ) {
     750                        DeclarationNode *newnode = new DeclarationNode;
     751                        newnode->type = ret;
     752                        return newnode;
     753                } else {
     754                        return 0;
     755                }
    657756        } else {
    658             assert( newnode->type->aggInst->aggregate->kind == TypeData::Aggregate );
    659             delete newnode->type->aggInst->aggregate->aggregate->members;
    660             newnode->type->aggInst->aggregate->aggregate->members = 0;
    661         }
    662     }
    663     newnode->type->forall = maybeClone( type->forall );
    664     newnode->storageClasses = storageClasses;
    665     newnode->name = assign_strptr( newName );
    666     return newnode;
    667 }
    668 
    669 DeclarationNode *DeclarationNode::cloneBaseType( DeclarationNode *o ) {
    670     if ( o ) {
    671         o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
    672         if ( type ) {
    673             TypeData *srcType = type;
    674             while( srcType->base ) {
    675                 srcType = srcType->base;
    676             }
    677             TypeData *newType = srcType->clone();
    678             if ( newType->kind == TypeData::AggregateInst ) {
    679                 // don't duplicate members
    680                 if ( newType->aggInst->aggregate->kind == TypeData::Enum ) {
    681                     delete newType->aggInst->aggregate->enumeration->constants;
    682                     newType->aggInst->aggregate->enumeration->constants = 0;
    683                 } else {
    684                     assert( newType->aggInst->aggregate->kind == TypeData::Aggregate );
    685                     delete newType->aggInst->aggregate->aggregate->members;
    686                     newType->aggInst->aggregate->aggregate->members = 0;
    687                 }
    688             }
    689             newType->forall = maybeClone( type->forall );
    690             if ( ! o->type ) {
    691                 o->type = newType;
    692             } else {
    693                 addTypeToType( newType, o->type );
    694                 delete newType;
    695             }
    696         }
    697     }
    698     return o;
    699 }
    700 
    701 DeclarationNode *DeclarationNode::cloneType( string *newName ) {
    702     DeclarationNode *newnode = new DeclarationNode;
    703     newnode->type = maybeClone( type );
    704     newnode->storageClasses = storageClasses;
    705     newnode->name = assign_strptr( newName );
    706     return newnode;
    707 }
    708 
    709 DeclarationNode *DeclarationNode::cloneType( DeclarationNode *o ) {
    710     if ( o ) {
    711         o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
    712         if ( type ) {
    713             TypeData *newType = type->clone();
    714             if ( ! o->type ) {
    715                 o->type = newType;
    716             } else {
    717                 addTypeToType( newType, o->type );
    718                 delete newType;
    719             }
    720         }
    721     }
    722     return o;
    723 }
    724 
    725 DeclarationNode *DeclarationNode::appendList( DeclarationNode *node ) {
    726     if ( node != 0 ) {
    727         set_link( node );
    728     }
    729     return this;
    730 }
    731 
    732 DeclarationNode *DeclarationNode::extractAggregate() const {
    733     if ( type ) {
    734         TypeData *ret = type->extractAggregate();
    735         if ( ret ) {
    736             DeclarationNode *newnode = new DeclarationNode;
    737             newnode->type = ret;
    738             return newnode;
    739         } else {
    740             return 0;
    741         }
    742     } else {
    743         return 0;
    744     }
     757                return 0;
     758        }
    745759}
    746760
    747761void buildList( const DeclarationNode *firstNode, std::list< Declaration* > &outputList ) {
    748     SemanticError errors;
    749     std::back_insert_iterator< std::list< Declaration* > > out( outputList );
    750     const DeclarationNode *cur = firstNode;
    751     while( cur ) {
    752         try {
    753             if ( DeclarationNode *extr = cur->extractAggregate() ) {
    754                 // handle the case where a structure declaration is contained within an object or type
    755                 // declaration
    756                 Declaration *decl = extr->build();
    757                 if ( decl ) {
    758                    *out++ = decl;
    759                 }
    760             }
    761             Declaration *decl = cur->build();
    762             if ( decl ) {
    763                 *out++ = decl;
    764             }
    765         } catch( SemanticError &e ) {
    766             errors.append( e );
    767         }
    768         cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
    769     }
    770     if ( ! errors.isEmpty() ) {
    771         throw errors;
    772     }
     762        SemanticError errors;
     763        std::back_insert_iterator< std::list< Declaration* > > out( outputList );
     764        const DeclarationNode *cur = firstNode;
     765        while( cur ) {
     766                try {
     767                        if ( DeclarationNode *extr = cur->extractAggregate() ) {
     768                                // handle the case where a structure declaration is contained within an object or type declaration
     769                                Declaration *decl = extr->build();
     770                                if ( decl ) {
     771                                        *out++ = decl;
     772                                }
     773                        }
     774                        Declaration *decl = cur->build();
     775                        if ( decl ) {
     776                                *out++ = decl;
     777                        }
     778                } catch( SemanticError &e ) {
     779                        errors.append( e );
     780                }
     781                cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
     782        }
     783        if ( ! errors.isEmpty() ) {
     784                throw errors;
     785        }
    773786}
    774787
    775788void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType* > &outputList ) {
    776     SemanticError errors;
    777     std::back_insert_iterator< std::list< DeclarationWithType* > > out( outputList );
    778     const DeclarationNode *cur = firstNode;
    779     while( cur ) {
    780         try {
     789        SemanticError errors;
     790        std::back_insert_iterator< std::list< DeclarationWithType* > > out( outputList );
     791        const DeclarationNode *cur = firstNode;
     792        while( cur ) {
     793                try {
    781794///       if ( DeclarationNode *extr = cur->extractAggregate() ) {
    782795///     // handle the case where a structure declaration is contained within an object or type
     
    787800///     }
    788801///       }
    789             Declaration *decl = cur->build();
    790             if ( decl ) {
    791                 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
    792                    *out++ = dwt;
    793                 } else if ( StructDecl *agg = dynamic_cast< StructDecl* >( decl ) ) {
    794                     StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
    795                     *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
    796                     delete agg;
    797                 } else if ( UnionDecl *agg = dynamic_cast< UnionDecl* >( decl ) ) {
    798                     UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
    799                     *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
    800                 }
    801             }
    802         } catch( SemanticError &e ) {
    803             errors.append( e );
    804         }
    805         cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
    806     }
    807     if ( ! errors.isEmpty() ) {
    808         throw errors;
    809     }
     802                        Declaration *decl = cur->build();
     803                        if ( decl ) {
     804                                if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
     805                                        *out++ = dwt;
     806                                } else if ( StructDecl *agg = dynamic_cast< StructDecl* >( decl ) ) {
     807                                        StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
     808                                        *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
     809                                        delete agg;
     810                                } else if ( UnionDecl *agg = dynamic_cast< UnionDecl* >( decl ) ) {
     811                                        UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
     812                                        *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
     813                                }
     814                        }
     815                } catch( SemanticError &e ) {
     816                        errors.append( e );
     817                }
     818                cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
     819        }
     820        if ( ! errors.isEmpty() ) {
     821                throw errors;
     822        }
    810823}
    811824
    812825void buildTypeList( const DeclarationNode *firstNode, std::list< Type* > &outputList ) {
    813     SemanticError errors;
    814     std::back_insert_iterator< std::list< Type* > > out( outputList );
    815     const DeclarationNode *cur = firstNode;
    816     while( cur ) {
    817         try {
    818            *out++ = cur->buildType();
    819         } catch( SemanticError &e ) {
    820             errors.append( e );
    821         }
    822         cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
    823     }
    824     if ( ! errors.isEmpty() ) {
    825         throw errors;
    826     }
     826        SemanticError errors;
     827        std::back_insert_iterator< std::list< Type* > > out( outputList );
     828        const DeclarationNode *cur = firstNode;
     829        while( cur ) {
     830                try {
     831                        *out++ = cur->buildType();
     832                } catch( SemanticError &e ) {
     833                        errors.append( e );
     834                }
     835                cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
     836        }
     837        if ( ! errors.isEmpty() ) {
     838                throw errors;
     839        }
    827840}
    828841
    829842Declaration *DeclarationNode::build() const {
    830843
    831     if ( ! type ) {
    832         if ( buildInline() ) {
    833             throw SemanticError( "invalid inline specification in declaration of ", this );
     844        if ( ! type ) {
     845                if ( buildInline() ) {
     846                        throw SemanticError( "invalid inline specification in declaration of ", this );
     847                } else {
     848                        return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) );
     849                }
    834850        } else {
    835             return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) );
    836         }
    837     } else {
    838         Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildInline(), linkage, maybeBuild< Initializer >(initializer) );
    839         return newDecl;
    840     }
    841     // we should never get here
    842     assert( false );
    843     return 0;
     851                Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildInline(), linkage, maybeBuild< Initializer >(initializer) );
     852                return newDecl;
     853        }
     854        // we should never get here
     855        assert( false );
     856        return 0;
    844857}
    845858
    846859Type *DeclarationNode::buildType() const {
    847     assert( type );
     860        assert( type );
    848861 
    849     switch ( type->kind ) {
    850       case TypeData::Enum:
    851         return new EnumInstType( type->buildQualifiers(), type->enumeration->name );
    852       case TypeData::Aggregate: {
    853           ReferenceToType *ret;
    854           switch ( type->aggregate->kind ) {
    855             case DeclarationNode::Struct:
    856               ret = new StructInstType( type->buildQualifiers(), type->aggregate->name );
    857               break;
    858             case DeclarationNode::Union:
    859               ret = new UnionInstType( type->buildQualifiers(), type->aggregate->name );
    860               break;
    861             case DeclarationNode::Context:
    862               ret = new ContextInstType( type->buildQualifiers(), type->aggregate->name );
    863               break;
    864             default:
    865               assert( false );
    866           } // switch
    867           buildList( type->aggregate->actuals, ret->get_parameters() );
    868           return ret;
    869       }
    870       case TypeData::Symbolic: {
    871           TypeInstType *ret = new TypeInstType( type->buildQualifiers(), type->symbolic->name, false );
    872           buildList( type->symbolic->actuals, ret->get_parameters() );
    873           return ret;
    874       }
    875       default:
    876         return type->build();
    877     } // switch
     862        switch ( type->kind ) {
     863          case TypeData::Enum:
     864                return new EnumInstType( type->buildQualifiers(), type->enumeration->name );
     865          case TypeData::Aggregate: {
     866                  ReferenceToType *ret;
     867                  switch ( type->aggregate->kind ) {
     868                        case DeclarationNode::Struct:
     869                          ret = new StructInstType( type->buildQualifiers(), type->aggregate->name );
     870                          break;
     871                        case DeclarationNode::Union:
     872                          ret = new UnionInstType( type->buildQualifiers(), type->aggregate->name );
     873                          break;
     874                        case DeclarationNode::Context:
     875                          ret = new ContextInstType( type->buildQualifiers(), type->aggregate->name );
     876                          break;
     877                        default:
     878                          assert( false );
     879                  } // switch
     880                  buildList( type->aggregate->actuals, ret->get_parameters() );
     881                  return ret;
     882          }
     883          case TypeData::Symbolic: {
     884                  TypeInstType *ret = new TypeInstType( type->buildQualifiers(), type->symbolic->name, false );
     885                  buildList( type->symbolic->actuals, ret->get_parameters() );
     886                  return ret;
     887          }
     888          default:
     889                return type->build();
     890        } // switch
    878891}
    879892
    880893Declaration::StorageClass DeclarationNode::buildStorageClass() const {
    881     static const Declaration::StorageClass scMap[] = { 
    882         Declaration::Extern,
    883         Declaration::Static,
    884         Declaration::Auto,
    885         Declaration::Register,
    886         Declaration::Inline,
    887         Declaration::Fortran
    888     }; 
     894        static const Declaration::StorageClass scMap[] = { 
     895                Declaration::Extern,
     896                Declaration::Static,
     897                Declaration::Auto,
     898                Declaration::Register,
     899                Declaration::Inline,
     900                Declaration::Fortran
     901        }; 
    889902 
    890     Declaration::StorageClass ret = Declaration::NoStorageClass;
    891     for ( std::list< StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
    892         assert( unsigned( *i ) < sizeof( scMap ) / sizeof( scMap[0] ) );
    893         if ( *i == Inline ) continue;
    894         if ( ret == Declaration::NoStorageClass ) {
    895             ret = scMap[ *i ];
     903        Declaration::StorageClass ret = Declaration::NoStorageClass;
     904        for ( std::list< StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
     905                assert( unsigned( *i ) < sizeof( scMap ) / sizeof( scMap[0] ) );
     906                if ( *i == Inline ) continue;
     907                if ( ret == Declaration::NoStorageClass ) {
     908                        ret = scMap[ *i ];
     909                } else {
     910                        throw SemanticError( "invalid combination of storage classes in declaration of ", this );
     911                }
     912        }
     913        return ret;
     914}
     915
     916bool DeclarationNode::buildInline() const {
     917        std::list< StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), Inline );
     918        if ( first == storageClasses.end() ) {
     919                return false;
    896920        } else {
    897             throw SemanticError( "invalid combination of storage classes in declaration of ", this );
    898         }
    899     }
    900     return ret;
    901 }
    902 
    903 bool DeclarationNode::buildInline() const {
    904     std::list< StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), Inline );
    905     if ( first == storageClasses.end() ) {
     921                std::list< StorageClass >::const_iterator next = std::find( ++first, storageClasses.end(), Inline );
     922                if ( next == storageClasses.end() ) {
     923                        return true;
     924                } else {
     925                        throw SemanticError( "duplicate inline specification in declaration of ", this );
     926                }
     927        }
     928        // we should never get here
    906929        return false;
    907     } else {
    908         std::list< StorageClass >::const_iterator next = std::find( ++first, storageClasses.end(), Inline );
    909         if ( next == storageClasses.end() ) {
    910             return true;
    911         } else {
    912             throw SemanticError( "duplicate inline specification in declaration of ", this );
    913         }
    914     }
    915     // we should never get here
    916     return false;
    917 }
     930}
     931
     932// Local Variables: //
     933// tab-width: 4 //
     934// mode: c++ //
     935// compile-command: "make install" //
     936// End: //
  • translator/Parser/ExpressionNode.cc

    rb8508a2 rb87a5ed  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// ExpressionNode.cc --
     8//
     9// Author           : Rodolfo G. Esteves
     10// Created On       : Sat May 16 13:17:07 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat May 16 13:19:35 2015
     13// Update Count     : 2
     14//
     15
    116#include <cassert>
    217#include <cctype>
     
    1732
    1833ExpressionNode::ExpressionNode( string *name_) : ParseNode( *name_ ), argName( 0 ) {
    19     delete name_;
     34        delete name_;
    2035}
    2136
    2237ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) {
    23     if ( other.argName ) {
    24         argName = other.argName->clone();
    25     } else {
    26         argName = 0;
    27     } // if
     38        if ( other.argName ) {
     39                argName = other.argName->clone();
     40        } else {
     41                argName = 0;
     42        } // if
    2843}
    2944
    3045ExpressionNode * ExpressionNode::set_asArgName( std::string *aName ) {
    31     argName = new VarRefNode( aName );
    32     return this;
     46        argName = new VarRefNode( aName );
     47        return this;
    3348}
    3449
    3550ExpressionNode * ExpressionNode::set_asArgName( ExpressionNode *aDesignator ) {
    36     argName = aDesignator;
    37     return this;
     51        argName = aDesignator;
     52        return this;
    3853}
    3954
    4055void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
    41     if ( argName ) {
    42         os << string(' ', indent ) << "(designated by:  ";
    43         argName->printOneLine( os, indent );
    44         os << ")" << std::endl;
    45     } // if
     56        if ( argName ) {
     57                os << string(' ', indent ) << "(designated by:  ";
     58                argName->printOneLine( os, indent );
     59                os << ")" << std::endl;
     60        } // if
    4661}
    4762
     
    4964
    5065NullExprNode *NullExprNode::clone() const {
    51     return new NullExprNode();
     66        return new NullExprNode();
    5267}
    5368
    5469void NullExprNode::print( std::ostream & os, int indent ) const {
    55     printDesignation( os );
    56     os << "null expression";
     70        printDesignation( os );
     71        os << "null expression";
    5772}
    5873
    5974void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
    60     printDesignation( os );
    61     os << "null";
     75        printDesignation( os );
     76        os << "null";
    6277}
    6378
    6479Expression *NullExprNode::build() const {
    65     return 0;
     80        return 0;
    6681}
    6782
    6883CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ){
    69     return new CommaExprNode( this, exp );
     84        return new CommaExprNode( this, exp );
    7085}
    7186
     
    7792
    7893ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), sign( true ), longs(0), size(0) {
    79     if ( inVal ) {
    80         value = *inVal;
    81         delete inVal;
    82     } else {
    83         value = "";
    84     } // if
    85 
    86     classify( value );
    87 }
    88 
    89 ConstantNode::ConstantNode( const ConstantNode &other )
    90     : ExpressionNode( other ), type( other.type ), value( other.value ), sign( other.sign ), base( other.base ), longs( other.longs ), size( other.size ) {
     94        if ( inVal ) {
     95                value = *inVal;
     96                delete inVal;
     97        } else {
     98                value = "";
     99        } // if
     100
     101        classify( value );
     102}
     103
     104ConstantNode::ConstantNode( const ConstantNode &other ) : ExpressionNode( other ), type( other.type ), value( other.value ), sign( other.sign ),
     105                                                                                                                  base( other.base ), longs( other.longs ), size( other.size ) {
    91106}
    92107
    93108// for some reason, std::tolower doesn't work as an argument to std::transform in g++ 3.1
    94109inline char tolower_hack( char c ) {
    95     return std::tolower( c );
     110        return std::tolower( c );
    96111}
    97112
    98113void ConstantNode::classify( std::string &str ){
    99     switch ( type ){
    100       case Integer:
    101       case Float:
    102         {
    103             std::string sfx("");
    104             char c;
    105             int i = str.length() - 1;
    106 
    107             while ( i >= 0 && !isxdigit( c = str.at( i--)) )
    108                 sfx += c;
    109 
    110             value = str.substr( 0, i + 2 );
    111 
    112             // get rid of underscores
    113             value.erase( remove( value.begin(), value.end(), '_'), value.end());
    114 
    115             std::transform( sfx.begin(), sfx.end(), sfx.begin(), tolower_hack );
    116 
    117             if ( sfx.find("ll") != string::npos ){
    118                 longs = 2;
    119             } else if ( sfx.find("l") != string::npos ){
    120                 longs = 1;
    121             } // if
    122 
    123             assert(( longs >= 0) && ( longs <= 2));
    124 
    125             if ( sfx.find("u") != string::npos )
    126                 sign = false;
    127 
    128             break;
     114        switch ( type ){
     115          case Integer:
     116          case Float:
     117                {
     118                        std::string sfx("");
     119                        char c;
     120                        int i = str.length() - 1;
     121
     122                        while ( i >= 0 && !isxdigit( c = str.at( i--)) )
     123                                sfx += c;
     124
     125                        value = str.substr( 0, i + 2 );
     126
     127                        // get rid of underscores
     128                        value.erase( remove( value.begin(), value.end(), '_'), value.end());
     129
     130                        std::transform( sfx.begin(), sfx.end(), sfx.begin(), tolower_hack );
     131
     132                        if ( sfx.find("ll") != string::npos ){
     133                                longs = 2;
     134                        } else if ( sfx.find("l") != string::npos ){
     135                                longs = 1;
     136                        } // if
     137
     138                        assert(( longs >= 0) && ( longs <= 2));
     139
     140                        if ( sfx.find("u") != string::npos )
     141                                sign = false;
     142
     143                        break;
     144                }
     145          case Character:
     146                {
     147                        // remove underscores from hex and oct escapes
     148                        if ( str.substr(1,2) == "\\x")
     149                                value.erase( remove( value.begin(), value.end(), '_'), value.end());
     150
     151                        break;
     152                }
     153          default:
     154                // shouldn't be here
     155                ;
    129156        }
    130       case Character:
    131         {
    132             // remove underscores from hex and oct escapes
    133             if ( str.substr(1,2) == "\\x")
    134                 value.erase( remove( value.begin(), value.end(), '_'), value.end());
    135 
    136             break;
     157}
     158
     159ConstantNode::Type ConstantNode::get_type( void ) const {
     160        return type;
     161}
     162
     163ConstantNode *ConstantNode::append( std::string *newValue ) {
     164        if ( newValue ) {
     165                if ( type == String ){
     166                        std::string temp = *newValue;
     167                        value.resize( value.size() - 1 );
     168                        value += newValue->substr(1, newValue->size());
     169                } else
     170                        value += *newValue;
     171
     172                delete newValue;
     173        } // if
     174        return this;
     175}
     176
     177void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
     178        os << string( indent, ' ');
     179        printDesignation( os );
     180
     181        switch ( type ) {
     182                /* integers */
     183          case Integer:
     184                os << value ;
     185                break;
     186          case Float:
     187                os << value ;
     188                break;
     189
     190          case Character:
     191                os << "'" << value << "'";
     192                break;
     193
     194          case String:
     195                os << '"' << value << '"';
     196                break;
    137197        }
    138       default:
    139         // shouldn't be here
    140         ;
    141     }
    142 }
    143 
    144 ConstantNode::Type ConstantNode::get_type( void ) const {
    145     return type;
    146 }
    147 
    148 ConstantNode *ConstantNode::append( std::string *newValue ) {
    149     if ( newValue ) {
    150         if ( type == String ){
    151             std::string temp = *newValue;
    152             value.resize( value.size() - 1 );
    153             value += newValue->substr(1, newValue->size());
    154         } else
    155             value += *newValue;
    156 
    157         delete newValue;
    158     } // if
    159     return this;
    160 }
    161 
    162 void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
    163     os << string( indent, ' ');
    164     printDesignation( os );
    165 
    166     switch ( type ) {
    167         /* integers */
    168       case Integer:
    169         os << value ;
    170         break;
    171       case Float:
    172         os << value ;
    173         break;
    174 
    175       case Character:
    176         os << "'" << value << "'";
    177         break;
    178 
    179       case String:
    180         os << '"' << value << '"';
    181         break;
    182     }
    183 
    184     os << ' ';
     198
     199        os << ' ';
    185200}
    186201
    187202void ConstantNode::print( std::ostream &os, int indent ) const {
    188     printOneLine( os, indent );
    189     os << endl;
     203        printOneLine( os, indent );
     204        os << endl;
    190205}
    191206
    192207Expression *ConstantNode::build() const {
    193     ::Type::Qualifiers q;
    194     BasicType *bt;
    195 
    196     switch ( get_type()){
    197       case Integer:
    198         /* Cfr. standard 6.4.4.1 */
    199         //bt.set_kind( BasicType::SignedInt );
    200         bt = new BasicType( q, BasicType::SignedInt );
    201         break;
    202       case Float:
    203         bt = new BasicType( q, BasicType::Float );
    204         break;
    205       case Character:
    206         bt = new BasicType( q, BasicType::Char );
    207         break;
    208       case String:
    209         // string should probably be a primitive type
    210         ArrayType *at;
    211         std::string value = get_value();
    212         at = new ArrayType( q, new BasicType( q, BasicType::Char ),
    213                            new ConstantExpr( Constant( new BasicType( q, BasicType::SignedInt ),
    214                                                        toString( value.size() - 1 ) ) ),  // account for '\0'
    215                            false, false );
    216         return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
    217     }
    218     return new ConstantExpr(  Constant( bt, get_value()),  maybeBuild< Expression >( get_argName() ) );
     208        ::Type::Qualifiers q;
     209        BasicType *bt;
     210
     211        switch ( get_type()){
     212          case Integer:
     213                /* Cfr. standard 6.4.4.1 */
     214                //bt.set_kind( BasicType::SignedInt );
     215                bt = new BasicType( q, BasicType::SignedInt );
     216                break;
     217          case Float:
     218                bt = new BasicType( q, BasicType::Float );
     219                break;
     220          case Character:
     221                bt = new BasicType( q, BasicType::Char );
     222                break;
     223          case String:
     224                // string should probably be a primitive type
     225                ArrayType *at;
     226                std::string value = get_value();
     227                at = new ArrayType( q, new BasicType( q, BasicType::Char ),
     228                                                        new ConstantExpr( Constant( new BasicType( q, BasicType::SignedInt ),
     229                                                                                                                toString( value.size() - 1 ) ) ),  // account for '\0'
     230                                                        false, false );
     231                return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
     232        }
     233        return new ConstantExpr(  Constant( bt, get_value()),  maybeBuild< Expression >( get_argName() ) );
    219234}
    220235
     
    227242
    228243Expression *VarRefNode::build() const {
    229     return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
     244        return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
    230245}
    231246
    232247void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
    233     printDesignation( os );
    234     os << get_name() << ' ';
     248        printDesignation( os );
     249        os << get_name() << ' ';
    235250}
    236251
    237252void VarRefNode::print( std::ostream &os, int indent ) const {
    238     printDesignation( os );
    239     os << '\r' << string( indent, ' ') << "Referencing: ";
    240     os << "Variable: " << get_name();
    241     os << endl;
     253        printDesignation( os );
     254        os << '\r' << string( indent, ' ') << "Referencing: ";
     255        os << "Variable: " << get_name();
     256        os << endl;
    242257}
    243258
     
    250265
    251266OperatorNode::Type OperatorNode::get_type( void ) const{
    252     return type;
     267        return type;
    253268}
    254269
    255270void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
    256     printDesignation( os );
    257     os << OpName[ type ] << ' ';
     271        printDesignation( os );
     272        os << OpName[ type ] << ' ';
    258273}
    259274
    260275void OperatorNode::print( std::ostream &os, int indent ) const{
    261     printDesignation( os );
    262     os << '\r' << string( indent, ' ') << "Operator: " << OpName[type] << endl;
    263     return;
     276        printDesignation( os );
     277        os << '\r' << string( indent, ' ') << "Operator: " << OpName[type] << endl;
     278        return;
    264279}
    265280
    266281std::string OperatorNode::get_typename( void ) const{
    267     return string( OpName[ type ]);
     282        return string( OpName[ type ]);
    268283}
    269284
    270285const char *OperatorNode::OpName[] = {
    271     "TupleC",  "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
    272     // triadic
    273     "Cond",   "NCond",
    274     // diadic
    275     "SizeOf",      "AlignOf", "Attr", "CompLit", "Plus",    "Minus",   "Mul",     "Div",     "Mod",      "Or",
    276     "And",       "BitOr",   "BitAnd",  "Xor",     "Cast",    "LShift",  "RShift",  "LThan",   "GThan",
    277     "LEThan",    "GEThan", "Eq",      "Neq",     "Assign",  "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
    278     "MinusAssn", "LSAssn", "RSAssn",  "AndAssn", "ERAssn",  "OrAssn",  "Index",   "FieldSel","PFieldSel",
    279     "Range",
    280     // monadic
    281     "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
     286        "TupleC",  "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
     287        // triadic
     288        "Cond",   "NCond",
     289        // diadic
     290        "SizeOf",      "AlignOf", "Attr", "CompLit", "Plus",    "Minus",   "Mul",     "Div",     "Mod",      "Or",
     291        "And",       "BitOr",   "BitAnd",  "Xor",     "Cast",    "LShift",  "RShift",  "LThan",   "GThan",
     292        "LEThan",    "GEThan", "Eq",      "Neq",     "Assign",  "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
     293        "MinusAssn", "LSAssn", "RSAssn",  "AndAssn", "ERAssn",  "OrAssn",  "Index",   "FieldSel","PFieldSel",
     294        "Range",
     295        // monadic
     296        "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
    282297};
    283298
     
    289304
    290305CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
    291     function( f ), arguments( args ) {
     306        function( f ), arguments( args ) {
    292307}
    293308
    294309CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
    295     function( f ), arguments( arg1) {
    296     arguments->set_link( arg2);
     310        function( f ), arguments( arg1) {
     311        arguments->set_link( arg2);
    297312}
    298313
    299314CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
    300     ParseNode *cur = other.arguments;
    301     while ( cur ) {
    302         if ( arguments ) {
    303             arguments->set_link( cur->clone() );
    304         } else {
    305             arguments = ( ExpressionNode*)cur->clone();
    306         } // if
    307         cur = cur->get_link();
    308     }
     315        ParseNode *cur = other.arguments;
     316        while ( cur ) {
     317                if ( arguments ) {
     318                        arguments->set_link( cur->clone() );
     319                } else {
     320                        arguments = ( ExpressionNode*)cur->clone();
     321                } // if
     322                cur = cur->get_link();
     323        }
    309324}
    310325
    311326CompositeExprNode::~CompositeExprNode() {
    312     delete function;
    313     delete arguments;
     327        delete function;
     328        delete arguments;
    314329}
    315330
    316331// the names that users use to define operator functions
    317332static const char *opFuncName[] = {
    318     "",  "", "",
    319     "",   "",
    320     // diadic
    321     "",   "", "", "", "?+?",    "?-?",   "?*?",     "?/?",     "?%?",     "",       "",
    322     "?|?",  "?&?",  "?^?",     "",    "?<<?",  "?>>?",  "?<?",   "?>?",    "?<=?",
    323     "?>=?", "?==?",      "?!=?",     "?=?",  "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
    324     "?<<=?", "?>>=?",  "?&=?", "?^=?",  "?|=?",  "?[?]",   "","","Range",
    325     // monadic
    326     "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "LabAddress"
     333        "",  "", "",
     334        "",   "",
     335        // diadic
     336        "",   "", "", "", "?+?",    "?-?",   "?*?",     "?/?",     "?%?",     "",       "",
     337        "?|?",  "?&?",  "?^?",     "",    "?<<?",  "?>>?",  "?<?",   "?>?",    "?<=?",
     338        "?>=?", "?==?",      "?!=?",     "?=?",  "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
     339        "?<<=?", "?>>=?",  "?&=?", "?^=?",  "?|=?",  "?[?]",   "","","Range",
     340        // monadic
     341        "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "LabAddress"
    327342};
    328343
     
    330345
    331346Expression *CompositeExprNode::build() const {
    332     OperatorNode *op;
    333     std::list<Expression *> args;
    334 
    335     buildList( get_args(), args );
    336 
    337     if ( ! ( op = dynamic_cast<OperatorNode *>( function )) ) {
    338         // a function as opposed to an operator
    339         return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));
    340     } else {
    341         switch ( op->get_type()){
    342           case OperatorNode::Incr:
    343           case OperatorNode::Decr:
    344           case OperatorNode::IncrPost:
    345           case OperatorNode::DecrPost:
    346           case OperatorNode::Assign:
    347           case OperatorNode::MulAssn:
    348           case OperatorNode::DivAssn:
    349           case OperatorNode::ModAssn:
    350           case OperatorNode::PlusAssn:
    351           case OperatorNode::MinusAssn:
    352           case OperatorNode::LSAssn:
    353           case OperatorNode::RSAssn:
    354           case OperatorNode::AndAssn:
    355           case OperatorNode::ERAssn:
    356           case OperatorNode::OrAssn:
    357             // the rewrite rules for these expressions specify that the first argument has its address taken
    358             assert( !args.empty() );
    359             args.front() = new AddressExpr( args.front() );
    360             break;
    361           default:
    362             /* do nothing */
    363             ;
    364         }
    365 
    366         switch ( op->get_type() ) {
    367           case OperatorNode::Incr:
    368           case OperatorNode::Decr:
    369           case OperatorNode::IncrPost:
    370           case OperatorNode::DecrPost:
    371           case OperatorNode::Assign:
    372           case OperatorNode::MulAssn:
    373           case OperatorNode::DivAssn:
    374           case OperatorNode::ModAssn:
    375           case OperatorNode::PlusAssn:
    376           case OperatorNode::MinusAssn:
    377           case OperatorNode::LSAssn:
    378           case OperatorNode::RSAssn:
    379           case OperatorNode::AndAssn:
    380           case OperatorNode::ERAssn:
    381           case OperatorNode::OrAssn:
    382           case OperatorNode::Plus:
    383           case OperatorNode::Minus:
    384           case OperatorNode::Mul:
    385           case OperatorNode::Div:
    386           case OperatorNode::Mod:
    387           case OperatorNode::BitOr:
    388           case OperatorNode::BitAnd:
    389           case OperatorNode::Xor:
    390           case OperatorNode::LShift:
    391           case OperatorNode::RShift:
    392           case OperatorNode::LThan:
    393           case OperatorNode::GThan:
    394           case OperatorNode::LEThan:
    395           case OperatorNode::GEThan:
    396           case OperatorNode::Eq:
    397           case OperatorNode::Neq:
    398           case OperatorNode::Index:
    399           case OperatorNode::Range:
    400           case OperatorNode::UnPlus:
    401           case OperatorNode::UnMinus:
    402           case OperatorNode::PointTo:
    403           case OperatorNode::Neg:
    404           case OperatorNode::BitNeg:
    405           case OperatorNode::LabelAddress:
    406             return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
    407           case OperatorNode::AddressOf:
    408             assert( args.size() == 1 );
    409             assert( args.front() );
    410 
    411             return new AddressExpr( args.front() );
    412           case OperatorNode::Cast:
    413             {
    414                 TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
    415                 assert( arg );
    416 
    417                 DeclarationNode *decl_node = arg->get_decl();
    418                 ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
    419 
    420                 Type *targetType = decl_node->buildType();
    421                 if ( dynamic_cast< VoidType* >( targetType ) ) {
    422                     delete targetType;
    423                     return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
    424                 } else {
    425                     return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
    426                 } // if
    427             }
    428           case OperatorNode::FieldSel:
    429             {
    430                 assert( args.size() == 2 );
    431 
    432                 NameExpr *member = dynamic_cast<NameExpr *>( args.back());
    433                 // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
    434 
    435                 if ( member != 0 ) {
    436                     UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
    437                     delete member;
    438                     return ret;
    439                 /* else if ( memberTup != 0 )
    440                    {
    441                    UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
    442                    delete member;
    443                    return ret;
    444                    } */
    445                 } else
    446                     assert( false );
    447             }
    448           case OperatorNode::PFieldSel:
    449             {
    450                 assert( args.size() == 2 );
    451 
    452                 NameExpr *member = dynamic_cast<NameExpr *>( args.back());  // modify for Tuples   xxx
    453                 assert( member != 0 );
    454 
    455                 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    456                 deref->get_args().push_back( args.front() );
    457 
    458                 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
    459                 delete member;
    460                 return ret;
    461             }
    462           case OperatorNode::AlignOf:
    463           case OperatorNode::SizeOf:
    464             {
     347        OperatorNode *op;
     348        std::list<Expression *> args;
     349
     350        buildList( get_args(), args );
     351
     352        if ( ! ( op = dynamic_cast<OperatorNode *>( function )) ) {
     353                // a function as opposed to an operator
     354                return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));
     355        } else {
     356                switch ( op->get_type()){
     357                  case OperatorNode::Incr:
     358                  case OperatorNode::Decr:
     359                  case OperatorNode::IncrPost:
     360                  case OperatorNode::DecrPost:
     361                  case OperatorNode::Assign:
     362                  case OperatorNode::MulAssn:
     363                  case OperatorNode::DivAssn:
     364                  case OperatorNode::ModAssn:
     365                  case OperatorNode::PlusAssn:
     366                  case OperatorNode::MinusAssn:
     367                  case OperatorNode::LSAssn:
     368                  case OperatorNode::RSAssn:
     369                  case OperatorNode::AndAssn:
     370                  case OperatorNode::ERAssn:
     371                  case OperatorNode::OrAssn:
     372                        // the rewrite rules for these expressions specify that the first argument has its address taken
     373                        assert( !args.empty() );
     374                        args.front() = new AddressExpr( args.front() );
     375                        break;
     376                  default:
     377                        /* do nothing */
     378                        ;
     379                }
     380
     381                switch ( op->get_type() ) {
     382                  case OperatorNode::Incr:
     383                  case OperatorNode::Decr:
     384                  case OperatorNode::IncrPost:
     385                  case OperatorNode::DecrPost:
     386                  case OperatorNode::Assign:
     387                  case OperatorNode::MulAssn:
     388                  case OperatorNode::DivAssn:
     389                  case OperatorNode::ModAssn:
     390                  case OperatorNode::PlusAssn:
     391                  case OperatorNode::MinusAssn:
     392                  case OperatorNode::LSAssn:
     393                  case OperatorNode::RSAssn:
     394                  case OperatorNode::AndAssn:
     395                  case OperatorNode::ERAssn:
     396                  case OperatorNode::OrAssn:
     397                  case OperatorNode::Plus:
     398                  case OperatorNode::Minus:
     399                  case OperatorNode::Mul:
     400                  case OperatorNode::Div:
     401                  case OperatorNode::Mod:
     402                  case OperatorNode::BitOr:
     403                  case OperatorNode::BitAnd:
     404                  case OperatorNode::Xor:
     405                  case OperatorNode::LShift:
     406                  case OperatorNode::RShift:
     407                  case OperatorNode::LThan:
     408                  case OperatorNode::GThan:
     409                  case OperatorNode::LEThan:
     410                  case OperatorNode::GEThan:
     411                  case OperatorNode::Eq:
     412                  case OperatorNode::Neq:
     413                  case OperatorNode::Index:
     414                  case OperatorNode::Range:
     415                  case OperatorNode::UnPlus:
     416                  case OperatorNode::UnMinus:
     417                  case OperatorNode::PointTo:
     418                  case OperatorNode::Neg:
     419                  case OperatorNode::BitNeg:
     420                  case OperatorNode::LabelAddress:
     421                        return new UntypedExpr( new NameExpr( opFuncName[ op->get_type() ] ), args );
     422                  case OperatorNode::AddressOf:
     423                        assert( args.size() == 1 );
     424                        assert( args.front() );
     425
     426                        return new AddressExpr( args.front() );
     427                  case OperatorNode::Cast:
     428                        {
     429                                TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
     430                                assert( arg );
     431
     432                                DeclarationNode *decl_node = arg->get_decl();
     433                                ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
     434
     435                                Type *targetType = decl_node->buildType();
     436                                if ( dynamic_cast< VoidType* >( targetType ) ) {
     437                                        delete targetType;
     438                                        return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
     439                                } else {
     440                                        return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
     441                                } // if
     442                        }
     443                  case OperatorNode::FieldSel:
     444                        {
     445                                assert( args.size() == 2 );
     446
     447                                NameExpr *member = dynamic_cast<NameExpr *>( args.back());
     448                                // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
     449
     450                                if ( member != 0 ) {
     451                                        UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
     452                                        delete member;
     453                                        return ret;
     454                                        /* else if ( memberTup != 0 )
     455                                           {
     456                                           UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
     457                                           delete member;
     458                                           return ret;
     459                                           } */
     460                                } else
     461                                        assert( false );
     462                        }
     463                  case OperatorNode::PFieldSel:
     464                        {
     465                                assert( args.size() == 2 );
     466
     467                                NameExpr *member = dynamic_cast<NameExpr *>( args.back());  // modify for Tuples   xxx
     468                                assert( member != 0 );
     469
     470                                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     471                                deref->get_args().push_back( args.front() );
     472
     473                                UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
     474                                delete member;
     475                                return ret;
     476                        }
     477                  case OperatorNode::AlignOf:
     478                  case OperatorNode::SizeOf:
     479                        {
    465480///     bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
    466481
    467                 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
    468                     return new SizeofExpr( arg->get_decl()->buildType());
    469                 } else {
    470                     return new SizeofExpr( args.front());
    471                 } // if
    472             }
    473           case OperatorNode::Attr:
    474             {
    475                 VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
    476                 assert( var );
    477                 if ( !get_args()->get_link() ) {
    478                     return new AttrExpr( var->build(), ( Expression*)0);
    479                 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
    480                     return new AttrExpr( var->build(), arg->get_decl()->buildType());
    481                 } else {
    482                     return new AttrExpr( var->build(), args.back());
    483                 } // if
    484             }
    485           case OperatorNode::CompLit:
    486             throw UnimplementedError( "C99 compound literals" );
    487             // the short-circuited operators
    488           case OperatorNode::Or:
    489           case OperatorNode::And:
    490             assert( args.size() == 2);
    491             return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
    492           case OperatorNode::Cond:
    493             {
    494                 assert( args.size() == 3);
    495                 std::list< Expression* >::const_iterator i = args.begin();
    496                 Expression *arg1 = notZeroExpr( *i++ );
    497                 Expression *arg2 = *i++;
    498                 Expression *arg3 = *i++;
    499                 return new ConditionalExpr( arg1, arg2, arg3 );
    500             }
    501           case OperatorNode::NCond:
    502             throw UnimplementedError( "GNU 2-argument conditional expression" );
    503           case OperatorNode::Comma:
    504             {
    505                 assert( args.size() == 2);
    506                 std::list< Expression* >::const_iterator i = args.begin();
    507                 Expression *ret = *i++;
    508                 while ( i != args.end() ) {
    509                     ret = new CommaExpr( ret, *i++ );
    510                 }
    511                 return ret;
    512             }
    513             // Tuples
    514           case OperatorNode::TupleC:
    515             {
    516                 TupleExpr *ret = new TupleExpr();
    517                 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
    518                 return ret;
    519             }
    520           default:
    521             // shouldn't happen
    522             return 0;
    523         }
    524     }
    525 }
    526 
    527 void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
    528     printDesignation( os );
    529     os << "( ";
    530     function->printOneLine( os, indent );
    531     for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
    532         cur->printOneLine( os, indent );
    533     }
    534     os << ") ";
    535 }
    536 
    537 void CompositeExprNode::print( std::ostream &os, int indent ) const {
    538     printDesignation( os );
    539     os << '\r' << string( indent, ' ') << "Application of: " << endl;
    540     function->print( os, indent + ParseNode::indent_by );
    541 
    542     os << '\r' << string( indent, ' ') ;
    543     if ( arguments ) {
    544         os << "... on arguments: " << endl;
    545         arguments->printList( os, indent + ParseNode::indent_by );
    546     } else
    547         os << "... on no arguments: " << endl;
    548 }
    549 
    550 void CompositeExprNode::set_function( ExpressionNode *f ){
    551     function = f;
    552 }
    553 
    554 void CompositeExprNode::set_args( ExpressionNode *args ){
    555     arguments = args;
    556 }
    557 
    558 ExpressionNode *CompositeExprNode::get_function( void ) const {
    559     return function;
    560 }
    561 
    562 ExpressionNode *CompositeExprNode::get_args( void ) const {
    563     return arguments;
    564 }
    565 
    566 void CompositeExprNode::add_arg( ExpressionNode *arg ){
    567     if ( arguments )
    568         arguments->set_link( arg );
    569     else
    570         set_args( arg );
    571 }
    572 
    573 CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
    574 
    575 CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
    576 }
    577 
    578 CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
    579 }
    580 
    581 CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ){
    582     add_arg( exp );
    583 
    584     return this;
    585 }
    586 
    587 CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
    588 }
    589 
    590 ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
    591 
    592 ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
    593 }
    594 
    595 ValofExprNode::~ValofExprNode() {
    596     delete body;
    597 }
    598 
    599 void ValofExprNode::print( std::ostream &os, int indent ) const {
    600     printDesignation( os );
    601     os << string( indent, ' ') << "Valof Expression:" << std::endl;
    602     get_body()->print( os, indent + 4);
    603 }
    604 
    605 void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
    606     assert( false );
    607 }
    608 
    609 Expression *ValofExprNode::build() const {
    610     return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
    611 }
    612 
    613 ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
    614     if ( init_ == 0 )
    615         init = 0;
    616     else {
    617         DeclarationNode *decl;
    618         ExpressionNode *exp;
    619 
    620         if (( decl = dynamic_cast<DeclarationNode *>( init_)) != 0)
    621             init = new StatementNode( decl );
    622         else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
    623             init = new StatementNode( StatementNode::Exp, exp );
    624         else
    625             throw SemanticError("Error in for control expression");
    626     }
    627 }
    628 
    629 ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
    630     : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
    631 }
    632 
    633 ForCtlExprNode::~ForCtlExprNode(){
    634     delete init;
    635     delete condition;
    636     delete change;
    637 }
    638 
    639 Expression *ForCtlExprNode::build() const {
    640     // this shouldn't be used!
    641     assert( false );
    642     return 0;
    643 }
    644 
    645 void ForCtlExprNode::print( std::ostream &os, int indent ) const{
    646     os << string( indent,' ') << "For Control Expression -- : " << endl;
    647 
    648     os << "