mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 19:06:44 +00:00
[C++20] [Modules] Makes sure internal declaration won't be found by other TU (#123059)
Close https://github.com/llvm/llvm-project/issues/61427 And this is also helpful to implement https://github.com/llvm/llvm-project/issues/112294 partially. The implementation strategy mimics https://github.com/llvm/llvm-project/pull/122887. This patch split the internal declarations from the general lookup table so that other TU can't find the internal declarations.
This commit is contained in:
parent
22637a877a
commit
fb2c9d940a
@ -740,6 +740,8 @@ enum ASTRecordTypes {
|
||||
CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION = 75,
|
||||
|
||||
UPDATE_MODULE_LOCAL_VISIBLE = 76,
|
||||
|
||||
UPDATE_TU_LOCAL_VISIBLE = 77,
|
||||
};
|
||||
|
||||
/// Record types used within a source manager block.
|
||||
@ -1340,6 +1342,10 @@ enum DeclCode {
|
||||
/// only visible from DeclContext in the same module.
|
||||
DECL_CONTEXT_MODULE_LOCAL_VISIBLE,
|
||||
|
||||
/// A record that stores the set of declarations that are only visible
|
||||
/// to the TU.
|
||||
DECL_CONTEXT_TU_LOCAL_VISIBLE,
|
||||
|
||||
/// A LabelDecl record.
|
||||
DECL_LABEL,
|
||||
|
||||
|
@ -528,6 +528,7 @@ private:
|
||||
uint64_t LexicalOffset;
|
||||
uint64_t VisibleOffset;
|
||||
uint64_t ModuleLocalOffset;
|
||||
uint64_t TULocalOffset;
|
||||
};
|
||||
|
||||
using DelayedNamespaceOffsetMapTy =
|
||||
@ -640,6 +641,9 @@ private:
|
||||
llvm::DenseMap<const DeclContext *,
|
||||
serialization::reader::ModuleLocalLookupTable>
|
||||
ModuleLocalLookups;
|
||||
llvm::DenseMap<const DeclContext *,
|
||||
serialization::reader::DeclContextLookupTable>
|
||||
TULocalLookups;
|
||||
|
||||
using SpecLookupTableTy =
|
||||
llvm::DenseMap<const Decl *,
|
||||
@ -670,6 +674,7 @@ private:
|
||||
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> PendingVisibleUpdates;
|
||||
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates>
|
||||
PendingModuleLocalVisibleUpdates;
|
||||
llvm::DenseMap<GlobalDeclID, DeclContextVisibleUpdates> TULocalUpdates;
|
||||
|
||||
using SpecializationsUpdate = SmallVector<UpdateData, 1>;
|
||||
using SpecializationsUpdateMap =
|
||||
@ -704,11 +709,17 @@ private:
|
||||
llvm::BitstreamCursor &Cursor,
|
||||
uint64_t Offset, DeclContext *DC);
|
||||
|
||||
enum class VisibleDeclContextStorageKind {
|
||||
GenerallyVisible,
|
||||
ModuleLocalVisible,
|
||||
TULocalVisible,
|
||||
};
|
||||
|
||||
/// Read the record that describes the visible contents of a DC.
|
||||
bool ReadVisibleDeclContextStorage(ModuleFile &M,
|
||||
llvm::BitstreamCursor &Cursor,
|
||||
uint64_t Offset, GlobalDeclID ID,
|
||||
bool IsModuleLocal);
|
||||
VisibleDeclContextStorageKind VisibleKind);
|
||||
|
||||
bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor,
|
||||
uint64_t Offset, Decl *D, bool IsPartial);
|
||||
@ -1148,6 +1159,10 @@ private:
|
||||
unsigned NumModuleLocalVisibleDeclContexts = 0,
|
||||
TotalModuleLocalVisibleDeclContexts = 0;
|
||||
|
||||
/// Number of TU Local decl contexts read/total
|
||||
unsigned NumTULocalVisibleDeclContexts = 0,
|
||||
TotalTULocalVisibleDeclContexts = 0;
|
||||
|
||||
/// Total size of modules, in bits, currently loaded
|
||||
uint64_t TotalModulesSizeInBits = 0;
|
||||
|
||||
@ -1481,6 +1496,9 @@ public:
|
||||
const serialization::reader::ModuleLocalLookupTable *
|
||||
getModuleLocalLookupTables(DeclContext *Primary) const;
|
||||
|
||||
const serialization::reader::DeclContextLookupTable *
|
||||
getTULocalLookupTables(DeclContext *Primary) const;
|
||||
|
||||
/// Get the loaded specializations lookup tables for \p D,
|
||||
/// if any.
|
||||
serialization::reader::LazySpecializationInfoLookupTable *
|
||||
|
@ -496,6 +496,9 @@ private:
|
||||
/// file.
|
||||
unsigned NumModuleLocalDeclContexts = 0;
|
||||
|
||||
/// The number of TULocal declcontexts written to the AST file.
|
||||
unsigned NumTULocalDeclContexts = 0;
|
||||
|
||||
/// A mapping from each known submodule to its ID number, which will
|
||||
/// be a positive integer.
|
||||
llvm::DenseMap<const Module *, unsigned> SubmoduleIDs;
|
||||
@ -594,12 +597,14 @@ private:
|
||||
void
|
||||
GenerateNameLookupTable(ASTContext &Context, const DeclContext *DC,
|
||||
llvm::SmallVectorImpl<char> &LookupTable,
|
||||
llvm::SmallVectorImpl<char> &ModuleLocalLookupTable);
|
||||
llvm::SmallVectorImpl<char> &ModuleLocalLookupTable,
|
||||
llvm::SmallVectorImpl<char> &TULocalLookupTable);
|
||||
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context,
|
||||
const DeclContext *DC);
|
||||
void WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC,
|
||||
uint64_t &VisibleBlockOffset,
|
||||
uint64_t &ModuleLocalBlockOffset);
|
||||
uint64_t &ModuleLocalBlockOffset,
|
||||
uint64_t &TULocalBlockOffset);
|
||||
void WriteTypeDeclOffsets();
|
||||
void WriteFileDeclIDsMap();
|
||||
void WriteComments(ASTContext &Context);
|
||||
@ -633,8 +638,10 @@ private:
|
||||
unsigned DeclContextLexicalAbbrev = 0;
|
||||
unsigned DeclContextVisibleLookupAbbrev = 0;
|
||||
unsigned DeclModuleLocalVisibleLookupAbbrev = 0;
|
||||
unsigned DeclTULocalLookupAbbrev = 0;
|
||||
unsigned UpdateVisibleAbbrev = 0;
|
||||
unsigned ModuleLocalUpdateVisibleAbbrev = 0;
|
||||
unsigned TULocalUpdateVisibleAbbrev = 0;
|
||||
unsigned DeclRecordAbbrev = 0;
|
||||
unsigned DeclTypedefAbbrev = 0;
|
||||
unsigned DeclVarAbbrev = 0;
|
||||
|
@ -1425,10 +1425,9 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M,
|
||||
BitstreamCursor &Cursor,
|
||||
uint64_t Offset, GlobalDeclID ID,
|
||||
bool IsModuleLocal) {
|
||||
bool ASTReader::ReadVisibleDeclContextStorage(
|
||||
ModuleFile &M, BitstreamCursor &Cursor, uint64_t Offset, GlobalDeclID ID,
|
||||
ASTReader::VisibleDeclContextStorageKind VisibleKind) {
|
||||
assert(Offset != 0);
|
||||
|
||||
SavedStreamPosition SavedPosition(Cursor);
|
||||
@ -1452,22 +1451,42 @@ bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M,
|
||||
return true;
|
||||
}
|
||||
unsigned RecCode = MaybeRecCode.get();
|
||||
if (!IsModuleLocal && RecCode != DECL_CONTEXT_VISIBLE) {
|
||||
Error("Expected visible lookup table block");
|
||||
return true;
|
||||
}
|
||||
if (IsModuleLocal && RecCode != DECL_CONTEXT_MODULE_LOCAL_VISIBLE) {
|
||||
Error("Expected module local visible lookup table block");
|
||||
return true;
|
||||
switch (VisibleKind) {
|
||||
case VisibleDeclContextStorageKind::GenerallyVisible:
|
||||
if (RecCode != DECL_CONTEXT_VISIBLE) {
|
||||
Error("Expected visible lookup table block");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case VisibleDeclContextStorageKind::ModuleLocalVisible:
|
||||
if (RecCode != DECL_CONTEXT_MODULE_LOCAL_VISIBLE) {
|
||||
Error("Expected module local visible lookup table block");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case VisibleDeclContextStorageKind::TULocalVisible:
|
||||
if (RecCode != DECL_CONTEXT_TU_LOCAL_VISIBLE) {
|
||||
Error("Expected TU local lookup table block");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// We can't safely determine the primary context yet, so delay attaching the
|
||||
// lookup table until we're done with recursive deserialization.
|
||||
auto *Data = (const unsigned char*)Blob.data();
|
||||
if (!IsModuleLocal)
|
||||
switch (VisibleKind) {
|
||||
case VisibleDeclContextStorageKind::GenerallyVisible:
|
||||
PendingVisibleUpdates[ID].push_back(UpdateData{&M, Data});
|
||||
else
|
||||
break;
|
||||
case VisibleDeclContextStorageKind::ModuleLocalVisible:
|
||||
PendingModuleLocalVisibleUpdates[ID].push_back(UpdateData{&M, Data});
|
||||
break;
|
||||
case VisibleDeclContextStorageKind::TULocalVisible:
|
||||
if (M.Kind == MK_MainFile)
|
||||
TULocalUpdates[ID].push_back(UpdateData{&M, Data});
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3613,6 +3632,21 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
|
||||
break;
|
||||
}
|
||||
|
||||
case UPDATE_TU_LOCAL_VISIBLE: {
|
||||
if (F.Kind != MK_MainFile)
|
||||
break;
|
||||
unsigned Idx = 0;
|
||||
GlobalDeclID ID = ReadDeclID(F, Record, Idx);
|
||||
auto *Data = (const unsigned char *)Blob.data();
|
||||
TULocalUpdates[ID].push_back(UpdateData{&F, Data});
|
||||
// If we've already loaded the decl, perform the updates when we finish
|
||||
// loading this block.
|
||||
if (Decl *D = GetExistingDecl(ID))
|
||||
PendingUpdateRecords.push_back(
|
||||
PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
|
||||
break;
|
||||
}
|
||||
|
||||
case CXX_ADDED_TEMPLATE_SPECIALIZATION: {
|
||||
unsigned Idx = 0;
|
||||
GlobalDeclID ID = ReadDeclID(F, Record, Idx);
|
||||
@ -3717,6 +3751,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
|
||||
TotalLexicalDeclContexts += Record[2];
|
||||
TotalVisibleDeclContexts += Record[3];
|
||||
TotalModuleLocalVisibleDeclContexts += Record[4];
|
||||
TotalTULocalVisibleDeclContexts += Record[5];
|
||||
break;
|
||||
|
||||
case UNUSED_FILESCOPED_DECLS:
|
||||
@ -4002,7 +4037,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
|
||||
break;
|
||||
|
||||
case DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD: {
|
||||
if (Record.size() % 4 != 0)
|
||||
if (Record.size() % 5 != 0)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"invalid DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD block in AST "
|
||||
@ -4021,9 +4056,12 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
|
||||
uint64_t LocalModuleLocalOffset = Record[I++];
|
||||
uint64_t ModuleLocalOffset =
|
||||
LocalModuleLocalOffset ? BaseOffset + LocalModuleLocalOffset : 0;
|
||||
uint64_t TULocalLocalOffset = Record[I++];
|
||||
uint64_t TULocalOffset =
|
||||
TULocalLocalOffset ? BaseOffset + TULocalLocalOffset : 0;
|
||||
|
||||
DelayedNamespaceOffsetMap[ID] = {LexicalOffset, VisibleOffset,
|
||||
ModuleLocalOffset};
|
||||
ModuleLocalOffset, TULocalOffset};
|
||||
|
||||
assert(!GetExistingDecl(ID) &&
|
||||
"We shouldn't load the namespace in the front of delayed "
|
||||
@ -8473,6 +8511,15 @@ bool ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
|
||||
}
|
||||
}
|
||||
|
||||
if (auto It = TULocalLookups.find(DC); It != TULocalLookups.end()) {
|
||||
++NumTULocalVisibleDeclContexts;
|
||||
for (GlobalDeclID ID : It->second.Table.find(Name)) {
|
||||
NamedDecl *ND = cast<NamedDecl>(GetDecl(ID));
|
||||
if (ND->getDeclName() == Name && Found.insert(ND).second)
|
||||
Decls.push_back(ND);
|
||||
}
|
||||
}
|
||||
|
||||
SetExternalVisibleDeclsForName(DC, Name, Decls);
|
||||
return !Decls.empty();
|
||||
}
|
||||
@ -8500,6 +8547,7 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
|
||||
|
||||
findAll(Lookups, NumVisibleDeclContextsRead);
|
||||
findAll(ModuleLocalLookups, NumModuleLocalVisibleDeclContexts);
|
||||
findAll(TULocalLookups, NumTULocalVisibleDeclContexts);
|
||||
|
||||
for (DeclsMap::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
|
||||
SetExternalVisibleDeclsForName(DC, I->first, I->second);
|
||||
@ -8519,6 +8567,12 @@ ASTReader::getModuleLocalLookupTables(DeclContext *Primary) const {
|
||||
return I == ModuleLocalLookups.end() ? nullptr : &I->second;
|
||||
}
|
||||
|
||||
const serialization::reader::DeclContextLookupTable *
|
||||
ASTReader::getTULocalLookupTables(DeclContext *Primary) const {
|
||||
auto I = TULocalLookups.find(Primary);
|
||||
return I == TULocalLookups.end() ? nullptr : &I->second;
|
||||
}
|
||||
|
||||
serialization::reader::LazySpecializationInfoLookupTable *
|
||||
ASTReader::getLoadedSpecializationsLookupTables(const Decl *D, bool IsPartial) {
|
||||
assert(D->isCanonicalDecl());
|
||||
@ -8634,6 +8688,11 @@ void ASTReader::PrintStats() {
|
||||
NumModuleLocalVisibleDeclContexts, TotalModuleLocalVisibleDeclContexts,
|
||||
((float)NumModuleLocalVisibleDeclContexts /
|
||||
TotalModuleLocalVisibleDeclContexts * 100));
|
||||
if (TotalTULocalVisibleDeclContexts)
|
||||
std::fprintf(stderr, " %u/%u visible declcontexts in GMF read (%f%%)\n",
|
||||
NumTULocalVisibleDeclContexts, TotalTULocalVisibleDeclContexts,
|
||||
((float)NumTULocalVisibleDeclContexts /
|
||||
TotalTULocalVisibleDeclContexts * 100));
|
||||
if (TotalNumMethodPoolEntries)
|
||||
std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
|
||||
NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
|
||||
|
@ -414,7 +414,8 @@ public:
|
||||
void VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl *D);
|
||||
|
||||
void VisitDeclContext(DeclContext *DC, uint64_t &LexicalOffset,
|
||||
uint64_t &VisibleOffset, uint64_t &ModuleLocalOffset);
|
||||
uint64_t &VisibleOffset, uint64_t &ModuleLocalOffset,
|
||||
uint64_t &TULocalOffset);
|
||||
|
||||
template <typename T>
|
||||
RedeclarableResult VisitRedeclarable(Redeclarable<T> *D);
|
||||
@ -1859,7 +1860,9 @@ void ASTDeclReader::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
|
||||
uint64_t LexicalOffset = 0;
|
||||
uint64_t VisibleOffset = 0;
|
||||
uint64_t ModuleLocalOffset = 0;
|
||||
VisitDeclContext(D, LexicalOffset, VisibleOffset, ModuleLocalOffset);
|
||||
uint64_t TULocalOffset = 0;
|
||||
VisitDeclContext(D, LexicalOffset, VisibleOffset, ModuleLocalOffset,
|
||||
TULocalOffset);
|
||||
D->IsCBuffer = Record.readBool();
|
||||
D->KwLoc = readSourceLocation();
|
||||
D->LBraceLoc = readSourceLocation();
|
||||
@ -2770,10 +2773,12 @@ void ASTDeclReader::VisitLifetimeExtendedTemporaryDecl(
|
||||
|
||||
void ASTDeclReader::VisitDeclContext(DeclContext *DC, uint64_t &LexicalOffset,
|
||||
uint64_t &VisibleOffset,
|
||||
uint64_t &ModuleLocalOffset) {
|
||||
uint64_t &ModuleLocalOffset,
|
||||
uint64_t &TULocalOffset) {
|
||||
LexicalOffset = ReadLocalOffset();
|
||||
VisibleOffset = ReadLocalOffset();
|
||||
ModuleLocalOffset = ReadLocalOffset();
|
||||
TULocalOffset = ReadLocalOffset();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -3903,6 +3908,7 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
|
||||
case DECL_CONTEXT_LEXICAL:
|
||||
case DECL_CONTEXT_VISIBLE:
|
||||
case DECL_CONTEXT_MODULE_LOCAL_VISIBLE:
|
||||
case DECL_CONTEXT_TU_LOCAL_VISIBLE:
|
||||
case DECL_SPECIALIZATIONS:
|
||||
case DECL_PARTIAL_SPECIALIZATIONS:
|
||||
llvm_unreachable("Record cannot be de-serialized with readDeclRecord");
|
||||
@ -4213,9 +4219,10 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
|
||||
uint64_t LexicalOffset = 0;
|
||||
uint64_t VisibleOffset = 0;
|
||||
uint64_t ModuleLocalOffset = 0;
|
||||
uint64_t TULocalOffset = 0;
|
||||
|
||||
Reader.VisitDeclContext(DC, LexicalOffset, VisibleOffset,
|
||||
ModuleLocalOffset);
|
||||
Reader.VisitDeclContext(DC, LexicalOffset, VisibleOffset, ModuleLocalOffset,
|
||||
TULocalOffset);
|
||||
|
||||
// Get the lexical and visible block for the delayed namespace.
|
||||
// It is sufficient to judge if ID is in DelayedNamespaceOffsetMap.
|
||||
@ -4227,18 +4234,24 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
|
||||
LexicalOffset = Iter->second.LexicalOffset;
|
||||
VisibleOffset = Iter->second.VisibleOffset;
|
||||
ModuleLocalOffset = Iter->second.ModuleLocalOffset;
|
||||
TULocalOffset = Iter->second.TULocalOffset;
|
||||
}
|
||||
|
||||
if (LexicalOffset &&
|
||||
ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, LexicalOffset, DC))
|
||||
return nullptr;
|
||||
if (VisibleOffset &&
|
||||
ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, VisibleOffset, ID,
|
||||
/*IsModuleLocal=*/false))
|
||||
if (VisibleOffset && ReadVisibleDeclContextStorage(
|
||||
*Loc.F, DeclsCursor, VisibleOffset, ID,
|
||||
VisibleDeclContextStorageKind::GenerallyVisible))
|
||||
return nullptr;
|
||||
if (ModuleLocalOffset &&
|
||||
ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, ModuleLocalOffset,
|
||||
ID, /*IsModuleLocal=*/true))
|
||||
ReadVisibleDeclContextStorage(
|
||||
*Loc.F, DeclsCursor, ModuleLocalOffset, ID,
|
||||
VisibleDeclContextStorageKind::ModuleLocalVisible))
|
||||
return nullptr;
|
||||
if (TULocalOffset && ReadVisibleDeclContextStorage(
|
||||
*Loc.F, DeclsCursor, TULocalOffset, ID,
|
||||
VisibleDeclContextStorageKind::TULocalVisible))
|
||||
return nullptr;
|
||||
}
|
||||
assert(Record.getIdx() == Record.size());
|
||||
@ -4404,6 +4417,18 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
|
||||
DC->setHasExternalVisibleStorage(true);
|
||||
}
|
||||
|
||||
if (auto I = TULocalUpdates.find(ID); I != TULocalUpdates.end()) {
|
||||
auto Updates = std::move(I->second);
|
||||
TULocalUpdates.erase(I);
|
||||
|
||||
auto *DC = cast<DeclContext>(D)->getPrimaryContext();
|
||||
for (const auto &Update : Updates)
|
||||
TULocalLookups[DC].Table.add(
|
||||
Update.Mod, Update.Data,
|
||||
reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod));
|
||||
DC->setHasExternalVisibleStorage(true);
|
||||
}
|
||||
|
||||
// Load any pending related decls.
|
||||
if (D->isCanonicalDecl()) {
|
||||
if (auto IT = RelatedDeclsMap.find(ID); IT != RelatedDeclsMap.end()) {
|
||||
|
@ -4047,6 +4047,13 @@ protected:
|
||||
: Writer(Writer) {}
|
||||
|
||||
public:
|
||||
data_type getData(const DeclIDsTy &LocalIDs) {
|
||||
unsigned Start = DeclIDs.size();
|
||||
for (auto ID : LocalIDs)
|
||||
DeclIDs.push_back(ID);
|
||||
return std::make_pair(Start, DeclIDs.size());
|
||||
}
|
||||
|
||||
data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) {
|
||||
unsigned Start = DeclIDs.size();
|
||||
DeclIDs.insert(
|
||||
@ -4139,23 +4146,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class ModuleLocalNameLookupTrait : public ASTDeclContextNameLookupTraitBase {
|
||||
class ModuleLevelNameLookupTrait : public ASTDeclContextNameLookupTraitBase {
|
||||
public:
|
||||
using primary_module_hash_type = unsigned;
|
||||
|
||||
using key_type = std::pair<DeclarationNameKey, primary_module_hash_type>;
|
||||
using key_type_ref = key_type;
|
||||
|
||||
explicit ModuleLocalNameLookupTrait(ASTWriter &Writer)
|
||||
explicit ModuleLevelNameLookupTrait(ASTWriter &Writer)
|
||||
: ASTDeclContextNameLookupTraitBase(Writer) {}
|
||||
|
||||
data_type getData(const DeclIDsTy &LocalIDs) {
|
||||
unsigned Start = DeclIDs.size();
|
||||
for (auto ID : LocalIDs)
|
||||
DeclIDs.push_back(ID);
|
||||
return std::make_pair(Start, DeclIDs.size());
|
||||
}
|
||||
|
||||
static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; }
|
||||
|
||||
hash_value_type ComputeHash(key_type Key) {
|
||||
@ -4203,19 +4203,46 @@ static bool isModuleLocalDecl(NamedDecl *D) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isTULocalInNamedModules(NamedDecl *D) {
|
||||
Module *NamedModule = D->getTopLevelOwningNamedModule();
|
||||
if (!NamedModule)
|
||||
return false;
|
||||
|
||||
// For none-top level decls, we choose to move it to the general visible
|
||||
// lookup table. Since the consumer may get its parent somehow and performs
|
||||
// a lookup in it (considering looking up the operator function in lambda).
|
||||
// The difference between module local lookup table and TU local lookup table
|
||||
// is, the consumers still have a chance to lookup in the module local lookup
|
||||
// table but **now** the consumers won't read the TU local lookup table if
|
||||
// the consumer is not the original TU.
|
||||
//
|
||||
// FIXME: It seems to be an optimization chance (and also a more correct
|
||||
// semantics) to remain the TULocal lookup table and performing similar lookup
|
||||
// with the module local lookup table except that we only allow the lookups
|
||||
// with the same module unit.
|
||||
if (!D->getNonTransparentDeclContext()->isFileContext())
|
||||
return false;
|
||||
|
||||
return D->getLinkageInternal() == Linkage::Internal;
|
||||
}
|
||||
|
||||
// Trait used for the on-disk hash table used in the method pool.
|
||||
template <bool CollectingTULocalDecls>
|
||||
class ASTDeclContextNameLookupTrait : public ASTDeclContextNameLookupTraitBase {
|
||||
public:
|
||||
using ModuleLocalDeclsMapTy =
|
||||
llvm::DenseMap<ModuleLocalNameLookupTrait::key_type, DeclIDsTy>;
|
||||
using ModuleLevelDeclsMapTy =
|
||||
llvm::DenseMap<ModuleLevelNameLookupTrait::key_type, DeclIDsTy>;
|
||||
|
||||
private:
|
||||
ModuleLocalDeclsMapTy ModuleLocalDeclsMap;
|
||||
|
||||
public:
|
||||
using key_type = DeclarationNameKey;
|
||||
using key_type_ref = key_type;
|
||||
|
||||
using TULocalDeclsMapTy = llvm::DenseMap<key_type, DeclIDsTy>;
|
||||
|
||||
private:
|
||||
ModuleLevelDeclsMapTy ModuleLocalDeclsMap;
|
||||
TULocalDeclsMapTy TULocalDeclsMap;
|
||||
|
||||
public:
|
||||
explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer)
|
||||
: ASTDeclContextNameLookupTraitBase(Writer) {}
|
||||
|
||||
@ -4251,15 +4278,30 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (CollectingTULocalDecls) {
|
||||
if (isTULocalInNamedModules(D)) {
|
||||
auto Iter = TULocalDeclsMap.find(D->getDeclName());
|
||||
if (Iter == TULocalDeclsMap.end())
|
||||
TULocalDeclsMap.insert({D->getDeclName(), DeclIDsTy{ID}});
|
||||
else
|
||||
Iter->second.push_back(ID);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
DeclIDs.push_back(ID);
|
||||
}
|
||||
return std::make_pair(Start, DeclIDs.size());
|
||||
}
|
||||
|
||||
const ModuleLocalDeclsMapTy &getModuleLocalDecls() {
|
||||
using ASTDeclContextNameLookupTraitBase::getData;
|
||||
|
||||
const ModuleLevelDeclsMapTy &getModuleLocalDecls() {
|
||||
return ModuleLocalDeclsMap;
|
||||
}
|
||||
|
||||
const TULocalDeclsMapTy &getTULocalDecls() { return TULocalDeclsMap; }
|
||||
|
||||
static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; }
|
||||
|
||||
hash_value_type ComputeHash(key_type Name) { return Name.getHash(); }
|
||||
@ -4487,7 +4529,8 @@ static bool isLookupResultNotInteresting(ASTWriter &Writer,
|
||||
void ASTWriter::GenerateNameLookupTable(
|
||||
ASTContext &Context, const DeclContext *ConstDC,
|
||||
llvm::SmallVectorImpl<char> &LookupTable,
|
||||
llvm::SmallVectorImpl<char> &ModuleLocalLookupTable) {
|
||||
llvm::SmallVectorImpl<char> &ModuleLocalLookupTable,
|
||||
llvm::SmallVectorImpl<char> &TULookupTable) {
|
||||
assert(!ConstDC->hasLazyLocalLexicalLookups() &&
|
||||
!ConstDC->hasLazyExternalLexicalLookups() &&
|
||||
"must call buildLookups first");
|
||||
@ -4497,9 +4540,11 @@ void ASTWriter::GenerateNameLookupTable(
|
||||
assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table");
|
||||
|
||||
// Create the on-disk hash table representation.
|
||||
MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
|
||||
ASTDeclContextNameLookupTrait> Generator;
|
||||
ASTDeclContextNameLookupTrait Trait(*this);
|
||||
MultiOnDiskHashTableGenerator<
|
||||
reader::ASTDeclContextNameLookupTrait,
|
||||
ASTDeclContextNameLookupTrait</*CollectingTULocal=*/true>>
|
||||
Generator;
|
||||
ASTDeclContextNameLookupTrait</*CollectingTULocal=*/true> Trait(*this);
|
||||
|
||||
// The first step is to collect the declaration names which we need to
|
||||
// serialize into the name lookup table, and to collect them in a stable
|
||||
@ -4671,26 +4716,45 @@ void ASTWriter::GenerateNameLookupTable(
|
||||
Generator.emit(LookupTable, Trait, Lookups ? &Lookups->Table : nullptr);
|
||||
|
||||
const auto &ModuleLocalDecls = Trait.getModuleLocalDecls();
|
||||
if (ModuleLocalDecls.empty())
|
||||
return;
|
||||
if (!ModuleLocalDecls.empty()) {
|
||||
MultiOnDiskHashTableGenerator<reader::ModuleLocalNameLookupTrait,
|
||||
ModuleLevelNameLookupTrait>
|
||||
ModuleLocalLookupGenerator;
|
||||
ModuleLevelNameLookupTrait ModuleLocalTrait(*this);
|
||||
|
||||
MultiOnDiskHashTableGenerator<reader::ModuleLocalNameLookupTrait,
|
||||
ModuleLocalNameLookupTrait>
|
||||
ModuleLocalLookupGenerator;
|
||||
ModuleLocalNameLookupTrait ModuleLocalTrait(*this);
|
||||
for (const auto &ModuleLocalIter : ModuleLocalDecls) {
|
||||
const auto &Key = ModuleLocalIter.first;
|
||||
const auto &IDs = ModuleLocalIter.second;
|
||||
ModuleLocalLookupGenerator.insert(Key, ModuleLocalTrait.getData(IDs),
|
||||
ModuleLocalTrait);
|
||||
}
|
||||
|
||||
for (const auto &ModuleLocalIter : ModuleLocalDecls) {
|
||||
const auto &Key = ModuleLocalIter.first;
|
||||
const auto &IDs = ModuleLocalIter.second;
|
||||
ModuleLocalLookupGenerator.insert(Key, ModuleLocalTrait.getData(IDs),
|
||||
ModuleLocalTrait);
|
||||
auto *ModuleLocalLookups =
|
||||
Chain ? Chain->getModuleLocalLookupTables(DC) : nullptr;
|
||||
ModuleLocalLookupGenerator.emit(
|
||||
ModuleLocalLookupTable, ModuleLocalTrait,
|
||||
ModuleLocalLookups ? &ModuleLocalLookups->Table : nullptr);
|
||||
}
|
||||
|
||||
auto *ModuleLocalLookups =
|
||||
Chain ? Chain->getModuleLocalLookupTables(DC) : nullptr;
|
||||
ModuleLocalLookupGenerator.emit(
|
||||
ModuleLocalLookupTable, ModuleLocalTrait,
|
||||
ModuleLocalLookups ? &ModuleLocalLookups->Table : nullptr);
|
||||
const auto &TULocalDecls = Trait.getTULocalDecls();
|
||||
if (!TULocalDecls.empty() && !isGeneratingReducedBMI()) {
|
||||
MultiOnDiskHashTableGenerator<
|
||||
reader::ASTDeclContextNameLookupTrait,
|
||||
ASTDeclContextNameLookupTrait</*CollectingTULocal=*/false>>
|
||||
TULookupGenerator;
|
||||
ASTDeclContextNameLookupTrait</*CollectingTULocal=*/false> TULocalTrait(
|
||||
*this);
|
||||
|
||||
for (const auto &TULocalIter : TULocalDecls) {
|
||||
const auto &Key = TULocalIter.first;
|
||||
const auto &IDs = TULocalIter.second;
|
||||
TULookupGenerator.insert(Key, TULocalTrait.getData(IDs), TULocalTrait);
|
||||
}
|
||||
|
||||
auto *TULocalLookups = Chain ? Chain->getTULocalLookupTables(DC) : nullptr;
|
||||
TULookupGenerator.emit(TULookupTable, TULocalTrait,
|
||||
TULocalLookups ? &TULocalLookups->Table : nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/// Write the block containing all of the declaration IDs
|
||||
@ -4701,7 +4765,12 @@ void ASTWriter::GenerateNameLookupTable(
|
||||
void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
|
||||
DeclContext *DC,
|
||||
uint64_t &VisibleBlockOffset,
|
||||
uint64_t &ModuleLocalBlockOffset) {
|
||||
uint64_t &ModuleLocalBlockOffset,
|
||||
uint64_t &TULocalBlockOffset) {
|
||||
assert(VisibleBlockOffset == 0);
|
||||
assert(ModuleLocalBlockOffset == 0);
|
||||
assert(TULocalBlockOffset == 0);
|
||||
|
||||
// If we imported a key declaration of this namespace, write the visible
|
||||
// lookup results as an update record for it rather than including them
|
||||
// on this declaration. We will only look at key declarations on reload.
|
||||
@ -4788,7 +4857,9 @@ void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
|
||||
// Create the on-disk hash table in a buffer.
|
||||
SmallString<4096> LookupTable;
|
||||
SmallString<4096> ModuleLocalLookupTable;
|
||||
GenerateNameLookupTable(Context, DC, LookupTable, ModuleLocalLookupTable);
|
||||
SmallString<4096> TULookupTable;
|
||||
GenerateNameLookupTable(Context, DC, LookupTable, ModuleLocalLookupTable,
|
||||
TULookupTable);
|
||||
|
||||
// Write the lookup table
|
||||
RecordData::value_type Record[] = {DECL_CONTEXT_VISIBLE};
|
||||
@ -4796,17 +4867,26 @@ void ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
|
||||
LookupTable);
|
||||
++NumVisibleDeclContexts;
|
||||
|
||||
if (ModuleLocalLookupTable.empty())
|
||||
return;
|
||||
if (!ModuleLocalLookupTable.empty()) {
|
||||
ModuleLocalBlockOffset = Stream.GetCurrentBitNo();
|
||||
assert(ModuleLocalBlockOffset > VisibleBlockOffset);
|
||||
// Write the lookup table
|
||||
RecordData::value_type ModuleLocalRecord[] = {
|
||||
DECL_CONTEXT_MODULE_LOCAL_VISIBLE};
|
||||
Stream.EmitRecordWithBlob(DeclModuleLocalVisibleLookupAbbrev,
|
||||
ModuleLocalRecord, ModuleLocalLookupTable);
|
||||
++NumModuleLocalDeclContexts;
|
||||
}
|
||||
|
||||
ModuleLocalBlockOffset = Stream.GetCurrentBitNo();
|
||||
assert(ModuleLocalBlockOffset > VisibleBlockOffset);
|
||||
// Write the lookup table
|
||||
RecordData::value_type ModuleLocalRecord[] = {
|
||||
DECL_CONTEXT_MODULE_LOCAL_VISIBLE};
|
||||
Stream.EmitRecordWithBlob(DeclModuleLocalVisibleLookupAbbrev,
|
||||
ModuleLocalRecord, ModuleLocalLookupTable);
|
||||
++NumModuleLocalDeclContexts;
|
||||
if (!TULookupTable.empty()) {
|
||||
TULocalBlockOffset = Stream.GetCurrentBitNo();
|
||||
// Write the lookup table
|
||||
RecordData::value_type TULocalDeclsRecord[] = {
|
||||
DECL_CONTEXT_TU_LOCAL_VISIBLE};
|
||||
Stream.EmitRecordWithBlob(DeclTULocalLookupAbbrev, TULocalDeclsRecord,
|
||||
TULookupTable);
|
||||
++NumTULocalDeclContexts;
|
||||
}
|
||||
}
|
||||
|
||||
/// Write an UPDATE_VISIBLE block for the given context.
|
||||
@ -4824,7 +4904,9 @@ void ASTWriter::WriteDeclContextVisibleUpdate(ASTContext &Context,
|
||||
// Create the on-disk hash table in a buffer.
|
||||
SmallString<4096> LookupTable;
|
||||
SmallString<4096> ModuleLocalLookupTable;
|
||||
GenerateNameLookupTable(Context, DC, LookupTable, ModuleLocalLookupTable);
|
||||
SmallString<4096> TULookupTable;
|
||||
GenerateNameLookupTable(Context, DC, LookupTable, ModuleLocalLookupTable,
|
||||
TULookupTable);
|
||||
|
||||
// If we're updating a namespace, select a key declaration as the key for the
|
||||
// update record; those are the only ones that will be checked on reload.
|
||||
@ -4836,14 +4918,20 @@ void ASTWriter::WriteDeclContextVisibleUpdate(ASTContext &Context,
|
||||
getDeclID(cast<Decl>(DC)).getRawValue()};
|
||||
Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
|
||||
|
||||
if (ModuleLocalLookupTable.empty())
|
||||
return;
|
||||
if (!ModuleLocalLookupTable.empty()) {
|
||||
// Write the module local lookup table
|
||||
RecordData::value_type ModuleLocalRecord[] = {
|
||||
UPDATE_MODULE_LOCAL_VISIBLE, getDeclID(cast<Decl>(DC)).getRawValue()};
|
||||
Stream.EmitRecordWithBlob(ModuleLocalUpdateVisibleAbbrev, ModuleLocalRecord,
|
||||
ModuleLocalLookupTable);
|
||||
}
|
||||
|
||||
// Write the module local lookup table
|
||||
RecordData::value_type ModuleLocalRecord[] = {
|
||||
UPDATE_MODULE_LOCAL_VISIBLE, getDeclID(cast<Decl>(DC)).getRawValue()};
|
||||
Stream.EmitRecordWithBlob(ModuleLocalUpdateVisibleAbbrev, ModuleLocalRecord,
|
||||
ModuleLocalLookupTable);
|
||||
if (!TULookupTable.empty()) {
|
||||
RecordData::value_type GMFRecord[] = {
|
||||
UPDATE_TU_LOCAL_VISIBLE, getDeclID(cast<Decl>(DC)).getRawValue()};
|
||||
Stream.EmitRecordWithBlob(TULocalUpdateVisibleAbbrev, GMFRecord,
|
||||
TULookupTable);
|
||||
}
|
||||
}
|
||||
|
||||
/// Write an FP_PRAGMA_OPTIONS block for the given FPOptions.
|
||||
@ -6031,9 +6119,12 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot,
|
||||
}
|
||||
|
||||
// Some simple statistics
|
||||
RecordData::value_type Record[] = {
|
||||
NumStatements, NumMacros, NumLexicalDeclContexts, NumVisibleDeclContexts,
|
||||
NumModuleLocalDeclContexts};
|
||||
RecordData::value_type Record[] = {NumStatements,
|
||||
NumMacros,
|
||||
NumLexicalDeclContexts,
|
||||
NumVisibleDeclContexts,
|
||||
NumModuleLocalDeclContexts,
|
||||
NumTULocalDeclContexts};
|
||||
Stream.EmitRecord(STATISTICS, Record);
|
||||
Stream.ExitBlock();
|
||||
Stream.FlushToWord();
|
||||
@ -6112,7 +6203,9 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
|
||||
uint64_t LexicalOffset = WriteDeclContextLexicalBlock(Context, NS);
|
||||
uint64_t VisibleOffset = 0;
|
||||
uint64_t ModuleLocalOffset = 0;
|
||||
WriteDeclContextVisibleBlock(Context, NS, VisibleOffset, ModuleLocalOffset);
|
||||
uint64_t TULocalOffset = 0;
|
||||
WriteDeclContextVisibleBlock(Context, NS, VisibleOffset, ModuleLocalOffset,
|
||||
TULocalOffset);
|
||||
|
||||
// Write the offset relative to current block.
|
||||
if (LexicalOffset)
|
||||
@ -6124,10 +6217,14 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
|
||||
if (ModuleLocalOffset)
|
||||
ModuleLocalOffset -= DeclTypesBlockStartOffset;
|
||||
|
||||
if (TULocalOffset)
|
||||
TULocalOffset -= DeclTypesBlockStartOffset;
|
||||
|
||||
AddDeclRef(NS, DelayedNamespaceRecord);
|
||||
DelayedNamespaceRecord.push_back(LexicalOffset);
|
||||
DelayedNamespaceRecord.push_back(VisibleOffset);
|
||||
DelayedNamespaceRecord.push_back(ModuleLocalOffset);
|
||||
DelayedNamespaceRecord.push_back(TULocalOffset);
|
||||
}
|
||||
|
||||
// The process of writing lexical and visible block for delayed namespace
|
||||
@ -6213,6 +6310,12 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
|
||||
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
|
||||
ModuleLocalUpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
|
||||
|
||||
Abv = std::make_shared<llvm::BitCodeAbbrev>();
|
||||
Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_TU_LOCAL_VISIBLE));
|
||||
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
|
||||
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
|
||||
TULocalUpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
|
||||
|
||||
// And a visible updates block for the translation unit.
|
||||
WriteDeclContextVisibleUpdate(Context, TU);
|
||||
|
||||
|
@ -2069,6 +2069,7 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC) {
|
||||
uint64_t LexicalOffset = 0;
|
||||
uint64_t VisibleOffset = 0;
|
||||
uint64_t ModuleLocalOffset = 0;
|
||||
uint64_t TULocalOffset = 0;
|
||||
|
||||
if (Writer.isGeneratingReducedBMI() && isa<NamespaceDecl>(DC) &&
|
||||
cast<NamespaceDecl>(DC)->isFromExplicitGlobalModule()) {
|
||||
@ -2080,12 +2081,14 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC) {
|
||||
LexicalOffset =
|
||||
Writer.WriteDeclContextLexicalBlock(Record.getASTContext(), DC);
|
||||
Writer.WriteDeclContextVisibleBlock(Record.getASTContext(), DC,
|
||||
VisibleOffset, ModuleLocalOffset);
|
||||
VisibleOffset, ModuleLocalOffset,
|
||||
TULocalOffset);
|
||||
}
|
||||
|
||||
Record.AddOffset(LexicalOffset);
|
||||
Record.AddOffset(VisibleOffset);
|
||||
Record.AddOffset(ModuleLocalOffset);
|
||||
Record.AddOffset(TULocalOffset);
|
||||
}
|
||||
|
||||
const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) {
|
||||
@ -2441,6 +2444,7 @@ void ASTWriter::WriteDeclAbbrevs() {
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // VisibleOffset
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ModuleLocalOffset
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TULocalOffset
|
||||
DeclEnumAbbrev = Stream.EmitAbbrev(std::move(Abv));
|
||||
|
||||
// Abbreviation for DECL_RECORD
|
||||
@ -2494,6 +2498,7 @@ void ASTWriter::WriteDeclAbbrevs() {
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // VisibleOffset
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ModuleLocalOffset
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TULocalOffset
|
||||
DeclRecordAbbrev = Stream.EmitAbbrev(std::move(Abv));
|
||||
|
||||
// Abbreviation for DECL_PARM_VAR
|
||||
@ -2836,6 +2841,11 @@ void ASTWriter::WriteDeclAbbrevs() {
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
|
||||
DeclModuleLocalVisibleLookupAbbrev = Stream.EmitAbbrev(std::move(Abv));
|
||||
|
||||
Abv = std::make_shared<BitCodeAbbrev>();
|
||||
Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_TU_LOCAL_VISIBLE));
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
|
||||
DeclTULocalLookupAbbrev = Stream.EmitAbbrev(std::move(Abv));
|
||||
|
||||
Abv = std::make_shared<BitCodeAbbrev>();
|
||||
Abv->Add(BitCodeAbbrevOp(serialization::DECL_SPECIALIZATIONS));
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
|
||||
|
@ -61,6 +61,6 @@ void test() {
|
||||
|
||||
// error: S::f is visible in instantiation context, but R::g has internal
|
||||
// linkage and cannot be used outside N.cpp
|
||||
apply(x, S::Z()); // expected-error@N.cpp:10 {{no matching function for call to 'g'}}
|
||||
// expected-note@-1 {{in instantiation of function template specialization 'apply<R::X, S::Z>' requested here}}
|
||||
apply(x, S::Z()); // expected-error@N.cpp:10 {{use of undeclared identifier 'g'}}
|
||||
// expected-note@-1 {{requested here}}
|
||||
}
|
||||
|
@ -66,11 +66,7 @@ void test_late() {
|
||||
// expected-note@p2.cpp:18 {{'exported' declared here}}
|
||||
#endif
|
||||
|
||||
internal = 1;
|
||||
#ifndef IMPLEMENTATION
|
||||
// expected-error@-2 {{declaration of 'internal' must be imported from module 'A' before it is required}}
|
||||
// expected-note@p2.cpp:20 {{declaration here is not visible}}
|
||||
#endif
|
||||
internal = 1; // expected-error {{use of undeclared identifier 'internal'}}
|
||||
|
||||
not_exported_private = 1;
|
||||
#ifndef IMPLEMENTATION
|
||||
@ -78,11 +74,7 @@ void test_late() {
|
||||
// expected-error@-3 {{undeclared identifier}}
|
||||
#endif
|
||||
|
||||
internal_private = 1;
|
||||
#ifndef IMPLEMENTATION
|
||||
// FIXME: should not be visible here
|
||||
// expected-error@-3 {{undeclared identifier}}
|
||||
#endif
|
||||
internal_private = 1; // expected-error {{use of undeclared identifier 'internal_private'}}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -128,7 +128,6 @@ void f(a::b, a::c) {}
|
||||
//
|
||||
// CHECK-DAG: @_ZW6Module25extern_var_module_linkage = external {{(dso_local )?}}global
|
||||
// CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr {{(dso_local )?}}global
|
||||
// CHECK-DAG: @_ZL25static_var_module_linkage = internal {{(dso_local )?}}global i32 0,
|
||||
// CHECK-DAG: @_ZW6Module24const_var_module_linkage = available_externally {{(dso_local )?}}constant i32 3,
|
||||
|
||||
module Module;
|
||||
@ -152,10 +151,6 @@ void use() {
|
||||
(void)&extern_var_module_linkage;
|
||||
(void)&inline_var_module_linkage;
|
||||
|
||||
// FIXME: Issue #61427 Internal-linkage declarations in the interface TU
|
||||
// should not be not visible here.
|
||||
(void)&static_var_module_linkage; // FIXME: Should not be visible here.
|
||||
|
||||
(void)&const_var_module_linkage; // FIXME: will be visible after P2788R0
|
||||
}
|
||||
|
||||
|
@ -45,16 +45,14 @@ module M;
|
||||
void use_from_module_impl() {
|
||||
external_linkage_fn();
|
||||
module_linkage_fn();
|
||||
internal_linkage_fn(); // expected-error {{no matching function for call to 'internal_linkage_fn'}}
|
||||
internal_linkage_fn(); // expected-error {{use of undeclared identifier 'internal_linkage_fn'}} // expected-note@* {{}}
|
||||
(void)external_linkage_class{};
|
||||
(void)module_linkage_class{};
|
||||
(void)external_linkage_var;
|
||||
(void)module_linkage_var;
|
||||
|
||||
// FIXME: Issue #61427 Internal-linkage declarations in the interface TU
|
||||
// should not be not visible here.
|
||||
(void)internal_linkage_class{};
|
||||
(void)internal_linkage_var;
|
||||
(void)internal_linkage_class{}; // expected-error {{use of undeclared identifier 'internal_linkage_class'}} //expected-error{{}}
|
||||
(void)internal_linkage_var; // expected-error {{use of undeclared identifier 'internal_linkage_var'}}
|
||||
}
|
||||
|
||||
//--- user.cpp
|
||||
@ -63,11 +61,10 @@ import M;
|
||||
void use_from_module_impl() {
|
||||
external_linkage_fn();
|
||||
module_linkage_fn(); // expected-error {{use of undeclared identifier 'module_linkage_fn'}}
|
||||
internal_linkage_fn(); // expected-error {{declaration of 'internal_linkage_fn' must be imported}}
|
||||
internal_linkage_fn(); // expected-error {{use of undeclared identifier 'internal_linkage_fn'}}
|
||||
(void)external_linkage_class{};
|
||||
(void)module_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}}
|
||||
(void)module_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}} // expected-note@* {{}}
|
||||
(void)internal_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}}
|
||||
// expected-note@M.cppm:10 {{declaration here is not visible}}
|
||||
(void)external_linkage_var;
|
||||
(void)module_linkage_var; // expected-error {{undeclared identifier}}
|
||||
(void)internal_linkage_var; // expected-error {{undeclared identifier}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user