Changes in / [e3987770:8731d8c]
- Location:
- src
- Files:
-
- 9 edited
-
CodeGen/CodeGenerator.cc (modified) (17 diffs)
-
CodeGen/CodeGenerator.h (modified) (2 diffs)
-
CodeGen/GenType.cc (modified) (8 diffs)
-
CodeGen/GenType.h (modified) (1 diff)
-
CodeGen/Generate.cc (modified) (1 diff)
-
CodeGen/Generate.h (modified) (1 diff)
-
SynTree/Declaration.h (modified) (3 diffs)
-
main.cc (modified) (4 diffs)
-
tests/.expect/memberCtors-ERR1.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
re3987770 r8731d8c 89 89 } 90 90 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) {}91 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ) {} 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 , genC);138 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty ); 139 139 140 140 asmName( functionDecl ); … … 147 147 148 148 void CodeGenerator::visit( ObjectDecl * objectDecl ) { 149 if (objectDecl->get_name().empty() && genC ) { 150 // only generate an anonymous name when generating C code, otherwise it clutters the output too much 149 if (objectDecl->get_name().empty()) { 151 150 static UniqueName name = { "__anonymous_object" }; 152 151 objectDecl->set_name( name.newName() ); … … 157 156 158 157 handleStorageClass( objectDecl ); 159 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty , genC);158 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty ); 160 159 161 160 asmName( objectDecl ); … … 172 171 } 173 172 174 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl , const std::string & kind) {173 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl ) { 175 174 genAttributes( aggDecl->get_attributes() ); 176 175 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 184 output << kind;185 176 if ( aggDecl->get_name() != "" ) 186 177 output << aggDecl->get_name(); 187 178 179 // std::list< Declaration * > & memb = aggDecl->get_members(); 180 // if ( ! memb.empty() ) { 188 181 if ( aggDecl->has_body() ) { 189 182 std::list< Declaration * > & memb = aggDecl->get_members(); … … 205 198 void CodeGenerator::visit( StructDecl * structDecl ) { 206 199 extension( structDecl ); 207 handleAggregate( structDecl, "struct " ); 200 output << "struct "; 201 handleAggregate( structDecl ); 208 202 } 209 203 210 204 void CodeGenerator::visit( UnionDecl * unionDecl ) { 211 205 extension( unionDecl ); 212 handleAggregate( unionDecl, "union " ); 206 output << "union "; 207 handleAggregate( unionDecl ); 213 208 } 214 209 … … 247 242 248 243 void CodeGenerator::visit( TypedefDecl * typeDecl ) { 249 assert f( ! genC,"Typedefs are removed and substituted in earlier passes." );250 output << "typedef ";251 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;244 assert( false && "Typedefs are removed and substituted in earlier passes." ); 245 //output << "typedef "; 246 //output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty ); 252 247 } 253 248 254 249 void CodeGenerator::visit( TypeDecl * typeDecl ) { 255 if ( genC ) { 256 // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes, 257 // still to be done 258 extension( typeDecl ); 259 output << "extern unsigned long " << typeDecl->get_name(); 260 if ( typeDecl->get_base() ) { 261 output << " = sizeof( " << genType( typeDecl->get_base(), "", pretty, genC ) << " )"; 262 } // if 263 } else { 264 output << typeDecl->typeString() << " " << typeDecl->get_name(); 265 if ( ! typeDecl->get_assertions().empty() ) { 266 output << " | { "; 267 genCommaList( typeDecl->get_assertions().begin(), typeDecl->get_assertions().end() ); 268 output << " }"; 269 } 270 } 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 271 257 } 272 258 … … 307 293 308 294 void CodeGenerator::visit( ConstructorInit * init ){ 309 assertf( ! genC, "ConstructorInit nodes should not reach code generation." ); 310 // xxx - generate something reasonable for constructor/destructor pairs 311 output << "<ctorinit>"; 295 assertf( false, "ConstructorInit nodes should not make it to CodeGen." ); 312 296 } 313 297 … … 563 547 // at least one result type of cast, but not an lvalue 564 548 output << "("; 565 output << genType( castExpr->get_result(), "", pretty , genC);549 output << genType( castExpr->get_result(), "", pretty ); 566 550 output << ")"; 567 551 } else { … … 574 558 575 559 void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) { 576 assertf( ! genC, "UntypedMemberExpr should not reach code generation." ); 577 extension( memberExpr ); 578 memberExpr->get_aggregate()->accept( *this ); 579 output << "."; 580 memberExpr->get_member()->accept( *this ); 560 assert( false ); 581 561 } 582 562 … … 607 587 output << "sizeof("; 608 588 if ( sizeofExpr->get_isType() ) { 609 output << genType( sizeofExpr->get_type(), "", pretty , genC);589 output << genType( sizeofExpr->get_type(), "", pretty ); 610 590 } else { 611 591 sizeofExpr->get_expr()->accept( *this ); … … 619 599 output << "__alignof__("; 620 600 if ( alignofExpr->get_isType() ) { 621 output << genType( alignofExpr->get_type(), "", pretty , genC);601 output << genType( alignofExpr->get_type(), "", pretty ); 622 602 } else { 623 603 alignofExpr->get_expr()->accept( *this ); … … 627 607 628 608 void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) { 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 << ")"; 609 assert( false && "UntypedOffsetofExpr should not reach code generation." ); 634 610 } 635 611 … … 637 613 // use GCC builtin 638 614 output << "__builtin_offsetof("; 639 output << genType( offsetofExpr->get_type(), "", pretty , genC);615 output << genType( offsetofExpr->get_type(), "", pretty ); 640 616 output << ", " << mangleName( offsetofExpr->get_member() ); 641 617 output << ")"; … … 643 619 644 620 void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) { 645 assertf( ! genC, "OffsetPackExpr should not reach code generation." ); 646 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")"; 621 assert( false && "OffsetPackExpr should not reach code generation." ); 647 622 } 648 623 … … 680 655 } 681 656 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 } 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 ) {} 700 662 701 663 void CodeGenerator::visit( AsmExpr * asmExpr ) { … … 713 675 void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) { 714 676 assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) ); 715 output << "(" << genType( compLitExpr->get_result(), "", pretty , genC) << ")";677 output << "(" << genType( compLitExpr->get_result(), "", pretty ) << ")"; 716 678 compLitExpr->get_initializer()->accept( *this ); 717 679 } -
src/CodeGen/CodeGenerator.h
re3987770 r8731d8c 30 30 static int tabsize; 31 31 32 CodeGenerator( std::ostream &os, bool pretty = false , bool genC = false);32 CodeGenerator( std::ostream &os, bool pretty = 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 code124 123 125 124 void printDesignators( std::list< Expression * > & ); 126 125 void handleStorageClass( DeclarationWithType *decl ); 127 void handleAggregate( AggregateDecl *aggDecl , const std::string & kind);126 void handleAggregate( AggregateDecl *aggDecl ); 128 127 void handleTypedef( NamedTypeDecl *namedType ); 129 128 std::string mangleName( DeclarationWithType * decl ); -
src/CodeGen/GenType.cc
re3987770 r8731d8c 28 28 class GenType : public Visitor { 29 29 public: 30 GenType( const std::string &typeString, bool pretty = false , bool genC = false);30 GenType( const std::string &typeString, bool pretty = 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 );51 50 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); 52 51 53 52 std::string typeString; 54 53 bool pretty = false; // pretty print 55 bool genC = false; // generating C code?56 54 }; 57 55 58 std::string genType( Type *type, const std::string &baseString, bool pretty , bool genC) {59 GenType gt( baseString, pretty , genC);56 std::string genType( Type *type, const std::string &baseString, bool pretty ) { 57 GenType gt( baseString, pretty ); 60 58 std::ostringstream os; 61 59 62 60 if ( ! type->get_attributes().empty() ) { 63 CodeGenerator cg( os, pretty , genC);61 CodeGenerator cg( os, pretty ); 64 62 cg.genAttributes( type->get_attributes() ); 65 63 } // if … … 70 68 71 69 std::string genPrettyType( Type * type, const std::string & baseString ) { 72 return genType( type, baseString, true , false);70 return genType( type, baseString, true ); 73 71 } 74 72 75 GenType::GenType( const std::string &typeString, bool pretty , bool genC ) : typeString( typeString ), pretty( pretty ), genC( genC) {}73 GenType::GenType( const std::string &typeString, bool pretty ) : typeString( typeString ), pretty( pretty ) {} 76 74 77 75 void GenType::visit( VoidType *voidType ) { … … 114 112 } // if 115 113 if ( dimension != 0 ) { 116 CodeGenerator cg( os, pretty , genC);114 CodeGenerator cg( os, pretty ); 117 115 dimension->accept( cg ); 118 116 } else if ( isVarLen ) { … … 168 166 } // if 169 167 } else { 170 CodeGenerator cg( os, pretty , genC);168 CodeGenerator cg( os, pretty ); 171 169 os << "(" ; 172 170 … … 186 184 funcType->get_returnVals().front()->get_type()->accept( *this ); 187 185 } // if 188 189 // add forall190 if( ! funcType->get_forall().empty() && ! genC ) {191 // assertf( ! genC, "Aggregate type parameters should not reach code generation." );192 std::ostringstream os;193 CodeGenerator cg( os, pretty, genC );194 os << "forall(";195 cg.genCommaList( funcType->get_forall().begin(), funcType->get_forall().end() );196 os << ")" << std::endl;197 typeString = os.str() + typeString;198 }199 }200 201 std::string GenType::handleGeneric( ReferenceToType * refType ) {202 if ( ! refType->get_parameters().empty() ) {203 std::ostringstream os;204 CodeGenerator cg( os, pretty, genC );205 os << "(";206 cg.genCommaList( refType->get_parameters().begin(), refType->get_parameters().end() );207 os << ") ";208 return os.str();209 }210 return "";211 186 } 212 187 213 188 void GenType::visit( StructInstType *structInst ) { 214 typeString = structInst->get_name() + handleGeneric( structInst ) + " " + typeString; 215 if ( genC ) typeString = "struct " + typeString; 189 typeString = "struct " + structInst->get_name() + " " + typeString; 216 190 handleQualifiers( structInst ); 217 191 } 218 192 219 193 void GenType::visit( UnionInstType *unionInst ) { 220 typeString = unionInst->get_name() + handleGeneric( unionInst ) + " " + typeString; 221 if ( genC ) typeString = "union " + typeString; 194 typeString = "union " + unionInst->get_name() + " " + typeString; 222 195 handleQualifiers( unionInst ); 223 196 } 224 197 225 198 void GenType::visit( EnumInstType *enumInst ) { 226 typeString = enumInst->get_name() + " " + typeString; 227 if ( genC ) typeString = "enum " + typeString; 199 typeString = "enum " + enumInst->get_name() + " " + typeString; 228 200 handleQualifiers( enumInst ); 229 201 } … … 235 207 236 208 void GenType::visit( TupleType * tupleType ) { 237 assertf( ! genC, "Tuple types should not reach code generation." );209 assertf( pretty, "Tuple types should not make it to Code Gen." ); 238 210 Visitor::visit( tupleType ); 239 211 unsigned int i = 0; … … 242 214 for ( Type * t : *tupleType ) { 243 215 i++; 244 os << genType( t, "", pretty , genC) << (i == tupleType->size() ? "" : ", ");216 os << genType( t, "", pretty ) << (i == tupleType->size() ? "" : ", "); 245 217 } 246 218 os << "]"; -
src/CodeGen/GenType.h
re3987770 r8731d8c 21 21 22 22 namespace CodeGen { 23 std::string genType( Type *type, const std::string &baseString, bool pretty = false , bool genC = false);23 std::string genType( Type *type, const std::string &baseString, bool pretty = false ); 24 24 std::string genPrettyType( Type * type, const std::string & baseString ); 25 25 } // namespace CodeGen -
src/CodeGen/Generate.cc
re3987770 r8731d8c 27 27 28 28 namespace CodeGen { 29 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty , bool generateC) {30 CodeGen::CodeGenerator cgv( os, pretty , generateC);29 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty ) { 30 CodeGen::CodeGenerator cgv( os, pretty ); 31 31 for ( auto & dcl : translationUnit ) { 32 32 if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) { -
src/CodeGen/Generate.h
re3987770 r8731d8c 23 23 24 24 namespace CodeGen { 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);25 /// Generates code 26 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty ); 27 27 } // namespace CodeGen 28 28 -
src/SynTree/Declaration.h
re3987770 r8731d8c 167 167 std::list< DeclarationWithType* >& get_assertions() { return assertions; } 168 168 169 virtual NamedTypeDecl *clone() const = 0; 170 virtual void print( std::ostream &os, int indent = 0 ) const; 171 virtual void printShort( std::ostream &os, int indent = 0 ) const; 172 protected: 169 173 virtual std::string typeString() const = 0; 170 171 virtual NamedTypeDecl *clone() const = 0;172 virtual void print( std::ostream &os, int indent = 0 ) const;173 virtual void printShort( std::ostream &os, int indent = 0 ) const;174 protected:175 174 private: 176 175 Type *base; … … 203 202 TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; } 204 203 205 virtual std::string typeString() const;206 207 204 virtual TypeDecl *clone() const { return new TypeDecl( *this ); } 208 205 virtual void accept( Visitor &v ) { v.visit( this ); } 209 206 virtual TypeDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); } 210 207 private: 208 virtual std::string typeString() const; 211 209 Kind kind; 212 210 bool sized; … … 219 217 TypedefDecl( const TypedefDecl &other ) : Parent( other ) {} 220 218 221 virtual std::string typeString() const;222 223 219 virtual TypedefDecl *clone() const { return new TypedefDecl( *this ); } 224 220 virtual void accept( Visitor &v ) { v.visit( this ); } 225 221 virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); } 226 222 private: 223 virtual std::string typeString() const; 227 224 }; 228 225 -
src/main.cc
re3987770 r8731d8c 304 304 GenPoly::box( translationUnit ); 305 305 306 // print tree right before code generation 307 if ( codegenp ) { 308 dump( translationUnit ); 309 return 0; 310 } // if 311 306 312 if ( optind < argc ) { // any commands after the flags and input file ? => output file name 307 313 output = new ofstream( argv[ optind ] ); 308 314 } // if 309 315 310 CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp , true);316 CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp ); 311 317 312 318 CodeGen::FixMain::fix( *output, treep ? "../prelude/bootloader.c" : CFA_LIBDIR "/bootloader.c" ); … … 387 393 break; 388 394 case CtorInitFix: 389 case 'c': // print after constructors and destructors are replaced395 case 'c': 390 396 ctorinitp = true; 391 397 break; … … 444 450 validp = true; 445 451 break; 446 case 'y': // dump AST on error452 case 'y': 447 453 errorp = true; 448 454 break; 449 case 'z': // dump as codegen rather than AST455 case 'z': 450 456 codegenp = true; 451 break; 452 case 'Z': // prettyprint during codegen (i.e. print unmangled names, etc.) 457 case 'Z': 453 458 prettycodegenp = true; 454 459 break; … … 496 501 } // if 497 502 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 } 503 printAll( decls, out ); 504 504 deleteAll( translationUnit ); 505 505 } // dump -
src/tests/.expect/memberCtors-ERR1.txt
re3987770 r8731d8c 1 memberCtors.c:62 error: in void ?{}( B *b), field a2 used before being constructed1 memberCtors.c:62 error: in void ?{}(struct 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.