Changes in src/ResolvExpr/Resolver.cc [0dd9a5e:293dc1c]
- File:
-
- 1 edited
-
src/ResolvExpr/Resolver.cc (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r0dd9a5e r293dc1c 26 26 #include "RenameVars.h" // for RenameVars, global_renamer 27 27 #include "Resolver.h" 28 #include "ResolveTypeof.h"29 28 #include "ResolvMode.h" // for ResolvMode 30 29 #include "typeops.h" // for extractResultType 31 30 #include "Unify.h" // for unify 32 #include "CompilationState.h"33 31 #include "AST/Chain.hpp" 34 32 #include "AST/Decl.hpp" … … 47 45 #include "SymTab/Autogen.h" // for SizeType 48 46 #include "SymTab/Indexer.h" // for Indexer 49 #include "SymTab/Mangler.h" // for Mangler50 47 #include "SynTree/Declaration.h" // for ObjectDecl, TypeDecl, Declar... 51 48 #include "SynTree/Expression.h" // for Expression, CastExpr, InitExpr … … 1182 1179 } // anonymous namespace 1183 1180 1184 ast::ptr< ast::Expr > findSingleExpression(1185 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab1186 ) {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 } 1193 1190 1194 1191 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 }1199 1192 /// Predicate for "Candidate has integral type" 1200 1193 bool hasIntegralType( const Candidate & i ) { … … 1244 1237 ast::ptr< ast::Type > functionReturn = nullptr; 1245 1238 ast::CurrentObject currentObject; 1246 // for work previously in GenInit1247 static InitTweak::ManagedTypes_new managedTypes;1248 1249 1239 bool inEnumDecl = false; 1250 1240 … … 1254 1244 Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; } 1255 1245 1256 const ast::FunctionDecl *previsit( const ast::FunctionDecl * );1246 void previsit( const ast::FunctionDecl * ); 1257 1247 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 * ); 1261 1249 void previsit( const ast::EnumDecl * ); 1262 1250 const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * ); … … 1279 1267 const ast::CatchStmt * postvisit( const ast::CatchStmt * ); 1280 1268 const ast::WaitForStmt * previsit( const ast::WaitForStmt * ); 1281 const ast::WithStmt * previsit( const ast::WithStmt * );1282 1269 1283 1270 const ast::SingleInit * previsit( const ast::SingleInit * ); 1284 1271 const ast::ListInit * previsit( const ast::ListInit * ); 1285 1272 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);1292 1273 }; 1293 1274 // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver"); 1294 1295 InitTweak::ManagedTypes_new Resolver_new::managedTypes;1296 1275 1297 1276 void resolve( ast::TranslationUnit& translationUnit ) { … … 1318 1297 } 1319 1298 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 ) { 1357 1300 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 well1401 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 1421 1301 functionReturn = extractResultType( functionDecl->type ); 1422 return functionDecl;1423 1302 } 1424 1303 … … 1451 1330 } 1452 1331 1453 const ast::ObjectDecl *Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {1332 void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1454 1333 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1455 1334 // class-variable `initContext` is changed multiple times because the LHS is analyzed … … 1459 1338 // selecting the RHS. 1460 1339 GuardValue( currentObject ); 1461 1340 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1462 1341 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) { 1463 1342 // enumerator initializers should not use the enum type to initialize, since the 1464 1343 // enum type is still incomplete at this point. Use `int` instead. 1465 objectDecl = fixObjectType(objectDecl, symtab);1466 1344 currentObject = ast::CurrentObject{ 1467 1345 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1468 1346 } 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 reaching1476 // 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 designated1480 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 deeply1482 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 anything1501 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);1510 1347 } 1511 1348 … … 1514 1351 GuardValue( inEnumDecl ); 1515 1352 inEnumDecl = true; 1516 // don't need to fix types for enum fields 1517 } 1518 1353 } 1519 1354 1520 1355 const ast::StaticAssertDecl * Resolver_new::previsit( … … 1945 1780 } 1946 1781 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 candidates1956 expr = findKindExpression( expr, symtab, structOrUnion, "with expression" );1957 1958 // if with expression might be impure, create a temporary so that it is evaluated once1959 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 them1967 tmp->init = InitTweak::genCtorInit( loc, tmp );1968 }1969 // since tmp is freshly created, this should modify tmp in-place1970 tmp->accept( *visitor );1971 }1972 }1973 }1974 1782 1975 1783 … … 2067 1875 } 2068 1876 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 2084 1877 } // namespace ResolvExpr 2085 1878
Note:
See TracChangeset
for help on using the changeset viewer.