- Timestamp:
- Apr 17, 2017, 5:43:01 PM (8 years ago)
- 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
- Location:
- src
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r4ae83a4b re39241b 89 89 } 90 90 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 ) {} 92 92 93 93 CodeGenerator::CodeGenerator( std::ostream & os, std::string init, int indentation, bool infunp ) … … 136 136 functionDecl->get_funcSpec().print( output ); 137 137 138 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty );138 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty, genC ); 139 139 140 140 asmName( functionDecl ); … … 147 147 148 148 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 150 151 static UniqueName name = { "__anonymous_object" }; 151 152 objectDecl->set_name( name.newName() ); … … 156 157 157 158 handleStorageClass( objectDecl ); 158 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty );159 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC ); 159 160 160 161 asmName( objectDecl ); … … 174 175 genAttributes( aggDecl->get_attributes() ); 175 176 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 176 184 if ( aggDecl->get_name() != "" ) 177 185 output << aggDecl->get_name(); 178 186 179 // std::list< Declaration * > & memb = aggDecl->get_members();180 // if ( ! memb.empty() ) {181 187 if ( aggDecl->has_body() ) { 182 188 std::list< Declaration * > & memb = aggDecl->get_members(); … … 242 248 243 249 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; 247 253 } 248 254 249 255 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 } 257 272 } 258 273 … … 293 308 294 309 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>"; 296 313 } 297 314 … … 547 564 // at least one result type of cast, but not an lvalue 548 565 output << "("; 549 output << genType( castExpr->get_result(), "", pretty );566 output << genType( castExpr->get_result(), "", pretty, genC ); 550 567 output << ")"; 551 568 } else { … … 558 575 559 576 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(); 561 581 } 562 582 … … 587 607 output << "sizeof("; 588 608 if ( sizeofExpr->get_isType() ) { 589 output << genType( sizeofExpr->get_type(), "", pretty );609 output << genType( sizeofExpr->get_type(), "", pretty, genC ); 590 610 } else { 591 611 sizeofExpr->get_expr()->accept( *this ); … … 599 619 output << "__alignof__("; 600 620 if ( alignofExpr->get_isType() ) { 601 output << genType( alignofExpr->get_type(), "", pretty );621 output << genType( alignofExpr->get_type(), "", pretty, genC ); 602 622 } else { 603 623 alignofExpr->get_expr()->accept( *this ); … … 607 627 608 628 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 << ")"; 610 634 } 611 635 … … 613 637 // use GCC builtin 614 638 output << "__builtin_offsetof("; 615 output << genType( offsetofExpr->get_type(), "", pretty );639 output << genType( offsetofExpr->get_type(), "", pretty, genC ); 616 640 output << ", " << mangleName( offsetofExpr->get_member() ); 617 641 output << ")"; … … 619 643 620 644 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 ) << ")"; 622 647 } 623 648 … … 655 680 } 656 681 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 } 662 700 663 701 void CodeGenerator::visit( AsmExpr * asmExpr ) { … … 675 713 void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) { 676 714 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 ) << ")"; 678 716 compLitExpr->get_initializer()->accept( *this ); 679 717 } -
src/CodeGen/CodeGenerator.h
r4ae83a4b re39241b 30 30 static int tabsize; 31 31 32 CodeGenerator( std::ostream &os, bool pretty = false );32 CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false ); 33 33 CodeGenerator( std::ostream &os, std::string, int indent = 0, bool infun = false ); 34 34 CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false ); … … 121 121 LabelPrinter printLabels; 122 122 bool pretty = false; // pretty print 123 bool genC = false; // true if output has to be C code 123 124 124 125 void printDesignators( std::list< Expression * > & ); -
src/CodeGen/GenType.cc
r4ae83a4b re39241b 28 28 class GenType : public Visitor { 29 29 public: 30 GenType( const std::string &typeString, bool pretty = false );30 GenType( const std::string &typeString, bool pretty = false, bool genC = false ); 31 31 std::string get_typeString() const { return typeString; } 32 32 void set_typeString( const std::string &newValue ) { typeString = newValue; } … … 48 48 private: 49 49 void handleQualifiers( Type *type ); 50 std::string handleGeneric( ReferenceToType * refType ); 50 51 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); 51 52 52 53 std::string typeString; 53 54 bool pretty = false; // pretty print 55 bool genC = false; // generating C code? 54 56 }; 55 57 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 ); 58 60 std::ostringstream os; 59 61 60 62 if ( ! type->get_attributes().empty() ) { 61 CodeGenerator cg( os, pretty );63 CodeGenerator cg( os, pretty, genC ); 62 64 cg.genAttributes( type->get_attributes() ); 63 65 } // if … … 68 70 69 71 std::string genPrettyType( Type * type, const std::string & baseString ) { 70 return genType( type, baseString, true );72 return genType( type, baseString, true, false ); 71 73 } 72 74 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 ) {} 74 76 75 77 void GenType::visit( VoidType *voidType ) { … … 112 114 } // if 113 115 if ( dimension != 0 ) { 114 CodeGenerator cg( os, pretty );116 CodeGenerator cg( os, pretty, genC ); 115 117 dimension->accept( cg ); 116 118 } else if ( isVarLen ) { … … 166 168 } // if 167 169 } else { 168 CodeGenerator cg( os, pretty );170 CodeGenerator cg( os, pretty, genC ); 169 171 os << "(" ; 170 172 … … 186 188 } 187 189 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 188 202 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; 190 205 handleQualifiers( structInst ); 191 206 } 192 207 193 208 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; 195 211 handleQualifiers( unionInst ); 196 212 } 197 213 198 214 void GenType::visit( EnumInstType *enumInst ) { 199 typeString = "enum " + enumInst->get_name() + " " + typeString; 215 typeString = enumInst->get_name() + " " + typeString; 216 if ( genC ) typeString = "enum " + typeString; 200 217 handleQualifiers( enumInst ); 201 218 } … … 207 224 208 225 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." ); 210 227 Visitor::visit( tupleType ); 211 228 unsigned int i = 0; … … 214 231 for ( Type * t : *tupleType ) { 215 232 i++; 216 os << genType( t, "", pretty ) << (i == tupleType->size() ? "" : ", ");233 os << genType( t, "", pretty, genC ) << (i == tupleType->size() ? "" : ", "); 217 234 } 218 235 os << "]"; -
src/CodeGen/GenType.h
r4ae83a4b re39241b 21 21 22 22 namespace 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 ); 24 24 std::string genPrettyType( Type * type, const std::string & baseString ); 25 25 } // namespace CodeGen -
src/CodeGen/Generate.cc
r4ae83a4b re39241b 27 27 28 28 namespace 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 ); 31 31 for ( auto & dcl : translationUnit ) { 32 32 if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) { -
src/CodeGen/Generate.h
r4ae83a4b re39241b 23 23 24 24 namespace 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 ); 27 27 } // namespace CodeGen 28 28 -
src/SynTree/Declaration.h
r4ae83a4b re39241b 167 167 std::list< DeclarationWithType* >& get_assertions() { return assertions; } 168 168 169 virtual std::string typeString() const = 0; 170 169 171 virtual NamedTypeDecl *clone() const = 0; 170 172 virtual void print( std::ostream &os, int indent = 0 ) const; 171 173 virtual void printShort( std::ostream &os, int indent = 0 ) const; 172 174 protected: 173 virtual std::string typeString() const = 0;174 175 private: 175 176 Type *base; … … 202 203 TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; } 203 204 205 virtual std::string typeString() const; 206 204 207 virtual TypeDecl *clone() const { return new TypeDecl( *this ); } 205 208 virtual void accept( Visitor &v ) { v.visit( this ); } 206 209 virtual TypeDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); } 207 210 private: 208 virtual std::string typeString() const;209 211 Kind kind; 210 212 bool sized; … … 217 219 TypedefDecl( const TypedefDecl &other ) : Parent( other ) {} 218 220 221 virtual std::string typeString() const; 222 219 223 virtual TypedefDecl *clone() const { return new TypedefDecl( *this ); } 220 224 virtual void accept( Visitor &v ) { v.visit( this ); } 221 225 virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); } 222 226 private: 223 virtual std::string typeString() const;224 227 }; 225 228 -
src/main.cc
r4ae83a4b re39241b 304 304 GenPoly::box( translationUnit ); 305 305 306 // print tree right before code generation307 if ( codegenp ) {308 dump( translationUnit );309 return 0;310 } // if311 312 306 if ( optind < argc ) { // any commands after the flags and input file ? => output file name 313 307 output = new ofstream( argv[ optind ] ); 314 308 } // if 315 309 316 CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp );310 CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp, true ); 317 311 318 312 CodeGen::FixMain::fix( *output, treep ? "../prelude/bootloader.c" : CFA_LIBDIR "/bootloader.c" ); … … 393 387 break; 394 388 case CtorInitFix: 395 case 'c': 389 case 'c': // print after constructors and destructors are replaced 396 390 ctorinitp = true; 397 391 break; … … 450 444 validp = true; 451 445 break; 452 case 'y': 446 case 'y': // dump AST on error 453 447 errorp = true; 454 448 break; 455 case 'z': 449 case 'z': // dump as codegen rather than AST 456 450 codegenp = true; 457 case 'Z': 451 break; 452 case 'Z': // prettyprint during codegen (i.e. print unmangled names, etc.) 458 453 prettycodegenp = true; 459 454 break; … … 501 496 } // if 502 497 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 } 504 504 deleteAll( translationUnit ); 505 505 } // dump -
src/tests/.expect/memberCtors-ERR1.txt
r4ae83a4b re39241b 1 memberCtors.c:62 error: in void ?{}( structB *b), field a2 used before being constructed1 memberCtors.c:62 error: in void ?{}(B *b), field a2 used before being constructed 2 2 make: *** [memberCtors-ERR1] Error 1
Note: See TracChangeset
for help on using the changeset viewer.