@@ -2741,6 +2741,7 @@ class DeclDeserializer {
2741
2741
2742
2742
DeclAttribute *DAttrs = nullptr ;
2743
2743
DeclAttribute **AttrsNext = &DAttrs;
2744
+ SmallVector<serialization::BitOffset> customAttrOffsets;
2744
2745
2745
2746
Identifier privateDiscriminator;
2746
2747
unsigned localDiscriminator = ValueDecl::InvalidDiscriminator;
@@ -2829,8 +2830,15 @@ class DeclDeserializer {
2829
2830
2830
2831
// / Deserializes records common to all decls from \c MF.DeclTypesCursor (ie.
2831
2832
// / the invalid flag, attributes, and discriminators)
2833
+ // /
2834
+ // / Reads all attributes except for custom attributes that are skipped and
2835
+ // / their offsets added to \c customAttrOffsets.
2832
2836
llvm::Error deserializeDeclCommon ();
2833
2837
2838
+ // / Deserializes the custom attributes from \c MF.DeclTypesCursor, using the
2839
+ // / offsets in \c customAttrOffsets.
2840
+ llvm::Error deserializeCustomAttrs ();
2841
+
2834
2842
Expected<Decl *> getDeclCheckedImpl (
2835
2843
llvm::function_ref<bool (DeclAttributes)> matchAttributes = nullptr);
2836
2844
@@ -4804,13 +4812,67 @@ DeclDeserializer::readAvailable_DECL_ATTR(SmallVectorImpl<uint64_t> &scratch,
4804
4812
return attr;
4805
4813
}
4806
4814
4815
+ llvm::Error DeclDeserializer::deserializeCustomAttrs () {
4816
+ using namespace decls_block ;
4817
+
4818
+ SmallVector<uint64_t , 64 > scratch;
4819
+ StringRef blobData;
4820
+ for (auto attrOffset : customAttrOffsets) {
4821
+ if (auto error =
4822
+ MF.diagnoseFatalIfNotSuccess (MF.DeclTypeCursor .JumpToBit (attrOffset)))
4823
+ return error;
4824
+
4825
+ llvm::BitstreamEntry entry =
4826
+ MF.fatalIfUnexpected (MF.DeclTypeCursor .advance ());
4827
+ if (entry.Kind != llvm::BitstreamEntry::Record) {
4828
+ // We don't know how to serialize decls represented by sub-blocks.
4829
+ return MF.diagnoseFatal ();
4830
+ }
4831
+
4832
+ unsigned recordID = MF.fatalIfUnexpected (
4833
+ MF.DeclTypeCursor .readRecord (entry.ID , scratch, &blobData));
4834
+ assert (recordID == decls_block::Custom_DECL_ATTR &&
4835
+ " expecting only custom attributes in deserializeCustomAttrs" );
4836
+
4837
+ bool isImplicit;
4838
+ bool isArgUnsafe;
4839
+ TypeID typeID;
4840
+ serialization::decls_block::CustomDeclAttrLayout::readRecord (
4841
+ scratch, isImplicit, typeID, isArgUnsafe);
4842
+
4843
+ Expected<Type> deserialized = MF.getTypeChecked (typeID);
4844
+ if (!deserialized) {
4845
+ if (deserialized.errorIsA <XRefNonLoadedModuleError>() ||
4846
+ MF.allowCompilerErrors ()) {
4847
+ // A custom attribute defined behind an implementation-only import
4848
+ // is safe to drop when it can't be deserialized.
4849
+ // rdar://problem/56599179. When allowing errors we're doing a best
4850
+ // effort to create a module, so ignore in that case as well.
4851
+ consumeError (deserialized.takeError ());
4852
+ } else
4853
+ return deserialized.takeError ();
4854
+ } else if (!deserialized.get () && MF.allowCompilerErrors ()) {
4855
+ // Serialized an invalid attribute, just skip it when allowing errors
4856
+ } else {
4857
+ auto *TE = TypeExpr::createImplicit (deserialized.get (), ctx);
4858
+ auto custom = CustomAttr::create (ctx, SourceLoc (), TE, isImplicit);
4859
+ custom->setArgIsUnsafe (isArgUnsafe);
4860
+ AddAttribute (custom);
4861
+ }
4862
+ scratch.clear ();
4863
+ }
4864
+
4865
+ return llvm::Error::success ();
4866
+ }
4867
+
4807
4868
llvm::Error DeclDeserializer::deserializeDeclCommon () {
4808
4869
using namespace decls_block ;
4809
4870
4810
4871
SmallVector<uint64_t , 64 > scratch;
4811
4872
StringRef blobData;
4812
4873
while (true ) {
4813
4874
BCOffsetRAII restoreOffset (MF.DeclTypeCursor );
4875
+ serialization::BitOffset attrOffset = MF.DeclTypeCursor .GetCurrentBitNo ();
4814
4876
llvm::BitstreamEntry entry =
4815
4877
MF.fatalIfUnexpected (MF.DeclTypeCursor .advance ());
4816
4878
if (entry.Kind != llvm::BitstreamEntry::Record) {
@@ -5102,33 +5164,10 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() {
5102
5164
}
5103
5165
5104
5166
case decls_block::Custom_DECL_ATTR: {
5105
- bool isImplicit;
5106
- bool isArgUnsafe;
5107
- TypeID typeID;
5108
- serialization::decls_block::CustomDeclAttrLayout::readRecord (
5109
- scratch, isImplicit, typeID, isArgUnsafe);
5110
-
5111
- Expected<Type> deserialized = MF.getTypeChecked (typeID);
5112
- if (!deserialized) {
5113
- if (deserialized.errorIsA <XRefNonLoadedModuleError>() ||
5114
- MF.allowCompilerErrors ()) {
5115
- // A custom attribute defined behind an implementation-only import
5116
- // is safe to drop when it can't be deserialized.
5117
- // rdar://problem/56599179. When allowing errors we're doing a best
5118
- // effort to create a module, so ignore in that case as well.
5119
- consumeError (deserialized.takeError ());
5120
- skipAttr = true ;
5121
- } else
5122
- return deserialized.takeError ();
5123
- } else if (!deserialized.get () && MF.allowCompilerErrors ()) {
5124
- // Serialized an invalid attribute, just skip it when allowing errors
5125
- skipAttr = true ;
5126
- } else {
5127
- auto *TE = TypeExpr::createImplicit (deserialized.get (), ctx);
5128
- auto custom = CustomAttr::create (ctx, SourceLoc (), TE, isImplicit);
5129
- custom->setArgIsUnsafe (isArgUnsafe);
5130
- Attr = custom;
5131
- }
5167
+ // Deserialize the custom attributes after the attached decl,
5168
+ // skip for now.
5169
+ customAttrOffsets.push_back (attrOffset);
5170
+ skipAttr = true ;
5132
5171
break ;
5133
5172
}
5134
5173
@@ -5417,16 +5456,19 @@ DeclDeserializer::getDeclCheckedImpl(
5417
5456
switch (recordID) {
5418
5457
#define CASE (RECORD_NAME ) \
5419
5458
case decls_block::RECORD_NAME##Layout::Code: {\
5420
- auto decl = deserialize##RECORD_NAME (scratch, blobData); \
5421
- if (decl ) { \
5459
+ auto declOrError = deserialize##RECORD_NAME (scratch, blobData); \
5460
+ if (declOrError ) { \
5422
5461
/* \
5423
5462
// Set original declaration and parameter indices in `@differentiable` \
5424
5463
// attributes. \
5425
5464
*/ \
5426
5465
setOriginalDeclarationAndParameterIndicesInDifferentiableAttributes (\
5427
- decl .get (), DAttrs, diffAttrParamIndicesMap); \
5466
+ declOrError .get (), DAttrs, diffAttrParamIndicesMap); \
5428
5467
} \
5429
- return decl; \
5468
+ if (!declOrError) \
5469
+ return declOrError; \
5470
+ declOrOffset = declOrError.get (); \
5471
+ break ; \
5430
5472
}
5431
5473
5432
5474
CASE (TypeAlias)
@@ -5460,15 +5502,21 @@ DeclDeserializer::getDeclCheckedImpl(
5460
5502
uint32_t pathLen;
5461
5503
decls_block::XRefLayout::readRecord (scratch, baseModuleID, pathLen);
5462
5504
auto resolved = MF.resolveCrossReference (baseModuleID, pathLen);
5463
- if (resolved)
5464
- declOrOffset = resolved.get ();
5465
- return resolved;
5505
+ if (!resolved)
5506
+ return resolved;
5507
+ declOrOffset = resolved.get ();
5508
+ break ;
5466
5509
}
5467
5510
5468
5511
default :
5469
5512
// We don't know how to deserialize this kind of decl.
5470
5513
MF.fatal (llvm::make_error<InvalidRecordKindError>(recordID));
5471
5514
}
5515
+
5516
+ auto attrError = deserializeCustomAttrs ();
5517
+ if (attrError)
5518
+ return std::move (attrError);
5519
+ return declOrOffset;
5472
5520
}
5473
5521
5474
5522
// / Translate from the Serialization function type repr enum values to the AST
0 commit comments