@@ -181,6 +181,13 @@ namespace clang {
181181 static void setAnonymousDeclForMerging (ASTReader &Reader, DeclContext *DC,
182182 unsigned Index, NamedDecl *D);
183183
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+
184191 // / Results from loading a RedeclarableDecl.
185192 class RedeclarableResult {
186193 Decl *MergeWith;
@@ -598,7 +605,13 @@ void ASTDeclReader::VisitDecl(Decl *D) {
598605 auto *LexicalDC = readDeclAs<DeclContext>();
599606 if (!LexicalDC)
600607 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);
602615 // Avoid calling setLexicalDeclContext() directly because it uses
603616 // Decl::getASTContext() internally which is unsafe during derialization.
604617 D->setDeclContextsImpl (MergedSemaDC ? MergedSemaDC : SemaDC, LexicalDC,
@@ -3198,36 +3211,41 @@ uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint64_t LocalOffset) {
31983211 return LocalOffset + M.GlobalBitOffset ;
31993212}
32003213
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+
32013240// / Find the context in which we should search for previous declarations when
32023241// / looking for declarations to merge.
32033242DeclContext *ASTDeclReader::getPrimaryContextForMerging (ASTReader &Reader,
32043243 DeclContext *DC) {
32053244 if (auto *ND = dyn_cast<NamespaceDecl>(DC))
32063245 return ND->getOriginalNamespace ();
32073246
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);
32313249
32323250 if (auto *RD = dyn_cast<RecordDecl>(DC))
32333251 return RD->getDefinition ();
0 commit comments