Changeset 16ba4a6


Ignore:
Timestamp:
Nov 10, 2020, 12:20:37 AM (4 years ago)
Author:
Fangren Yu <f37yu@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
18f0b70
Parents:
3febb2d
Message:

factor out resolver calls in pre-resolution stage

Location:
src
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r3febb2d r16ba4a6  
    27642764                        old->location,
    27652765                        GET_ACCEPT_1(value, Expr),
    2766                         (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
     2766                        (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::NoConstruct
    27672767                );
    27682768        }
     
    27732773                        GET_ACCEPT_V(initializers, Init),
    27742774                        GET_ACCEPT_V(designations, Designation),
    2775                         (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
     2775                        (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::NoConstruct
    27762776                );
    27772777        }
  • src/AST/Decl.hpp

    r3febb2d r16ba4a6  
    7979        ptr<Expr> asmName;
    8080        bool isDeleted = false;
     81        bool isTypeFixed = false;
    8182
    8283        DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
  • src/AST/Init.hpp

    r3febb2d r16ba4a6  
    5050
    5151/// Flag for whether to construct from initialzier
    52 enum ConstructFlag { DoConstruct, MaybeConstruct };
     52enum ConstructFlag { NoConstruct, MaybeConstruct };
    5353
    5454/// Object initializer base class
     
    7171        ptr<Expr> value;
    7272
    73         SingleInit( const CodeLocation & loc, const Expr * val, ConstructFlag mc = DoConstruct )
     73        SingleInit( const CodeLocation & loc, const Expr * val, ConstructFlag mc = NoConstruct )
    7474        : Init( loc, mc ), value( val ) {}
    7575
     
    9090
    9191        ListInit( const CodeLocation & loc, std::vector<ptr<Init>> && is,
    92                 std::vector<ptr<Designation>> && ds = {}, ConstructFlag mc = DoConstruct );
     92                std::vector<ptr<Designation>> && ds = {}, ConstructFlag mc = NoConstruct );
    9393
    9494        using iterator = std::vector<ptr<Init>>::iterator;
     
    118118        ConstructorInit(
    119119                const CodeLocation & loc, const Stmt * ctor, const Stmt * dtor, const Init * init )
    120         : Init( loc, DoConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {}
     120        : Init( loc, MaybeConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {}
    121121
    122122        const Init * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/AST/Pass.impl.hpp

    r3febb2d r16ba4a6  
    683683                // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result.
    684684                auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() {
    685                         if ( enterScope ) __pass::symtab::enter(core, 0);
     685                        if ( enterScope ) {
     686                                __pass::symtab::enter(core, 0);
     687                                __pass::scope::enter(core, 0);
     688                        }
    686689                }, [this, leaveScope = !this->atFunctionTop]() {
    687                         if ( leaveScope ) __pass::symtab::leave(core, 0);
     690                        if ( leaveScope ) {
     691                                __pass::symtab::leave(core, 0);
     692                                __pass::scope::leave(core, 0);
     693                        }
    688694                });
    689695                ValueGuard< bool > guard2( atFunctionTop );
  • src/AST/Type.cpp

    r3febb2d r16ba4a6  
    211211        for ( const Type * ty : types ) {
    212212                members.emplace_back( new ObjectDecl{
    213                         CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, MaybeConstruct ),
     213                        CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, NoConstruct ),
    214214                        Storage::Classes{}, Linkage::Cforall } );
    215215        }
  • src/CodeGen/CodeGenerator.cc

    r3febb2d r16ba4a6  
    120120                // GCC builtins should always be printed unmangled
    121121                if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name;
    122                 if ( decl->mangleName != "" ) {
     122                if ( LinkageSpec::isMangled(decl->linkage) && decl->mangleName != "" ) {
    123123                        // need to incorporate scope level in order to differentiate names for destructors
    124124                        return decl->get_scopedMangleName();
  • src/CodeGen/FixMain.cc

    r3febb2d r16ba4a6  
    2626#include "SynTree/Declaration.h"   // for FunctionDecl, operator<<
    2727#include "SynTree/Type.h"          // for FunctionType
     28#include "SymTab/Mangler.h"
    2829
    2930namespace CodeGen {
     
    4748                if( main_signature ) {
    4849                        os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return ";
     50                        main_signature->mangleName = SymTab::Mangler::mangle(main_signature.get());
    4951
    5052                        os << main_signature->get_scopedMangleName() << "(";
  • src/CodeGen/FixNames.cc

    r3febb2d r16ba4a6  
    3131#include "SynTree/Type.h"          // for Type, BasicType, Type::Qualifiers
    3232#include "SynTree/Visitor.h"       // for Visitor, acceptAll
     33#include "CompilationState.h"
    3334
    3435namespace CodeGen {
     
    102103                if ( dwt->get_name() != "" ) {
    103104                        if ( LinkageSpec::isMangled( dwt->get_linkage() ) ) {
    104                                 dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
     105                                if (!useNewAST) {
     106                                        dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
     107                                }
    105108                                dwt->set_scopeLevel( scopeLevel );
    106109                        } // if
  • src/InitTweak/GenInit.cc

    r3febb2d r16ba4a6  
    2626#include "AST/Node.hpp"
    2727#include "AST/Stmt.hpp"
     28#include "CompilationState.h"
    2829#include "CodeGen/OperatorTable.h"
    2930#include "Common/PassVisitor.h"        // for PassVisitor, WithGuards, WithShort...
     
    122123
    123124        void genInit( std::list< Declaration * > & translationUnit ) {
     125                HoistArrayDimension::hoistArrayDimension( translationUnit );
    124126                fixReturnStatements( translationUnit );
    125                 HoistArrayDimension::hoistArrayDimension( translationUnit );
    126                 CtorDtor::generateCtorDtor( translationUnit );
     127
     128                if (!useNewAST) {
     129                        CtorDtor::generateCtorDtor( translationUnit );
     130                }
    127131        }
    128132
     
    192196
    193197                        // need to resolve array dimensions in order to accurately determine if constexpr
    194                         ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
    195                         // array is variable-length when the dimension is not constexpr
    196                         arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
     198                        if (!useNewAST) {
     199                                ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
     200                                // array is variable-length when the dimension is not constexpr
     201                                arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
     202                        }
    197203                        // don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects.
    198                         if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
     204                        // xxx - hoisting has no side effects anyways, so don't skip since we delay resolve     
     205                        // only skip in the most trivial case, which does not require resolve
     206                        if (dynamic_cast<ConstantExpr *>(arrayType->dimension)) return;
     207                        // if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
    199208
    200209                        ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
     
    245254        }
    246255
     256        // why is this not just on FunctionDecl?
    247257        void ManagedTypes::handleDWT( DeclarationWithType * dwt ) {
    248258                // if this function is a user-defined constructor or destructor, mark down the type as "managed"
     
    274284        void ManagedTypes::beginScope() { managedTypes.beginScope(); }
    275285        void ManagedTypes::endScope() { managedTypes.endScope(); }
     286
     287        bool ManagedTypes_new::isManaged( const ast::Type * type ) const {
     288                // references are never constructed
     289                if ( dynamic_cast< const ast::ReferenceType * >( type ) ) return false;
     290                if ( auto tupleType = dynamic_cast< const ast::TupleType * > ( type ) ) {
     291                        // tuple is also managed if any of its components are managed
     292                        for (auto & component : tupleType->types) {
     293                                if (isManaged(component)) return true;
     294                        }
     295                }
     296                // need to clear and reset qualifiers when determining if a type is managed
     297                // ValueGuard< Type::Qualifiers > qualifiers( type->get_qualifiers() );
     298                auto tmp = shallowCopy(type);
     299                tmp->qualifiers = {};
     300                // delete tmp at return
     301                ast::ptr<ast::Type> guard = tmp;
     302                // a type is managed if it appears in the map of known managed types, or if it contains any polymorphism (is a type variable or generic type containing a type variable)
     303                return managedTypes.find( Mangle::mangle( tmp, {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) ) != managedTypes.end() || GenPoly::isPolyType( tmp );
     304        }
     305
     306        bool ManagedTypes_new::isManaged( const ast::ObjectDecl * objDecl ) const {
     307                const ast::Type * type = objDecl->type;
     308                while ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) {
     309                        // must always construct VLAs with an initializer, since this is an error in C
     310                        if ( at->isVarLen && objDecl->init ) return true;
     311                        type = at->base;
     312                }
     313                return isManaged( type );
     314        }
     315
     316        void ManagedTypes_new::handleDWT( const ast::DeclWithType * dwt ) {
     317                // if this function is a user-defined constructor or destructor, mark down the type as "managed"
     318                if ( ! dwt->linkage.is_overrideable && CodeGen::isCtorDtor( dwt->name ) ) {
     319                        auto & params = GenPoly::getFunctionType( dwt->get_type())->params;
     320                        assert( ! params.empty() );
     321                        // Type * type = InitTweak::getPointerBase( params.front() );
     322                        // assert( type );
     323                        managedTypes.insert( Mangle::mangle( params.front(), {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) );
     324                }
     325        }
     326
     327        void ManagedTypes_new::handleStruct( const ast::StructDecl * aggregateDecl ) {
     328                // don't construct members, but need to take note if there is a managed member,
     329                // because that means that this type is also managed
     330                for ( auto & member : aggregateDecl->members ) {
     331                        if ( auto field = member.as<ast::ObjectDecl>() ) {
     332                                if ( isManaged( field ) ) {
     333                                        // generic parameters should not play a role in determining whether a generic type is constructed - construct all generic types, so that
     334                                        // polymorphic constructors make generic types managed types
     335                                        ast::StructInstType inst( aggregateDecl );
     336                                        managedTypes.insert( Mangle::mangle( &inst, {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) );
     337                                        break;
     338                                }
     339                        }
     340                }
     341        }
     342
     343        void ManagedTypes_new::beginScope() { managedTypes.beginScope(); }
     344        void ManagedTypes_new::endScope() { managedTypes.endScope(); }
    276345
    277346        ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) {
     
    370439        // constructable object
    371440        InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr };
     441        ast::ptr< ast::Expr > dstParam = new ast::VariableExpr(loc, objDecl);
    372442       
    373443        ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall(
    374                 srcParam, new ast::VariableExpr{ loc, objDecl }, loc, "?{}", objDecl );
     444                srcParam, dstParam, loc, "?{}", objDecl );
    375445        ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall(
    376                 nullParam, new ast::VariableExpr{ loc, objDecl }, loc, "^?{}", objDecl,
     446                nullParam, dstParam, loc, "^?{}", objDecl,
    377447                SymTab::LoopBackward );
    378448       
  • src/InitTweak/GenInit.h

    r3febb2d r16ba4a6  
    5252                GenPoly::ScopedSet< std::string > managedTypes;
    5353        };
     54
     55        class ManagedTypes_new {
     56        public:
     57                bool isManaged( const ast::ObjectDecl * objDecl ) const ; // determine if object is managed
     58                bool isManaged( const ast::Type * type ) const; // determine if type is managed
     59
     60                void handleDWT( const ast::DeclWithType * dwt ); // add type to managed if ctor/dtor
     61                void handleStruct( const ast::StructDecl * aggregateDecl ); // add type to managed if child is managed
     62
     63                void beginScope();
     64                void endScope();
     65        private:
     66                GenPoly::ScopedSet< std::string > managedTypes;
     67        };
    5468} // namespace
    5569
  • src/InitTweak/InitTweak.cc

    r3febb2d r16ba4a6  
    8787                };
    8888
     89                struct HasDesignations_new : public ast::WithShortCircuiting {
     90                        bool result = false;
     91
     92                        void previsit( const ast::Node * ) {
     93                                // short circuit if we already know there are designations
     94                                if ( result ) visit_children = false;
     95                        }
     96
     97                        void previsit( const ast::Designation * des ) {
     98                                // short circuit if we already know there are designations
     99                                if ( result ) visit_children = false;
     100                                else if ( ! des->designators.empty() ) {
     101                                        result = true;
     102                                        visit_children = false;
     103                                }
     104                        }
     105                };
     106
     107                struct InitDepthChecker_new : public ast::WithGuards {
     108                        bool result = true;
     109                        const ast::Type * type;
     110                        int curDepth = 0, maxDepth = 0;
     111                        InitDepthChecker_new( const ast::Type * type ) : type( type ) {
     112                                const ast::Type * t = type;
     113                                while ( auto at = dynamic_cast< const ast::ArrayType * >( t ) ) {
     114                                        maxDepth++;
     115                                        t = at->base;
     116                                }
     117                                maxDepth++;
     118                        }
     119                        void previsit( ListInit * ) {
     120                                curDepth++;
     121                                GuardAction( [this]() { curDepth--; } );
     122                                if ( curDepth > maxDepth ) result = false;
     123                        }
     124                };
     125
    89126                struct InitFlattener_old : public WithShortCircuiting {
    90127                        void previsit( SingleInit * singleInit ) {
     
    122159                maybeAccept( objDecl->init, checker );
    123160                return checker.pass.depthOkay;
     161        }
     162
     163        bool isDesignated( const ast::Init * init ) {
     164                ast::Pass<HasDesignations_new> finder;
     165                maybe_accept( init, finder );
     166                return finder.core.result;
     167        }
     168
     169        bool checkInitDepth( const ast::ObjectDecl * objDecl ) {
     170                ast::Pass<InitDepthChecker_new> checker( objDecl->type );
     171                maybe_accept( objDecl->init.get(), checker );
     172                return checker.core.result;
    124173        }
    125174
     
    358407                        if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) {
    359408                                for ( const ast::Init * init : *listInit ) {
    360                                         buildCallExpr( callExpr, index, dimension, init, out );
     409                                        buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );
    361410                                }
    362411                        } else {
    363                                 buildCallExpr( callExpr, index, dimension, init, out );
     412                                buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );
    364413                        }
    365414                } else {
     
    10271076        };
    10281077
     1078        struct ConstExprChecker_new : public ast::WithShortCircuiting {
     1079                // most expressions are not const expr
     1080                void previsit( const ast::Expr * ) { result = false; visit_children = false; }
     1081
     1082                void previsit( const ast::AddressExpr *addressExpr ) {
     1083                        visit_children = false;
     1084                        const ast::Expr * arg = addressExpr->arg;
     1085
     1086                        // address of a variable or member expression is constexpr
     1087                        if ( ! dynamic_cast< const ast::NameExpr * >( arg )
     1088                        && ! dynamic_cast< const ast::VariableExpr * >( arg )
     1089                        && ! dynamic_cast< const ast::MemberExpr * >( arg )
     1090                        && ! dynamic_cast< const ast::UntypedMemberExpr * >( arg ) ) result = false;
     1091                }
     1092
     1093                // these expressions may be const expr, depending on their children
     1094                void previsit( const ast::SizeofExpr * ) {}
     1095                void previsit( const ast::AlignofExpr * ) {}
     1096                void previsit( const ast::UntypedOffsetofExpr * ) {}
     1097                void previsit( const ast::OffsetofExpr * ) {}
     1098                void previsit( const ast::OffsetPackExpr * ) {}
     1099                void previsit( const ast::CommaExpr * ) {}
     1100                void previsit( const ast::LogicalExpr * ) {}
     1101                void previsit( const ast::ConditionalExpr * ) {}
     1102                void previsit( const ast::CastExpr * ) {}
     1103                void previsit( const ast::ConstantExpr * ) {}
     1104
     1105                void previsit( const ast::VariableExpr * varExpr ) {
     1106                        visit_children = false;
     1107
     1108                        if ( auto inst = varExpr->result.as<ast::EnumInstType>() ) {
     1109                                long long int value;
     1110                                if ( inst->base->valueOf( varExpr->var, value ) ) {
     1111                                        // enumerators are const expr
     1112                                        return;
     1113                                }
     1114                        }
     1115                        result = false;
     1116                }
     1117
     1118                bool result = true;
     1119        };
     1120
    10291121        bool isConstExpr( Expression * expr ) {
    10301122                if ( expr ) {
     
    10461138        }
    10471139
     1140        bool isConstExpr( const ast::Expr * expr ) {
     1141                if ( expr ) {
     1142                        ast::Pass<ConstExprChecker_new> checker;
     1143                        expr->accept( checker );
     1144                        return checker.core.result;
     1145                }
     1146                return true;
     1147        }
     1148
     1149        bool isConstExpr( const ast::Init * init ) {
     1150                if ( init ) {
     1151                        ast::Pass<ConstExprChecker_new> checker;
     1152                        init->accept( checker );
     1153                        return checker.core.result;
     1154                } // if
     1155                // for all intents and purposes, no initializer means const expr
     1156                return true;
     1157        }
     1158
    10481159        bool isConstructor( const std::string & str ) { return str == "?{}"; }
    10491160        bool isDestructor( const std::string & str ) { return str == "^?{}"; }
  • src/InitTweak/InitTweak.h

    r3febb2d r16ba4a6  
    5959        /// True if the Initializer contains designations
    6060        bool isDesignated( Initializer * init );
     61        bool isDesignated( const ast::Init * init );
    6162
    6263        /// True if the ObjectDecl's Initializer nesting level is not deeper than the depth of its
    6364        /// type, where the depth of its type is the number of nested ArrayTypes + 1
    6465        bool checkInitDepth( ObjectDecl * objDecl );
     66        bool checkInitDepth( const ast::ObjectDecl * objDecl );
    6567
    6668        /// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr)
     
    107109        bool isConstExpr( Expression * expr );
    108110        bool isConstExpr( Initializer * init );
     111
     112        bool isConstExpr( const ast::Expr * expr );
     113        bool isConstExpr( const ast::Init * init );
    109114
    110115        /// Modifies objDecl to have:
  • src/ResolvExpr/ResolveTypeof.cc

    r3febb2d r16ba4a6  
    2929#include "SynTree/Mutator.h"     // for Mutator
    3030#include "SynTree/Type.h"        // for TypeofType, Type
     31#include "SymTab/Mangler.h"
     32#include "InitTweak/InitTweak.h" // for isConstExpr
    3133
    3234namespace SymTab {
     
    163165}
    164166
     167const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab ) {
     168        if (!decl->isTypeFixed) {
     169                auto mutDecl = mutate(decl);
     170                auto resolvedType = resolveTypeof(decl->type, symtab);
     171                mutDecl->type = resolvedType;
     172
     173                // check variable length if object is an array.
     174                // xxx - should this be part of fixObjectType?
     175                if (auto arrayType = dynamic_cast<const ast::ArrayType *>(resolvedType)) {
     176                        if (auto varexpr = arrayType->dimension.as<ast::VariableExpr>()) {// hoisted previously
     177                                if (InitTweak::isConstExpr(varexpr->var.strict_as<ast::ObjectDecl>()->init)) {
     178                                        auto mutType = mutate(arrayType);
     179                                        mutType->isVarLen = ast::LengthFlag::VariableLen;
     180                                        mutDecl->type = mutType;
     181                                }
     182                        }
     183                }
     184
     185                if (!mutDecl->name.empty())
     186                        mutDecl->mangleName = Mangle::mangle(mutDecl); // do not mangle unnamed variables
     187               
     188                mutDecl->isTypeFixed = true;
     189                return mutDecl;
     190        }
     191        return decl;
     192}
     193
    165194} // namespace ResolvExpr
    166195
  • src/ResolvExpr/ResolveTypeof.h

    r3febb2d r16ba4a6  
    2323        class Type;
    2424        class SymbolTable;
     25        class ObjectDecl;
    2526}
    2627
     
    2829        Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
    2930        const ast::Type * resolveTypeof( const ast::Type *, const ast::SymbolTable & );
     31        const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab );
    3032} // namespace ResolvExpr
    3133
  • src/ResolvExpr/Resolver.cc

    r3febb2d r16ba4a6  
    2626#include "RenameVars.h"                  // for RenameVars, global_renamer
    2727#include "Resolver.h"
     28#include "ResolveTypeof.h"
    2829#include "ResolvMode.h"                  // for ResolvMode
    2930#include "typeops.h"                     // for extractResultType
    3031#include "Unify.h"                       // for unify
     32#include "CompilationState.h"
    3133#include "AST/Chain.hpp"
    3234#include "AST/Decl.hpp"
     
    4547#include "SymTab/Autogen.h"              // for SizeType
    4648#include "SymTab/Indexer.h"              // for Indexer
     49#include "SymTab/Mangler.h"              // for Mangler
    4750#include "SynTree/Declaration.h"         // for ObjectDecl, TypeDecl, Declar...
    4851#include "SynTree/Expression.h"          // for Expression, CastExpr, InitExpr
     
    11791182        } // anonymous namespace
    11801183
    1181                 ast::ptr< ast::Expr > findSingleExpression(
    1182                         const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
    1183                 ) {
    1184                         assert( untyped && type );
    1185                         ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
    1186                         ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
    1187                         removeExtraneousCast( newExpr, symtab );
    1188                         return newExpr;
    1189                 }
     1184        ast::ptr< ast::Expr > findSingleExpression(
     1185                const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
     1186        ) {
     1187                assert( untyped && type );
     1188                ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
     1189                ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
     1190                removeExtraneousCast( newExpr, symtab );
     1191                return newExpr;
     1192        }
    11901193
    11911194        namespace {
     1195                bool structOrUnion( const Candidate & i ) {
     1196                        const ast::Type * t = i.expr->result->stripReferences();
     1197                        return dynamic_cast< const ast::StructInstType * >( t ) || dynamic_cast< const ast::UnionInstType * >( t );
     1198                }
    11921199                /// Predicate for "Candidate has integral type"
    11931200                bool hasIntegralType( const Candidate & i ) {
     
    12371244                ast::ptr< ast::Type > functionReturn = nullptr;
    12381245                ast::CurrentObject currentObject;
     1246                // for work previously in GenInit
     1247                static InitTweak::ManagedTypes_new managedTypes;
     1248
    12391249                bool inEnumDecl = false;
    12401250
     
    12441254                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
    12451255
    1246                 void previsit( const ast::FunctionDecl * );
     1256                const ast::FunctionDecl * previsit( const ast::FunctionDecl * );
    12471257                const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
    1248                 void previsit( const ast::ObjectDecl * );
     1258                const ast::ObjectDecl * previsit( const ast::ObjectDecl * );
     1259                void previsit( const ast::AggregateDecl * );
     1260                void previsit( const ast::StructDecl * );
    12491261                void previsit( const ast::EnumDecl * );
    12501262                const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * );
     
    12671279                const ast::CatchStmt *       postvisit( const ast::CatchStmt * );
    12681280                const ast::WaitForStmt *     previsit( const ast::WaitForStmt * );
     1281                const ast::WithStmt *        previsit( const ast::WithStmt * );
    12691282
    12701283                const ast::SingleInit *      previsit( const ast::SingleInit * );
    12711284                const ast::ListInit *        previsit( const ast::ListInit * );
    12721285                const ast::ConstructorInit * previsit( const ast::ConstructorInit * );
     1286
     1287                void resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd);
     1288
     1289                void beginScope() { managedTypes.beginScope(); }
     1290                void endScope() { managedTypes.endScope(); }
    12731291        };
    12741292        // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver");
     1293
     1294        InitTweak::ManagedTypes_new Resolver_new::managedTypes;
    12751295
    12761296        void resolve( ast::TranslationUnit& translationUnit ) {
     
    12971317        }
    12981318
    1299         void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
     1319        namespace {
     1320                const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ast::SymbolTable & symtab) {
     1321                        std::string name = attr->normalizedName();
     1322                        if (name == "constructor" || name == "destructor") {
     1323                                if (attr->params.size() == 1) {
     1324                                        auto arg = attr->params.front();
     1325                                        auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), symtab );
     1326                                        auto result = eval(arg);
     1327
     1328                                        auto mutAttr = mutate(attr);
     1329                                        mutAttr->params.front() = resolved;
     1330                                        if (! result.second) {
     1331                                                SemanticWarning(loc, Warning::GccAttributes,
     1332                                                        toCString( name, " priorities must be integers from 0 to 65535 inclusive: ", arg ) );
     1333                                        }
     1334                                        else {
     1335                                                auto priority = result.first;
     1336                                                if (priority < 101) {
     1337                                                        SemanticWarning(loc, Warning::GccAttributes,
     1338                                                                toCString( name, " priorities from 0 to 100 are reserved for the implementation" ) );
     1339                                                } else if (priority < 201 && ! buildingLibrary()) {
     1340                                                        SemanticWarning(loc, Warning::GccAttributes,
     1341                                                                toCString( name, " priorities from 101 to 200 are reserved for the implementation" ) );
     1342                                                }
     1343                                        }
     1344                                        return mutAttr;
     1345                                } else if (attr->params.size() > 1) {
     1346                                        SemanticWarning(loc, Warning::GccAttributes, toCString( "too many arguments to ", name, " attribute" ) );
     1347                                } else {
     1348                                        SemanticWarning(loc, Warning::GccAttributes, toCString( "too few arguments to ", name, " attribute" ) );
     1349                                }
     1350                        }
     1351                        return attr;
     1352                }
     1353        }
     1354
     1355        const ast::FunctionDecl * Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
    13001356                GuardValue( functionReturn );
     1357
     1358                assert (functionDecl->unique());
     1359                if (!functionDecl->has_body() && !functionDecl->withExprs.empty()) {
     1360                        SemanticError(functionDecl->location, functionDecl, "Function without body has with declarations");
     1361                }
     1362
     1363                if (!functionDecl->isTypeFixed) {
     1364                        auto mutDecl = mutate(functionDecl);
     1365                        auto mutType = mutDecl->type.get_and_mutate();
     1366
     1367                        for (auto & attr: mutDecl->attributes) {
     1368                                attr = handleAttribute(mutDecl->location, attr, symtab);
     1369                        }
     1370
     1371                        // handle assertions. (seems deep)
     1372
     1373                        symtab.enterScope();
     1374                        for (auto & typeParam : mutType->forall) {
     1375                                auto mutParam = typeParam.get_and_mutate();
     1376                                symtab.addType(mutParam);
     1377                                for (auto & asst : mutParam->assertions) {
     1378                                        asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab);
     1379                                        symtab.addId(asst);
     1380                                }
     1381                                typeParam = mutParam;
     1382                        }
     1383
     1384                        // temporarily adds params to symbol table.
     1385                        // actual scoping rules for params and withexprs differ - see Pass::visit(FunctionDecl)
     1386
     1387                        std::vector<ast::ptr<ast::Type>> paramTypes;
     1388                        std::vector<ast::ptr<ast::Type>> returnTypes;
     1389
     1390                        for (auto & param : mutDecl->params) {
     1391                                param = fixObjectType(param.strict_as<ast::ObjectDecl>(), symtab);
     1392                                symtab.addId(param);
     1393                                paramTypes.emplace_back(param->get_type());
     1394                        }
     1395                        for (auto & ret : mutDecl->returns) {
     1396                                ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), symtab);
     1397                                returnTypes.emplace_back(ret->get_type());
     1398                        }
     1399                        // since function type in decl is just a view of param types, need to update that as well
     1400                        mutType->params = std::move(paramTypes);
     1401                        mutType->returns = std::move(returnTypes);
     1402
     1403                        std::list<ast::ptr<ast::Stmt>> newStmts;
     1404                        resolveWithExprs (mutDecl->withExprs, newStmts);
     1405
     1406                        if (mutDecl->stmts) {
     1407                                auto mutStmt = mutDecl->stmts.get_and_mutate();
     1408                                mutStmt->kids.splice(mutStmt->kids.begin(), std::move(newStmts));
     1409                                mutDecl->stmts = mutStmt;
     1410                        }
     1411
     1412                        symtab.leaveScope();
     1413
     1414                        mutDecl->mangleName = Mangle::mangle(mutDecl);
     1415                        mutDecl->isTypeFixed = true;
     1416                        functionDecl = mutDecl;
     1417                }
     1418                managedTypes.handleDWT(functionDecl);
     1419
    13011420                functionReturn = extractResultType( functionDecl->type );
     1421                return functionDecl;
    13021422        }
    13031423
     
    13301450        }
    13311451
    1332         void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
     1452        const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    13331453                // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
    13341454                // class-variable `initContext` is changed multiple times because the LHS is analyzed
     
    13381458                // selecting the RHS.
    13391459                GuardValue( currentObject );
    1340                 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
     1460
    13411461                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    13421462                        // enumerator initializers should not use the enum type to initialize, since the
    13431463                        // enum type is still incomplete at this point. Use `int` instead.
     1464                        objectDecl = fixObjectType(objectDecl, symtab);
    13441465                        currentObject = ast::CurrentObject{
    13451466                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
    13461467                }
     1468                else {
     1469                        if (!objectDecl->isTypeFixed) {
     1470                                auto newDecl = fixObjectType(objectDecl, symtab);
     1471                                auto mutDecl = mutate(newDecl);
     1472                               
     1473                                // generate CtorInit wrapper when necessary.
     1474                                // in certain cases, fixObjectType is called before reaching
     1475                                // this object in visitor pass, thus disabling CtorInit codegen.
     1476                                // this happens on aggregate members and function parameters.
     1477                                if ( InitTweak::tryConstruct( mutDecl ) && ( managedTypes.isManaged( mutDecl ) || ((! isInFunction() || mutDecl->storage.is_static ) && ! InitTweak::isConstExpr( mutDecl->init ) ) ) ) {
     1478                                        // constructed objects cannot be designated
     1479                                        if ( InitTweak::isDesignated( mutDecl->init ) ) SemanticError( mutDecl, "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n" );
     1480                                        // constructed objects should not have initializers nested too deeply
     1481                                        if ( ! InitTweak::checkInitDepth( mutDecl ) ) SemanticError( mutDecl, "Managed object's initializer is too deep " );
     1482
     1483                                        mutDecl->init = InitTweak::genCtorInit( mutDecl->location, mutDecl );
     1484                                }
     1485
     1486                                objectDecl = mutDecl;
     1487                        }
     1488                        currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
     1489                }
     1490               
     1491                return objectDecl;
     1492        }
     1493
     1494        void Resolver_new::previsit( const ast::AggregateDecl * _aggDecl ) {
     1495                auto aggDecl = mutate(_aggDecl);
     1496                assertf(aggDecl == _aggDecl, "type declarations must be unique");
     1497
     1498                for (auto & member: aggDecl->members) {
     1499                        // nested type decls are hoisted already. no need to do anything
     1500                        if (auto obj = member.as<ast::ObjectDecl>()) {
     1501                                member = fixObjectType(obj, symtab);
     1502                        }
     1503                }
     1504        }
     1505
     1506        void Resolver_new::previsit( const ast::StructDecl * structDecl ) {
     1507                previsit(static_cast<const ast::AggregateDecl *>(structDecl));
     1508                managedTypes.handleStruct(structDecl);
    13471509        }
    13481510
     
    13511513                GuardValue( inEnumDecl );
    13521514                inEnumDecl = true;
    1353         }
     1515                // don't need to fix types for enum fields
     1516        }
     1517
    13541518
    13551519        const ast::StaticAssertDecl * Resolver_new::previsit(
     
    17801944        }
    17811945
     1946        const ast::WithStmt * Resolver_new::previsit( const ast::WithStmt * withStmt ) {
     1947                auto mutStmt = mutate(withStmt);
     1948                resolveWithExprs(mutStmt->exprs, stmtsToAddBefore);
     1949                return mutStmt;
     1950        }
     1951
     1952        void Resolver_new::resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd) {
     1953                for (auto & expr : exprs) {
     1954                        // only struct- and union-typed expressions are viable candidates
     1955                        expr = findKindExpression( expr, symtab, structOrUnion, "with expression" );
     1956
     1957                        // if with expression might be impure, create a temporary so that it is evaluated once
     1958                        if ( Tuples::maybeImpure( expr ) ) {
     1959                                static UniqueName tmpNamer( "_with_tmp_" );
     1960                                const CodeLocation loc = expr->location;
     1961                                auto tmp = new ast::ObjectDecl(loc, tmpNamer.newName(), expr->result, new ast::SingleInit(loc, expr ) );
     1962                                expr = new ast::VariableExpr( loc, tmp );
     1963                                stmtsToAdd.push_back( new ast::DeclStmt(loc, tmp ) );
     1964                                if ( InitTweak::isConstructable( tmp->type ) ) {
     1965                                        // generate ctor/dtor and resolve them
     1966                                        tmp->init = InitTweak::genCtorInit( loc, tmp );
     1967                                }
     1968                                // since tmp is freshly created, this should modify tmp in-place
     1969                                tmp->accept( *visitor );
     1970                        }
     1971                }
     1972        }
    17821973
    17831974
  • src/SymTab/Autogen.cc

    r3febb2d r16ba4a6  
    3838#include "SynTree/Type.h"          // for FunctionType, Type, TypeInstType
    3939#include "SynTree/Visitor.h"       // for maybeAccept, Visitor, acceptAll
     40#include "CompilationState.h"
    4041
    4142class Attribute;
  • src/SymTab/Autogen.h

    r3febb2d r16ba4a6  
    167167                fExpr->args.emplace_back( dstParam );
    168168
    169                 const ast::Stmt * listInit = srcParam.buildListInit( fExpr );
     169                ast::ptr<ast::Stmt> listInit = srcParam.buildListInit( fExpr );
    170170
    171171                // fetch next set of arguments
  • src/SymTab/Validate.cc

    r3febb2d r16ba4a6  
    6464#include "Common/UniqueName.h"         // for UniqueName
    6565#include "Common/utility.h"            // for operator+, cloneAll, deleteAll
     66#include "CompilationState.h"          // skip some passes in new-ast build
    6667#include "Concurrency/Keywords.h"      // for applyKeywords
    6768#include "FixFunction.h"               // for FixFunction
     
    281282
    282283                void previsit( ObjectDecl * objDecl );
    283                 void previsit( ArrayType * arrayType );
     284                // void previsit( ArrayType * arrayType );
    284285        };
    285286
     
    368369                                mutateAll( translationUnit, compoundliteral );
    369370                        });
    370                         Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
    371                                 ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
    372                         });
     371                        if (!useNewAST) {
     372                                Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
     373                                        ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
     374                                });
     375                        }
    373376                }
    374377                {
    375378                        Stats::Heap::newPass("validate-F");
    376379                        Stats::Time::BlockGuard guard("validate-F");
    377                         Stats::Time::TimeCall("Fix Object Type",
    378                                 FixObjectType::fix, translationUnit);
     380                        if (!useNewAST) {
     381                                Stats::Time::TimeCall("Fix Object Type",
     382                                        FixObjectType::fix, translationUnit);
     383                        }
    379384                        Stats::Time::TimeCall("Array Length",
    380385                                ArrayLength::computeLength, translationUnit);
     
    383388                        Stats::Time::TimeCall("Fix Label Address",
    384389                                mutateAll<LabelAddressFixer>, translationUnit, labelAddrFixer);
    385                         Stats::Time::TimeCall("Handle Attributes",
    386                                 Validate::handleAttributes, translationUnit);
     390                        if (!useNewAST) {
     391                                Stats::Time::TimeCall("Handle Attributes",
     392                                        Validate::handleAttributes, translationUnit);
     393                        }
    387394                }
    388395        }
     
    13391346        }
    13401347
     1348        // xxx - this seems to be in HoistArrayDimension now.
     1349
     1350        /*
    13411351        void ArrayLength::previsit( ArrayType * type ) {
    13421352                if ( type->dimension ) {
     
    13501360                }
    13511361        }
     1362        */
    13521363
    13531364        struct LabelFinder {
Note: See TracChangeset for help on using the changeset viewer.