Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r0dd9a5e 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(); }
    1291                 bool onError(ast::ptr<ast::Decl> & decl);
    12921273        };
    12931274        // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver");
    1294 
    1295         InitTweak::ManagedTypes_new Resolver_new::managedTypes;
    12961275
    12971276        void resolve( ast::TranslationUnit& translationUnit ) {
     
    13181297        }
    13191298
    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 ) {
     1299        void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
    13571300                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 
    14211301                functionReturn = extractResultType( functionDecl->type );
    1422                 return functionDecl;
    14231302        }
    14241303
     
    14511330        }
    14521331
    1453         const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
     1332        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    14541333                // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
    14551334                // class-variable `initContext` is changed multiple times because the LHS is analyzed
     
    14591338                // selecting the RHS.
    14601339                GuardValue( currentObject );
    1461 
     1340                currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
    14621341                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    14631342                        // enumerator initializers should not use the enum type to initialize, since the
    14641343                        // enum type is still incomplete at this point. Use `int` instead.
    1465                         objectDecl = fixObjectType(objectDecl, symtab);
    14661344                        currentObject = ast::CurrentObject{
    14671345                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
    14681346                }
    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);
    15101347        }
    15111348
     
    15141351                GuardValue( inEnumDecl );
    15151352                inEnumDecl = true;
    1516                 // don't need to fix types for enum fields
    1517         }
    1518 
     1353        }
    15191354
    15201355        const ast::StaticAssertDecl * Resolver_new::previsit(
     
    19451780        }
    19461781
    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         }
    19741782
    19751783
     
    20671875        }
    20681876
    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 
    20841877} // namespace ResolvExpr
    20851878
Note: See TracChangeset for help on using the changeset viewer.