Changeset 54dd994 for src/SymTab


Ignore:
Timestamp:
Jun 24, 2019, 10:30:47 AM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
Children:
84917e2
Parents:
3c6e417 (diff), 9e0a360 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/SymTab
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r3c6e417 r54dd994  
    2424#include <vector>                  // for vector
    2525
     26#include "AST/Decl.hpp"
    2627#include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
    2728#include "Common/PassVisitor.h"    // for PassVisitor
     
    209210        }
    210211
     212        bool isUnnamedBitfield( const ast::ObjectDecl * obj ) {
     213                return obj && obj->name.empty() && obj->bitfieldWidth;
     214        }
     215
    211216        /// inserts a forward declaration for functionDecl into declsToAdd
    212217        void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) {
     
    388393
    389394        void StructFuncGenerator::makeMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward ) {
    390                 InitTweak::InitExpander srcParam( src );
     395                InitTweak::InitExpander_old srcParam( src );
    391396
    392397                // assign to destination
  • src/SymTab/Autogen.h

    r3c6e417 r54dd994  
    1717
    1818#include <cassert>                // for assert
     19#include <iterator>               // for back_inserter
    1920#include <string>                 // for string
    2021
     22#include "AST/Decl.hpp"
     23#include "AST/Expr.hpp"
     24#include "AST/Init.hpp"
     25#include "AST/Node.hpp"
     26#include "AST/Stmt.hpp"
     27#include "AST/Type.hpp"
    2128#include "CodeGen/OperatorTable.h"
    2229#include "Common/UniqueName.h"    // for UniqueName
     30#include "Common/utility.h"       // for splice
    2331#include "InitTweak/InitTweak.h"  // for InitExpander
    2432#include "SynTree/Constant.h"     // for Constant
     
    3644        /// returns true if obj's name is the empty string and it has a bitfield width
    3745        bool isUnnamedBitfield( ObjectDecl * obj );
     46        bool isUnnamedBitfield( const ast::ObjectDecl * obj );
    3847
    3948        /// generate the type of an assignment function for paramType.
     
    4958        FunctionType * genCopyType( Type * paramType, bool maybePolymorphic = true );
    5059
     60        /// Enum for loop direction
     61        enum LoopDirection { LoopBackward, LoopForward };
     62
    5163        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
    5264        template< typename OutputIterator >
    53         Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );
     65        Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );
     66
     67        template< typename OutIter >
     68        ast::ptr< ast::Stmt > genCall(
     69                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     70                const CodeLocation & loc, const std::string & fname, OutIter && out,
     71                const ast::Type * type, const ast::Type * addCast, LoopDirection forward = LoopForward );
    5472
    5573        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
    5674        /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
    5775        template< typename OutputIterator >
    58         Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {
     76        Statement * genScalarCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {
    5977                bool isReferenceCtorDtor = false;
    6078                if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
     
    106124        }
    107125
     126        /// inserts into out a generated call expression to function fname with arguments dstParam and
     127        /// srcParam. Should only be called with non-array types.
     128        /// optionally returns a statement which must be inserted prior to the containing loop, if
     129        /// there is one
     130        template< typename OutIter >
     131        ast::ptr< ast::Stmt > genScalarCall(
     132                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     133                const CodeLocation & loc, std::string fname, OutIter && out, const ast::Type * type,
     134                const ast::Type * addCast = nullptr
     135        ) {
     136                bool isReferenceCtorDtor = false;
     137                if ( dynamic_cast< const ast::ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
     138                        // reference constructors are essentially application of the rebind operator.
     139                        // apply & to both arguments, do not need a cast
     140                        fname = "?=?";
     141                        dstParam = new ast::AddressExpr{ dstParam };
     142                        addCast = nullptr;
     143                        isReferenceCtorDtor = true;
     144                }
     145
     146                // want to be able to generate assignment, ctor, and dtor generically, so fname is one of
     147                // "?=?", "?{}", or "^?{}"
     148                ast::UntypedExpr * fExpr = new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, fname } };
     149
     150                if ( addCast ) {
     151                        // cast to T& with qualifiers removed, so that qualified objects can be constructed and
     152                        // destructed with the same functions as non-qualified objects. Unfortunately, lvalue
     153                        // is considered a qualifier - for AddressExpr to resolve, its argument must have an
     154                        // lvalue-qualified type, so remove all qualifiers except lvalue.
     155                        // xxx -- old code actually removed lvalue too...
     156                        ast::ptr< ast::Type > guard = addCast;  // prevent castType from mutating addCast
     157                        ast::ptr< ast::Type > castType = addCast;
     158                        ast::remove_qualifiers(
     159                                castType,
     160                                ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Atomic );
     161                        dstParam = new ast::CastExpr{ dstParam, new ast::ReferenceType{ castType } };
     162                }
     163                fExpr->args.emplace_back( dstParam );
     164
     165                const ast::Stmt * listInit = srcParam.buildListInit( fExpr );
     166
     167                // fetch next set of arguments
     168                ++srcParam;
     169
     170                // return if adding reference fails -- will happen on default ctor and dtor
     171                if ( isReferenceCtorDtor && ! srcParam.addReference() ) return listInit;
     172
     173                std::vector< ast::ptr< ast::Expr > > args = *srcParam;
     174                splice( fExpr->args, args );
     175
     176                *out++ = new ast::ExprStmt{ loc, fExpr };
     177
     178                srcParam.clearArrayIndices();
     179               
     180                return listInit;
     181        }
     182
    108183        /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
    109184        /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
    110185        template< typename OutputIterator >
    111         void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {
     186        void genArrayCall( InitTweak::InitExpander_old & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {
    112187                static UniqueName indexName( "_index" );
    113188
     
    170245        }
    171246
     247        /// Store in out a loop which calls fname on each element of the array with srcParam and
     248        /// dstParam as arguments. If forward is true, loop goes from 0 to N-1, else N-1 to 0
     249        template< typename OutIter >
     250        void genArrayCall(
     251                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     252                const CodeLocation & loc, const std::string & fname, OutIter && out,
     253                const ast::ArrayType * array, const ast::Type * addCast = nullptr,
     254                LoopDirection forward = LoopForward
     255        ) {
     256                static UniqueName indexName( "_index" );
     257
     258                // for a flexible array member nothing is done -- user must define own assignment
     259                if ( ! array->dimension ) return;
     260
     261                if ( addCast ) {
     262                        // peel off array layer from cast
     263                        addCast = strict_dynamic_cast< const ast::ArrayType * >( addCast )->base;
     264                }
     265
     266                ast::ptr< ast::Expr > begin, end, cmp, update;
     267
     268                if ( forward ) {
     269                        // generate: for ( int i = 0; i < N; ++i )
     270                        begin = ast::ConstantExpr::from_int( loc, 0 );
     271                        end = array->dimension;
     272                        cmp = new ast::NameExpr{ loc, "?<?" };
     273                        update = new ast::NameExpr{ loc, "++?" };
     274                } else {
     275                        // generate: for ( int i = N-1; i >= 0; --i )
     276                        begin = new ast::UntypedExpr{
     277                                loc, new ast::NameExpr{ loc, "?-?" },
     278                                { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } };
     279                        end = ast::ConstantExpr::from_int( loc, 0 );
     280                        cmp = new ast::NameExpr{ loc, "?>=?" };
     281                        update = new ast::NameExpr{ loc, "--?" };
     282                }
     283
     284                ast::ptr< ast::DeclWithType > index = new ast::ObjectDecl{
     285                        loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt },
     286                        new ast::SingleInit{ loc, begin } };
     287               
     288                ast::ptr< ast::Expr > cond = new ast::UntypedExpr{
     289                        loc, cmp, { new ast::VariableExpr{ loc, index }, end } };
     290               
     291                ast::ptr< ast::Expr > inc = new ast::UntypedExpr{
     292                        loc, update, { new ast::VariableExpr{ loc, index } } };
     293               
     294                ast::ptr< ast::Expr > dstIndex = new ast::UntypedExpr{
     295                        loc, new ast::NameExpr{ loc, "?[?]" },
     296                        { dstParam, new ast::VariableExpr{ loc, index } } };
     297               
     298                // srcParam must keep track of the array indices to build the source parameter and/or
     299                // array list initializer
     300                srcParam.addArrayIndex( new ast::VariableExpr{ loc, index }, array->dimension );
     301
     302                // for stmt's body, eventually containing call
     303                ast::CompoundStmt * body = new ast::CompoundStmt{ loc };
     304                ast::ptr< ast::Stmt > listInit = genCall(
     305                        srcParam, dstIndex, loc, fname, std::back_inserter( body->kids ), array->base, addCast,
     306                        forward );
     307               
     308                // block containing the stmt and index variable
     309                ast::CompoundStmt * block = new ast::CompoundStmt{ loc };
     310                block->push_back( new ast::DeclStmt{ loc, index } );
     311                if ( listInit ) { block->push_back( listInit ); }
     312                block->push_back( new ast::ForStmt{ loc, {}, cond, inc, body } );
     313
     314                *out++ = block;
     315        }
     316
    172317        template< typename OutputIterator >
    173         Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {
     318        Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {
    174319                if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    175320                        genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     
    180325        }
    181326
     327        template< typename OutIter >
     328        ast::ptr< ast::Stmt > genCall(
     329                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     330                const CodeLocation & loc, const std::string & fname, OutIter && out,
     331                const ast::Type * type, const ast::Type * addCast, LoopDirection forward
     332        ) {
     333                if ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) {
     334                        genArrayCall(
     335                                srcParam, dstParam, loc, fname, std::forward< OutIter >(out), at, addCast,
     336                                forward );
     337                        return {};
     338                } else {
     339                        return genScalarCall(
     340                                srcParam, dstParam, loc, fname, std::forward< OutIter >( out ), type, addCast );
     341                }
     342        }
     343
    182344        /// inserts into out a generated call expression to function fname with arguments dstParam
    183345        /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
     
    185347        /// ImplicitCtorDtorStmt node.
    186348        template< typename OutputIterator >
    187         void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
     349        void genImplicitCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
    188350                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
    189351                assert( obj );
     
    213375                }
    214376        }
     377
     378        static inline ast::ptr< ast::Stmt > genImplicitCall(
     379                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     380                const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj,
     381                LoopDirection forward = LoopForward
     382        ) {
     383                // unnamed bit fields are not copied as they cannot be accessed
     384                if ( isUnnamedBitfield( obj ) ) return {};
     385
     386                ast::ptr< ast::Type > addCast = nullptr;
     387                if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) {
     388                        assert( dstParam->result );
     389                        addCast = dstParam->result;
     390                }
     391
     392                std::vector< ast::ptr< ast::Stmt > > stmts;
     393                genCall(
     394                        srcParam, dstParam, loc, fname, back_inserter( stmts ), obj->type, addCast, forward );
     395
     396                if ( stmts.empty() ) {
     397                        return {};
     398                } else if ( stmts.size() == 1 ) {
     399                        const ast::Stmt * callStmt = stmts.front();
     400                        if ( addCast ) {
     401                                // implicitly generated ctor/dtor calls should be wrapped so that later passes are
     402                                // aware they were generated.
     403                                callStmt = new ast::ImplicitCtorDtorStmt{ callStmt->location, callStmt };
     404                        }
     405                        return callStmt;
     406                } else {
     407                        assert( false );
     408                        return {};
     409                }
     410        }
    215411} // namespace SymTab
    216412
  • src/SymTab/FixFunction.cc

    r3c6e417 r54dd994  
    1818#include <list>                   // for list
    1919
    20 #include "Common/utility.h"       // for maybeClone
     20#include "AST/Decl.hpp"
     21#include "AST/Pass.hpp"
     22#include "AST/Type.hpp"
     23#include "Common/utility.h"       // for maybeClone, copy
    2124#include "SynTree/Declaration.h"  // for FunctionDecl, ObjectDecl, Declarati...
    2225#include "SynTree/Expression.h"   // for Expression
     
    2427
    2528namespace SymTab {
    26         FixFunction::FixFunction() : isVoid( false ) {}
     29        class FixFunction_old : public WithShortCircuiting {
     30                typedef Mutator Parent;
     31          public:
     32                FixFunction_old() : isVoid( false ) {}
    2733
     34                void premutate(FunctionDecl *functionDecl);
     35                DeclarationWithType* postmutate(FunctionDecl *functionDecl);
    2836
    29         DeclarationWithType * FixFunction::postmutate(FunctionDecl *functionDecl) {
     37                Type * postmutate(ArrayType * arrayType);
     38
     39                void premutate(ArrayType * arrayType);
     40                void premutate(VoidType * voidType);
     41                void premutate(BasicType * basicType);
     42                void premutate(PointerType * pointerType);
     43                void premutate(StructInstType * aggregateUseType);
     44                void premutate(UnionInstType * aggregateUseType);
     45                void premutate(EnumInstType * aggregateUseType);
     46                void premutate(TraitInstType * aggregateUseType);
     47                void premutate(TypeInstType * aggregateUseType);
     48                void premutate(TupleType * tupleType);
     49                void premutate(VarArgsType * varArgsType);
     50                void premutate(ZeroType * zeroType);
     51                void premutate(OneType * oneType);
     52
     53                bool isVoid;
     54        };
     55
     56        DeclarationWithType * FixFunction_old::postmutate(FunctionDecl *functionDecl) {
    3057                // can't delete function type because it may contain assertions, so transfer ownership to new object
    3158                ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes );
     
    4168        // does not cause an error
    4269
    43         Type * FixFunction::postmutate(ArrayType *arrayType) {
     70        Type * FixFunction_old::postmutate(ArrayType *arrayType) {
    4471                // need to recursively mutate the base type in order for multi-dimensional arrays to work.
    4572                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic );
     
    5178        }
    5279
    53         void FixFunction::premutate(VoidType *) {
     80        void FixFunction_old::premutate(VoidType *) {
    5481                isVoid = true;
    5582        }
    5683
    57         void FixFunction::premutate(FunctionDecl *) { visit_children = false; }
    58         void FixFunction::premutate(ArrayType *) { visit_children = false; }
    59         void FixFunction::premutate(BasicType *) { visit_children = false; }
    60         void FixFunction::premutate(PointerType *) { visit_children = false; }
    61         void FixFunction::premutate(StructInstType *) { visit_children = false; }
    62         void FixFunction::premutate(UnionInstType *) { visit_children = false; }
    63         void FixFunction::premutate(EnumInstType *) { visit_children = false; }
    64         void FixFunction::premutate(TraitInstType *) { visit_children = false; }
    65         void FixFunction::premutate(TypeInstType *) { visit_children = false; }
    66         void FixFunction::premutate(TupleType *) { visit_children = false; }
    67         void FixFunction::premutate(VarArgsType *) { visit_children = false; }
    68         void FixFunction::premutate(ZeroType *) { visit_children = false; }
    69         void FixFunction::premutate(OneType *) { visit_children = false; }
     84        void FixFunction_old::premutate(FunctionDecl *) { visit_children = false; }
     85        void FixFunction_old::premutate(ArrayType *) { visit_children = false; }
     86        void FixFunction_old::premutate(BasicType *) { visit_children = false; }
     87        void FixFunction_old::premutate(PointerType *) { visit_children = false; }
     88        void FixFunction_old::premutate(StructInstType *) { visit_children = false; }
     89        void FixFunction_old::premutate(UnionInstType *) { visit_children = false; }
     90        void FixFunction_old::premutate(EnumInstType *) { visit_children = false; }
     91        void FixFunction_old::premutate(TraitInstType *) { visit_children = false; }
     92        void FixFunction_old::premutate(TypeInstType *) { visit_children = false; }
     93        void FixFunction_old::premutate(TupleType *) { visit_children = false; }
     94        void FixFunction_old::premutate(VarArgsType *) { visit_children = false; }
     95        void FixFunction_old::premutate(ZeroType *) { visit_children = false; }
     96        void FixFunction_old::premutate(OneType *) { visit_children = false; }
    7097
    7198        bool fixFunction( DeclarationWithType *& dwt ) {
    72                 PassVisitor<FixFunction> fixer;
     99                PassVisitor<FixFunction_old> fixer;
    73100                dwt = dwt->acceptMutator( fixer );
    74101                return fixer.pass.isVoid;
    75102        }
     103
     104namespace {
     105        struct FixFunction_new final : public ast::WithShortCircuiting {
     106                bool isVoid = false;
     107
     108                void premutate( const ast::FunctionDecl * ) { visit_children = false; }
     109
     110                const ast::DeclWithType * postmutate( const ast::FunctionDecl * func ) {
     111                        return new ast::ObjectDecl{
     112                                func->location, func->name, new ast::PointerType{ func->type }, nullptr,
     113                                func->storage, func->linkage, nullptr, copy( func->attributes ) };
     114                }
     115
     116                void premutate( const ast::ArrayType * ) { visit_children = false; }
     117
     118                const ast::Type * postmutate( const ast::ArrayType * array ) {
     119                        return new ast::PointerType{
     120                                array->base, array->dimension, array->isVarLen, array->isStatic,
     121                                array->qualifiers };
     122                }
     123
     124                void premutate( const ast::VoidType * ) { isVoid = true; }
     125
     126                void premutate( const ast::BasicType * ) { visit_children = false; }
     127                void premutate( const ast::PointerType * ) { visit_children = false; }
     128                void premutate( const ast::StructInstType * ) { visit_children = false; }
     129                void premutate( const ast::UnionInstType * ) { visit_children = false; }
     130                void premutate( const ast::EnumInstType * ) { visit_children = false; }
     131                void premutate( const ast::TraitInstType * ) { visit_children = false; }
     132                void premutate( const ast::TypeInstType * ) { visit_children = false; }
     133                void premutate( const ast::TupleType * ) { visit_children = false; }
     134                void premutate( const ast::VarArgsType * ) { visit_children = false; }
     135                void premutate( const ast::ZeroType * ) { visit_children = false; }
     136                void premutate( const ast::OneType * ) { visit_children = false; }
     137        };
     138} // anonymous namespace
     139
     140const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid ) {
     141        ast::Pass< FixFunction_new > fixer;
     142        dwt = dwt->accept( fixer );
     143        isVoid |= fixer.pass.isVoid;
     144        return dwt;
     145}
     146
    76147} // namespace SymTab
    77148
  • src/SymTab/FixFunction.h

    r3c6e417 r54dd994  
    1919#include "SynTree/SynTree.h"    // for Types
    2020
     21namespace ast {
     22        class DeclWithType;
     23}
     24
    2125namespace SymTab {
    22         /// Replaces function and array types by equivalent pointer types.
    23         class FixFunction : public WithShortCircuiting {
    24                 typedef Mutator Parent;
    25           public:
    26                 FixFunction();
     26        /// Replaces function and array types by equivalent pointer types. Returns true if type is
     27        /// void
     28        bool fixFunction( DeclarationWithType *& );
    2729
    28                 void premutate(FunctionDecl *functionDecl);
    29                 DeclarationWithType* postmutate(FunctionDecl *functionDecl);
    30 
    31                 Type * postmutate(ArrayType * arrayType);
    32 
    33                 void premutate(ArrayType * arrayType);
    34                 void premutate(VoidType * voidType);
    35                 void premutate(BasicType * basicType);
    36                 void premutate(PointerType * pointerType);
    37                 void premutate(StructInstType * aggregateUseType);
    38                 void premutate(UnionInstType * aggregateUseType);
    39                 void premutate(EnumInstType * aggregateUseType);
    40                 void premutate(TraitInstType * aggregateUseType);
    41                 void premutate(TypeInstType * aggregateUseType);
    42                 void premutate(TupleType * tupleType);
    43                 void premutate(VarArgsType * varArgsType);
    44                 void premutate(ZeroType * zeroType);
    45                 void premutate(OneType * oneType);
    46 
    47                 bool isVoid;
    48         };
    49 
    50         bool fixFunction( DeclarationWithType *& );
     30        /// Returns declaration with function and array types replaced by equivalent pointer types.
     31        /// Sets isVoid to true if type is void
     32        const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid );
    5133} // namespace SymTab
    5234
  • src/SymTab/Validate.cc

    r3c6e417 r54dd994  
    4646#include <utility>                     // for pair
    4747
     48#include "AST/Decl.hpp"
     49#include "AST/Node.hpp"
     50#include "AST/Pass.hpp"
     51#include "AST/SymbolTable.hpp"
     52#include "AST/Type.hpp"
    4853#include "CodeGen/CodeGenerator.h"     // for genName
    4954#include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
     
    124129
    125130        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    126         struct EnumAndPointerDecay {
     131        struct EnumAndPointerDecay_old {
    127132                void previsit( EnumDecl *aggregateDecl );
    128133                void previsit( FunctionType *func );
     
    130135
    131136        /// Associates forward declarations of aggregates with their definitions
    132         struct LinkReferenceToTypes final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes>, public WithShortCircuiting {
    133                 LinkReferenceToTypes( const Indexer *indexer );
     137        struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting {
     138                LinkReferenceToTypes_old( const Indexer *indexer );
    134139                void postvisit( TypeInstType *typeInst );
    135140
     
    165170
    166171        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    167         struct ForallPointerDecay final {
     172        struct ForallPointerDecay_old final {
    168173                void previsit( ObjectDecl * object );
    169174                void previsit( FunctionDecl * func );
     
    290295
    291296        void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) {
    292                 PassVisitor<EnumAndPointerDecay> epc;
    293                 PassVisitor<LinkReferenceToTypes> lrt( nullptr );
    294                 PassVisitor<ForallPointerDecay> fpd;
     297                PassVisitor<EnumAndPointerDecay_old> epc;
     298                PassVisitor<LinkReferenceToTypes_old> lrt( nullptr );
     299                PassVisitor<ForallPointerDecay_old> fpd;
    295300                PassVisitor<CompoundLiteral> compoundliteral;
    296301                PassVisitor<ValidateGenericParameters> genericParams;
     
    305310                        ReplaceTypedef::replaceTypedef( translationUnit );
    306311                        ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    307                         acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling
     312                        acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling
    308313                }
    309314                {
     
    314319                        });
    315320                        Stats::Time::TimeBlock("Fix Qualified Types", [&]() {
    316                                 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes, because aggregate members are accessed
     321                                mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed
    317322                        });
    318323                        Stats::Time::TimeBlock("Hoist Structs", [&]() {
     
    326331                        Stats::Heap::newPass("validate-C");
    327332                        Stats::Time::BlockGuard guard("validate-C");
    328                         acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
     333                        acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes_old
    329334                        VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    330335                        ReturnChecker::checkFunctionReturns( translationUnit );
     
    344349                        });
    345350                        Stats::Time::TimeBlock("Generate Autogen routines", [&]() {
    346                                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
     351                                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay_old
    347352                        });
    348353                }
     
    385390
    386391        void validateType( Type *type, const Indexer *indexer ) {
    387                 PassVisitor<EnumAndPointerDecay> epc;
    388                 PassVisitor<LinkReferenceToTypes> lrt( indexer );
    389                 PassVisitor<ForallPointerDecay> fpd;
     392                PassVisitor<EnumAndPointerDecay_old> epc;
     393                PassVisitor<LinkReferenceToTypes_old> lrt( indexer );
     394                PassVisitor<ForallPointerDecay_old> fpd;
    390395                type->accept( epc );
    391396                type->accept( lrt );
     
    586591        }
    587592
    588         void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
     593        void EnumAndPointerDecay_old::previsit( EnumDecl *enumDecl ) {
    589594                // Set the type of each member of the enumeration to be EnumConstant
    590595                for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) {
     
    618623        }
    619624
    620         void EnumAndPointerDecay::previsit( FunctionType *func ) {
     625        void EnumAndPointerDecay_old::previsit( FunctionType *func ) {
    621626                // Fix up parameters and return types
    622627                fixFunctionList( func->parameters, func->isVarArgs, func );
     
    624629        }
    625630
    626         LinkReferenceToTypes::LinkReferenceToTypes( const Indexer *other_indexer ) {
     631        LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer *other_indexer ) {
    627632                if ( other_indexer ) {
    628633                        local_indexer = other_indexer;
     
    632637        }
    633638
    634         void LinkReferenceToTypes::postvisit( EnumInstType *enumInst ) {
     639        void LinkReferenceToTypes_old::postvisit( EnumInstType *enumInst ) {
    635640                EnumDecl *st = local_indexer->lookupEnum( enumInst->name );
    636641                // it's not a semantic error if the enum is not found, just an implicit forward declaration
     
    652657        }
    653658
    654         void LinkReferenceToTypes::postvisit( StructInstType *structInst ) {
     659        void LinkReferenceToTypes_old::postvisit( StructInstType *structInst ) {
    655660                StructDecl *st = local_indexer->lookupStruct( structInst->name );
    656661                // it's not a semantic error if the struct is not found, just an implicit forward declaration
     
    665670        }
    666671
    667         void LinkReferenceToTypes::postvisit( UnionInstType *unionInst ) {
     672        void LinkReferenceToTypes_old::postvisit( UnionInstType *unionInst ) {
    668673                UnionDecl *un = local_indexer->lookupUnion( unionInst->name );
    669674                // it's not a semantic error if the union is not found, just an implicit forward declaration
     
    678683        }
    679684
    680         void LinkReferenceToTypes::previsit( QualifiedType * ) {
     685        void LinkReferenceToTypes_old::previsit( QualifiedType * ) {
    681686                visit_children = false;
    682687        }
    683688
    684         void LinkReferenceToTypes::postvisit( QualifiedType * qualType ) {
     689        void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) {
    685690                // linking only makes sense for the 'oldest ancestor' of the qualified type
    686691                qualType->parent->accept( *visitor );
     
    729734        }
    730735
    731         void LinkReferenceToTypes::postvisit( TraitDecl * traitDecl ) {
     736        void LinkReferenceToTypes_old::postvisit( TraitDecl * traitDecl ) {
    732737                if ( traitDecl->name == "sized" ) {
    733738                        // "sized" is a special trait - flick the sized status on for the type variable
     
    751756        }
    752757
    753         void LinkReferenceToTypes::postvisit( TraitInstType * traitInst ) {
     758        void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) {
    754759                // handle other traits
    755760                TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
     
    777782        }
    778783
    779         void LinkReferenceToTypes::postvisit( EnumDecl *enumDecl ) {
     784        void LinkReferenceToTypes_old::postvisit( EnumDecl *enumDecl ) {
    780785                // visit enum members first so that the types of self-referencing members are updated properly
    781786                if ( enumDecl->body ) {
     
    799804        }
    800805
    801         void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) {
     806        void LinkReferenceToTypes_old::renameGenericParams( std::list< TypeDecl * > & params ) {
    802807                // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g.
    803808                //   forall(otype T)
     
    817822        }
    818823
    819         void LinkReferenceToTypes::previsit( StructDecl * structDecl ) {
     824        void LinkReferenceToTypes_old::previsit( StructDecl * structDecl ) {
    820825                renameGenericParams( structDecl->parameters );
    821826        }
    822827
    823         void LinkReferenceToTypes::previsit( UnionDecl * unionDecl ) {
     828        void LinkReferenceToTypes_old::previsit( UnionDecl * unionDecl ) {
    824829                renameGenericParams( unionDecl->parameters );
    825830        }
    826831
    827         void LinkReferenceToTypes::postvisit( StructDecl *structDecl ) {
     832        void LinkReferenceToTypes_old::postvisit( StructDecl *structDecl ) {
    828833                // visit struct members first so that the types of self-referencing members are updated properly
    829834                // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults)
     
    839844        }
    840845
    841         void LinkReferenceToTypes::postvisit( UnionDecl *unionDecl ) {
     846        void LinkReferenceToTypes_old::postvisit( UnionDecl *unionDecl ) {
    842847                if ( unionDecl->body ) {
    843848                        ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name );
     
    851856        }
    852857
    853         void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) {
     858        void LinkReferenceToTypes_old::postvisit( TypeInstType *typeInst ) {
    854859                // ensure generic parameter instances are renamed like the base type
    855860                if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;
     
    888893        }
    889894
    890         void ForallPointerDecay::previsit( ObjectDecl *object ) {
     895        void ForallPointerDecay_old::previsit( ObjectDecl *object ) {
    891896                // ensure that operator names only apply to functions or function pointers
    892897                if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) {
     
    896901        }
    897902
    898         void ForallPointerDecay::previsit( FunctionDecl *func ) {
     903        void ForallPointerDecay_old::previsit( FunctionDecl *func ) {
    899904                func->fixUniqueId();
    900905        }
    901906
    902         void ForallPointerDecay::previsit( FunctionType * ftype ) {
     907        void ForallPointerDecay_old::previsit( FunctionType * ftype ) {
    903908                forallFixer( ftype->forall, ftype );
    904909        }
    905910
    906         void ForallPointerDecay::previsit( StructDecl * aggrDecl ) {
     911        void ForallPointerDecay_old::previsit( StructDecl * aggrDecl ) {
    907912                forallFixer( aggrDecl->parameters, aggrDecl );
    908913        }
    909914
    910         void ForallPointerDecay::previsit( UnionDecl * aggrDecl ) {
     915        void ForallPointerDecay_old::previsit( UnionDecl * aggrDecl ) {
    911916                forallFixer( aggrDecl->parameters, aggrDecl );
    912917        }
     
    13681373        }
    13691374
    1370         const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) {
    1371                 #warning unimplemented
    1372                 (void)type; (void)symtab;
    1373                 assert(false);
    1374                 return nullptr;
    1375         }
     1375namespace {
     1376        /// Replaces enum types by int, and function/array types in function parameter and return
     1377        /// lists by appropriate pointers
     1378        struct EnumAndPointerDecay_new {
     1379                const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) {
     1380                        // set the type of each member of the enumeration to be EnumConstant
     1381                        for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {
     1382                                // build new version of object with EnumConstant
     1383                                ast::ptr< ast::ObjectDecl > obj =
     1384                                        enumDecl->members[i].strict_as< ast::ObjectDecl >();
     1385                                obj.get_and_mutate()->type =
     1386                                        new ast::EnumInstType{ enumDecl->name, ast::CV::Const };
     1387                               
     1388                                // set into decl
     1389                                ast::EnumDecl * mut = mutate( enumDecl );
     1390                                mut->members[i] = obj.get();
     1391                                enumDecl = mut;
     1392                        }
     1393                        return enumDecl;
     1394                }
     1395
     1396                static const ast::FunctionType * fixFunctionList(
     1397                        const ast::FunctionType * func,
     1398                        std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field,
     1399                        ast::ArgumentFlag isVarArgs = ast::FixedArgs
     1400                ) {
     1401                        const auto & dwts = func->*field;
     1402                        unsigned nvals = dwts.size();
     1403                        bool hasVoid = false;
     1404                        for ( unsigned i = 0; i < nvals; ++i ) {
     1405                                func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) );
     1406                        }
     1407                       
     1408                        // the only case in which "void" is valid is where it is the only one in the list
     1409                        if ( hasVoid && ( nvals > 1 || isVarArgs ) ) {
     1410                                SemanticError(
     1411                                        dwts.front()->location, func, "invalid type void in function type" );
     1412                        }
     1413
     1414                        // one void is the only thing in the list, remove it
     1415                        if ( hasVoid ) {
     1416                                func = ast::mutate_field(
     1417                                        func, field, std::vector< ast::ptr< ast::DeclWithType > >{} );
     1418                        }
     1419
     1420                        return func;
     1421                }
     1422
     1423                const ast::FunctionType * previsit( const ast::FunctionType * func ) {
     1424                        func = fixFunctionList( func, &ast::FunctionType::params, func->isVarArgs );
     1425                        return fixFunctionList( func, &ast::FunctionType::returns );
     1426                }
     1427        };
     1428
     1429        /// Associates forward declarations of aggregates with their definitions
     1430        struct LinkReferenceToTypes_new final
     1431        : public ast::WithSymbolTable, public ast::WithGuards, public
     1432          ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting {
     1433               
     1434                const ast::SymbolTable * localSyms;
     1435
     1436                LinkReferenceToTypes_new( const ast::SymbolTable & syms ) : localSyms( &syms ) {}
     1437
     1438                #warning incomplete
     1439        };
     1440
     1441        /// Replaces array and function types in forall lists by appropriate pointer type and assigns
     1442        /// each object and function declaration a unique ID
     1443        struct ForallPointerDecay_new {
     1444                #warning incomplete
     1445        };
     1446} // anonymous namespace
     1447
     1448const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) {
     1449        ast::Pass< EnumAndPointerDecay_new > epc;
     1450        ast::Pass< LinkReferenceToTypes_new > lrt{ symtab };
     1451        ast::Pass< ForallPointerDecay_new > fpd;
     1452
     1453        return type->accept( epc )->accept( lrt )->accept( fpd );
     1454}
     1455
    13761456} // namespace SymTab
    13771457
Note: See TracChangeset for help on using the changeset viewer.