Skip to content

Commit 2818867

Browse files
committed
Use mechanism for deserializing related decl
1 parent a91a49b commit 2818867

File tree

7 files changed

+46
-58
lines changed

7 files changed

+46
-58
lines changed

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -724,11 +724,9 @@ enum ASTRecordTypes {
724724
/// Record code for vtables to emit.
725725
VTABLES_TO_EMIT = 70,
726726

727-
/// Record code for the FunctionDecl to lambdas mapping. These lambdas have to
728-
/// be loaded right after the function they belong to. It is required to have
729-
/// canonical declaration for the lambda class from the same module as
730-
/// enclosing function.
731-
FUNCTION_DECL_TO_LAMBDAS_MAP = 71,
727+
/// Record code for related declarations that have to be deserialized together
728+
/// from the same module.
729+
RELATED_DECLS_MAP = 71,
732730

733731
/// Record code for Sema's vector of functions/blocks with effects to
734732
/// be verified.

clang/include/clang/Serialization/ASTReader.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -537,17 +537,14 @@ class ASTReader
537537
/// namespace as if it is not delayed.
538538
DelayedNamespaceOffsetMapTy DelayedNamespaceOffsetMap;
539539

540-
/// Mapping from FunctionDecl IDs to the corresponding lambda IDs.
541-
///
542-
/// These lambdas have to be loaded right after the function they belong to.
543-
/// It is required to have canonical declaration for lambda class from the
544-
/// same module as enclosing function. This is required to correctly resolve
545-
/// captured variables in the lambda. Without this, due to lazy
546-
/// deserialization, canonical declarations for the function and lambdas can
547-
/// be selected from different modules and DeclRefExprs may refer to the AST
548-
/// nodes that don't exist in the function.
549-
llvm::DenseMap<GlobalDeclID, SmallVector<GlobalDeclID, 4>>
550-
FunctionToLambdasMap;
540+
/// Mapping from main decl ID to the related decls IDs.
541+
///
542+
/// These related decls have to be loaded right after the main decl.
543+
/// It is required to have canonical declaration for related decls from the
544+
/// same module as the enclosing main decl. Without this, due to lazy
545+
/// deserialization, canonical declarations for the main decl and related can
546+
/// be selected from different modules.
547+
llvm::DenseMap<GlobalDeclID, SmallVector<GlobalDeclID, 4>> RelatedDeclsMap;
551548

552549
struct PendingUpdateRecord {
553550
Decl *D;

clang/include/clang/Serialization/ASTWriter.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,12 @@ class ASTWriter : public ASTDeserializationListener,
230230
/// instead of comparing the result of `getDeclID()` or `GetDeclRef()`.
231231
llvm::SmallPtrSet<const Decl *, 32> PredefinedDecls;
232232

233-
/// Mapping from FunctionDecl ID to the list of lambda IDs inside the
234-
/// function.
233+
/// Mapping from the main decl to related decls inside the main decls.
235234
///
236-
/// These lambdas have to be loaded right after the function they belong to.
237-
/// In order to have canonical declaration for lambda class from the same
238-
/// module as enclosing function during deserialization.
239-
llvm::DenseMap<LocalDeclID, SmallVector<LocalDeclID, 4>> FunctionToLambdasMap;
235+
/// These related decls have to be loaded right after the main decl they
236+
/// belong to. In order to have canonical declaration for related decls from
237+
/// the same module as the main decl during deserialization.
238+
llvm::DenseMap<LocalDeclID, SmallVector<LocalDeclID, 4>> RelatedDeclsMap;
240239

241240
/// Offset of each declaration in the bitstream, indexed by
242241
/// the declaration's ID.

clang/lib/Serialization/ASTReader.cpp

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3963,14 +3963,14 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
39633963
break;
39643964
}
39653965

3966-
case FUNCTION_DECL_TO_LAMBDAS_MAP:
3966+
case RELATED_DECLS_MAP:
39673967
for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) {
39683968
GlobalDeclID ID = ReadDeclID(F, Record, I);
3969-
auto &Lambdas = FunctionToLambdasMap[ID];
3969+
auto &RelatedDecls = RelatedDeclsMap[ID];
39703970
unsigned NN = Record[I++];
3971-
Lambdas.reserve(NN);
3971+
RelatedDecls.reserve(NN);
39723972
for (unsigned II = 0; II < NN; II++)
3973-
Lambdas.push_back(ReadDeclID(F, Record, I));
3973+
RelatedDecls.push_back(ReadDeclID(F, Record, I));
39743974
}
39753975
break;
39763976

@@ -10278,22 +10278,6 @@ void ASTReader::finishPendingActions() {
1027810278
PBEnd = PendingBodies.end();
1027910279
PB != PBEnd; ++PB) {
1028010280
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PB->first)) {
10281-
// For a function defined inline within a class template, force the
10282-
// canonical definition to be the one inside the canonical definition of
10283-
// the template. This ensures that we instantiate from a correct view
10284-
// of the template. This behaviour seems to be important only for inline
10285-
// friend functions. For normal member functions, it might results in
10286-
// selecting canonical decl from module A but body from module B.
10287-
//
10288-
// Sadly we can't do this more generally: we can't be sure that all
10289-
// copies of an arbitrary class definition will have the same members
10290-
// defined (eg, some member functions may not be instantiated, and some
10291-
// special members may or may not have been implicitly defined).
10292-
if (FD->getFriendObjectKind())
10293-
if (auto *RD = dyn_cast<CXXRecordDecl>(FD->getLexicalParent()))
10294-
if (RD->isDependentContext() && !RD->isThisDeclarationADefinition())
10295-
continue;
10296-
1029710281
// FIXME: Check for =delete/=default?
1029810282
const FunctionDecl *Defn = nullptr;
1029910283
if (!getContext().getLangOpts().Modules || !FD->hasBody(Defn)) {

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4329,13 +4329,12 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
43294329
DC->setHasExternalVisibleStorage(true);
43304330
}
43314331

4332-
// Load any pending lambdas for the function.
4333-
if (auto *FD = dyn_cast<FunctionDecl>(D); FD && FD->isCanonicalDecl()) {
4334-
if (auto IT = FunctionToLambdasMap.find(ID);
4335-
IT != FunctionToLambdasMap.end()) {
4332+
// Load any pending related decls.
4333+
if (D->isCanonicalDecl()) {
4334+
if (auto IT = RelatedDeclsMap.find(ID); IT != RelatedDeclsMap.end()) {
43364335
for (auto LID : IT->second)
43374336
GetDecl(LID);
4338-
FunctionToLambdasMap.erase(IT);
4337+
RelatedDeclsMap.erase(IT);
43394338
}
43404339
}
43414340

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@ void ASTWriter::WriteBlockInfoBlock() {
941941
RECORD(PENDING_IMPLICIT_INSTANTIATIONS);
942942
RECORD(UPDATE_VISIBLE);
943943
RECORD(DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD);
944-
RECORD(FUNCTION_DECL_TO_LAMBDAS_MAP);
944+
RECORD(RELATED_DECLS_MAP);
945945
RECORD(DECL_UPDATE_OFFSETS);
946946
RECORD(DECL_UPDATES);
947947
RECORD(CUDA_SPECIAL_DECL_REFS);
@@ -5972,23 +5972,23 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
59725972
Stream.EmitRecord(DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD,
59735973
DelayedNamespaceRecord);
59745974

5975-
if (!FunctionToLambdasMap.empty()) {
5976-
// TODO: on disk hash table for function to lambda mapping might be more
5975+
if (!RelatedDeclsMap.empty()) {
5976+
// TODO: on disk hash table for related decls mapping might be more
59775977
// efficent becuase it allows lazy deserialization.
5978-
RecordData FunctionToLambdasMapRecord;
5979-
for (const auto &Pair : FunctionToLambdasMap) {
5980-
FunctionToLambdasMapRecord.push_back(Pair.first.getRawValue());
5981-
FunctionToLambdasMapRecord.push_back(Pair.second.size());
5978+
RecordData RelatedDeclsMapRecord;
5979+
for (const auto &Pair : RelatedDeclsMap) {
5980+
RelatedDeclsMapRecord.push_back(Pair.first.getRawValue());
5981+
RelatedDeclsMapRecord.push_back(Pair.second.size());
59825982
for (const auto &Lambda : Pair.second)
5983-
FunctionToLambdasMapRecord.push_back(Lambda.getRawValue());
5983+
RelatedDeclsMapRecord.push_back(Lambda.getRawValue());
59845984
}
59855985

59865986
auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
5987-
Abv->Add(llvm::BitCodeAbbrevOp(FUNCTION_DECL_TO_LAMBDAS_MAP));
5987+
Abv->Add(llvm::BitCodeAbbrevOp(RELATED_DECLS_MAP));
59885988
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array));
59895989
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
59905990
unsigned FunctionToLambdaMapAbbrev = Stream.EmitAbbrev(std::move(Abv));
5991-
Stream.EmitRecord(FUNCTION_DECL_TO_LAMBDAS_MAP, FunctionToLambdasMapRecord,
5991+
Stream.EmitRecord(RELATED_DECLS_MAP, RelatedDeclsMapRecord,
59925992
FunctionToLambdaMapAbbrev);
59935993
}
59945994

clang/lib/Serialization/ASTWriterDecl.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,17 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
798798
}
799799
}
800800

801+
if (D->getFriendObjectKind()) {
802+
// For a function defined inline within a class template, we have to force
803+
// the canonical definition to be the one inside the canonical definition of
804+
// the template. Remember this relation to deserialize them together.
805+
if (auto *RD = dyn_cast<CXXRecordDecl>(D->getLexicalParent()))
806+
if (RD->isDependentContext() && RD->isThisDeclarationADefinition()) {
807+
Writer.RelatedDeclsMap[Writer.GetDeclRef(RD)].push_back(
808+
Writer.GetDeclRef(D));
809+
}
810+
}
811+
801812
Record.push_back(D->param_size());
802813
for (auto *P : D->parameters())
803814
Record.AddDeclRef(P);
@@ -1563,7 +1574,7 @@ void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
15631574
// For lambdas inside canonical FunctionDecl remember the mapping.
15641575
if (auto FD = llvm::dyn_cast_or_null<FunctionDecl>(D->getDeclContext());
15651576
FD && FD->isCanonicalDecl()) {
1566-
Writer.FunctionToLambdasMap[Writer.GetDeclRef(FD)].push_back(
1577+
Writer.RelatedDeclsMap[Writer.GetDeclRef(FD)].push_back(
15671578
Writer.GetDeclRef(D));
15681579
}
15691580
} else {

0 commit comments

Comments
 (0)