Changeset 90152a4 for src/CodeGen


Ignore:
Timestamp:
Aug 27, 2018, 4:40:34 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
b7c89aa
Parents:
f9feab8 (diff), 305581d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into cleanup-dtors

Location:
src/CodeGen
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rf9feab8 r90152a4  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep  3 20:42:52 2017
    13 // Update Count     : 490
     12// Last Modified On : Sat May  5 09:08:32 2018
     13// Update Count     : 494
    1414//
    1515#include "CodeGenerator.h"
     
    1818#include <list>                      // for _List_iterator, list, list<>::it...
    1919
    20 #include "Common/SemanticError.h"    // for SemanticError
    2120#include "Common/UniqueName.h"       // for UniqueName
    2221#include "Common/utility.h"          // for CodeLocation, toString
     
    117116        }
    118117
    119         CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), endl( *this ) {}
     118        CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), printExprTypes( printExprTypes ), endl( *this ) {}
    120119
    121120        string CodeGenerator::mangleName( DeclarationWithType * decl ) {
    122                 if ( pretty ) return decl->get_name();
    123                 if ( decl->get_mangleName() != "" ) {
     121                // GCC builtins should always be printed unmangled
     122                if ( pretty || decl->linkage.is_gcc_builtin ) return decl->name;
     123                if ( decl->mangleName != "" ) {
    124124                        // need to incorporate scope level in order to differentiate names for destructors
    125125                        return decl->get_scopedMangleName();
    126126                } else {
    127                         return decl->get_name();
     127                        return decl->name;
    128128                } // if
    129129        }
     
    133133                output << "__attribute__ ((";
    134134                for ( list< Attribute * >::iterator attr( attributes.begin() );; ) {
    135                         output << (*attr)->get_name();
    136                         if ( ! (*attr)->get_parameters().empty() ) {
     135                        output << (*attr)->name;
     136                        if ( ! (*attr)->parameters.empty() ) {
    137137                                output << "(";
    138                                 genCommaList( (*attr)->get_parameters().begin(), (*attr)->get_parameters().end() );
     138                                genCommaList( (*attr)->parameters.begin(), (*attr)->parameters.end() );
    139139                                output << ")";
    140140                        } // if
     
    160160        }
    161161
     162        // *** Expression
     163        void CodeGenerator::previsit( Expression * node ) {
     164                previsit( (BaseSyntaxNode *)node );
     165                GuardAction( [this, node](){
     166                        if ( printExprTypes && node->result ) {
     167                                output << " /* " << genType( node->result, "", pretty, genC ) << " */ ";
     168                        }
     169                } );
     170        }
     171
    162172        // *** Declarations
    163173        void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
     174                // deleted decls should never be used, so don't print them
     175                if ( functionDecl->isDeleted && genC ) return;
    164176                extension( functionDecl );
    165177                genAttributes( functionDecl->get_attributes() );
     
    175187                        functionDecl->get_statements()->accept( *visitor );
    176188                } // if
     189                if ( functionDecl->isDeleted ) {
     190                        output << " = void";
     191                }
    177192        }
    178193
    179194        void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
     195                // deleted decls should never be used, so don't print them
     196                if ( objectDecl->isDeleted && genC ) return;
    180197                if (objectDecl->get_name().empty() && genC ) {
    181198                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
     
    196213                        objectDecl->get_init()->accept( *visitor );
    197214                } // if
     215                if ( objectDecl->isDeleted ) {
     216                        output << " = void";
     217                }
    198218
    199219                if ( objectDecl->get_bitfieldWidth() ) {
     
    204224
    205225        void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) {
    206                 genAttributes( aggDecl->get_attributes() );
    207 
    208                 if( ! aggDecl->get_parameters().empty() && ! genC ) {
     226                if( ! aggDecl->parameters.empty() && ! genC ) {
    209227                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    210228                        output << "forall(";
    211                         genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
     229                        genCommaList( aggDecl->parameters.begin(), aggDecl->parameters.end() );
    212230                        output << ")" << endl;
    213231                        output << indent;
    214232                }
    215233
    216                 output << kind << aggDecl->get_name();
     234                output << kind;
     235                genAttributes( aggDecl->attributes );
     236                output << aggDecl->name;
    217237
    218238                if ( aggDecl->has_body() ) {
    219                         std::list< Declaration * > & memb = aggDecl->get_members();
     239                        std::list< Declaration * > & memb = aggDecl->members;
    220240                        output << " {" << endl;
    221241
     
    299319                        output << " }";
    300320                }
     321        }
     322
     323        void CodeGenerator::postvisit( StaticAssertDecl * assertDecl ) {
     324                output << "_Static_assert(";
     325                assertDecl->condition->accept( *visitor );
     326                output << ", ";
     327                assertDecl->message->accept( *visitor );
     328                output << ")";
    301329        }
    302330
     
    353381
    354382        void CodeGenerator::postvisit( Constant * constant ) {
    355                 output << constant->get_value() ;
     383                output << constant->get_value();
    356384        }
    357385
     
    570598                output << "(";
    571599                if ( castExpr->get_result()->isVoid() ) {
    572                         output << "(void)" ;
     600                        output << "(void)";
    573601                } else {
    574602                        // at least one result type of cast.
     
    579607                        output << ")";
    580608                } // if
    581                 castExpr->get_arg()->accept( *visitor );
     609                castExpr->arg->accept( *visitor );
     610                output << ")";
     611        }
     612
     613        void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) {
     614                assertf( ! genC, "KeywordCast should not reach code generation." );
     615                extension( castExpr );
     616                output << "((" << castExpr->targetString() << " &)";
     617                castExpr->arg->accept( *visitor );
    582618                output << ")";
    583619        }
     
    764800
    765801        void CodeGenerator::postvisit( StmtExpr * stmtExpr ) {
    766                 std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
     802                std::list< Statement * > & stmts = stmtExpr->statements->kids;
    767803                output << "({" << endl;
    768804                ++indent;
     
    775811                                // cannot cast to void, otherwise the expression statement has no value
    776812                                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
    777                                         exprStmt->get_expr()->accept( *visitor );
     813                                        exprStmt->expr->accept( *visitor );
    778814                                        output << ";" << endl;
    779815                                        ++i;
     
    796832                expr->callExpr->accept( *visitor );
    797833        }
     834
     835        void CodeGenerator::postvisit( DeletedExpr * expr ) {
     836                assertf( ! genC, "Deleted expressions should not reach code generation." );
     837                expr->expr->accept( *visitor );
     838        }
     839
     840        void CodeGenerator::postvisit( DefaultArgExpr * arg ) {
     841                assertf( ! genC, "Default argument expressions should not reach code generation." );
     842                arg->expr->accept( *visitor );
     843        }
     844
     845        void CodeGenerator::postvisit( GenericExpr * expr ) {
     846                assertf( ! genC, "C11 _Generic expressions should not reach code generation." );
     847                output << "_Generic(";
     848                expr->control->accept( *visitor );
     849                output << ", ";
     850                unsigned int numAssocs = expr->associations.size();
     851                unsigned int i = 0;
     852                for ( GenericExpr::Association & assoc : expr->associations ) {
     853                        if (assoc.isDefault) {
     854                                output << "default: ";
     855                        } else {
     856                                output << genType( assoc.type, "", pretty, genC ) << ": ";
     857                        }
     858                        assoc.expr->accept( *visitor );
     859                        if ( i+1 != numAssocs ) {
     860                                output << ", ";
     861                        }
     862                        i++;
     863                }
     864                output << ")";
     865        }
     866
    798867
    799868        // *** Statements
     
    848917                        } // for
    849918                } // if
    850                 output << " );" ;
     919                output << " );";
    851920        }
    852921
     
    856925                output << "( ";
    857926                if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor );
    858                 output << " )" ;
     927                output << " )";
     928        }
     929
     930        void CodeGenerator::postvisit( DirectiveStmt * dirStmt ) {
     931                output << endl << dirStmt->directive;                   // endl prevents spaces before directive
    859932        }
    860933
     
    873946
    874947        void CodeGenerator::postvisit( SwitchStmt * switchStmt ) {
    875                 output << "switch ( " ;
     948                output << "switch ( ";
    876949                switchStmt->get_condition()->accept( *visitor );
    877950                output << " ) ";
     
    899972                ++indent;
    900973                for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
    901                         output << indent << printLabels( (*i)->get_labels() )  ;
     974                        output << indent << printLabels( (*i)->get_labels() ) ;
    902975                        (*i)->accept( *visitor );
    903976                        output << endl;
     
    924997                        output << "continue";
    925998                        break;
     999                  case BranchStmt::FallThrough:
     1000                  case BranchStmt::FallThroughDefault:
     1001                        assertf( ! genC, "fallthru should not reach code generation." );
     1002                  output << "fallthru";
     1003                        break;
    9261004                } // switch
     1005                // print branch target for labelled break/continue/fallthru in debug mode
     1006                if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) {
     1007                        if ( ! branchStmt->get_target().empty() ) {
     1008                                output << " " << branchStmt->get_target();
     1009                        } else if ( branchStmt->get_type() == BranchStmt::FallThrough ) {
     1010                                output << " default";
     1011                        }
     1012                }
    9271013                output << ";";
    9281014        }
     
    10231109        void CodeGenerator::postvisit( WhileStmt * whileStmt ) {
    10241110                if ( whileStmt->get_isDoWhile() ) {
    1025                         output << "do" ;
     1111                        output << "do";
    10261112                } else {
    1027                         output << "while (" ;
     1113                        output << "while (";
    10281114                        whileStmt->get_condition()->accept( *visitor );
    10291115                        output << ")";
     
    10371123
    10381124                if ( whileStmt->get_isDoWhile() ) {
    1039                         output << " while (" ;
     1125                        output << " while (";
    10401126                        whileStmt->get_condition()->accept( *visitor );
    10411127                        output << ");";
  • src/CodeGen/CodeGenerator.h

    rf9feab8 r90152a4  
    2727
    2828namespace CodeGen {
    29         struct CodeGenerator : public WithShortCircuiting, public WithVisitorRef<CodeGenerator> {
     29        struct CodeGenerator : public WithShortCircuiting, public WithGuards, public WithVisitorRef<CodeGenerator> {
    3030          static int tabsize;
    3131
    32                 CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false, bool lineMarks = false );
     32                CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false, bool lineMarks = false, bool printExprTypes = false );
    3333
    3434                //*** Turn off visit_children for all nodes
     
    3838                void postvisit( BaseSyntaxNode * );
    3939
     40                //*** print type for all expressions
     41                void previsit( Expression * node );
     42
    4043                //*** Declaration
    4144                void postvisit( StructDecl * );
    4245                void postvisit( FunctionDecl * );
    4346                void postvisit( ObjectDecl * );
    44                 void postvisit( UnionDecl *aggregateDecl );
    45                 void postvisit( EnumDecl *aggregateDecl );
    46                 void postvisit( TraitDecl *aggregateDecl );
    47                 void postvisit( TypedefDecl *typeDecl );
    48                 void postvisit( TypeDecl *typeDecl );
     47                void postvisit( UnionDecl * aggregateDecl );
     48                void postvisit( EnumDecl * aggregateDecl );
     49                void postvisit( TraitDecl * aggregateDecl );
     50                void postvisit( TypedefDecl * typeDecl );
     51                void postvisit( TypeDecl * typeDecl );
     52                void postvisit( StaticAssertDecl * assertDecl );
    4953
    5054                //*** Initializer
     
    6569                void postvisit( LabelAddressExpr *addressExpr );
    6670                void postvisit( CastExpr *castExpr );
     71                void postvisit( KeywordCastExpr * castExpr );
    6772                void postvisit( VirtualCastExpr *castExpr );
    6873                void postvisit( UntypedMemberExpr *memberExpr );
     
    8893                void postvisit( StmtExpr * );
    8994                void postvisit( ConstructorExpr * );
     95                void postvisit( DeletedExpr * );
     96                void postvisit( DefaultArgExpr * );
     97                void postvisit( GenericExpr * );
    9098
    9199                //*** Statements
     
    93101                void postvisit( ExprStmt * );
    94102                void postvisit( AsmStmt * );
     103                void postvisit( DirectiveStmt * );
    95104                void postvisit( AsmDecl * );                            // special: statement in declaration context
    96105                void postvisit( IfStmt * );
     
    138147                bool genC = false;    // true if output has to be C code
    139148                bool lineMarks = false;
     149                bool printExprTypes = false;
    140150        public:
    141151                LineEnder endl;
  • src/CodeGen/FixMain.cc

    rf9feab8 r90152a4  
    2323
    2424#include "Common/SemanticError.h"  // for SemanticError
     25#include "CodeGen/GenType.h"       // for GenType
    2526#include "SynTree/Declaration.h"   // for FunctionDecl, operator<<
    2627#include "SynTree/Type.h"          // for FunctionType
     
    3031        std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr;
    3132
     33        template<typename container>
     34        std::string genTypeAt(const container& p, size_t idx) {
     35                return genType((*std::next(p.begin(), idx))->get_type(), "");
     36        }
     37
    3238        void FixMain::registerMain(FunctionDecl* functionDecl)
    3339        {
    3440                if(main_signature) {
    35                         throw SemanticError("Multiple definition of main routine\n", functionDecl);
     41                        SemanticError(functionDecl, "Multiple definition of main routine\n");
    3642                }
    3743                main_signature.reset( functionDecl->clone() );
     
    4349
    4450                        os << main_signature->get_scopedMangleName() << "(";
    45                         switch(main_signature->get_functionType()->get_parameters().size()) {
    46                                 case 3: os << "argc, argv, envp"; break;
    47                                 case 2: os << "argc, argv"; break;
     51                        const auto& params = main_signature->get_functionType()->get_parameters();
     52                        switch(params.size()) {
     53                                case 3: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv, (" << genTypeAt(params, 2) << ")envp"; break;
     54                                case 2: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv"; break;
    4855                                case 0: break;
    4956                                default : assert(false);
  • src/CodeGen/FixNames.cc

    rf9feab8 r90152a4  
    5656                auto && name = SymTab::Mangler::mangle( mainDecl.get() );
    5757                // std::cerr << name << std::endl;
    58                 return name;
     58                return std::move(name);
    5959        }
    6060        std::string mangle_main_args() {
     
    7979                auto&& name = SymTab::Mangler::mangle( mainDecl.get() );
    8080                // std::cerr << name << std::endl;
    81                 return name;
     81                return std::move(name);
    8282        }
    8383
     
    118118                        int nargs = functionDecl->get_functionType()->get_parameters().size();
    119119                        if( !(nargs == 0 || nargs == 2 || nargs == 3) ) {
    120                                 throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl);
     120                                SemanticError(functionDecl, "Main expected to have 0, 2 or 3 arguments\n");
    121121                        }
    122122                        functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) );
  • src/CodeGen/GenType.cc

    rf9feab8 r90152a4  
    2626
    2727namespace CodeGen {
    28         class GenType : public Visitor {
    29           public:
    30                 GenType( const std::string &typeString, bool pretty = false, bool genC = false, bool lineMarks = false );
    31                 std::string get_typeString() const { return typeString; }
    32                 void set_typeString( const std::string &newValue ) { typeString = newValue; }
    33 
    34                 virtual void visit( FunctionType *funcType );
    35                 virtual void visit( VoidType *voidType );
    36                 virtual void visit( BasicType *basicType );
    37                 virtual void visit( PointerType *pointerType );
    38                 virtual void visit( ArrayType *arrayType );
    39                 virtual void visit( ReferenceType *refType );
    40                 virtual void visit( StructInstType *structInst );
    41                 virtual void visit( UnionInstType *unionInst );
    42                 virtual void visit( EnumInstType *enumInst );
    43                 virtual void visit( TypeInstType *typeInst );
    44                 virtual void visit( TupleType * tupleType );
    45                 virtual void visit( VarArgsType *varArgsType );
    46                 virtual void visit( ZeroType *zeroType );
    47                 virtual void visit( OneType *oneType );
     28        struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting {
     29                std::string typeString;
     30                GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks );
     31
     32                void previsit( BaseSyntaxNode * );
     33                void postvisit( BaseSyntaxNode * );
     34
     35                void postvisit( FunctionType * funcType );
     36                void postvisit( VoidType * voidType );
     37                void postvisit( BasicType * basicType );
     38                void postvisit( PointerType * pointerType );
     39                void postvisit( ArrayType * arrayType );
     40                void postvisit( ReferenceType * refType );
     41                void postvisit( StructInstType * structInst );
     42                void postvisit( UnionInstType * unionInst );
     43                void postvisit( EnumInstType * enumInst );
     44                void postvisit( TypeInstType * typeInst );
     45                void postvisit( TupleType  * tupleType );
     46                void postvisit( VarArgsType * varArgsType );
     47                void postvisit( ZeroType * zeroType );
     48                void postvisit( OneType * oneType );
     49                void postvisit( GlobalScopeType * globalType );
     50                void postvisit( TraitInstType * inst );
     51                void postvisit( TypeofType * typeof );
     52                void postvisit( QualifiedType * qualType );
    4853
    4954          private:
     
    5257                void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    5358
    54                 std::string typeString;
    55                 bool pretty = false; // pretty print
    56                 bool genC = false;   // generating C code?
    57                 bool lineMarks = false;
     59                bool pretty = false;    // pretty print
     60                bool genC = false;      // generating C code?
     61                bool lineMarks = false; // lineMarks on for CodeGenerator?
    5862        };
    5963
    6064        std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {
    61                 GenType gt( baseString, pretty, genC, lineMarks );
     65                PassVisitor<GenType> gt( baseString, pretty, genC, lineMarks );
    6266                std::ostringstream os;
    6367
     
    6872
    6973                type->accept( gt );
    70                 return os.str() + gt.get_typeString();
     74                return os.str() + gt.pass.typeString;
    7175        }
    7276
     
    7781        GenType::GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks ) : typeString( typeString ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {}
    7882
    79         void GenType::visit( VoidType *voidType ) {
     83        // *** BaseSyntaxNode
     84        void GenType::previsit( BaseSyntaxNode * ) {
     85                // turn off automatic recursion for all nodes, to allow each visitor to
     86                // precisely control the order in which its children are visited.
     87                visit_children = false;
     88        }
     89
     90        void GenType::postvisit( BaseSyntaxNode * node ) {
     91                std::stringstream ss;
     92                node->print( ss );
     93                assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() );
     94        }
     95
     96        void GenType::postvisit( VoidType * voidType ) {
    8097                typeString = "void " + typeString;
    8198                handleQualifiers( voidType );
    8299        }
    83100
    84         void GenType::visit( BasicType *basicType ) {
    85                 BasicType::Kind kind = basicType->get_kind();
     101        void GenType::postvisit( BasicType * basicType ) {
     102                BasicType::Kind kind = basicType->kind;
    86103                assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES );
    87104                typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString;
     
    89106        }
    90107
    91         void GenType::genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ) {
     108        void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool isStatic ) {
    92109                std::ostringstream os;
    93110                if ( typeString != "" ) {
     
    126143                typeString = os.str();
    127144
    128                 base->accept( *this );
    129         }
    130 
    131         void GenType::visit( PointerType *pointerType ) {
    132                 assert( pointerType->get_base() != 0);
    133                 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->get_dimension() ) {
    134                         genArray( pointerType->get_qualifiers(), pointerType->get_base(), pointerType->get_dimension(), pointerType->get_isVarLen(), pointerType->get_isStatic() );
     145                base->accept( *visitor );
     146        }
     147
     148        void GenType::postvisit( PointerType * pointerType ) {
     149                assert( pointerType->base != 0);
     150                if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) {
     151                        genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() );
    135152                } else {
    136153                        handleQualifiers( pointerType );
     
    140157                                typeString = "*" + typeString;
    141158                        } // if
    142                         pointerType->get_base()->accept( *this );
    143                 } // if
    144         }
    145 
    146         void GenType::visit( ArrayType *arrayType ) {
    147                 genArray( arrayType->get_qualifiers(), arrayType->get_base(), arrayType->get_dimension(), arrayType->get_isVarLen(), arrayType->get_isStatic() );
    148         }
    149 
    150         void GenType::visit( ReferenceType *refType ) {
    151                 assert( refType->get_base() != 0);
     159                        pointerType->base->accept( *visitor );
     160                } // if
     161        }
     162
     163        void GenType::postvisit( ArrayType * arrayType ) {
     164                genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() );
     165        }
     166
     167        void GenType::postvisit( ReferenceType * refType ) {
     168                assert( refType->base != 0);
    152169                assertf( ! genC, "Reference types should not reach code generation." );
    153170                handleQualifiers( refType );
    154171                typeString = "&" + typeString;
    155                 refType->get_base()->accept( *this );
    156         }
    157 
    158         void GenType::visit( FunctionType *funcType ) {
     172                refType->base->accept( *visitor );
     173        }
     174
     175        void GenType::postvisit( FunctionType * funcType ) {
    159176                std::ostringstream os;
    160177
     
    169186                /************* parameters ***************/
    170187
    171                 const std::list<DeclarationWithType *> &pars = funcType->get_parameters();
     188                const std::list<DeclarationWithType *> &pars = funcType->parameters;
    172189
    173190                if ( pars.empty() ) {
     
    191208                typeString = os.str();
    192209
    193                 if ( funcType->get_returnVals().size() == 0 ) {
     210                if ( funcType->returnVals.size() == 0 ) {
    194211                        typeString = "void " + typeString;
    195212                } else {
    196                         funcType->get_returnVals().front()->get_type()->accept( *this );
     213                        funcType->returnVals.front()->get_type()->accept( *visitor );
    197214                } // if
    198215
    199216                // add forall
    200                 if( ! funcType->get_forall().empty() && ! genC ) {
     217                if( ! funcType->forall.empty() && ! genC ) {
    201218                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    202219                        std::ostringstream os;
    203220                        PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
    204221                        os << "forall(";
    205                         cg.pass.genCommaList( funcType->get_forall().begin(), funcType->get_forall().end() );
     222                        cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() );
    206223                        os << ")" << std::endl;
    207224                        typeString = os.str() + typeString;
     
    221238        }
    222239
    223         void GenType::visit( StructInstType *structInst )  {
    224                 typeString = structInst->get_name() + handleGeneric( structInst ) + " " + typeString;
     240        void GenType::postvisit( StructInstType * structInst )  {
     241                typeString = structInst->name + handleGeneric( structInst ) + " " + typeString;
    225242                if ( genC ) typeString = "struct " + typeString;
    226243                handleQualifiers( structInst );
    227244        }
    228245
    229         void GenType::visit( UnionInstType *unionInst ) {
    230                 typeString = unionInst->get_name() + handleGeneric( unionInst ) + " " + typeString;
     246        void GenType::postvisit( UnionInstType * unionInst ) {
     247                typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString;
    231248                if ( genC ) typeString = "union " + typeString;
    232249                handleQualifiers( unionInst );
    233250        }
    234251
    235         void GenType::visit( EnumInstType *enumInst ) {
    236                 typeString = enumInst->get_name() + " " + typeString;
     252        void GenType::postvisit( EnumInstType * enumInst ) {
     253                typeString = enumInst->name + " " + typeString;
    237254                if ( genC ) typeString = "enum " + typeString;
    238255                handleQualifiers( enumInst );
    239256        }
    240257
    241         void GenType::visit( TypeInstType *typeInst ) {
    242                 typeString = typeInst->get_name() + " " + typeString;
     258        void GenType::postvisit( TypeInstType * typeInst ) {
     259                typeString = typeInst->name + " " + typeString;
    243260                handleQualifiers( typeInst );
    244261        }
    245262
    246         void GenType::visit( TupleType * tupleType ) {
     263        void GenType::postvisit( TupleType * tupleType ) {
    247264                assertf( ! genC, "Tuple types should not reach code generation." );
    248265                unsigned int i = 0;
     
    257274        }
    258275
    259         void GenType::visit( VarArgsType *varArgsType ) {
     276        void GenType::postvisit( VarArgsType * varArgsType ) {
    260277                typeString = "__builtin_va_list " + typeString;
    261278                handleQualifiers( varArgsType );
    262279        }
    263280
    264         void GenType::visit( ZeroType *zeroType ) {
     281        void GenType::postvisit( ZeroType * zeroType ) {
    265282                // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    266283                typeString = (pretty ? "zero_t " : "long int ") + typeString;
     
    268285        }
    269286
    270         void GenType::visit( OneType *oneType ) {
     287        void GenType::postvisit( OneType * oneType ) {
    271288                // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    272289                typeString = (pretty ? "one_t " : "long int ") + typeString;
     
    274291        }
    275292
    276         void GenType::handleQualifiers( Type *type ) {
     293        void GenType::postvisit( GlobalScopeType * globalType ) {
     294                assertf( ! genC, "Global scope type should not reach code generation." );
     295                handleQualifiers( globalType );
     296        }
     297
     298        void GenType::postvisit( TraitInstType * inst ) {
     299                assertf( ! genC, "Trait types should not reach code generation." );
     300                typeString = inst->name + " " + typeString;
     301                handleQualifiers( inst );
     302        }
     303
     304        void GenType::postvisit( TypeofType * typeof ) {
     305                std::ostringstream os;
     306                PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     307                os << "typeof(";
     308                typeof->expr->accept( cg );
     309                os << ") " << typeString;
     310                typeString = os.str();
     311                handleQualifiers( typeof );
     312        }
     313
     314        void GenType::postvisit( QualifiedType * qualType ) {
     315                assertf( ! genC, "Qualified types should not reach code generation." );
     316                std::ostringstream os;
     317                os << genType( qualType->parent, "", pretty, genC, lineMarks ) << "." << genType( qualType->child, "", pretty, genC, lineMarks ) << typeString;
     318                typeString = os.str();
     319                handleQualifiers( qualType );
     320        }
     321
     322        void GenType::handleQualifiers( Type * type ) {
    277323                if ( type->get_const() ) {
    278324                        typeString = "const " + typeString;
  • src/CodeGen/Generate.cc

    rf9feab8 r90152a4  
    4646        } // namespace
    4747
    48         void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks ) {
     48        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks, bool printExprTypes ) {
    4949                cleanTree( translationUnit );
    5050
    51                 PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks );
     51                PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks, printExprTypes );
    5252                for ( auto & dcl : translationUnit ) {
    5353                        if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {
     
    6666                        os << CodeGen::genPrettyType( type, "" );
    6767                } else {
    68                         PassVisitor<CodeGenerator> cgv( os, true, false, false );
     68                        PassVisitor<CodeGenerator> cgv( os, true, false, false, false );
    6969                        node->accept( cgv );
    7070                }
  • src/CodeGen/Generate.h

    rf9feab8 r90152a4  
    2424namespace CodeGen {
    2525        /// 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 , bool lineMarks = false );
     26        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC = false , bool lineMarks = false, bool printTypeExpr = false );
    2727
    2828        /// Generate code for a single node -- helpful for debugging in gdb
  • src/CodeGen/OperatorTable.cc

    rf9feab8 r90152a4  
    7979        } // namespace
    8080
    81         bool operatorLookup( std::string funcName, OperatorInfo &info ) {
     81        bool operatorLookup( const std::string & funcName, OperatorInfo & info ) {
    8282                static bool init = false;
    8383                if ( ! init ) {
     
    100100                        return true;
    101101                } // if
     102        }
     103
     104        bool isOperator( const std::string & funcName ) {
     105                OperatorInfo info;
     106                return operatorLookup( funcName, info );
    102107        }
    103108
  • src/CodeGen/OperatorTable.h

    rf9feab8 r90152a4  
    4141        };
    4242
    43         bool operatorLookup( std::string funcName, OperatorInfo &info );
     43        bool isOperator( const std::string & funcName );
     44        bool operatorLookup( const std::string & funcName, OperatorInfo & info );
    4445
    4546        bool isConstructor( const std::string & );
Note: See TracChangeset for help on using the changeset viewer.