Changeset e39241b for src


Ignore:
Timestamp:
Apr 17, 2017, 5:43:01 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
7069652
Parents:
4ae83a4b
Message:

allow codegen as an alternative to AST dump after any pass with the -z option

Location:
src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r4ae83a4b re39241b  
    8989        }
    9090
    91         CodeGenerator::CodeGenerator( std::ostream & os, bool pretty ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ) {}
     91        CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ) {}
    9292
    9393        CodeGenerator::CodeGenerator( std::ostream & os, std::string init, int indentation, bool infunp )
     
    136136                functionDecl->get_funcSpec().print( output );
    137137
    138                 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty );
     138                output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty, genC );
    139139
    140140                asmName( functionDecl );
     
    147147
    148148        void CodeGenerator::visit( ObjectDecl * objectDecl ) {
    149                 if (objectDecl->get_name().empty()) {
     149                if (objectDecl->get_name().empty() && genC ) {
     150                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
    150151                        static UniqueName name = { "__anonymous_object" };
    151152                        objectDecl->set_name( name.newName() );
     
    156157
    157158                handleStorageClass( objectDecl );
    158                 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty );
     159                output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC );
    159160
    160161                asmName( objectDecl );
     
    174175                genAttributes( aggDecl->get_attributes() );
    175176
     177                if( ! aggDecl->get_parameters().empty() && ! genC ) {
     178                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
     179                        output << "forall(";
     180                        genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
     181                        output << ")" << endl;
     182                }
     183
    176184                if ( aggDecl->get_name() != "" )
    177185                        output << aggDecl->get_name();
    178186
    179                 // std::list< Declaration * > & memb = aggDecl->get_members();
    180                 // if ( ! memb.empty() ) {
    181187                if ( aggDecl->has_body() ) {
    182188                        std::list< Declaration * > & memb = aggDecl->get_members();
     
    242248
    243249        void CodeGenerator::visit( TypedefDecl * typeDecl ) {
    244                 assert( false && "Typedefs are removed and substituted in earlier passes." );
    245                 //output << "typedef ";
    246                 //output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty );
     250                assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
     251                output << "typedef ";
     252                output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
    247253        }
    248254
    249255        void CodeGenerator::visit( TypeDecl * typeDecl ) {
    250                 // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
    251                 // still to be done
    252                 extension( typeDecl );
    253                 output << "extern unsigned long " << typeDecl->get_name();
    254                 if ( typeDecl->get_base() ) {
    255                         output << " = sizeof( " << genType( typeDecl->get_base(), "", pretty ) << " )";
    256                 } // if
     256                if ( genC ) {
     257                        // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
     258                        // still to be done
     259                        extension( typeDecl );
     260                        output << "extern unsigned long " << typeDecl->get_name();
     261                        if ( typeDecl->get_base() ) {
     262                                output << " = sizeof( " << genType( typeDecl->get_base(), "", pretty, genC ) << " )";
     263                        } // if
     264                } else {
     265                        output << typeDecl->typeString() << " " << typeDecl->get_name();
     266                        if ( ! typeDecl->get_assertions().empty() ) {
     267                                output << " | { ";
     268                                genCommaList( typeDecl->get_assertions().begin(), typeDecl->get_assertions().end() );
     269                                output << " }";
     270                        }
     271                }
    257272        }
    258273
     
    293308
    294309        void CodeGenerator::visit( ConstructorInit * init ){
    295                 assertf( false, "ConstructorInit nodes should not make it to CodeGen." );
     310                assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
     311                // xxx - generate something reasonable for constructor/destructor pairs
     312                output << "<ctorinit>";
    296313        }
    297314
     
    547564                        // at least one result type of cast, but not an lvalue
    548565                        output << "(";
    549                         output << genType( castExpr->get_result(), "", pretty );
     566                        output << genType( castExpr->get_result(), "", pretty, genC );
    550567                        output << ")";
    551568                } else {
     
    558575
    559576        void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {
    560                 assert( false );
     577                assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
     578                extension( memberExpr );
     579                memberExpr->get_aggregate()->accept( *this );
     580                output << "." << memberExpr->get_member();
    561581        }
    562582
     
    587607                output << "sizeof(";
    588608                if ( sizeofExpr->get_isType() ) {
    589                         output << genType( sizeofExpr->get_type(), "", pretty );
     609                        output << genType( sizeofExpr->get_type(), "", pretty, genC );
    590610                } else {
    591611                        sizeofExpr->get_expr()->accept( *this );
     
    599619                output << "__alignof__(";
    600620                if ( alignofExpr->get_isType() ) {
    601                         output << genType( alignofExpr->get_type(), "", pretty );
     621                        output << genType( alignofExpr->get_type(), "", pretty, genC );
    602622                } else {
    603623                        alignofExpr->get_expr()->accept( *this );
     
    607627
    608628        void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) {
    609                 assert( false && "UntypedOffsetofExpr should not reach code generation." );
     629                assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
     630                output << "offsetof(";
     631                output << genType( offsetofExpr->get_type(), "", pretty, genC );
     632                output << ", " << offsetofExpr->get_member();
     633                output << ")";
    610634        }
    611635
     
    613637                // use GCC builtin
    614638                output << "__builtin_offsetof(";
    615                 output << genType( offsetofExpr->get_type(), "", pretty );
     639                output << genType( offsetofExpr->get_type(), "", pretty, genC );
    616640                output << ", " << mangleName( offsetofExpr->get_member() );
    617641                output << ")";
     
    619643
    620644        void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) {
    621                 assert( false && "OffsetPackExpr should not reach code generation." );
     645                assertf( ! genC, "OffsetPackExpr should not reach code generation." );
     646                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
    622647        }
    623648
     
    655680        }
    656681
    657         void CodeGenerator::visit( UntypedTupleExpr * tupleExpr ) { assertf( false, "UntypedTupleExpr should not make it to Code Gen" ); }
    658 
    659         void CodeGenerator::visit( TupleExpr * tupleExpr ) { assertf( false, "TupleExpr should not make it to Code Gen" ); }
    660 
    661         void CodeGenerator::visit( TypeExpr * typeExpr ) {}
     682        void CodeGenerator::visit( UntypedTupleExpr * tupleExpr ) {
     683                assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
     684                output << "[";
     685                genCommaList( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end() );
     686                output << "]";
     687        }
     688
     689        void CodeGenerator::visit( TupleExpr * tupleExpr ) {
     690                assertf( ! genC, "TupleExpr should not reach code generation." );
     691                output << "[";
     692                genCommaList( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end() );
     693                output << "]";
     694        }
     695
     696        void CodeGenerator::visit( TypeExpr * typeExpr ) {
     697                assertf( ! genC, "TypeExpr should not reach code generation." );
     698                output<< genType( typeExpr->get_type(), "", pretty, genC );
     699        }
    662700
    663701        void CodeGenerator::visit( AsmExpr * asmExpr ) {
     
    675713        void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) {
    676714                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    677                 output << "(" << genType( compLitExpr->get_result(), "", pretty ) << ")";
     715                output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
    678716                compLitExpr->get_initializer()->accept( *this );
    679717        }
  • src/CodeGen/CodeGenerator.h

    r4ae83a4b re39241b  
    3030                static int tabsize;
    3131
    32                 CodeGenerator( std::ostream &os, bool pretty = false );
     32                CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false );
    3333                CodeGenerator( std::ostream &os, std::string, int indent = 0, bool infun = false );
    3434                CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false );
     
    121121                LabelPrinter printLabels;
    122122                bool pretty = false;  // pretty print
     123                bool genC = false;    // true if output has to be C code
    123124
    124125                void printDesignators( std::list< Expression * > & );
  • src/CodeGen/GenType.cc

    r4ae83a4b re39241b  
    2828        class GenType : public Visitor {
    2929          public:
    30                 GenType( const std::string &typeString, bool pretty = false );
     30                GenType( const std::string &typeString, bool pretty = false, bool genC = false );
    3131                std::string get_typeString() const { return typeString; }
    3232                void set_typeString( const std::string &newValue ) { typeString = newValue; }
     
    4848          private:
    4949                void handleQualifiers( Type *type );
     50                std::string handleGeneric( ReferenceToType * refType );
    5051                void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    5152
    5253                std::string typeString;
    5354                bool pretty = false; // pretty print
     55                bool genC = false;   // generating C code?
    5456        };
    5557
    56         std::string genType( Type *type, const std::string &baseString, bool pretty ) {
    57                 GenType gt( baseString, pretty );
     58        std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC ) {
     59                GenType gt( baseString, pretty, genC );
    5860                std::ostringstream os;
    5961
    6062                if ( ! type->get_attributes().empty() ) {
    61                         CodeGenerator cg( os, pretty );
     63                        CodeGenerator cg( os, pretty, genC );
    6264                        cg.genAttributes( type->get_attributes() );
    6365                } // if
     
    6870
    6971  std::string genPrettyType( Type * type, const std::string & baseString ) {
    70         return genType( type, baseString, true );
     72        return genType( type, baseString, true, false );
    7173  }
    7274
    73         GenType::GenType( const std::string &typeString, bool pretty ) : typeString( typeString ), pretty( pretty ) {}
     75        GenType::GenType( const std::string &typeString, bool pretty, bool genC ) : typeString( typeString ), pretty( pretty ), genC( genC ) {}
    7476
    7577        void GenType::visit( VoidType *voidType ) {
     
    112114                } // if
    113115                if ( dimension != 0 ) {
    114                         CodeGenerator cg( os, pretty );
     116                        CodeGenerator cg( os, pretty, genC );
    115117                        dimension->accept( cg );
    116118                } else if ( isVarLen ) {
     
    166168                        } // if
    167169                } else {
    168                         CodeGenerator cg( os, pretty );
     170                        CodeGenerator cg( os, pretty, genC );
    169171                        os << "(" ;
    170172
     
    186188        }
    187189
     190        std::string GenType::handleGeneric( ReferenceToType * refType ) {
     191                if ( ! refType->get_parameters().empty() ) {
     192                        std::ostringstream os;
     193                        CodeGenerator cg( os, pretty, genC );
     194                        os << "(";
     195                        cg.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() );
     196                        os << ") ";
     197                        return os.str();
     198                }
     199                return "";
     200        }
     201
    188202        void GenType::visit( StructInstType *structInst )  {
    189                 typeString = "struct " + structInst->get_name() + " " + typeString;
     203                typeString = structInst->get_name() + handleGeneric( structInst ) + " " + typeString;
     204                if ( genC ) typeString = "struct " + typeString;
    190205                handleQualifiers( structInst );
    191206        }
    192207
    193208        void GenType::visit( UnionInstType *unionInst ) {
    194                 typeString = "union " + unionInst->get_name() + " " + typeString;
     209                typeString = unionInst->get_name() + handleGeneric( unionInst ) + " " + typeString;
     210                if ( genC ) typeString = "union " + typeString;
    195211                handleQualifiers( unionInst );
    196212        }
    197213
    198214        void GenType::visit( EnumInstType *enumInst ) {
    199                 typeString = "enum " + enumInst->get_name() + " " + typeString;
     215                typeString = enumInst->get_name() + " " + typeString;
     216                if ( genC ) typeString = "enum " + typeString;
    200217                handleQualifiers( enumInst );
    201218        }
     
    207224
    208225        void GenType::visit( TupleType * tupleType ) {
    209                 assertf( pretty, "Tuple types should not make it to Code Gen." );
     226                assertf( ! genC, "Tuple types should not reach code generation." );
    210227                Visitor::visit( tupleType );
    211228                unsigned int i = 0;
     
    214231                for ( Type * t : *tupleType ) {
    215232                        i++;
    216                         os << genType( t, "", pretty ) << (i == tupleType->size() ? "" : ", ");
     233                        os << genType( t, "", pretty, genC ) << (i == tupleType->size() ? "" : ", ");
    217234                }
    218235                os << "]";
  • src/CodeGen/GenType.h

    r4ae83a4b re39241b  
    2121
    2222namespace CodeGen {
    23         std::string genType( Type *type, const std::string &baseString, bool pretty = false );
     23        std::string genType( Type *type, const std::string &baseString, bool pretty = false, bool genC = false );
    2424  std::string genPrettyType( Type * type, const std::string & baseString );
    2525} // namespace CodeGen
  • src/CodeGen/Generate.cc

    r4ae83a4b re39241b  
    2727
    2828namespace CodeGen {
    29         void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty ) {
    30                 CodeGen::CodeGenerator cgv( os, pretty );
     29        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC ) {
     30                CodeGen::CodeGenerator cgv( os, pretty, generateC );
    3131                for ( auto & dcl : translationUnit ) {
    3232                        if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {
  • src/CodeGen/Generate.h

    r4ae83a4b re39241b  
    2323
    2424namespace CodeGen {
    25         /// Generates code
    26         void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty );
     25        /// Generates code. doIntrinsics determines if intrinsic functions are printed, pretty formats output nicely (e.g., uses unmangled names, etc.), generateC is true when the output must consist only of C code (allows some assertions, etc.)
     26        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC = false );
    2727} // namespace CodeGen
    2828
  • src/SynTree/Declaration.h

    r4ae83a4b re39241b  
    167167        std::list< DeclarationWithType* >& get_assertions() { return assertions; }
    168168
     169        virtual std::string typeString() const = 0;
     170
    169171        virtual NamedTypeDecl *clone() const = 0;
    170172        virtual void print( std::ostream &os, int indent = 0 ) const;
    171173        virtual void printShort( std::ostream &os, int indent = 0 ) const;
    172174  protected:
    173         virtual std::string typeString() const = 0;
    174175  private:
    175176        Type *base;
     
    202203        TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; }
    203204
     205        virtual std::string typeString() const;
     206
    204207        virtual TypeDecl *clone() const { return new TypeDecl( *this ); }
    205208        virtual void accept( Visitor &v ) { v.visit( this ); }
    206209        virtual TypeDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    207210  private:
    208         virtual std::string typeString() const;
    209211        Kind kind;
    210212        bool sized;
     
    217219        TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
    218220
     221        virtual std::string typeString() const;
     222
    219223        virtual TypedefDecl *clone() const { return new TypedefDecl( *this ); }
    220224        virtual void accept( Visitor &v ) { v.visit( this ); }
    221225        virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    222226  private:
    223         virtual std::string typeString() const;
    224227};
    225228
  • src/main.cc

    r4ae83a4b re39241b  
    304304                GenPoly::box( translationUnit );
    305305
    306                 // print tree right before code generation
    307                 if ( codegenp ) {
    308                         dump( translationUnit );
    309                         return 0;
    310                 } // if
    311 
    312306                if ( optind < argc ) {                                                  // any commands after the flags and input file ? => output file name
    313307                        output = new ofstream( argv[ optind ] );
    314308                } // if
    315309
    316                 CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp );
     310                CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp, true );
    317311
    318312                CodeGen::FixMain::fix( *output, treep ? "../prelude/bootloader.c" : CFA_LIBDIR "/bootloader.c" );
     
    393387                        break;
    394388                  case CtorInitFix:
    395                   case 'c':
     389                  case 'c':                                                                             // print after constructors and destructors are replaced
    396390                        ctorinitp = true;
    397391                        break;
     
    450444                        validp = true;
    451445                        break;
    452                   case 'y':
     446                  case 'y':                                                                             // dump AST on error
    453447                        errorp = true;
    454448                        break;
    455                   case 'z':
     449                  case 'z':                                                                             // dump as codegen rather than AST
    456450                        codegenp = true;
    457                         case 'Z':
     451                        break;
     452                        case 'Z':                                                                       // prettyprint during codegen (i.e. print unmangled names, etc.)
    458453                        prettycodegenp = true;
    459454                        break;
     
    501496        } // if
    502497
    503         printAll( decls, out );
     498        // depending on commandline options, either generate code or dump the AST
     499        if ( codegenp ) {
     500                CodeGen::generate( decls, out, ! noprotop, prettycodegenp );
     501        } else {
     502                printAll( decls, out );
     503        }
    504504        deleteAll( translationUnit );
    505505} // dump
  • src/tests/.expect/memberCtors-ERR1.txt

    r4ae83a4b re39241b  
    1 memberCtors.c:62 error: in void ?{}(struct B *b), field a2 used before being constructed
     1memberCtors.c:62 error: in void ?{}(B *b), field a2 used before being constructed
    22make: *** [memberCtors-ERR1] Error 1
Note: See TracChangeset for help on using the changeset viewer.