Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r16ba4a6f r293dc1c  
    2626#include "RenameVars.h"                  // for RenameVars, global_renamer
    2727#include "Resolver.h"
    28 #include "ResolveTypeof.h"
    2928#include "ResolvMode.h"                  // for ResolvMode
    3029#include "typeops.h"                     // for extractResultType
    3130#include "Unify.h"                       // for unify
    32 #include "CompilationState.h"
    3331#include "AST/Chain.hpp"
    3432#include "AST/Decl.hpp"
     
    4745#include "SymTab/Autogen.h"              // for SizeType
    4846#include "SymTab/Indexer.h"              // for Indexer
    49 #include "SymTab/Mangler.h"              // for Mangler
    5047#include "SynTree/Declaration.h"         // for ObjectDecl, TypeDecl, Declar...
    5148#include "SynTree/Expression.h"          // for Expression, CastExpr, InitExpr
     
    11821179        } // anonymous namespace
    11831180
    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         }
     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                }
    11931190
    11941191        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                 }
    11991192                /// Predicate for "Candidate has integral type"
    12001193                bool hasIntegralType( const Candidate & i ) {
     
    12441237                ast::ptr< ast::Type > functionReturn = nullptr;
    12451238                ast::CurrentObject currentObject;
    1246                 // for work previously in GenInit
    1247                 static InitTweak::ManagedTypes_new managedTypes;
    1248 
    12491239                bool inEnumDecl = false;
    12501240
     
    12541244                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
    12551245
    1256                 const ast::FunctionDecl * previsit( const ast::FunctionDecl * );
     1246                void previsit( const ast::FunctionDecl * );
    12571247                const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
    1258                 const ast::ObjectDecl * previsit( const ast::ObjectDecl * );
    1259                 void previsit( const ast::AggregateDecl * );
    1260                 void previsit( const ast::StructDecl * );
     1248                void previsit( const ast::ObjectDecl * );
    12611249                void previsit( const ast::EnumDecl * );
    12621250                const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * );
     
    12791267                const ast::CatchStmt *       postvisit( const ast::CatchStmt * );
    12801268                const ast::WaitForStmt *     previsit( const ast::WaitForStmt * );
    1281                 const ast::WithStmt *        previsit( const ast::WithStmt * );
    12821269
    12831270                const ast::SingleInit *      previsit( const ast::SingleInit * );
    12841271                const ast::ListInit *        previsit( const ast::ListInit * );
    12851272                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(); }
    12911273        };
    12921274        // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver");
    1293 
    1294         InitTweak::ManagedTypes_new Resolver_new::managedTypes;
    12951275
    12961276        void resolve( ast::TranslationUnit& translationUnit ) {
     
    13171297        }
    13181298
    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 ) {
     1299        void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
    13561300                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 
    14201301                functionReturn = extractResultType( functionDecl->type );
    1421                 return functionDecl;
    14221302        }
    14231303
     
    14501330        }
    14511331
    1452         const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
     1332        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    14531333                // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
    14541334                // class-variable `initContext` is changed multiple times because the LHS is analyzed
     
    14581338                // selecting the RHS.
    14591339                GuardValue( currentObject );
    1460 
     1340                currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
    14611341                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    14621342                        // enumerator initializers should not use the enum type to initialize, since the
    14631343                        // enum type is still incomplete at this point. Use `int` instead.
    1464                         objectDecl = fixObjectType(objectDecl, symtab);
    14651344                        currentObject = ast::CurrentObject{
    14661345                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
    14671346                }
    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);
    15091347        }
    15101348
     
    15131351                GuardValue( inEnumDecl );
    15141352                inEnumDecl = true;
    1515                 // don't need to fix types for enum fields
    1516         }
    1517 
     1353        }
    15181354
    15191355        const ast::StaticAssertDecl * Resolver_new::previsit(
     
    19441780        }
    19451781
    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         }
    19731782
    19741783
Note: See TracChangeset for help on using the changeset viewer.