Skip to content

Commit 8ab290b

Browse files
committed
[C++20] [Modules] Makes sure internal declaration won't be found by other TU
Close #61427 And this is also helpful to implement #112294 partially. The implementation strategy mimics #122887. This patch split the internal declarations from the general lookup table so that other TU can't find the internal declarations.
1 parent 6affc18 commit 8ab290b

File tree

11 files changed

+318
-115
lines changed

11 files changed

+318
-115
lines changed

Diff for: clang/include/clang/Serialization/ASTBitCodes.h

+6
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,8 @@ enum ASTRecordTypes {
740740
CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION = 75,
741741

742742
UPDATE_MODULE_LOCAL_VISIBLE = 76,
743+
744+
UPDATE_TU_LOCAL_VISIBLE = 77,
743745
};
744746

745747
/// Record types used within a source manager block.
@@ -1340,6 +1342,10 @@ enum DeclCode {
13401342
/// only visible from DeclContext in the same module.
13411343
DECL_CONTEXT_MODULE_LOCAL_VISIBLE,
13421344

1345+
/// A record that stores the set of declarations that are only visible
1346+
/// to the TU.
1347+
DECL_CONTEXT_TU_LOCAL_VISIBLE,
1348+
13431349
/// A LabelDecl record.
13441350
DECL_LABEL,
13451351

Diff for: clang/include/clang/Serialization/ASTReader.h

+19-1
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ class ASTReader
528528
uint64_t LexicalOffset;
529529
uint64_t VisibleOffset;
530530
uint64_t ModuleLocalOffset;
531+
uint64_t TULocalOffset;
531532
};
532533

533534
using DelayedNamespaceOffsetMapTy =
@@ -640,6 +641,9 @@ class ASTReader
640641
llvm::DenseMap<const DeclContext *,
641642
serialization::reader::ModuleLocalLookupTable>
642643
ModuleLocalLookups;
644+
llvm::DenseMap<const DeclContext *,
645+
serialization::reader::DeclContextLookupTable>
646+
TULocalLookups;
643647

644648
using SpecLookupTableTy =
645649
llvm::DenseMap<const Decl *,
@@ -670,6 +674,7 @@ class ASTReader
670674
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> PendingVisibleUpdates;
671675
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates>
672676
PendingModuleLocalVisibleUpdates;
677+
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> TULocalUpdates;
673678

674679
using SpecializationsUpdate = SmallVector<UpdateData, 1>;
675680
using SpecializationsUpdateMap =
@@ -704,11 +709,17 @@ class ASTReader
704709
llvm::BitstreamCursor &Cursor,
705710
uint64_t Offset, DeclContext *DC);
706711

712+
enum class VisibleDeclContextStorageKind {
713+
GenerallyVisible,
714+
ModuleLocalVisible,
715+
TULocalVisible,
716+
};
717+
707718
/// Read the record that describes the visible contents of a DC.
708719
bool ReadVisibleDeclContextStorage(ModuleFile &M,
709720
llvm::BitstreamCursor &Cursor,
710721
uint64_t Offset, GlobalDeclID ID,
711-
bool IsModuleLocal);
722+
VisibleDeclContextStorageKind VisibleKind);
712723

713724
bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
714725
uint64_t Offset, Decl *D, bool IsPartial);
@@ -1148,6 +1159,10 @@ class ASTReader
11481159
unsigned NumModuleLocalVisibleDeclContexts = 0,
11491160
TotalModuleLocalVisibleDeclContexts = 0;
11501161

1162+
/// Number of TU Local decl contexts read/total
1163+
unsigned NumTULocalVisibleDeclContexts = 0,
1164+
TotalTULocalVisibleDeclContexts = 0;
1165+
11511166
/// Total size of modules, in bits, currently loaded
11521167
uint64_t TotalModulesSizeInBits = 0;
11531168

@@ -1463,6 +1478,9 @@ class ASTReader
14631478
const serialization::reader::ModuleLocalLookupTable *
14641479
getModuleLocalLookupTables(DeclContext *Primary) const;
14651480

1481+
const serialization::reader::DeclContextLookupTable *
1482+
getTULocalLookupTables(DeclContext *Primary) const;
1483+
14661484
/// Get the loaded specializations lookup tables for \p D,
14671485
/// if any.
14681486
serialization::reader::LazySpecializationInfoLookupTable *

Diff for: clang/include/clang/Serialization/ASTWriter.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,9 @@ class ASTWriter : public ASTDeserializationListener,
496496
/// file.
497497
unsigned NumModuleLocalDeclContexts = 0;
498498

499+
/// The number of TULocal declcontexts written to the AST file.
500+
unsigned NumTULocalDeclContexts = 0;
501+
499502
/// A mapping from each known submodule to its ID number, which will
500503
/// be a positive integer.
501504
llvm::DenseMap<const Module *, unsigned> SubmoduleIDs;
@@ -594,12 +597,14 @@ class ASTWriter : public ASTDeserializationListener,
594597
void
595598
GenerateNameLookupTable(ASTContext &Context, const DeclContext *DC,
596599
llvm::SmallVectorImpl<char> &LookupTable,
597-
llvm::SmallVectorImpl<char> &ModuleLocalLookupTable);
600+
llvm::SmallVectorImpl<char> &ModuleLocalLookupTable,
601+
llvm::SmallVectorImpl<char> &TULocalLookupTable);
598602
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context,
599603
const DeclContext *DC);
600604
void WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC,
601605
uint64_t &VisibleBlockOffset,
602-
uint64_t &ModuleLocalBlockOffset);
606+
uint64_t &ModuleLocalBlockOffset,
607+
uint64_t &TULocalBlockOffset);
603608
void WriteTypeDeclOffsets();
604609
void WriteFileDeclIDsMap();
605610
void WriteComments(ASTContext &Context);
@@ -633,8 +638,10 @@ class ASTWriter : public ASTDeserializationListener,
633638
unsigned DeclContextLexicalAbbrev = 0;
634639
unsigned DeclContextVisibleLookupAbbrev = 0;
635640
unsigned DeclModuleLocalVisibleLookupAbbrev = 0;
641+
unsigned DeclTULocalLookupAbbrev = 0;
636642
unsigned UpdateVisibleAbbrev = 0;
637643
unsigned ModuleLocalUpdateVisibleAbbrev = 0;
644+
unsigned TULocalUpdateVisibleAbbrev = 0;
638645
unsigned DeclRecordAbbrev = 0;
639646
unsigned DeclTypedefAbbrev = 0;
640647
unsigned DeclVarAbbrev = 0;

Diff for: clang/lib/Serialization/ASTReader.cpp

+74-15
Original file line numberDiff line numberDiff line change
@@ -1425,10 +1425,9 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
14251425
return false;
14261426
}
14271427

1428-
bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M,
1429-
BitstreamCursor &Cursor,
1430-
uint64_t Offset, GlobalDeclID ID,
1431-
bool IsModuleLocal) {
1428+
bool ASTReader::ReadVisibleDeclContextStorage(
1429+
ModuleFile &M, BitstreamCursor &Cursor, uint64_t Offset, GlobalDeclID ID,
1430+
ASTReader::VisibleDeclContextStorageKind VisibleKind) {
14321431
assert(Offset != 0);
14331432

14341433
SavedStreamPosition SavedPosition(Cursor);
@@ -1452,22 +1451,42 @@ bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M,
14521451
return true;
14531452
}
14541453
unsigned RecCode = MaybeRecCode.get();
1455-
if (!IsModuleLocal && RecCode != DECL_CONTEXT_VISIBLE) {
1456-
Error("Expected visible lookup table block");
1457-
return true;
1458-
}
1459-
if (IsModuleLocal && RecCode != DECL_CONTEXT_MODULE_LOCAL_VISIBLE) {
1460-
Error("Expected module local visible lookup table block");
1461-
return true;
1454+
switch (VisibleKind) {
1455+
case VisibleDeclContextStorageKind::GenerallyVisible:
1456+
if (RecCode != DECL_CONTEXT_VISIBLE) {
1457+
Error("Expected visible lookup table block");
1458+
return true;
1459+
}
1460+
break;
1461+
case VisibleDeclContextStorageKind::ModuleLocalVisible:
1462+
if (RecCode != DECL_CONTEXT_MODULE_LOCAL_VISIBLE) {
1463+
Error("Expected module local visible lookup table block");
1464+
return true;
1465+
}
1466+
break;
1467+
case VisibleDeclContextStorageKind::TULocalVisible:
1468+
if (RecCode != DECL_CONTEXT_TU_LOCAL_VISIBLE) {
1469+
Error("Expected TU local lookup table block");
1470+
return true;
1471+
}
1472+
break;
14621473
}
14631474

14641475
// We can't safely determine the primary context yet, so delay attaching the
14651476
// lookup table until we're done with recursive deserialization.
14661477
auto *Data = (const unsigned char*)Blob.data();
1467-
if (!IsModuleLocal)
1478+
switch (VisibleKind) {
1479+
case VisibleDeclContextStorageKind::GenerallyVisible:
14681480
PendingVisibleUpdates[ID].push_back(UpdateData{&M, Data});
1469-
else
1481+
break;
1482+
case VisibleDeclContextStorageKind::ModuleLocalVisible:
14701483
PendingModuleLocalVisibleUpdates[ID].push_back(UpdateData{&M, Data});
1484+
break;
1485+
case VisibleDeclContextStorageKind::TULocalVisible:
1486+
if (M.Kind == MK_MainFile)
1487+
TULocalUpdates[ID].push_back(UpdateData{&M, Data});
1488+
break;
1489+
}
14711490
return false;
14721491
}
14731492

@@ -3613,6 +3632,21 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
36133632
break;
36143633
}
36153634

3635+
case UPDATE_TU_LOCAL_VISIBLE: {
3636+
if (F.Kind != MK_MainFile)
3637+
break;
3638+
unsigned Idx = 0;
3639+
GlobalDeclID ID = ReadDeclID(F, Record, Idx);
3640+
auto *Data = (const unsigned char *)Blob.data();
3641+
TULocalUpdates[ID].push_back(UpdateData{&F, Data});
3642+
// If we've already loaded the decl, perform the updates when we finish
3643+
// loading this block.
3644+
if (Decl *D = GetExistingDecl(ID))
3645+
PendingUpdateRecords.push_back(
3646+
PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
3647+
break;
3648+
}
3649+
36163650
case CXX_ADDED_TEMPLATE_SPECIALIZATION: {
36173651
unsigned Idx = 0;
36183652
GlobalDeclID ID = ReadDeclID(F, Record, Idx);
@@ -3717,6 +3751,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
37173751
TotalLexicalDeclContexts += Record[2];
37183752
TotalVisibleDeclContexts += Record[3];
37193753
TotalModuleLocalVisibleDeclContexts += Record[4];
3754+
TotalTULocalVisibleDeclContexts += Record[5];
37203755
break;
37213756

37223757
case UNUSED_FILESCOPED_DECLS:
@@ -4002,7 +4037,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
40024037
break;
40034038

40044039
case DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD: {
4005-
if (Record.size() % 4 != 0)
4040+
if (Record.size() % 5 != 0)
40064041
return llvm::createStringError(
40074042
std::errc::illegal_byte_sequence,
40084043
"invalid DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD block in AST "
@@ -4021,9 +4056,12 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
40214056
uint64_t LocalModuleLocalOffset = Record[I++];
40224057
uint64_t ModuleLocalOffset =
40234058
LocalModuleLocalOffset ? BaseOffset + LocalModuleLocalOffset : 0;
4059+
uint64_t TULocalLocalOffset = Record[I++];
4060+
uint64_t TULocalOffset =
4061+
TULocalLocalOffset ? BaseOffset + TULocalLocalOffset : 0;
40244062

40254063
DelayedNamespaceOffsetMap[ID] = {LexicalOffset, VisibleOffset,
4026-
ModuleLocalOffset};
4064+
ModuleLocalOffset, TULocalOffset};
40274065

40284066
assert(!GetExistingDecl(ID) &&
40294067
"We shouldn't load the namespace in the front of delayed "
@@ -8471,6 +8509,15 @@ bool ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
84718509
}
84728510
}
84738511

8512+
if (auto It = TULocalLookups.find(DC); It != TULocalLookups.end()) {
8513+
++NumTULocalVisibleDeclContexts;
8514+
for (GlobalDeclID ID : It->second.Table.find(Name)) {
8515+
NamedDecl *ND = cast<NamedDecl>(GetDecl(ID));
8516+
if (ND->getDeclName() == Name && Found.insert(ND).second)
8517+
Decls.push_back(ND);
8518+
}
8519+
}
8520+
84748521
SetExternalVisibleDeclsForName(DC, Name, Decls);
84758522
return !Decls.empty();
84768523
}
@@ -8498,6 +8545,7 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
84988545

84998546
findAll(Lookups, NumVisibleDeclContextsRead);
85008547
findAll(ModuleLocalLookups, NumModuleLocalVisibleDeclContexts);
8548+
findAll(TULocalLookups, NumTULocalVisibleDeclContexts);
85018549

85028550
for (DeclsMap::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
85038551
SetExternalVisibleDeclsForName(DC, I->first, I->second);
@@ -8517,6 +8565,12 @@ ASTReader::getModuleLocalLookupTables(DeclContext *Primary) const {
85178565
return I == ModuleLocalLookups.end() ? nullptr : &I->second;
85188566
}
85198567

8568+
const serialization::reader::DeclContextLookupTable *
8569+
ASTReader::getTULocalLookupTables(DeclContext *Primary) const {
8570+
auto I = TULocalLookups.find(Primary);
8571+
return I == TULocalLookups.end() ? nullptr : &I->second;
8572+
}
8573+
85208574
serialization::reader::LazySpecializationInfoLookupTable *
85218575
ASTReader::getLoadedSpecializationsLookupTables(const Decl *D, bool IsPartial) {
85228576
assert(D->isCanonicalDecl());
@@ -8632,6 +8686,11 @@ void ASTReader::PrintStats() {
86328686
NumModuleLocalVisibleDeclContexts, TotalModuleLocalVisibleDeclContexts,
86338687
((float)NumModuleLocalVisibleDeclContexts /
86348688
TotalModuleLocalVisibleDeclContexts * 100));
8689+
if (TotalTULocalVisibleDeclContexts)
8690+
std::fprintf(stderr, " %u/%u visible declcontexts in GMF read (%f%%)\n",
8691+
NumTULocalVisibleDeclContexts, TotalTULocalVisibleDeclContexts,
8692+
((float)NumTULocalVisibleDeclContexts /
8693+
TotalTULocalVisibleDeclContexts * 100));
86358694
if (TotalNumMethodPoolEntries)
86368695
std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
86378696
NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,

Diff for: clang/lib/Serialization/ASTReaderDecl.cpp

+35-10
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> {
414414
void VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl *D);
415415

416416
void VisitDeclContext(DeclContext *DC, uint64_t &LexicalOffset,
417-
uint64_t &VisibleOffset, uint64_t &ModuleLocalOffset);
417+
uint64_t &VisibleOffset, uint64_t &ModuleLocalOffset,
418+
uint64_t &TULocalOffset);
418419

419420
template <typename T>
420421
RedeclarableResult VisitRedeclarable(Redeclarable<T> *D);
@@ -1859,7 +1860,9 @@ void ASTDeclReader::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
18591860
uint64_t LexicalOffset = 0;
18601861
uint64_t VisibleOffset = 0;
18611862
uint64_t ModuleLocalOffset = 0;
1862-
VisitDeclContext(D, LexicalOffset, VisibleOffset, ModuleLocalOffset);
1863+
uint64_t TULocalOffset = 0;
1864+
VisitDeclContext(D, LexicalOffset, VisibleOffset, ModuleLocalOffset,
1865+
TULocalOffset);
18631866
D->IsCBuffer = Record.readBool();
18641867
D->KwLoc = readSourceLocation();
18651868
D->LBraceLoc = readSourceLocation();
@@ -2770,10 +2773,12 @@ void ASTDeclReader::VisitLifetimeExtendedTemporaryDecl(
27702773

27712774
void ASTDeclReader::VisitDeclContext(DeclContext *DC, uint64_t &LexicalOffset,
27722775
uint64_t &VisibleOffset,
2773-
uint64_t &ModuleLocalOffset) {
2776+
uint64_t &ModuleLocalOffset,
2777+
uint64_t &TULocalOffset) {
27742778
LexicalOffset = ReadLocalOffset();
27752779
VisibleOffset = ReadLocalOffset();
27762780
ModuleLocalOffset = ReadLocalOffset();
2781+
TULocalOffset = ReadLocalOffset();
27772782
}
27782783

27792784
template <typename T>
@@ -3875,6 +3880,7 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
38753880
case DECL_CONTEXT_LEXICAL:
38763881
case DECL_CONTEXT_VISIBLE:
38773882
case DECL_CONTEXT_MODULE_LOCAL_VISIBLE:
3883+
case DECL_CONTEXT_TU_LOCAL_VISIBLE:
38783884
case DECL_SPECIALIZATIONS:
38793885
case DECL_PARTIAL_SPECIALIZATIONS:
38803886
llvm_unreachable("Record cannot be de-serialized with readDeclRecord");
@@ -4185,9 +4191,10 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
41854191
uint64_t LexicalOffset = 0;
41864192
uint64_t VisibleOffset = 0;
41874193
uint64_t ModuleLocalOffset = 0;
4194+
uint64_t TULocalOffset = 0;
41884195

4189-
Reader.VisitDeclContext(DC, LexicalOffset, VisibleOffset,
4190-
ModuleLocalOffset);
4196+
Reader.VisitDeclContext(DC, LexicalOffset, VisibleOffset, ModuleLocalOffset,
4197+
TULocalOffset);
41914198

41924199
// Get the lexical and visible block for the delayed namespace.
41934200
// It is sufficient to judge if ID is in DelayedNamespaceOffsetMap.
@@ -4199,18 +4206,24 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
41994206
LexicalOffset = Iter->second.LexicalOffset;
42004207
VisibleOffset = Iter->second.VisibleOffset;
42014208
ModuleLocalOffset = Iter->second.ModuleLocalOffset;
4209+
TULocalOffset = Iter->second.TULocalOffset;
42024210
}
42034211

42044212
if (LexicalOffset &&
42054213
ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, LexicalOffset, DC))
42064214
return nullptr;
4207-
if (VisibleOffset &&
4208-
ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, VisibleOffset, ID,
4209-
/*IsModuleLocal=*/false))
4215+
if (VisibleOffset && ReadVisibleDeclContextStorage(
4216+
*Loc.F, DeclsCursor, VisibleOffset, ID,
4217+
VisibleDeclContextStorageKind::GenerallyVisible))
42104218
return nullptr;
42114219
if (ModuleLocalOffset &&
4212-
ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, ModuleLocalOffset,
4213-
ID, /*IsModuleLocal=*/true))
4220+
ReadVisibleDeclContextStorage(
4221+
*Loc.F, DeclsCursor, ModuleLocalOffset, ID,
4222+
VisibleDeclContextStorageKind::ModuleLocalVisible))
4223+
return nullptr;
4224+
if (TULocalOffset && ReadVisibleDeclContextStorage(
4225+
*Loc.F, DeclsCursor, TULocalOffset, ID,
4226+
VisibleDeclContextStorageKind::TULocalVisible))
42144227
return nullptr;
42154228
}
42164229
assert(Record.getIdx() == Record.size());
@@ -4376,6 +4389,18 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
43764389
DC->setHasExternalVisibleStorage(true);
43774390
}
43784391

4392+
if (auto I = TULocalUpdates.find(ID); I != TULocalUpdates.end()) {
4393+
auto Updates = std::move(I->second);
4394+
TULocalUpdates.erase(I);
4395+
4396+
auto *DC = cast<DeclContext>(D)->getPrimaryContext();
4397+
for (const auto &Update : Updates)
4398+
TULocalLookups[DC].Table.add(
4399+
Update.Mod, Update.Data,
4400+
reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod));
4401+
DC->setHasExternalVisibleStorage(true);
4402+
}
4403+
43794404
// Load any pending related decls.
43804405
if (D->isCanonicalDecl()) {
43814406
if (auto IT = RelatedDeclsMap.find(ID); IT != RelatedDeclsMap.end()) {

0 commit comments

Comments
 (0)