Ticket #280: compound-literal-expr.diff

File compound-literal-expr.diff, 11.6 KB (added by ajbeach, 4 months ago)

Work-in-progress attempt to fix the resolution of the CompoundLiteralExpr.

  • libcfa/prelude/builtins.c

    diff --git a/libcfa/prelude/builtins.c b/libcfa/prelude/builtins.c
    index 240358527..666e53e6e 100644
    a b struct __Destructor {  
    2727// Defined destructor in the case that non-generated code wants to use __Destructor.
    2828forall( T & )
    2929inline 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//      }
    3334}
    3435
    3536// 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 )  
    342342// --- CompoundLiteralExpr
    343343
    344344CompoundLiteralExpr::CompoundLiteralExpr( const CodeLocation & loc, const Type * t, const Init * i )
    345 : Expr( loc ), init( i ) {
     345: Expr( loc ), init( i ), decl( nullptr ) {
    346346        assert( t && i );
    347347        result = t;
    348348}
    349349
     350CompoundLiteralExpr::CompoundLiteralExpr( const CodeLocation & loc, const ObjectDecl * d )
     351: Expr( loc ), init( nullptr ), decl( d ) {
     352        assert( d );
     353        result = deepCopy( d->type );
     354}
     355
    350356bool CompoundLiteralExpr::get_lvalue() const {
    351357        return true;
    352358}
  • src/AST/Expr.hpp

    diff --git a/src/AST/Expr.hpp b/src/AST/Expr.hpp
    index 41be27950..30a5fbb37 100644
    a b private:  
    688688class CompoundLiteralExpr final : public Expr {
    689689public:
    690690        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;
    691694
    692695        CompoundLiteralExpr( const CodeLocation & loc, const Type * t, const Init * i );
     696        CompoundLiteralExpr( const CodeLocation & loc, const ObjectDecl * d );
    693697
    694698        bool get_lvalue() const final;
    695699
  • 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  
    15831583                        maybe_accept( node, &CompoundLiteralExpr::result );
    15841584                }
    15851585                maybe_accept( node, &CompoundLiteralExpr::init );
     1586                maybe_accept( node, &CompoundLiteralExpr::decl );
    15861587        }
    15871588
    15881589        VISIT_END( Expr, node );
    const ast::Init * ast::Pass< core_t >::visit( const ast::ConstructorInit * node  
    21202121        if ( __visit_children() ) {
    21212122                maybe_accept( node, &ConstructorInit::ctor );
    21222123                maybe_accept( node, &ConstructorInit::dtor );
    2123                 maybe_accept( node, &ConstructorInit::init );
    21242124        }
    21252125
    21262126        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:  
    13421342                safe_print( node->result );
    13431343                os << indent;
    13441344                safe_print( node->init );
     1345                os << indent;
     1346                safe_print( node->decl );
    13451347                --indent;
    13461348                postprint( node );
    13471349
  • 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 ) {  
    904904}
    905905
    906906void 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 );
    909908        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        }
    911917}
    912918
    913919void 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  
    4444#include "AST/Print.hpp"
    4545#include "AST/SymbolTable.hpp"
    4646#include "AST/Type.hpp"
     47#include "Common/UniqueName.hpp"
    4748#include "Common/Utility.hpp"       // for move, copy
    4849#include "SymTab/Mangler.hpp"
    4950#include "Tuples/Tuples.hpp"        // for handleTupleAssignment
     51#include "InitTweak/GenInit.hpp"    // for genCtorInit
    5052#include "InitTweak/InitTweak.hpp"  // for getPointerBase
    5153
    5254#include "Common/Stats/Counter.hpp"
    namespace {  
    688690                void postvisit( const ast::CommaExpr * commaExpr );
    689691                void postvisit( const ast::ImplicitCopyCtorExpr * ctorExpr );
    690692                void postvisit( const ast::ConstructorExpr * ctorExpr );
     693                void postvisit( const ast::CompoundLiteralExpr * compoundExpr );
    691694                void postvisit( const ast::RangeExpr * rangeExpr );
    692695                void postvisit( const ast::UntypedTupleExpr * tupleExpr );
    693696                void postvisit( const ast::TupleExpr * tupleExpr );
    namespace {  
    10491052                // Find function matches
    10501053                CandidateList found;
    10511054                SemanticErrorException errors;
    1052                
    10531055                for ( CandidateRef & func : funcFinder ) {
    10541056                        try {
    10551057                                PRINT(
    namespace {  
    16691671                }
    16701672        }
    16711673
     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
    16721718        void Finder::postvisit( const ast::RangeExpr * rangeExpr ) {
    16731719                // resolve low and high, accept candidates where low and high types unify
    16741720                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 ) {  
    439439        ast::Pass< Resolver >::run( translationUnit, translationUnit.global );
    440440}
    441441
     442// Does this need to return a ptr?
     443ast::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
     450ast::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
    442457ast::ptr< ast::Init > resolveCtorInit(
    443458        const ast::ConstructorInit * ctorInit, const ResolveContext & context
    444459) {
  • src/ResolvExpr/Resolver.hpp

    diff --git a/src/ResolvExpr/Resolver.hpp b/src/ResolvExpr/Resolver.hpp
    index 85e790d74..e2732f90d 100644
    a b struct ResolveContext {  
    4343void resolve( ast::TranslationUnit& translationUnit );
    4444/// Searches expr and returns the first DeletedExpr found, otherwise nullptr
    4545const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr );
     46/// Resolve the declaration (and all its declarations) in the given context.
     47ast::ptr< ast::Decl > resolveSingleDecl(
     48        const ast::Decl * decl, const ResolveContext & );
    4649/// Find the expression candidate that is the unique
    4750/// best match for `untyped` in a `void` context.
    4851ast::ptr< ast::Expr > resolveInVoidContext(
    ast::ptr< ast::Expr > findSingleExpression(  
    5457ast::ptr< ast::Expr > findVoidExpression(
    5558        const ast::Expr * untyped, const ResolveContext & );
    5659/// Resolves a constructor init expression
     60ast::ptr< ast::Init > resolveInit(
     61        const ast::Init * init, const ResolveContext & context );
    5762ast::ptr< ast::Init > resolveCtorInit(
    5863        const ast::ConstructorInit * ctorInit, const ResolveContext & context );
    5964/// 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 :  
    3030        ast::Storage::Classes storageClasses;
    3131
    3232        void previsit( const ast::ObjectDecl * decl );
     33        const ast::CompoundLiteralExpr * previsit( const ast::CompoundLiteralExpr * );
    3334        const ast::Expr * postvisit( const ast::CompoundLiteralExpr * expr );
    3435};
    3536
    void CompoundLiteral::previsit( const ast::ObjectDecl * decl ) {  
    3738        storageClasses = decl->storage;
    3839}
    3940
     41const 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
    4050const ast::Expr * CompoundLiteral::postvisit(
    4151                const ast::CompoundLiteralExpr * expr ) {
    4252        static UniqueName litName( "_compLit" );
    const ast::Expr * CompoundLiteral::postvisit(  
    4454        // Transform: [storageClasses] ... (struct S){...} ...
    4555        // Into:      [storageClasses] struct S _compLit = {...};
    4656        //                             ... _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
    5370                );
     71        } else {
     72                assert( false );
     73        }
    5474        // FIXME: A resolution of #280 could make the unused attribute unnecessary here
    5575        //     (let test nowarn/unused decide)
    5676        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[] ) {  
    233233                PASS( "Implement Virtual Destructors", Virtual::implementVirtDtors, transUnit );
    234234                PASS( "Implement Mutex", Concurrency::implementMutex, transUnit );
    235235                PASS( "Implement Thread Start", Concurrency::implementThreadStarter, transUnit );
    236                 PASS( "Compound Literal", Validate::handleCompoundLiterals, transUnit );
    237236                PASS( "Set Length From Initializer", Validate::setLengthFromInitializer, transUnit );
    238237                PASS( "Find Global Decls", Validate::findGlobalDecls, transUnit );
    239238
    int main( int argc, char * argv[] ) {  
    273272
    274273                PASS( "Resolve", ResolvExpr::resolve, transUnit );
    275274                DUMP( exprp, transUnit );
     275                PASS( "Compound Literal", Validate::handleCompoundLiterals, transUnit );
    276276                PASS( "Fix Init", InitTweak::fix, transUnit, buildingLibrary() ); // Here
    277277                PASS( "Erase With", ResolvExpr::eraseWith, transUnit );
    278278