Changeset 90152a4 for src/CodeGen
- Timestamp:
- Aug 27, 2018, 4:40:34 PM (7 years ago)
- 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. - Location:
- src/CodeGen
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
rf9feab8 r90152a4 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : S un Sep 3 20:42:52 201713 // Update Count : 49 012 // Last Modified On : Sat May 5 09:08:32 2018 13 // Update Count : 494 14 14 // 15 15 #include "CodeGenerator.h" … … 18 18 #include <list> // for _List_iterator, list, list<>::it... 19 19 20 #include "Common/SemanticError.h" // for SemanticError21 20 #include "Common/UniqueName.h" // for UniqueName 22 21 #include "Common/utility.h" // for CodeLocation, toString … … 117 116 } 118 117 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 ) {} 120 119 121 120 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 != "" ) { 124 124 // need to incorporate scope level in order to differentiate names for destructors 125 125 return decl->get_scopedMangleName(); 126 126 } else { 127 return decl-> get_name();127 return decl->name; 128 128 } // if 129 129 } … … 133 133 output << "__attribute__ (("; 134 134 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() ) { 137 137 output << "("; 138 genCommaList( (*attr)-> get_parameters().begin(), (*attr)->get_parameters().end() );138 genCommaList( (*attr)->parameters.begin(), (*attr)->parameters.end() ); 139 139 output << ")"; 140 140 } // if … … 160 160 } 161 161 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 162 172 // *** Declarations 163 173 void CodeGenerator::postvisit( FunctionDecl * functionDecl ) { 174 // deleted decls should never be used, so don't print them 175 if ( functionDecl->isDeleted && genC ) return; 164 176 extension( functionDecl ); 165 177 genAttributes( functionDecl->get_attributes() ); … … 175 187 functionDecl->get_statements()->accept( *visitor ); 176 188 } // if 189 if ( functionDecl->isDeleted ) { 190 output << " = void"; 191 } 177 192 } 178 193 179 194 void CodeGenerator::postvisit( ObjectDecl * objectDecl ) { 195 // deleted decls should never be used, so don't print them 196 if ( objectDecl->isDeleted && genC ) return; 180 197 if (objectDecl->get_name().empty() && genC ) { 181 198 // only generate an anonymous name when generating C code, otherwise it clutters the output too much … … 196 213 objectDecl->get_init()->accept( *visitor ); 197 214 } // if 215 if ( objectDecl->isDeleted ) { 216 output << " = void"; 217 } 198 218 199 219 if ( objectDecl->get_bitfieldWidth() ) { … … 204 224 205 225 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 ) { 209 227 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 210 228 output << "forall("; 211 genCommaList( aggDecl-> get_parameters().begin(), aggDecl->get_parameters().end() );229 genCommaList( aggDecl->parameters.begin(), aggDecl->parameters.end() ); 212 230 output << ")" << endl; 213 231 output << indent; 214 232 } 215 233 216 output << kind << aggDecl->get_name(); 234 output << kind; 235 genAttributes( aggDecl->attributes ); 236 output << aggDecl->name; 217 237 218 238 if ( aggDecl->has_body() ) { 219 std::list< Declaration * > & memb = aggDecl-> get_members();239 std::list< Declaration * > & memb = aggDecl->members; 220 240 output << " {" << endl; 221 241 … … 299 319 output << " }"; 300 320 } 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 << ")"; 301 329 } 302 330 … … 353 381 354 382 void CodeGenerator::postvisit( Constant * constant ) { 355 output << constant->get_value() 383 output << constant->get_value(); 356 384 } 357 385 … … 570 598 output << "("; 571 599 if ( castExpr->get_result()->isVoid() ) { 572 output << "(void)" 600 output << "(void)"; 573 601 } else { 574 602 // at least one result type of cast. … … 579 607 output << ")"; 580 608 } // 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 ); 582 618 output << ")"; 583 619 } … … 764 800 765 801 void CodeGenerator::postvisit( StmtExpr * stmtExpr ) { 766 std::list< Statement * > & stmts = stmtExpr-> get_statements()->get_kids();802 std::list< Statement * > & stmts = stmtExpr->statements->kids; 767 803 output << "({" << endl; 768 804 ++indent; … … 775 811 // cannot cast to void, otherwise the expression statement has no value 776 812 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) { 777 exprStmt-> get_expr()->accept( *visitor );813 exprStmt->expr->accept( *visitor ); 778 814 output << ";" << endl; 779 815 ++i; … … 796 832 expr->callExpr->accept( *visitor ); 797 833 } 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 798 867 799 868 // *** Statements … … 848 917 } // for 849 918 } // if 850 output << " );" 919 output << " );"; 851 920 } 852 921 … … 856 925 output << "( "; 857 926 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 859 932 } 860 933 … … 873 946 874 947 void CodeGenerator::postvisit( SwitchStmt * switchStmt ) { 875 output << "switch ( " 948 output << "switch ( "; 876 949 switchStmt->get_condition()->accept( *visitor ); 877 950 output << " ) "; … … 899 972 ++indent; 900 973 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() ) ; 902 975 (*i)->accept( *visitor ); 903 976 output << endl; … … 924 997 output << "continue"; 925 998 break; 999 case BranchStmt::FallThrough: 1000 case BranchStmt::FallThroughDefault: 1001 assertf( ! genC, "fallthru should not reach code generation." ); 1002 output << "fallthru"; 1003 break; 926 1004 } // 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 } 927 1013 output << ";"; 928 1014 } … … 1023 1109 void CodeGenerator::postvisit( WhileStmt * whileStmt ) { 1024 1110 if ( whileStmt->get_isDoWhile() ) { 1025 output << "do" 1111 output << "do"; 1026 1112 } else { 1027 output << "while (" 1113 output << "while ("; 1028 1114 whileStmt->get_condition()->accept( *visitor ); 1029 1115 output << ")"; … … 1037 1123 1038 1124 if ( whileStmt->get_isDoWhile() ) { 1039 output << " while (" 1125 output << " while ("; 1040 1126 whileStmt->get_condition()->accept( *visitor ); 1041 1127 output << ");"; -
src/CodeGen/CodeGenerator.h
rf9feab8 r90152a4 27 27 28 28 namespace CodeGen { 29 struct CodeGenerator : public WithShortCircuiting, public With VisitorRef<CodeGenerator> {29 struct CodeGenerator : public WithShortCircuiting, public WithGuards, public WithVisitorRef<CodeGenerator> { 30 30 static int tabsize; 31 31 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 ); 33 33 34 34 //*** Turn off visit_children for all nodes … … 38 38 void postvisit( BaseSyntaxNode * ); 39 39 40 //*** print type for all expressions 41 void previsit( Expression * node ); 42 40 43 //*** Declaration 41 44 void postvisit( StructDecl * ); 42 45 void postvisit( FunctionDecl * ); 43 46 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 ); 49 53 50 54 //*** Initializer … … 65 69 void postvisit( LabelAddressExpr *addressExpr ); 66 70 void postvisit( CastExpr *castExpr ); 71 void postvisit( KeywordCastExpr * castExpr ); 67 72 void postvisit( VirtualCastExpr *castExpr ); 68 73 void postvisit( UntypedMemberExpr *memberExpr ); … … 88 93 void postvisit( StmtExpr * ); 89 94 void postvisit( ConstructorExpr * ); 95 void postvisit( DeletedExpr * ); 96 void postvisit( DefaultArgExpr * ); 97 void postvisit( GenericExpr * ); 90 98 91 99 //*** Statements … … 93 101 void postvisit( ExprStmt * ); 94 102 void postvisit( AsmStmt * ); 103 void postvisit( DirectiveStmt * ); 95 104 void postvisit( AsmDecl * ); // special: statement in declaration context 96 105 void postvisit( IfStmt * ); … … 138 147 bool genC = false; // true if output has to be C code 139 148 bool lineMarks = false; 149 bool printExprTypes = false; 140 150 public: 141 151 LineEnder endl; -
src/CodeGen/FixMain.cc
rf9feab8 r90152a4 23 23 24 24 #include "Common/SemanticError.h" // for SemanticError 25 #include "CodeGen/GenType.h" // for GenType 25 26 #include "SynTree/Declaration.h" // for FunctionDecl, operator<< 26 27 #include "SynTree/Type.h" // for FunctionType … … 30 31 std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr; 31 32 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 32 38 void FixMain::registerMain(FunctionDecl* functionDecl) 33 39 { 34 40 if(main_signature) { 35 throw SemanticError("Multiple definition of main routine\n", functionDecl);41 SemanticError(functionDecl, "Multiple definition of main routine\n"); 36 42 } 37 43 main_signature.reset( functionDecl->clone() ); … … 43 49 44 50 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; 48 55 case 0: break; 49 56 default : assert(false); -
src/CodeGen/FixNames.cc
rf9feab8 r90152a4 56 56 auto && name = SymTab::Mangler::mangle( mainDecl.get() ); 57 57 // std::cerr << name << std::endl; 58 return name;58 return std::move(name); 59 59 } 60 60 std::string mangle_main_args() { … … 79 79 auto&& name = SymTab::Mangler::mangle( mainDecl.get() ); 80 80 // std::cerr << name << std::endl; 81 return name;81 return std::move(name); 82 82 } 83 83 … … 118 118 int nargs = functionDecl->get_functionType()->get_parameters().size(); 119 119 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"); 121 121 } 122 122 functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) ); -
src/CodeGen/GenType.cc
rf9feab8 r90152a4 26 26 27 27 namespace 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 ); 48 53 49 54 private: … … 52 57 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); 53 58 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? 58 62 }; 59 63 60 64 std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) { 61 GenTypegt( baseString, pretty, genC, lineMarks );65 PassVisitor<GenType> gt( baseString, pretty, genC, lineMarks ); 62 66 std::ostringstream os; 63 67 … … 68 72 69 73 type->accept( gt ); 70 return os.str() + gt. get_typeString();74 return os.str() + gt.pass.typeString; 71 75 } 72 76 … … 77 81 GenType::GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks ) : typeString( typeString ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {} 78 82 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 ) { 80 97 typeString = "void " + typeString; 81 98 handleQualifiers( voidType ); 82 99 } 83 100 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; 86 103 assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES ); 87 104 typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString; … … 89 106 } 90 107 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 ) { 92 109 std::ostringstream os; 93 110 if ( typeString != "" ) { … … 126 143 typeString = os.str(); 127 144 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() ); 135 152 } else { 136 153 handleQualifiers( pointerType ); … … 140 157 typeString = "*" + typeString; 141 158 } // 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); 152 169 assertf( ! genC, "Reference types should not reach code generation." ); 153 170 handleQualifiers( refType ); 154 171 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 ) { 159 176 std::ostringstream os; 160 177 … … 169 186 /************* parameters ***************/ 170 187 171 const std::list<DeclarationWithType *> &pars = funcType-> get_parameters();188 const std::list<DeclarationWithType *> &pars = funcType->parameters; 172 189 173 190 if ( pars.empty() ) { … … 191 208 typeString = os.str(); 192 209 193 if ( funcType-> get_returnVals().size() == 0 ) {210 if ( funcType->returnVals.size() == 0 ) { 194 211 typeString = "void " + typeString; 195 212 } else { 196 funcType-> get_returnVals().front()->get_type()->accept( *this);213 funcType->returnVals.front()->get_type()->accept( *visitor ); 197 214 } // if 198 215 199 216 // add forall 200 if( ! funcType-> get_forall().empty() && ! genC ) {217 if( ! funcType->forall.empty() && ! genC ) { 201 218 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 202 219 std::ostringstream os; 203 220 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks ); 204 221 os << "forall("; 205 cg.pass.genCommaList( funcType-> get_forall().begin(), funcType->get_forall().end() );222 cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() ); 206 223 os << ")" << std::endl; 207 224 typeString = os.str() + typeString; … … 221 238 } 222 239 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; 225 242 if ( genC ) typeString = "struct " + typeString; 226 243 handleQualifiers( structInst ); 227 244 } 228 245 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; 231 248 if ( genC ) typeString = "union " + typeString; 232 249 handleQualifiers( unionInst ); 233 250 } 234 251 235 void GenType:: visit( EnumInstType *enumInst ) {236 typeString = enumInst-> get_name()+ " " + typeString;252 void GenType::postvisit( EnumInstType * enumInst ) { 253 typeString = enumInst->name + " " + typeString; 237 254 if ( genC ) typeString = "enum " + typeString; 238 255 handleQualifiers( enumInst ); 239 256 } 240 257 241 void GenType:: visit( TypeInstType *typeInst ) {242 typeString = typeInst-> get_name()+ " " + typeString;258 void GenType::postvisit( TypeInstType * typeInst ) { 259 typeString = typeInst->name + " " + typeString; 243 260 handleQualifiers( typeInst ); 244 261 } 245 262 246 void GenType:: visit( TupleType * tupleType ) {263 void GenType::postvisit( TupleType * tupleType ) { 247 264 assertf( ! genC, "Tuple types should not reach code generation." ); 248 265 unsigned int i = 0; … … 257 274 } 258 275 259 void GenType:: visit( VarArgsType *varArgsType ) {276 void GenType::postvisit( VarArgsType * varArgsType ) { 260 277 typeString = "__builtin_va_list " + typeString; 261 278 handleQualifiers( varArgsType ); 262 279 } 263 280 264 void GenType:: visit( ZeroType *zeroType ) {281 void GenType::postvisit( ZeroType * zeroType ) { 265 282 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 266 283 typeString = (pretty ? "zero_t " : "long int ") + typeString; … … 268 285 } 269 286 270 void GenType:: visit( OneType *oneType ) {287 void GenType::postvisit( OneType * oneType ) { 271 288 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 272 289 typeString = (pretty ? "one_t " : "long int ") + typeString; … … 274 291 } 275 292 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 ) { 277 323 if ( type->get_const() ) { 278 324 typeString = "const " + typeString; -
src/CodeGen/Generate.cc
rf9feab8 r90152a4 46 46 } // namespace 47 47 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 ) { 49 49 cleanTree( translationUnit ); 50 50 51 PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks );51 PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks, printExprTypes ); 52 52 for ( auto & dcl : translationUnit ) { 53 53 if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) { … … 66 66 os << CodeGen::genPrettyType( type, "" ); 67 67 } else { 68 PassVisitor<CodeGenerator> cgv( os, true, false, false );68 PassVisitor<CodeGenerator> cgv( os, true, false, false, false ); 69 69 node->accept( cgv ); 70 70 } -
src/CodeGen/Generate.h
rf9feab8 r90152a4 24 24 namespace CodeGen { 25 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 , 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 ); 27 27 28 28 /// Generate code for a single node -- helpful for debugging in gdb -
src/CodeGen/OperatorTable.cc
rf9feab8 r90152a4 79 79 } // namespace 80 80 81 bool operatorLookup( std::string funcName, OperatorInfo &info ) {81 bool operatorLookup( const std::string & funcName, OperatorInfo & info ) { 82 82 static bool init = false; 83 83 if ( ! init ) { … … 100 100 return true; 101 101 } // if 102 } 103 104 bool isOperator( const std::string & funcName ) { 105 OperatorInfo info; 106 return operatorLookup( funcName, info ); 102 107 } 103 108 -
src/CodeGen/OperatorTable.h
rf9feab8 r90152a4 41 41 }; 42 42 43 bool operatorLookup( std::string funcName, OperatorInfo &info ); 43 bool isOperator( const std::string & funcName ); 44 bool operatorLookup( const std::string & funcName, OperatorInfo & info ); 44 45 45 46 bool isConstructor( const std::string & );
Note:
See TracChangeset
for help on using the changeset viewer.