@@ -442,13 +442,13 @@ StructType *TryCatch::getExcType(LLVMContext &context) {
442
442
}
443
443
444
444
GlobalVariable *TryCatch::getTypeIdxVar (Module *module,
445
- types::Type *catchType ) {
445
+ const std::string &name ) {
446
446
LLVMContext &context = module->getContext ();
447
447
auto *typeInfoType = getTypeInfoType (context);
448
448
const std::string typeVarName =
449
- " seq.typeidx." + (catchType ? catchType-> getName () : " <all>" );
449
+ " seq.typeidx." + (name. empty () ? " <all>" : name );
450
450
GlobalVariable *tidx = module->getGlobalVariable (typeVarName);
451
- int idx = catchType ? catchType-> getID () : 0 ;
451
+ int idx = types::Type:: getID (name) ;
452
452
if (!tidx)
453
453
tidx = new GlobalVariable (
454
454
*module, typeInfoType, true , GlobalValue::PrivateLinkage,
@@ -459,6 +459,11 @@ GlobalVariable *TryCatch::getTypeIdxVar(Module *module,
459
459
return tidx;
460
460
}
461
461
462
+ GlobalVariable *TryCatch::getTypeIdxVar (Module *module,
463
+ types::Type *catchType) {
464
+ return getTypeIdxVar (module, catchType ? catchType->getName () : " " );
465
+ }
466
+
462
467
void TryCatch::resolveTypes () {
463
468
scope->resolveTypes ();
464
469
for (auto *block : catchBlocks)
@@ -1352,7 +1357,7 @@ Continue *Continue::clone(Generic *ref) {
1352
1357
SEQ_RETURN_CLONE (x);
1353
1358
}
1354
1359
1355
- Assert::Assert (Expr *expr) : Stmt(" assert" ), expr(expr) {}
1360
+ Assert::Assert (Expr *expr, Expr *msg ) : Stmt(" assert" ), expr(expr), msg(msg ) {}
1356
1361
1357
1362
void Assert::resolveTypes () { expr->resolveTypes (); }
1358
1363
@@ -1365,32 +1370,47 @@ void Assert::codegen0(BasicBlock *&block) {
1365
1370
LLVMContext &context = block->getContext ();
1366
1371
Module *module = block->getModule ();
1367
1372
Function *func = block->getParent ();
1368
-
1369
1373
const bool test = isTest (getBase ());
1370
- auto *assertFail = cast<Function>(module->getOrInsertFunction (
1371
- test ? " seq_test_failed" : " seq_assert_failed" , Type::getVoidTy (context),
1372
- types::Str->getLLVMType (context), types::Int->getLLVMType (context)));
1373
- assertFail->setDoesNotThrow ();
1374
- if (!test)
1375
- assertFail->setDoesNotReturn ();
1374
+
1376
1375
Value *check = expr->codegen (getBase (), block);
1377
1376
check = expr->getType ()->boolValue (check, block, getTryCatch ());
1378
- Value *file = StrExpr (getSrcInfo ().file ).codegen (getBase (), block);
1379
- Value *line = IntExpr (getSrcInfo ().line ).codegen (getBase (), block);
1377
+
1378
+ Value *msgVal = nullptr ;
1379
+ if (msg) {
1380
+ msgVal = msg->codegen (getBase (), block);
1381
+ msgVal = msg->getType ()->strValue (msgVal, block, getTryCatch ());
1382
+ } else {
1383
+ msgVal = StrExpr (" " ).codegen (getBase (), block);
1384
+ }
1380
1385
1381
1386
BasicBlock *fail = BasicBlock::Create (context, " assert_fail" , func);
1382
1387
BasicBlock *pass = BasicBlock::Create (context, " assert_pass" , func);
1383
1388
1384
1389
IRBuilder<> builder (block);
1385
1390
check = builder.CreateTrunc (check, builder.getInt1Ty ());
1386
1391
builder.CreateCondBr (check, pass, fail);
1387
-
1388
1392
builder.SetInsertPoint (fail);
1389
- builder.CreateCall (assertFail, {file, line});
1390
- if (test)
1393
+ if (test) {
1394
+ Function *testFailed = Func::getBuiltin (" _test_failed" )->getFunc (module);
1395
+ Value *file = StrExpr (getSrcInfo ().file ).codegen (getBase (), fail);
1396
+ Value *line = IntExpr (getSrcInfo ().line ).codegen (getBase (), fail);
1397
+ builder.CreateCall (testFailed, {file, line, msgVal});
1391
1398
builder.CreateBr (pass);
1392
- else
1399
+ } else {
1400
+ Func *f = Func::getBuiltin (" _make_assert_error" );
1401
+ Function *assertExc = f->getFunc (module);
1402
+ types::Type *assertErrorType = f->getFuncType ()->getBaseType (0 );
1403
+
1404
+ Value *excVal = builder.CreateCall (assertExc, msgVal);
1405
+ ValueExpr excArg (assertErrorType, excVal);
1406
+ Throw raise (&excArg);
1407
+ raise .setBase (getBase ());
1408
+ raise .setSrcInfo (getSrcInfo ());
1409
+ raise .codegen (fail);
1410
+
1411
+ builder.SetInsertPoint (fail);
1393
1412
builder.CreateUnreachable ();
1413
+ }
1394
1414
1395
1415
block = pass;
1396
1416
}
@@ -1399,7 +1419,7 @@ Assert *Assert::clone(Generic *ref) {
1399
1419
if (ref->seenClone (this ))
1400
1420
return (Assert *)ref->getClone (this );
1401
1421
1402
- auto *x = new Assert (expr->clone (ref));
1422
+ auto *x = new Assert (expr->clone (ref), msg ? msg-> clone (ref) : msg );
1403
1423
ref->addClone (this , x);
1404
1424
Stmt::setCloneBase (x, ref);
1405
1425
SEQ_RETURN_CLONE (x);
0 commit comments