13
13
#include " swift/Serialization/ModuleFile.h"
14
14
#include " swift/Serialization/ModuleFormat.h"
15
15
#include " swift/AST/ASTContext.h"
16
+ #include " swift/AST/DiagnosticsSema.h"
16
17
#include " swift/AST/ForeignErrorConvention.h"
17
18
#include " swift/AST/GenericEnvironment.h"
18
19
#include " swift/AST/Initializer.h"
@@ -95,7 +96,7 @@ namespace {
95
96
}
96
97
};
97
98
98
- class PrettyXRefTrace : public llvm ::PrettyStackTraceEntry {
99
+ class XRefTracePath {
99
100
class PathPiece {
100
101
public:
101
102
enum class Kind {
@@ -196,12 +197,11 @@ namespace {
196
197
}
197
198
};
198
199
199
- private:
200
200
ModuleDecl &baseM;
201
201
SmallVector<PathPiece, 8 > path;
202
202
203
203
public:
204
- PrettyXRefTrace (ModuleDecl &M) : baseM(M) {}
204
+ explicit XRefTracePath (ModuleDecl &M) : baseM(M) {}
205
205
206
206
void addValue (Identifier name) {
207
207
path.push_back ({ PathPiece::Kind::Value, name });
@@ -241,16 +241,27 @@ namespace {
241
241
path.pop_back ();
242
242
}
243
243
244
- void print (raw_ostream &os) const override {
244
+ void print (raw_ostream &os, StringRef leading = " " ) const {
245
245
os << " Cross-reference to module '" << baseM.getName () << " '\n " ;
246
246
for (auto &piece : path) {
247
- os << " \t ... " ;
247
+ os << leading << " ... " ;
248
248
piece.print (os);
249
249
os << " \n " ;
250
250
}
251
251
}
252
252
};
253
253
254
+ class PrettyXRefTrace :
255
+ public llvm::PrettyStackTraceEntry,
256
+ public XRefTracePath {
257
+ public:
258
+ explicit PrettyXRefTrace (ModuleDecl &M) : XRefTracePath(M) {}
259
+
260
+ void print (raw_ostream &os) const override {
261
+ XRefTracePath::print (os, " \t " );
262
+ }
263
+ };
264
+
254
265
class PrettyStackTraceModuleFile : public llvm ::PrettyStackTraceEntry {
255
266
const char *Action;
256
267
const ModuleFile *MF;
@@ -262,6 +273,30 @@ namespace {
262
273
os << Action << " \' " << getNameOfModule (MF) << " '\n " ;
263
274
}
264
275
};
276
+
277
+ class XRefError : public llvm ::ErrorInfo<XRefError> {
278
+ friend ErrorInfo;
279
+ static const char ID;
280
+
281
+ XRefTracePath path;
282
+ const char *message;
283
+ public:
284
+ template <size_t N>
285
+ XRefError (const char (&message)[N], XRefTracePath path)
286
+ : path(path), message(message) {}
287
+
288
+ void log (raw_ostream &OS) const override {
289
+ OS << message << " \n " ;
290
+ path.print (OS);
291
+ }
292
+
293
+ std::error_code convertToErrorCode () const override {
294
+ // This is a deprecated part of llvm::Error, so we just return a very
295
+ // generic value.
296
+ return {EINVAL, std::generic_category ()};
297
+ }
298
+ };
299
+ const char XRefError::ID = ' \0 ' ;
265
300
} // end anonymous namespace
266
301
267
302
@@ -286,6 +321,17 @@ static bool skipRecord(llvm::BitstreamCursor &cursor, unsigned recordKind) {
286
321
#endif
287
322
}
288
323
324
+ void ModuleFile::fatal (llvm::Error error) {
325
+ if (FileContext) {
326
+ getContext ().Diags .diagnose (SourceLoc (), diag::serialization_fatal, Name);
327
+ }
328
+
329
+ logAllUnhandledErrors (std::move (error), llvm::errs (),
330
+ " \n *** DESERIALIZATION FAILURE (please include this "
331
+ " section in any bug report) ***\n " );
332
+ abort ();
333
+ }
334
+
289
335
ModuleFile &ModuleFile::getModuleFileForDelayedActions () {
290
336
assert (FileContext && " cannot delay actions before associating with a file" );
291
337
ModuleDecl *associatedModule = getAssociatedModule ();
@@ -1421,9 +1467,7 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
1421
1467
}
1422
1468
1423
1469
if (values.empty ()) {
1424
- return llvm::make_error<llvm::StringError>(
1425
- " top-level value not found" ,
1426
- std::error_code (EINVAL, std::generic_category ()));
1470
+ return llvm::make_error<XRefError>(" top-level value not found" , pathTrace);
1427
1471
}
1428
1472
1429
1473
// Filters for values discovered in the remaining path pieces.
@@ -1542,18 +1586,16 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
1542
1586
pathTrace.addType (filterTy);
1543
1587
1544
1588
if (values.size () != 1 ) {
1545
- return llvm::make_error<llvm::StringError>(
1546
- " multiple matching base values" ,
1547
- std::error_code (EINVAL, std::generic_category ()));
1589
+ return llvm::make_error<XRefError>(" multiple matching base values" ,
1590
+ pathTrace);
1548
1591
}
1549
1592
1550
1593
auto nominal = dyn_cast<NominalTypeDecl>(values.front ());
1551
1594
values.clear ();
1552
1595
1553
1596
if (!nominal) {
1554
- return llvm::make_error<llvm::StringError>(
1555
- " base is not a nominal type" ,
1556
- std::error_code (EINVAL, std::generic_category ()));
1597
+ return llvm::make_error<XRefError>(" base is not a nominal type" ,
1598
+ pathTrace);
1557
1599
}
1558
1600
1559
1601
auto members = nominal->lookupDirect (memberName);
@@ -1642,9 +1684,8 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
1642
1684
1643
1685
case XREF_GENERIC_PARAM_PATH_PIECE: {
1644
1686
if (values.size () != 1 ) {
1645
- return llvm::make_error<llvm::StringError>(
1646
- " multiple matching base values" ,
1647
- std::error_code (EINVAL, std::generic_category ()));
1687
+ return llvm::make_error<XRefError>(" multiple matching base values" ,
1688
+ pathTrace);
1648
1689
}
1649
1690
1650
1691
uint32_t paramIndex;
@@ -1678,14 +1719,14 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
1678
1719
paramList = fn->getGenericParams ();
1679
1720
1680
1721
if (!paramList) {
1681
- return llvm::make_error<llvm::StringError >(
1722
+ return llvm::make_error<XRefError >(
1682
1723
" cross-reference to generic param for non-generic type" ,
1683
- std::error_code (EINVAL, std::generic_category ()) );
1724
+ pathTrace );
1684
1725
}
1685
1726
if (paramIndex >= paramList->size ()) {
1686
- return llvm::make_error<llvm::StringError >(
1727
+ return llvm::make_error<XRefError >(
1687
1728
" generic argument index out of bounds" ,
1688
- std::error_code (EINVAL, std::generic_category ()) );
1729
+ pathTrace );
1689
1730
}
1690
1731
1691
1732
values.clear ();
@@ -1709,9 +1750,7 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
1709
1750
}
1710
1751
1711
1752
if (values.empty ()) {
1712
- return llvm::make_error<llvm::StringError>(
1713
- " result not found" ,
1714
- std::error_code (EINVAL, std::generic_category ()));
1753
+ return llvm::make_error<XRefError>(" result not found" , pathTrace);
1715
1754
}
1716
1755
1717
1756
// Reset the module filter.
@@ -2156,8 +2195,7 @@ static uint64_t encodeLazyConformanceContextData(uint64_t numProtocols,
2156
2195
Decl *ModuleFile::getDecl (DeclID DID, Optional<DeclContext *> ForcedContext) {
2157
2196
Expected<Decl *> deserialized = getDeclChecked (DID, ForcedContext);
2158
2197
if (!deserialized) {
2159
- error ();
2160
- return nullptr ;
2198
+ fatal (deserialized.takeError ());
2161
2199
}
2162
2200
return deserialized.get ();
2163
2201
}
@@ -3685,8 +3723,7 @@ Optional<swift::ResultConvention> getActualResultConvention(uint8_t raw) {
3685
3723
Type ModuleFile::getType (TypeID TID) {
3686
3724
Expected<Type> deserialized = getTypeChecked (TID);
3687
3725
if (!deserialized) {
3688
- error ();
3689
- return Type ();
3726
+ fatal (deserialized.takeError ());
3690
3727
}
3691
3728
return deserialized.get ();
3692
3729
}
0 commit comments