Changeset 16ba4a6f for src/ResolvExpr
- Timestamp:
- Nov 10, 2020, 12:20:37 AM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 18f0b70
- Parents:
- 3febb2d
- Location:
- src/ResolvExpr
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/ResolveTypeof.cc
r3febb2d r16ba4a6f 29 29 #include "SynTree/Mutator.h" // for Mutator 30 30 #include "SynTree/Type.h" // for TypeofType, Type 31 #include "SymTab/Mangler.h" 32 #include "InitTweak/InitTweak.h" // for isConstExpr 31 33 32 34 namespace SymTab { … … 163 165 } 164 166 167 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab ) { 168 if (!decl->isTypeFixed) { 169 auto mutDecl = mutate(decl); 170 auto resolvedType = resolveTypeof(decl->type, symtab); 171 mutDecl->type = resolvedType; 172 173 // check variable length if object is an array. 174 // xxx - should this be part of fixObjectType? 175 if (auto arrayType = dynamic_cast<const ast::ArrayType *>(resolvedType)) { 176 if (auto varexpr = arrayType->dimension.as<ast::VariableExpr>()) {// hoisted previously 177 if (InitTweak::isConstExpr(varexpr->var.strict_as<ast::ObjectDecl>()->init)) { 178 auto mutType = mutate(arrayType); 179 mutType->isVarLen = ast::LengthFlag::VariableLen; 180 mutDecl->type = mutType; 181 } 182 } 183 } 184 185 if (!mutDecl->name.empty()) 186 mutDecl->mangleName = Mangle::mangle(mutDecl); // do not mangle unnamed variables 187 188 mutDecl->isTypeFixed = true; 189 return mutDecl; 190 } 191 return decl; 192 } 193 165 194 } // namespace ResolvExpr 166 195 -
src/ResolvExpr/ResolveTypeof.h
r3febb2d r16ba4a6f 23 23 class Type; 24 24 class SymbolTable; 25 class ObjectDecl; 25 26 } 26 27 … … 28 29 Type *resolveTypeof( Type*, const SymTab::Indexer &indexer ); 29 30 const ast::Type * resolveTypeof( const ast::Type *, const ast::SymbolTable & ); 31 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab ); 30 32 } // namespace ResolvExpr 31 33 -
src/ResolvExpr/Resolver.cc
r3febb2d r16ba4a6f 26 26 #include "RenameVars.h" // for RenameVars, global_renamer 27 27 #include "Resolver.h" 28 #include "ResolveTypeof.h" 28 29 #include "ResolvMode.h" // for ResolvMode 29 30 #include "typeops.h" // for extractResultType 30 31 #include "Unify.h" // for unify 32 #include "CompilationState.h" 31 33 #include "AST/Chain.hpp" 32 34 #include "AST/Decl.hpp" … … 45 47 #include "SymTab/Autogen.h" // for SizeType 46 48 #include "SymTab/Indexer.h" // for Indexer 49 #include "SymTab/Mangler.h" // for Mangler 47 50 #include "SynTree/Declaration.h" // for ObjectDecl, TypeDecl, Declar... 48 51 #include "SynTree/Expression.h" // for Expression, CastExpr, InitExpr … … 1179 1182 } // anonymous namespace 1180 1183 1181 1182 1183 1184 1185 1186 1187 1188 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 } 1190 1193 1191 1194 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 } 1192 1199 /// Predicate for "Candidate has integral type" 1193 1200 bool hasIntegralType( const Candidate & i ) { … … 1237 1244 ast::ptr< ast::Type > functionReturn = nullptr; 1238 1245 ast::CurrentObject currentObject; 1246 // for work previously in GenInit 1247 static InitTweak::ManagedTypes_new managedTypes; 1248 1239 1249 bool inEnumDecl = false; 1240 1250 … … 1244 1254 Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; } 1245 1255 1246 voidprevisit( const ast::FunctionDecl * );1256 const ast::FunctionDecl * previsit( const ast::FunctionDecl * ); 1247 1257 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 * ); 1249 1261 void previsit( const ast::EnumDecl * ); 1250 1262 const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * ); … … 1267 1279 const ast::CatchStmt * postvisit( const ast::CatchStmt * ); 1268 1280 const ast::WaitForStmt * previsit( const ast::WaitForStmt * ); 1281 const ast::WithStmt * previsit( const ast::WithStmt * ); 1269 1282 1270 1283 const ast::SingleInit * previsit( const ast::SingleInit * ); 1271 1284 const ast::ListInit * previsit( const ast::ListInit * ); 1272 1285 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(); } 1273 1291 }; 1274 1292 // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver"); 1293 1294 InitTweak::ManagedTypes_new Resolver_new::managedTypes; 1275 1295 1276 1296 void resolve( ast::TranslationUnit& translationUnit ) { … … 1297 1317 } 1298 1318 1299 void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) { 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 ) { 1300 1356 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 1301 1420 functionReturn = extractResultType( functionDecl->type ); 1421 return functionDecl; 1302 1422 } 1303 1423 … … 1330 1450 } 1331 1451 1332 voidResolver_new::previsit( const ast::ObjectDecl * objectDecl ) {1452 const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1333 1453 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1334 1454 // class-variable `initContext` is changed multiple times because the LHS is analyzed … … 1338 1458 // selecting the RHS. 1339 1459 GuardValue( currentObject ); 1340 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1460 1341 1461 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) { 1342 1462 // enumerator initializers should not use the enum type to initialize, since the 1343 1463 // enum type is still incomplete at this point. Use `int` instead. 1464 objectDecl = fixObjectType(objectDecl, symtab); 1344 1465 currentObject = ast::CurrentObject{ 1345 1466 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1346 1467 } 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); 1347 1509 } 1348 1510 … … 1351 1513 GuardValue( inEnumDecl ); 1352 1514 inEnumDecl = true; 1353 } 1515 // don't need to fix types for enum fields 1516 } 1517 1354 1518 1355 1519 const ast::StaticAssertDecl * Resolver_new::previsit( … … 1780 1944 } 1781 1945 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 } 1782 1973 1783 1974
Note: See TracChangeset
for help on using the changeset viewer.