Changeset b82d140 for src/ResolvExpr


Ignore:
Timestamp:
Nov 10, 2020, 12:44:44 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
080b0a1, 883c4d9, f33eab7
Parents:
82a2fed (diff), cdacb73 (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/ResolvExpr
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ResolveTypeof.cc

    r82a2fed rb82d140  
    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
     167struct FixArrayDimension {
     168        // should not require a mutable symbol table - prevent pass template instantiation
     169        const ast::SymbolTable & _symtab;
     170        FixArrayDimension(const ast::SymbolTable & symtab): _symtab(symtab) {}
     171
     172        const ast::ArrayType * previsit (const ast::ArrayType * arrayType) {
     173                if (!arrayType->dimension) return arrayType;
     174                auto mutType = mutate(arrayType);
     175                ast::ptr<ast::Type> sizetype = ast::sizeType ? ast::sizeType : new ast::BasicType(ast::BasicType::LongUnsignedInt);
     176                mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, _symtab);
     177
     178                if (InitTweak::isConstExpr(mutType->dimension)) {
     179                        mutType->isVarLen = ast::LengthFlag::FixedLen;
     180                }
     181                else {
     182                        mutType->isVarLen = ast::LengthFlag::VariableLen;
     183                }
     184                return mutType;
     185        }
     186};
     187
     188const ast::Type * fixArrayType( const ast::Type * type, const ast::SymbolTable & symtab) {
     189        ast::Pass<FixArrayDimension> visitor {symtab};
     190        return type->accept(visitor);
     191}
     192
     193const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab ) {
     194        if (!decl->isTypeFixed) {
     195                auto mutDecl = mutate(decl);
     196                auto resolvedType = resolveTypeof(decl->type, symtab);
     197                resolvedType = fixArrayType(resolvedType, symtab);
     198                mutDecl->type = resolvedType;
     199
     200                // check variable length if object is an array.
     201                // xxx - should this be part of fixObjectType?
     202
     203                /*
     204                if (auto arrayType = dynamic_cast<const ast::ArrayType *>(resolvedType)) {
     205                        auto dimExpr = findSingleExpression(arrayType->dimension, ast::sizeType, symtab);
     206                        if (auto varexpr = arrayType->dimension.as<ast::VariableExpr>()) {// hoisted previously
     207                                if (InitTweak::isConstExpr(varexpr->var.strict_as<ast::ObjectDecl>()->init)) {
     208                                        auto mutType = mutate(arrayType);
     209                                        mutType->isVarLen = ast::LengthFlag::VariableLen;
     210                                        mutDecl->type = mutType;
     211                                }
     212                        }
     213                }
     214                */
     215
     216
     217                if (!mutDecl->name.empty())
     218                        mutDecl->mangleName = Mangle::mangle(mutDecl); // do not mangle unnamed variables
     219               
     220                mutDecl->isTypeFixed = true;
     221                return mutDecl;
     222        }
     223        return decl;
     224}
     225
    165226} // namespace ResolvExpr
    166227
  • src/ResolvExpr/ResolveTypeof.h

    r82a2fed rb82d140  
    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

    r82a2fed rb82d140  
    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(); }
     1291                bool onError(ast::ptr<ast::Decl> & decl);
    12731292        };
    12741293        // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver");
     1294
     1295        InitTweak::ManagedTypes_new Resolver_new::managedTypes;
    12751296
    12761297        void resolve( ast::TranslationUnit& translationUnit ) {
     
    12971318        }
    12981319
    1299         void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
     1320        namespace {
     1321                const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ast::SymbolTable & symtab) {
     1322                        std::string name = attr->normalizedName();
     1323                        if (name == "constructor" || name == "destructor") {
     1324                                if (attr->params.size() == 1) {
     1325                                        auto arg = attr->params.front();
     1326                                        auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), symtab );
     1327                                        auto result = eval(arg);
     1328
     1329                                        auto mutAttr = mutate(attr);
     1330                                        mutAttr->params.front() = resolved;
     1331                                        if (! result.second) {
     1332                                                SemanticWarning(loc, Warning::GccAttributes,
     1333                                                        toCString( name, " priorities must be integers from 0 to 65535 inclusive: ", arg ) );
     1334                                        }
     1335                                        else {
     1336                                                auto priority = result.first;
     1337                                                if (priority < 101) {
     1338                                                        SemanticWarning(loc, Warning::GccAttributes,
     1339                                                                toCString( name, " priorities from 0 to 100 are reserved for the implementation" ) );
     1340                                                } else if (priority < 201 && ! buildingLibrary()) {
     1341                                                        SemanticWarning(loc, Warning::GccAttributes,
     1342                                                                toCString( name, " priorities from 101 to 200 are reserved for the implementation" ) );
     1343                                                }
     1344                                        }
     1345                                        return mutAttr;
     1346                                } else if (attr->params.size() > 1) {
     1347                                        SemanticWarning(loc, Warning::GccAttributes, toCString( "too many arguments to ", name, " attribute" ) );
     1348                                } else {
     1349                                        SemanticWarning(loc, Warning::GccAttributes, toCString( "too few arguments to ", name, " attribute" ) );
     1350                                }
     1351                        }
     1352                        return attr;
     1353                }
     1354        }
     1355
     1356        const ast::FunctionDecl * Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
    13001357                GuardValue( functionReturn );
     1358
     1359                assert (functionDecl->unique());
     1360                if (!functionDecl->has_body() && !functionDecl->withExprs.empty()) {
     1361                        SemanticError(functionDecl->location, functionDecl, "Function without body has with declarations");
     1362                }
     1363
     1364                if (!functionDecl->isTypeFixed) {
     1365                        auto mutDecl = mutate(functionDecl);
     1366                        auto mutType = mutDecl->type.get_and_mutate();
     1367
     1368                        for (auto & attr: mutDecl->attributes) {
     1369                                attr = handleAttribute(mutDecl->location, attr, symtab);
     1370                        }
     1371
     1372                        // handle assertions. (seems deep)
     1373
     1374                        symtab.enterScope();
     1375                        for (auto & typeParam : mutType->forall) {
     1376                                auto mutParam = typeParam.get_and_mutate();
     1377                                symtab.addType(mutParam);
     1378                                for (auto & asst : mutParam->assertions) {
     1379                                        asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab);
     1380                                        symtab.addId(asst);
     1381                                }
     1382                                typeParam = mutParam;
     1383                        }
     1384
     1385                        // temporarily adds params to symbol table.
     1386                        // actual scoping rules for params and withexprs differ - see Pass::visit(FunctionDecl)
     1387
     1388                        std::vector<ast::ptr<ast::Type>> paramTypes;
     1389                        std::vector<ast::ptr<ast::Type>> returnTypes;
     1390
     1391                        for (auto & param : mutDecl->params) {
     1392                                param = fixObjectType(param.strict_as<ast::ObjectDecl>(), symtab);
     1393                                symtab.addId(param);
     1394                                paramTypes.emplace_back(param->get_type());
     1395                        }
     1396                        for (auto & ret : mutDecl->returns) {
     1397                                ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), symtab);
     1398                                returnTypes.emplace_back(ret->get_type());
     1399                        }
     1400                        // since function type in decl is just a view of param types, need to update that as well
     1401                        mutType->params = std::move(paramTypes);
     1402                        mutType->returns = std::move(returnTypes);
     1403
     1404                        std::list<ast::ptr<ast::Stmt>> newStmts;
     1405                        resolveWithExprs (mutDecl->withExprs, newStmts);
     1406
     1407                        if (mutDecl->stmts) {
     1408                                auto mutStmt = mutDecl->stmts.get_and_mutate();
     1409                                mutStmt->kids.splice(mutStmt->kids.begin(), std::move(newStmts));
     1410                                mutDecl->stmts = mutStmt;
     1411                        }
     1412
     1413                        symtab.leaveScope();
     1414
     1415                        mutDecl->mangleName = Mangle::mangle(mutDecl);
     1416                        mutDecl->isTypeFixed = true;
     1417                        functionDecl = mutDecl;
     1418                }
     1419                managedTypes.handleDWT(functionDecl);
     1420
    13011421                functionReturn = extractResultType( functionDecl->type );
     1422                return functionDecl;
    13021423        }
    13031424
     
    13301451        }
    13311452
    1332         void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
     1453        const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    13331454                // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
    13341455                // class-variable `initContext` is changed multiple times because the LHS is analyzed
     
    13381459                // selecting the RHS.
    13391460                GuardValue( currentObject );
    1340                 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
     1461
    13411462                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    13421463                        // enumerator initializers should not use the enum type to initialize, since the
    13431464                        // enum type is still incomplete at this point. Use `int` instead.
     1465                        objectDecl = fixObjectType(objectDecl, symtab);
    13441466                        currentObject = ast::CurrentObject{
    13451467                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
    13461468                }
     1469                else {
     1470                        if (!objectDecl->isTypeFixed) {
     1471                                auto newDecl = fixObjectType(objectDecl, symtab);
     1472                                auto mutDecl = mutate(newDecl);
     1473                               
     1474                                // generate CtorInit wrapper when necessary.
     1475                                // in certain cases, fixObjectType is called before reaching
     1476                                // this object in visitor pass, thus disabling CtorInit codegen.
     1477                                // this happens on aggregate members and function parameters.
     1478                                if ( InitTweak::tryConstruct( mutDecl ) && ( managedTypes.isManaged( mutDecl ) || ((! isInFunction() || mutDecl->storage.is_static ) && ! InitTweak::isConstExpr( mutDecl->init ) ) ) ) {
     1479                                        // constructed objects cannot be designated
     1480                                        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" );
     1481                                        // constructed objects should not have initializers nested too deeply
     1482                                        if ( ! InitTweak::checkInitDepth( mutDecl ) ) SemanticError( mutDecl, "Managed object's initializer is too deep " );
     1483
     1484                                        mutDecl->init = InitTweak::genCtorInit( mutDecl->location, mutDecl );
     1485                                }
     1486
     1487                                objectDecl = mutDecl;
     1488                        }
     1489                        currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
     1490                }
     1491               
     1492                return objectDecl;
     1493        }
     1494
     1495        void Resolver_new::previsit( const ast::AggregateDecl * _aggDecl ) {
     1496                auto aggDecl = mutate(_aggDecl);
     1497                assertf(aggDecl == _aggDecl, "type declarations must be unique");
     1498
     1499                for (auto & member: aggDecl->members) {
     1500                        // nested type decls are hoisted already. no need to do anything
     1501                        if (auto obj = member.as<ast::ObjectDecl>()) {
     1502                                member = fixObjectType(obj, symtab);
     1503                        }
     1504                }
     1505        }
     1506
     1507        void Resolver_new::previsit( const ast::StructDecl * structDecl ) {
     1508                previsit(static_cast<const ast::AggregateDecl *>(structDecl));
     1509                managedTypes.handleStruct(structDecl);
    13471510        }
    13481511
     
    13511514                GuardValue( inEnumDecl );
    13521515                inEnumDecl = true;
    1353         }
     1516                // don't need to fix types for enum fields
     1517        }
     1518
    13541519
    13551520        const ast::StaticAssertDecl * Resolver_new::previsit(
     
    17801945        }
    17811946
     1947        const ast::WithStmt * Resolver_new::previsit( const ast::WithStmt * withStmt ) {
     1948                auto mutStmt = mutate(withStmt);
     1949                resolveWithExprs(mutStmt->exprs, stmtsToAddBefore);
     1950                return mutStmt;
     1951        }
     1952
     1953        void Resolver_new::resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd) {
     1954                for (auto & expr : exprs) {
     1955                        // only struct- and union-typed expressions are viable candidates
     1956                        expr = findKindExpression( expr, symtab, structOrUnion, "with expression" );
     1957
     1958                        // if with expression might be impure, create a temporary so that it is evaluated once
     1959                        if ( Tuples::maybeImpure( expr ) ) {
     1960                                static UniqueName tmpNamer( "_with_tmp_" );
     1961                                const CodeLocation loc = expr->location;
     1962                                auto tmp = new ast::ObjectDecl(loc, tmpNamer.newName(), expr->result, new ast::SingleInit(loc, expr ) );
     1963                                expr = new ast::VariableExpr( loc, tmp );
     1964                                stmtsToAdd.push_back( new ast::DeclStmt(loc, tmp ) );
     1965                                if ( InitTweak::isConstructable( tmp->type ) ) {
     1966                                        // generate ctor/dtor and resolve them
     1967                                        tmp->init = InitTweak::genCtorInit( loc, tmp );
     1968                                }
     1969                                // since tmp is freshly created, this should modify tmp in-place
     1970                                tmp->accept( *visitor );
     1971                        }
     1972                }
     1973        }
    17821974
    17831975
     
    18752067        }
    18762068
     2069        // suppress error on autogen functions and mark invalid autogen as deleted.
     2070        bool Resolver_new::onError(ast::ptr<ast::Decl> & decl) {
     2071                if (auto functionDecl = decl.as<ast::FunctionDecl>()) {
     2072                        // xxx - can intrinsic gen ever fail?
     2073                        if (functionDecl->linkage == ast::Linkage::AutoGen) {
     2074                                auto mutDecl = mutate(functionDecl);
     2075                                mutDecl->isDeleted = true;
     2076                                mutDecl->stmts = nullptr;
     2077                                decl = mutDecl;
     2078                                return false;
     2079                        }
     2080                }
     2081                return true;
     2082        }
     2083
    18772084} // namespace ResolvExpr
    18782085
  • src/ResolvExpr/SatisfyAssertions.cpp

    r82a2fed rb82d140  
    247247                                auto it = inferred.find( slot );
    248248                                if ( it == inferred.end() ) {
    249                                         std::cerr << "missing assertion " << slot << std::endl;
     249                                        // std::cerr << "missing assertion " << slot << std::endl;
    250250                                        missingSlots.push_back(slot);
    251251                                        continue;
Note: See TracChangeset for help on using the changeset viewer.