@@ -181,6 +181,13 @@ namespace clang {
181
181
static void setAnonymousDeclForMerging (ASTReader &Reader, DeclContext *DC,
182
182
unsigned Index, NamedDecl *D);
183
183
184
+ // / Commit to a primary definition of the class RD, which is known to be
185
+ // / a definition of the class. We might not have read the definition data
186
+ // / for it yet. If we haven't then allocate placeholder definition data
187
+ // / now too.
188
+ static CXXRecordDecl *getOrFakePrimaryClassDefinition (ASTReader &Reader,
189
+ CXXRecordDecl *RD);
190
+
184
191
// / Results from loading a RedeclarableDecl.
185
192
class RedeclarableResult {
186
193
Decl *MergeWith;
@@ -598,7 +605,13 @@ void ASTDeclReader::VisitDecl(Decl *D) {
598
605
auto *LexicalDC = readDeclAs<DeclContext>();
599
606
if (!LexicalDC)
600
607
LexicalDC = SemaDC;
601
- DeclContext *MergedSemaDC = Reader.MergedDeclContexts .lookup (SemaDC);
608
+ // If the context is a class, we might not have actually merged it yet, in
609
+ // the case where the definition comes from an update record.
610
+ DeclContext *MergedSemaDC;
611
+ if (auto *RD = dyn_cast<CXXRecordDecl>(SemaDC))
612
+ MergedSemaDC = getOrFakePrimaryClassDefinition (Reader, RD);
613
+ else
614
+ MergedSemaDC = Reader.MergedDeclContexts .lookup (SemaDC);
602
615
// Avoid calling setLexicalDeclContext() directly because it uses
603
616
// Decl::getASTContext() internally which is unsafe during derialization.
604
617
D->setDeclContextsImpl (MergedSemaDC ? MergedSemaDC : SemaDC, LexicalDC,
@@ -3198,36 +3211,41 @@ uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint64_t LocalOffset) {
3198
3211
return LocalOffset + M.GlobalBitOffset ;
3199
3212
}
3200
3213
3214
+ CXXRecordDecl *
3215
+ ASTDeclReader::getOrFakePrimaryClassDefinition (ASTReader &Reader,
3216
+ CXXRecordDecl *RD) {
3217
+ // Try to dig out the definition.
3218
+ auto *DD = RD->DefinitionData ;
3219
+ if (!DD)
3220
+ DD = RD->getCanonicalDecl ()->DefinitionData ;
3221
+
3222
+ // If there's no definition yet, then DC's definition is added by an update
3223
+ // record, but we've not yet loaded that update record. In this case, we
3224
+ // commit to DC being the canonical definition now, and will fix this when
3225
+ // we load the update record.
3226
+ if (!DD) {
3227
+ DD = new (Reader.getContext ()) struct CXXRecordDecl ::DefinitionData(RD);
3228
+ RD->setCompleteDefinition (true );
3229
+ RD->DefinitionData = DD;
3230
+ RD->getCanonicalDecl ()->DefinitionData = DD;
3231
+
3232
+ // Track that we did this horrible thing so that we can fix it later.
3233
+ Reader.PendingFakeDefinitionData .insert (
3234
+ std::make_pair (DD, ASTReader::PendingFakeDefinitionKind::Fake));
3235
+ }
3236
+
3237
+ return DD->Definition ;
3238
+ }
3239
+
3201
3240
// / Find the context in which we should search for previous declarations when
3202
3241
// / looking for declarations to merge.
3203
3242
DeclContext *ASTDeclReader::getPrimaryContextForMerging (ASTReader &Reader,
3204
3243
DeclContext *DC) {
3205
3244
if (auto *ND = dyn_cast<NamespaceDecl>(DC))
3206
3245
return ND->getOriginalNamespace ();
3207
3246
3208
- if (auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
3209
- // Try to dig out the definition.
3210
- auto *DD = RD->DefinitionData ;
3211
- if (!DD)
3212
- DD = RD->getCanonicalDecl ()->DefinitionData ;
3213
-
3214
- // If there's no definition yet, then DC's definition is added by an update
3215
- // record, but we've not yet loaded that update record. In this case, we
3216
- // commit to DC being the canonical definition now, and will fix this when
3217
- // we load the update record.
3218
- if (!DD) {
3219
- DD = new (Reader.getContext ()) struct CXXRecordDecl ::DefinitionData(RD);
3220
- RD->setCompleteDefinition (true );
3221
- RD->DefinitionData = DD;
3222
- RD->getCanonicalDecl ()->DefinitionData = DD;
3223
-
3224
- // Track that we did this horrible thing so that we can fix it later.
3225
- Reader.PendingFakeDefinitionData .insert (
3226
- std::make_pair (DD, ASTReader::PendingFakeDefinitionKind::Fake));
3227
- }
3228
-
3229
- return DD->Definition ;
3230
- }
3247
+ if (auto *RD = dyn_cast<CXXRecordDecl>(DC))
3248
+ return getOrFakePrimaryClassDefinition (Reader, RD);
3231
3249
3232
3250
if (auto *RD = dyn_cast<RecordDecl>(DC))
3233
3251
return RD->getDefinition ();
0 commit comments