Skip to content

Commit 1270392

Browse files
committed
Use mechanism for deserializing related decl
1 parent 663bf19 commit 1270392

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
@@ -725,11 +725,9 @@ enum ASTRecordTypes {
725725
/// Record code for vtables to emit.
726726
VTABLES_TO_EMIT = 70,
727727

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

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

clang/include/clang/Serialization/ASTReader.h

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

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

547544
struct PendingUpdateRecord {
548545
Decl *D;

clang/include/clang/Serialization/ASTWriter.h

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

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

244243
/// Offset of each declaration in the bitstream, indexed by
245244
/// the declaration's ID.

clang/lib/Serialization/ASTReader.cpp

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3856,14 +3856,14 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
38563856
break;
38573857
}
38583858

3859-
case FUNCTION_DECL_TO_LAMBDAS_MAP:
3859+
case RELATED_DECLS_MAP:
38603860
for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) {
38613861
GlobalDeclID ID = ReadDeclID(F, Record, I);
3862-
auto &Lambdas = FunctionToLambdasMap[ID];
3862+
auto &RelatedDecls = RelatedDeclsMap[ID];
38633863
unsigned NN = Record[I++];
3864-
Lambdas.reserve(NN);
3864+
RelatedDecls.reserve(NN);
38653865
for (unsigned II = 0; II < NN; II++)
3866-
Lambdas.push_back(ReadDeclID(F, Record, I));
3866+
RelatedDecls.push_back(ReadDeclID(F, Record, I));
38673867
}
38683868
break;
38693869

@@ -10055,22 +10055,6 @@ void ASTReader::finishPendingActions() {
1005510055
PBEnd = PendingBodies.end();
1005610056
PB != PBEnd; ++PB) {
1005710057
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PB->first)) {
10058-
// For a function defined inline within a class template, force the
10059-
// canonical definition to be the one inside the canonical definition of
10060-
// the template. This ensures that we instantiate from a correct view
10061-
// of the template. This behaviour seems to be important only for inline
10062-
// friend functions. For normal member functions, it might results in
10063-
// selecting canonical decl from module A but body from module B.
10064-
//
10065-
// Sadly we can't do this more generally: we can't be sure that all
10066-
// copies of an arbitrary class definition will have the same members
10067-
// defined (eg, some member functions may not be instantiated, and some
10068-
// special members may or may not have been implicitly defined).
10069-
if (FD->getFriendObjectKind())
10070-
if (auto *RD = dyn_cast<CXXRecordDecl>(FD->getLexicalParent()))
10071-
if (RD->isDependentContext() && !RD->isThisDeclarationADefinition())
10072-
continue;
10073-
1007410058
// FIXME: Check for =delete/=default?
1007510059
const FunctionDecl *Defn = nullptr;
1007610060
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
@@ -4352,13 +4352,12 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
43524352
DC->setHasExternalVisibleStorage(true);
43534353
}
43544354

4355-
// Load any pending lambdas for the function.
4356-
if (auto *FD = dyn_cast<FunctionDecl>(D); FD && FD->isCanonicalDecl()) {
4357-
if (auto IT = FunctionToLambdasMap.find(ID);
4358-
IT != FunctionToLambdasMap.end()) {
4355+
// Load any pending related decls.
4356+
if (D->isCanonicalDecl()) {
4357+
if (auto IT = RelatedDeclsMap.find(ID); IT != RelatedDeclsMap.end()) {
43594358
for (auto LID : IT->second)
43604359
GetDecl(LID);
4361-
FunctionToLambdasMap.erase(IT);
4360+
RelatedDeclsMap.erase(IT);
43624361
}
43634362
}
43644363
}

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ void ASTWriter::WriteBlockInfoBlock() {
903903
RECORD(PENDING_IMPLICIT_INSTANTIATIONS);
904904
RECORD(UPDATE_VISIBLE);
905905
RECORD(DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD);
906-
RECORD(FUNCTION_DECL_TO_LAMBDAS_MAP);
906+
RECORD(RELATED_DECLS_MAP);
907907
RECORD(DECL_UPDATE_OFFSETS);
908908
RECORD(DECL_UPDATES);
909909
RECORD(CUDA_SPECIAL_DECL_REFS);
@@ -5720,23 +5720,23 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
57205720
Stream.EmitRecord(DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD,
57215721
DelayedNamespaceRecord);
57225722

5723-
if (!FunctionToLambdasMap.empty()) {
5724-
// TODO: on disk hash table for function to lambda mapping might be more
5723+
if (!RelatedDeclsMap.empty()) {
5724+
// TODO: on disk hash table for related decls mapping might be more
57255725
// efficent becuase it allows lazy deserialization.
5726-
RecordData FunctionToLambdasMapRecord;
5727-
for (const auto &Pair : FunctionToLambdasMap) {
5728-
FunctionToLambdasMapRecord.push_back(Pair.first.getRawValue());
5729-
FunctionToLambdasMapRecord.push_back(Pair.second.size());
5726+
RecordData RelatedDeclsMapRecord;
5727+
for (const auto &Pair : RelatedDeclsMap) {
5728+
RelatedDeclsMapRecord.push_back(Pair.first.getRawValue());
5729+
RelatedDeclsMapRecord.push_back(Pair.second.size());
57305730
for (const auto &Lambda : Pair.second)
5731-
FunctionToLambdasMapRecord.push_back(Lambda.getRawValue());
5731+
RelatedDeclsMapRecord.push_back(Lambda.getRawValue());
57325732
}
57335733

57345734
auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
5735-
Abv->Add(llvm::BitCodeAbbrevOp(FUNCTION_DECL_TO_LAMBDAS_MAP));
5735+
Abv->Add(llvm::BitCodeAbbrevOp(RELATED_DECLS_MAP));
57365736
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array));
57375737
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
57385738
unsigned FunctionToLambdaMapAbbrev = Stream.EmitAbbrev(std::move(Abv));
5739-
Stream.EmitRecord(FUNCTION_DECL_TO_LAMBDAS_MAP, FunctionToLambdasMapRecord,
5739+
Stream.EmitRecord(RELATED_DECLS_MAP, RelatedDeclsMapRecord,
57405740
FunctionToLambdaMapAbbrev);
57415741
}
57425742

clang/lib/Serialization/ASTWriterDecl.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,17 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
761761
}
762762
}
763763

764+
if (D->getFriendObjectKind()) {
765+
// For a function defined inline within a class template, we have to force
766+
// the canonical definition to be the one inside the canonical definition of
767+
// the template. Remember this relation to deserialize them together.
768+
if (auto *RD = dyn_cast<CXXRecordDecl>(D->getLexicalParent()))
769+
if (RD->isDependentContext() && RD->isThisDeclarationADefinition()) {
770+
Writer.RelatedDeclsMap[Writer.GetDeclRef(RD)].push_back(
771+
Writer.GetDeclRef(D));
772+
}
773+
}
774+
764775
Record.push_back(D->param_size());
765776
for (auto *P : D->parameters())
766777
Record.AddDeclRef(P);
@@ -1524,7 +1535,7 @@ void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
15241535
// For lambdas inside canonical FunctionDecl remember the mapping.
15251536
if (auto FD = llvm::dyn_cast_or_null<FunctionDecl>(D->getDeclContext());
15261537
FD && FD->isCanonicalDecl()) {
1527-
Writer.FunctionToLambdasMap[Writer.GetDeclRef(FD)].push_back(
1538+
Writer.RelatedDeclsMap[Writer.GetDeclRef(FD)].push_back(
15281539
Writer.GetDeclRef(D));
15291540
}
15301541
} else {

0 commit comments

Comments
 (0)