@@ -2740,6 +2740,7 @@ class DeclDeserializer {
2740
2740
2741
2741
DeclAttribute *DAttrs = nullptr ;
2742
2742
DeclAttribute **AttrsNext = &DAttrs;
2743
+ SmallVector<serialization::BitOffset> customAttrOffsets;
2743
2744
2744
2745
Identifier privateDiscriminator;
2745
2746
unsigned localDiscriminator = 0 ;
@@ -2828,8 +2829,15 @@ class DeclDeserializer {
2828
2829
2829
2830
// / Deserializes records common to all decls from \c MF.DeclTypesCursor (ie.
2830
2831
// / the invalid flag, attributes, and discriminators)
2832
+ // /
2833
+ // / Reads all attributes except for custom attributes that are skipped and
2834
+ // / their offsets added to \c customAttrOffsets.
2831
2835
llvm::Error deserializeDeclCommon ();
2832
2836
2837
+ // / Deserializes the custom attributes from \c MF.DeclTypesCursor, using the
2838
+ // / offsets in \c customAttrOffsets.
2839
+ llvm::Error deserializeCustomAttrs ();
2840
+
2833
2841
Expected<Decl *> getDeclCheckedImpl (
2834
2842
llvm::function_ref<bool (DeclAttributes)> matchAttributes = nullptr);
2835
2843
@@ -4776,13 +4784,67 @@ DeclDeserializer::readAvailable_DECL_ATTR(SmallVectorImpl<uint64_t> &scratch,
4776
4784
return attr;
4777
4785
}
4778
4786
4787
+ llvm::Error DeclDeserializer::deserializeCustomAttrs () {
4788
+ using namespace decls_block ;
4789
+
4790
+ SmallVector<uint64_t , 64 > scratch;
4791
+ StringRef blobData;
4792
+ for (auto attrOffset : customAttrOffsets) {
4793
+ if (auto error =
4794
+ MF.diagnoseFatalIfNotSuccess (MF.DeclTypeCursor .JumpToBit (attrOffset)))
4795
+ return error;
4796
+
4797
+ llvm::BitstreamEntry entry =
4798
+ MF.fatalIfUnexpected (MF.DeclTypeCursor .advance ());
4799
+ if (entry.Kind != llvm::BitstreamEntry::Record) {
4800
+ // We don't know how to serialize decls represented by sub-blocks.
4801
+ return MF.diagnoseFatal ();
4802
+ }
4803
+
4804
+ unsigned recordID = MF.fatalIfUnexpected (
4805
+ MF.DeclTypeCursor .readRecord (entry.ID , scratch, &blobData));
4806
+ assert (recordID == decls_block::Custom_DECL_ATTR &&
4807
+ " expecting only custom attributes in deserializeCustomAttrs" );
4808
+
4809
+ bool isImplicit;
4810
+ bool isArgUnsafe;
4811
+ TypeID typeID;
4812
+ serialization::decls_block::CustomDeclAttrLayout::readRecord (
4813
+ scratch, isImplicit, typeID, isArgUnsafe);
4814
+
4815
+ Expected<Type> deserialized = MF.getTypeChecked (typeID);
4816
+ if (!deserialized) {
4817
+ if (deserialized.errorIsA <XRefNonLoadedModuleError>() ||
4818
+ MF.allowCompilerErrors ()) {
4819
+ // A custom attribute defined behind an implementation-only import
4820
+ // is safe to drop when it can't be deserialized.
4821
+ // rdar://problem/56599179. When allowing errors we're doing a best
4822
+ // effort to create a module, so ignore in that case as well.
4823
+ consumeError (deserialized.takeError ());
4824
+ } else
4825
+ return deserialized.takeError ();
4826
+ } else if (!deserialized.get () && MF.allowCompilerErrors ()) {
4827
+ // Serialized an invalid attribute, just skip it when allowing errors
4828
+ } else {
4829
+ auto *TE = TypeExpr::createImplicit (deserialized.get (), ctx);
4830
+ auto custom = CustomAttr::create (ctx, SourceLoc (), TE, isImplicit);
4831
+ custom->setArgIsUnsafe (isArgUnsafe);
4832
+ AddAttribute (custom);
4833
+ }
4834
+ scratch.clear ();
4835
+ }
4836
+
4837
+ return llvm::Error::success ();
4838
+ }
4839
+
4779
4840
llvm::Error DeclDeserializer::deserializeDeclCommon () {
4780
4841
using namespace decls_block ;
4781
4842
4782
4843
SmallVector<uint64_t , 64 > scratch;
4783
4844
StringRef blobData;
4784
4845
while (true ) {
4785
4846
BCOffsetRAII restoreOffset (MF.DeclTypeCursor );
4847
+ serialization::BitOffset attrOffset = MF.DeclTypeCursor .GetCurrentBitNo ();
4786
4848
llvm::BitstreamEntry entry =
4787
4849
MF.fatalIfUnexpected (MF.DeclTypeCursor .advance ());
4788
4850
if (entry.Kind != llvm::BitstreamEntry::Record) {
@@ -5074,33 +5136,10 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() {
5074
5136
}
5075
5137
5076
5138
case decls_block::Custom_DECL_ATTR: {
5077
- bool isImplicit;
5078
- bool isArgUnsafe;
5079
- TypeID typeID;
5080
- serialization::decls_block::CustomDeclAttrLayout::readRecord (
5081
- scratch, isImplicit, typeID, isArgUnsafe);
5082
-
5083
- Expected<Type> deserialized = MF.getTypeChecked (typeID);
5084
- if (!deserialized) {
5085
- if (deserialized.errorIsA <XRefNonLoadedModuleError>() ||
5086
- MF.allowCompilerErrors ()) {
5087
- // A custom attribute defined behind an implementation-only import
5088
- // is safe to drop when it can't be deserialized.
5089
- // rdar://problem/56599179. When allowing errors we're doing a best
5090
- // effort to create a module, so ignore in that case as well.
5091
- consumeError (deserialized.takeError ());
5092
- skipAttr = true ;
5093
- } else
5094
- return deserialized.takeError ();
5095
- } else if (!deserialized.get () && MF.allowCompilerErrors ()) {
5096
- // Serialized an invalid attribute, just skip it when allowing errors
5097
- skipAttr = true ;
5098
- } else {
5099
- auto *TE = TypeExpr::createImplicit (deserialized.get (), ctx);
5100
- auto custom = CustomAttr::create (ctx, SourceLoc (), TE, isImplicit);
5101
- custom->setArgIsUnsafe (isArgUnsafe);
5102
- Attr = custom;
5103
- }
5139
+ // Deserialize the custom attributes after the attached decl,
5140
+ // skip for now.
5141
+ customAttrOffsets.push_back (attrOffset);
5142
+ skipAttr = true ;
5104
5143
break ;
5105
5144
}
5106
5145
@@ -5389,16 +5428,19 @@ DeclDeserializer::getDeclCheckedImpl(
5389
5428
switch (recordID) {
5390
5429
#define CASE (RECORD_NAME ) \
5391
5430
case decls_block::RECORD_NAME##Layout::Code: {\
5392
- auto decl = deserialize##RECORD_NAME (scratch, blobData); \
5393
- if (decl ) { \
5431
+ auto declOrError = deserialize##RECORD_NAME (scratch, blobData); \
5432
+ if (declOrError ) { \
5394
5433
/* \
5395
5434
// Set original declaration and parameter indices in `@differentiable` \
5396
5435
// attributes. \
5397
5436
*/ \
5398
5437
setOriginalDeclarationAndParameterIndicesInDifferentiableAttributes (\
5399
- decl .get (), DAttrs, diffAttrParamIndicesMap); \
5438
+ declOrError .get (), DAttrs, diffAttrParamIndicesMap); \
5400
5439
} \
5401
- return decl; \
5440
+ if (!declOrError) \
5441
+ return declOrError; \
5442
+ declOrOffset = declOrError.get (); \
5443
+ break ; \
5402
5444
}
5403
5445
5404
5446
CASE (TypeAlias)
@@ -5432,15 +5474,21 @@ DeclDeserializer::getDeclCheckedImpl(
5432
5474
uint32_t pathLen;
5433
5475
decls_block::XRefLayout::readRecord (scratch, baseModuleID, pathLen);
5434
5476
auto resolved = MF.resolveCrossReference (baseModuleID, pathLen);
5435
- if (resolved)
5436
- declOrOffset = resolved.get ();
5437
- return resolved;
5477
+ if (!resolved)
5478
+ return resolved;
5479
+ declOrOffset = resolved.get ();
5480
+ break ;
5438
5481
}
5439
5482
5440
5483
default :
5441
5484
// We don't know how to deserialize this kind of decl.
5442
5485
MF.fatal (llvm::make_error<InvalidRecordKindError>(recordID));
5443
5486
}
5487
+
5488
+ auto attrError = deserializeCustomAttrs ();
5489
+ if (attrError)
5490
+ return std::move (attrError);
5491
+ return declOrOffset;
5444
5492
}
5445
5493
5446
5494
// / Translate from the Serialization function type repr enum values to the AST
0 commit comments