Ticket #280: compound-literal-expr.diff
File compound-literal-expr.diff, 11.6 KB (added by , 4 months ago) |
---|
-
libcfa/prelude/builtins.c
diff --git a/libcfa/prelude/builtins.c b/libcfa/prelude/builtins.c index 240358527..666e53e6e 100644
a b struct __Destructor { 27 27 // Defined destructor in the case that non-generated code wants to use __Destructor. 28 28 forall( T & ) 29 29 inline void ^?{}( __Destructor(T) & x ) { 30 if ( x.object && x.dtor ) { 31 x.dtor( x.object ); 32 } 30 // MAKE SURE TO CHANGE THIS BACK!!! 31 // if ( x.object && x.dtor ) { 32 // x.dtor( x.object ); 33 // } 33 34 } 34 35 35 36 // Easy interface into __Destructor's destructor for easy codegen purposes. -
src/AST/Expr.cpp
diff --git a/src/AST/Expr.cpp b/src/AST/Expr.cpp index 4f9d7d17a..4f46ebd25 100644
a b ConstructorExpr::ConstructorExpr( const CodeLocation & loc, const Expr * call ) 342 342 // --- CompoundLiteralExpr 343 343 344 344 CompoundLiteralExpr::CompoundLiteralExpr( const CodeLocation & loc, const Type * t, const Init * i ) 345 : Expr( loc ), init( i ) {345 : Expr( loc ), init( i ), decl( nullptr ) { 346 346 assert( t && i ); 347 347 result = t; 348 348 } 349 349 350 CompoundLiteralExpr::CompoundLiteralExpr( const CodeLocation & loc, const ObjectDecl * d ) 351 : Expr( loc ), init( nullptr ), decl( d ) { 352 assert( d ); 353 result = deepCopy( d->type ); 354 } 355 350 356 bool CompoundLiteralExpr::get_lvalue() const { 351 357 return true; 352 358 } -
src/AST/Expr.hpp
diff --git a/src/AST/Expr.hpp b/src/AST/Expr.hpp index 41be27950..30a5fbb37 100644
a b private: 688 688 class CompoundLiteralExpr final : public Expr { 689 689 public: 690 690 ptr<Init> init; 691 // TODO: Reduce the CompoundLiteralExpr to an ObjectDecl but don't 692 // hoist it yet. (Temp fix for testing.) 693 ptr<ObjectDecl> decl; 691 694 692 695 CompoundLiteralExpr( const CodeLocation & loc, const Type * t, const Init * i ); 696 CompoundLiteralExpr( const CodeLocation & loc, const ObjectDecl * d ); 693 697 694 698 bool get_lvalue() const final; 695 699 -
src/AST/Pass.impl.hpp
diff --git a/src/AST/Pass.impl.hpp b/src/AST/Pass.impl.hpp index b027ebb51..8c0b1c528 100644
a b const ast::Expr * ast::Pass< core_t >::visit( const ast::CompoundLiteralExpr * n 1583 1583 maybe_accept( node, &CompoundLiteralExpr::result ); 1584 1584 } 1585 1585 maybe_accept( node, &CompoundLiteralExpr::init ); 1586 maybe_accept( node, &CompoundLiteralExpr::decl ); 1586 1587 } 1587 1588 1588 1589 VISIT_END( Expr, node ); … … const ast::Init * ast::Pass< core_t >::visit( const ast::ConstructorInit * node 2120 2121 if ( __visit_children() ) { 2121 2122 maybe_accept( node, &ConstructorInit::ctor ); 2122 2123 maybe_accept( node, &ConstructorInit::dtor ); 2123 maybe_accept( node, &ConstructorInit::init );2124 2124 } 2125 2125 2126 2126 VISIT_END( Init, node ); -
src/AST/Print.cpp
diff --git a/src/AST/Print.cpp b/src/AST/Print.cpp index 3f30b5459..7570e9d64 100644
a b public: 1342 1342 safe_print( node->result ); 1343 1343 os << indent; 1344 1344 safe_print( node->init ); 1345 os << indent; 1346 safe_print( node->decl ); 1345 1347 --indent; 1346 1348 postprint( node ); 1347 1349 -
src/CodeGen/CodeGenerator.cpp
diff --git a/src/CodeGen/CodeGenerator.cpp b/src/CodeGen/CodeGenerator.cpp index 33d26febc..df98164fa 100644
a b void CodeGenerator::postvisit( ast::AsmExpr const * expr ) { 904 904 } 905 905 906 906 void CodeGenerator::postvisit( ast::CompoundLiteralExpr const * expr ) { 907 //assert( expr->result && dynamic_cast<ast::ListInit const *>( expr->init ) ); 908 assert( expr->result && expr->init.as<ast::ListInit>() ); 907 assert( expr->result ); 909 908 output << "(" << genType( expr->result, "", options ) << ")"; 910 expr->init->accept( *visitor ); 909 if ( expr->init ) { 910 //assert( expr->init.as<ast::ListInit>() ); 911 expr->init->accept( *visitor ); 912 } else { 913 assert( expr->decl ); 914 //assert( expr->decl->init.as<ast::ListInit>() ); 915 expr->decl->init->accept( *visitor ); 916 } 911 917 } 912 918 913 919 void CodeGenerator::postvisit( ast::UniqueExpr const * expr ) { -
src/ResolvExpr/CandidateFinder.cpp
diff --git a/src/ResolvExpr/CandidateFinder.cpp b/src/ResolvExpr/CandidateFinder.cpp index 10bc39809..4ebf4251f 100644
a b 44 44 #include "AST/Print.hpp" 45 45 #include "AST/SymbolTable.hpp" 46 46 #include "AST/Type.hpp" 47 #include "Common/UniqueName.hpp" 47 48 #include "Common/Utility.hpp" // for move, copy 48 49 #include "SymTab/Mangler.hpp" 49 50 #include "Tuples/Tuples.hpp" // for handleTupleAssignment 51 #include "InitTweak/GenInit.hpp" // for genCtorInit 50 52 #include "InitTweak/InitTweak.hpp" // for getPointerBase 51 53 52 54 #include "Common/Stats/Counter.hpp" … … namespace { 688 690 void postvisit( const ast::CommaExpr * commaExpr ); 689 691 void postvisit( const ast::ImplicitCopyCtorExpr * ctorExpr ); 690 692 void postvisit( const ast::ConstructorExpr * ctorExpr ); 693 void postvisit( const ast::CompoundLiteralExpr * compoundExpr ); 691 694 void postvisit( const ast::RangeExpr * rangeExpr ); 692 695 void postvisit( const ast::UntypedTupleExpr * tupleExpr ); 693 696 void postvisit( const ast::TupleExpr * tupleExpr ); … … namespace { 1049 1052 // Find function matches 1050 1053 CandidateList found; 1051 1054 SemanticErrorException errors; 1052 1053 1055 for ( CandidateRef & func : funcFinder ) { 1054 1056 try { 1055 1057 PRINT( … … namespace { 1669 1671 } 1670 1672 } 1671 1673 1674 void Finder::postvisit( const ast::CompoundLiteralExpr * expr ) { 1675 // We are getting recursive cases. I don't know if this is a not 1676 // supposed to happen (as a no-op) or not. 1677 if ( !expr->init ) { 1678 assert( expr->decl ); 1679 addCandidate( ast::deepCopy( expr ), tenv ); 1680 return; 1681 } 1682 1683 // These names should never make it to code generation, but it does 1684 // so for now they must be uniquely named. 1685 static UniqueName compLit("_compLitExpr"); 1686 const CodeLocation& location = expr->location; 1687 //const ast::Type * type = expr->result; 1688 1689 ast::ptr<ast::ObjectDecl> decl0 = new ast::ObjectDecl( location, 1690 compLit.newName(), 1691 expr->result, 1692 ast::deepCopy( expr->init ) 1693 ); 1694 1695 ast::ptr<ast::Decl> newDecl = ResolvExpr::resolveSingleDecl( 1696 decl0.get(), context 1697 ); 1698 1699 ast::ObjectDecl const * objectDecl = newDecl.strict_as<ast::ObjectDecl>(); 1700 1701 addCandidate( 1702 new ast::CompoundLiteralExpr( location, objectDecl ), 1703 tenv ); 1704 1705 // Should has been resolved. 1706 // This has all three fields set, ctor or init should be cleared. 1707 // ast::ptr<ast::ConstructorInit> init = 1708 // InitTweak::genCtorInit( location, decl ); 1709 1710 // genCtorInit produces unresolved code. 1711 // ast::ptr<ast::Init> init2 = resolveCtorInit( init, context ); 1712 1713 // addCandidate( 1714 // new ast::CompoundLiteralExpr( location, objectDecl ), 1715 // tenv ); 1716 } 1717 1672 1718 void Finder::postvisit( const ast::RangeExpr * rangeExpr ) { 1673 1719 // resolve low and high, accept candidates where low and high types unify 1674 1720 CandidateFinder finder1( context, tenv ); -
src/ResolvExpr/Resolver.cpp
diff --git a/src/ResolvExpr/Resolver.cpp b/src/ResolvExpr/Resolver.cpp index 1054d25ff..10d5a6005 100644
a b void resolve( ast::TranslationUnit& translationUnit ) { 439 439 ast::Pass< Resolver >::run( translationUnit, translationUnit.global ); 440 440 } 441 441 442 // Does this need to return a ptr? 443 ast::ptr< ast::Decl > resolveSingleDecl( 444 const ast::Decl * decl, const ResolveContext & context ) { 445 assert( decl ); 446 ast::Pass< Resolver > resolver( context ); 447 return decl->accept( resolver ); 448 } 449 450 ast::ptr< ast::Init > resolveInit( 451 const ast::Init * init, const ResolveContext & context ) { 452 assert( init ); 453 ast::Pass< Resolver > resolver( context ); 454 return init->accept( resolver ); 455 } 456 442 457 ast::ptr< ast::Init > resolveCtorInit( 443 458 const ast::ConstructorInit * ctorInit, const ResolveContext & context 444 459 ) { -
src/ResolvExpr/Resolver.hpp
diff --git a/src/ResolvExpr/Resolver.hpp b/src/ResolvExpr/Resolver.hpp index 85e790d74..e2732f90d 100644
a b struct ResolveContext { 43 43 void resolve( ast::TranslationUnit& translationUnit ); 44 44 /// Searches expr and returns the first DeletedExpr found, otherwise nullptr 45 45 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ); 46 /// Resolve the declaration (and all its declarations) in the given context. 47 ast::ptr< ast::Decl > resolveSingleDecl( 48 const ast::Decl * decl, const ResolveContext & ); 46 49 /// Find the expression candidate that is the unique 47 50 /// best match for `untyped` in a `void` context. 48 51 ast::ptr< ast::Expr > resolveInVoidContext( … … ast::ptr< ast::Expr > findSingleExpression( 54 57 ast::ptr< ast::Expr > findVoidExpression( 55 58 const ast::Expr * untyped, const ResolveContext & ); 56 59 /// Resolves a constructor init expression 60 ast::ptr< ast::Init > resolveInit( 61 const ast::Init * init, const ResolveContext & context ); 57 62 ast::ptr< ast::Init > resolveCtorInit( 58 63 const ast::ConstructorInit * ctorInit, const ResolveContext & context ); 59 64 /// Resolves a statement expression -
src/Validate/CompoundLiteral.cpp
diff --git a/src/Validate/CompoundLiteral.cpp b/src/Validate/CompoundLiteral.cpp index 72e253915..0dd90ca6b 100644
a b struct CompoundLiteral final : 30 30 ast::Storage::Classes storageClasses; 31 31 32 32 void previsit( const ast::ObjectDecl * decl ); 33 const ast::CompoundLiteralExpr * previsit( const ast::CompoundLiteralExpr * ); 33 34 const ast::Expr * postvisit( const ast::CompoundLiteralExpr * expr ); 34 35 }; 35 36 … … void CompoundLiteral::previsit( const ast::ObjectDecl * decl ) { 37 38 storageClasses = decl->storage; 38 39 } 39 40 41 const ast::CompoundLiteralExpr * CompoundLiteral::previsit( const ast::CompoundLiteralExpr * expr ) { 42 if ( expr->decl ) { 43 auto mut = ast::mutate( expr ); 44 mut->decl.get_and_mutate()->storage = storageClasses; 45 return mut; 46 } 47 return expr; 48 } 49 40 50 const ast::Expr * CompoundLiteral::postvisit( 41 51 const ast::CompoundLiteralExpr * expr ) { 42 52 static UniqueName litName( "_compLit" ); … … const ast::Expr * CompoundLiteral::postvisit( 44 54 // Transform: [storageClasses] ... (struct S){...} ... 45 55 // Into: [storageClasses] struct S _compLit = {...}; 46 56 // ... _compLit ... 47 ast::ObjectDecl * temp = new ast::ObjectDecl( 48 expr->location, 49 litName.newName(), 50 expr->result, 51 expr->init, 52 storageClasses 57 ast::ObjectDecl * temp; 58 if ( expr->decl ) { 59 temp = ast::mutate( expr->decl.get() ); 60 // I tried doing renaming, but that might require remangling. 61 temp->name = litName.newName(); 62 temp->mangleName = ""; 63 } else if ( expr->init ) { 64 temp = new ast::ObjectDecl( 65 expr->location, 66 litName.newName(), 67 expr->result, 68 expr->init, 69 storageClasses 53 70 ); 71 } else { 72 assert( false ); 73 } 54 74 // FIXME: A resolution of #280 could make the unused attribute unnecessary here 55 75 // (let test nowarn/unused decide) 56 76 temp->attributes.push_back( new ast::Attribute( "unused" ) ); -
src/main.cpp
diff --git a/src/main.cpp b/src/main.cpp index da1c9e93a..2d8efb127 100644
a b int main( int argc, char * argv[] ) { 233 233 PASS( "Implement Virtual Destructors", Virtual::implementVirtDtors, transUnit ); 234 234 PASS( "Implement Mutex", Concurrency::implementMutex, transUnit ); 235 235 PASS( "Implement Thread Start", Concurrency::implementThreadStarter, transUnit ); 236 PASS( "Compound Literal", Validate::handleCompoundLiterals, transUnit );237 236 PASS( "Set Length From Initializer", Validate::setLengthFromInitializer, transUnit ); 238 237 PASS( "Find Global Decls", Validate::findGlobalDecls, transUnit ); 239 238 … … int main( int argc, char * argv[] ) { 273 272 274 273 PASS( "Resolve", ResolvExpr::resolve, transUnit ); 275 274 DUMP( exprp, transUnit ); 275 PASS( "Compound Literal", Validate::handleCompoundLiterals, transUnit ); 276 276 PASS( "Fix Init", InitTweak::fix, transUnit, buildingLibrary() ); // Here 277 277 PASS( "Erase With", ResolvExpr::eraseWith, transUnit ); 278 278