@@ -37,6 +37,7 @@ STATISTIC(NumNestedTypeShortcuts,
37
37
38
38
using namespace swift ;
39
39
using namespace swift ::serialization;
40
+ using llvm::Expected;
40
41
41
42
StringRef swift::getNameOfModule (const ModuleFile *MF) {
42
43
return MF->Name ;
@@ -1298,8 +1299,8 @@ static void filterValues(Type expectedTy, ModuleDecl *expectedModule,
1298
1299
values.erase (newEnd, values.end ());
1299
1300
}
1300
1301
1301
- Decl *ModuleFile::resolveCrossReference (ModuleDecl *baseModule,
1302
- uint32_t pathLen) {
1302
+ Expected< Decl *>
1303
+ ModuleFile::resolveCrossReference (ModuleDecl *baseModule, uint32_t pathLen) {
1303
1304
using namespace decls_block ;
1304
1305
assert (baseModule && " missing dependency" );
1305
1306
PrettyXRefTrace pathTrace (*baseModule);
@@ -1420,8 +1421,9 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
1420
1421
}
1421
1422
1422
1423
if (values.empty ()) {
1423
- error ();
1424
- return nullptr ;
1424
+ return llvm::make_error<llvm::StringError>(
1425
+ " top-level value not found" ,
1426
+ std::error_code (EINVAL, std::generic_category ()));
1425
1427
}
1426
1428
1427
1429
// Filters for values discovered in the remaining path pieces.
@@ -1540,16 +1542,18 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
1540
1542
pathTrace.addType (filterTy);
1541
1543
1542
1544
if (values.size () != 1 ) {
1543
- error ();
1544
- return nullptr ;
1545
+ return llvm::make_error<llvm::StringError>(
1546
+ " multiple matching base values" ,
1547
+ std::error_code (EINVAL, std::generic_category ()));
1545
1548
}
1546
1549
1547
1550
auto nominal = dyn_cast<NominalTypeDecl>(values.front ());
1548
1551
values.clear ();
1549
1552
1550
1553
if (!nominal) {
1551
- error ();
1552
- return nullptr ;
1554
+ return llvm::make_error<llvm::StringError>(
1555
+ " base is not a nominal type" ,
1556
+ std::error_code (EINVAL, std::generic_category ()));
1553
1557
}
1554
1558
1555
1559
auto members = nominal->lookupDirect (memberName);
@@ -1638,8 +1642,9 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
1638
1642
1639
1643
case XREF_GENERIC_PARAM_PATH_PIECE: {
1640
1644
if (values.size () != 1 ) {
1641
- error ();
1642
- return nullptr ;
1645
+ return llvm::make_error<llvm::StringError>(
1646
+ " multiple matching base values" ,
1647
+ std::error_code (EINVAL, std::generic_category ()));
1643
1648
}
1644
1649
1645
1650
uint32_t paramIndex;
@@ -1672,9 +1677,15 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
1672
1677
} else if (auto fn = dyn_cast<AbstractFunctionDecl>(base))
1673
1678
paramList = fn->getGenericParams ();
1674
1679
1675
- if (!paramList || paramIndex >= paramList->size ()) {
1676
- error ();
1677
- return nullptr ;
1680
+ if (!paramList) {
1681
+ return llvm::make_error<llvm::StringError>(
1682
+ " cross-reference to generic param for non-generic type" ,
1683
+ std::error_code (EINVAL, std::generic_category ()));
1684
+ }
1685
+ if (paramIndex >= paramList->size ()) {
1686
+ return llvm::make_error<llvm::StringError>(
1687
+ " generic argument index out of bounds" ,
1688
+ std::error_code (EINVAL, std::generic_category ()));
1678
1689
}
1679
1690
1680
1691
values.clear ();
@@ -1698,8 +1709,9 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
1698
1709
}
1699
1710
1700
1711
if (values.empty ()) {
1701
- error ();
1702
- return nullptr ;
1712
+ return llvm::make_error<llvm::StringError>(
1713
+ " result not found" ,
1714
+ std::error_code (EINVAL, std::generic_category ()));
1703
1715
}
1704
1716
1705
1717
// Reset the module filter.
@@ -1718,8 +1730,9 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
1718
1730
1719
1731
// When all is said and done, we should have a single value here to return.
1720
1732
if (values.size () != 1 ) {
1721
- error ();
1722
- return nullptr ;
1733
+ return llvm::make_error<llvm::StringError>(
1734
+ " result is ambiguous" ,
1735
+ std::error_code (EINVAL, std::generic_category ()));
1723
1736
}
1724
1737
1725
1738
return values.front ();
@@ -2141,6 +2154,16 @@ static uint64_t encodeLazyConformanceContextData(uint64_t numProtocols,
2141
2154
}
2142
2155
2143
2156
Decl *ModuleFile::getDecl (DeclID DID, Optional<DeclContext *> ForcedContext) {
2157
+ Expected<Decl *> deserialized = getDeclChecked (DID, ForcedContext);
2158
+ if (!deserialized) {
2159
+ error ();
2160
+ return nullptr ;
2161
+ }
2162
+ return deserialized.get ();
2163
+ }
2164
+
2165
+ Expected<Decl *>
2166
+ ModuleFile::getDeclChecked (DeclID DID, Optional<DeclContext *> ForcedContext) {
2144
2167
if (DID == 0 )
2145
2168
return nullptr ;
2146
2169
@@ -3542,7 +3565,10 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
3542
3565
ModuleID baseModuleID;
3543
3566
uint32_t pathLen;
3544
3567
decls_block::XRefLayout::readRecord (scratch, baseModuleID, pathLen);
3545
- declOrOffset = resolveCrossReference (getModule (baseModuleID), pathLen);
3568
+ auto resolved = resolveCrossReference (getModule (baseModuleID), pathLen);
3569
+ if (!resolved)
3570
+ return resolved;
3571
+ declOrOffset = resolved.get ();
3546
3572
break ;
3547
3573
}
3548
3574
@@ -3657,6 +3683,15 @@ Optional<swift::ResultConvention> getActualResultConvention(uint8_t raw) {
3657
3683
}
3658
3684
3659
3685
Type ModuleFile::getType (TypeID TID) {
3686
+ Expected<Type> deserialized = getTypeChecked (TID);
3687
+ if (!deserialized) {
3688
+ error ();
3689
+ return Type ();
3690
+ }
3691
+ return deserialized.get ();
3692
+ }
3693
+
3694
+ Expected<Type> ModuleFile::getTypeChecked (TypeID TID) {
3660
3695
if (TID == 0 )
3661
3696
return Type ();
3662
3697
0 commit comments