summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-05-15 20:05:43 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-05-15 20:05:43 +0000
commit42413141641e26462a0d0c95f62b09fea5df78e9 (patch)
treedfcc51b854345c51e563fdbb5f28c1e7cb24310a /clang/lib/Serialization
parente70f8103781f1c4749b0de99aab050637bb5bd67 (diff)
downloadbcm5719-llvm-42413141641e26462a0d0c95f62b09fea5df78e9.tar.gz
bcm5719-llvm-42413141641e26462a0d0c95f62b09fea5df78e9.zip
[modules] Add local submodule visibility support for declarations.
With this change, enabling -fmodules-local-submodule-visibility results in name visibility rules being applied to submodules of the current module in addition to imported modules (that is, names no longer "leak" between submodules of the same top-level module). This also makes it much safer to textually include a non-modular library into a module: each submodule that textually includes that library will get its own "copy" of that library, and so the library becomes visible no matter which including submodule you import. llvm-svn: 237473
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp7
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp45
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp4
3 files changed, 39 insertions, 17 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index c4b4aec24a0..08fd923f47d 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7997,7 +7997,7 @@ void ASTReader::getInputFiles(ModuleFile &F,
std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
// If we know the owning module, use it.
- if (Module *M = D->getOwningModule())
+ if (Module *M = D->getImportedOwningModule())
return M->getFullModuleName();
// Otherwise, use the name of the top-level module the decl is within.
@@ -8168,6 +8168,11 @@ void ASTReader::finishPendingActions() {
MD->setLazyBody(PB->second);
}
PendingBodies.clear();
+
+ // Do some cleanup.
+ for (auto *ND : PendingMergedDefinitionsToDeduplicate)
+ getContext().deduplicateMergedDefinitonsFor(ND);
+ PendingMergedDefinitionsToDeduplicate.clear();
}
void ASTReader::diagnoseOdrViolations() {
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 4ff81d8d92b..ed684537a66 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -458,24 +458,28 @@ void ASTDeclReader::VisitDecl(Decl *D) {
D->FromASTFile = true;
D->setModulePrivate(Record[Idx++]);
D->Hidden = D->isModulePrivate();
-
+
// Determine whether this declaration is part of a (sub)module. If so, it
// may not yet be visible.
if (unsigned SubmoduleID = readSubmoduleID(Record, Idx)) {
// Store the owning submodule ID in the declaration.
D->setOwningModuleID(SubmoduleID);
-
- // Module-private declarations are never visible, so there is no work to do.
- if (!D->isModulePrivate()) {
- if (Module *Owner = Reader.getSubmodule(SubmoduleID)) {
- if (Owner->NameVisibility != Module::AllVisible) {
- // The owning module is not visible. Mark this declaration as hidden.
- D->Hidden = true;
-
- // Note that this declaration was hidden because its owning module is
- // not yet visible.
- Reader.HiddenNamesMap[Owner].push_back(D);
- }
+
+ if (D->Hidden) {
+ // Module-private declarations are never visible, so there is no work to do.
+ } else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) {
+ // If local visibility is being tracked, this declaration will become
+ // hidden and visible as the owning module does. Inform Sema that this
+ // declaration might not be visible.
+ D->Hidden = true;
+ } else if (Module *Owner = Reader.getSubmodule(SubmoduleID)) {
+ if (Owner->NameVisibility != Module::AllVisible) {
+ // The owning module is not visible. Mark this declaration as hidden.
+ D->Hidden = true;
+
+ // Note that this declaration was hidden because its owning module is
+ // not yet visible.
+ Reader.HiddenNamesMap[Owner].push_back(D);
}
}
}
@@ -1399,7 +1403,12 @@ void ASTDeclReader::MergeDefinitionData(
// If MergeDD is visible or becomes visible, make the definition visible.
if (!MergeDD.Definition->isHidden())
DD.Definition->Hidden = false;
- else {
+ else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) {
+ Reader.getContext().mergeDefinitionIntoModule(
+ DD.Definition, MergeDD.Definition->getImportedOwningModule(),
+ /*NotifyListeners*/ false);
+ Reader.PendingMergedDefinitionsToDeduplicate.insert(DD.Definition);
+ } else {
auto SubmoduleID = MergeDD.Definition->getOwningModuleID();
assert(SubmoduleID && "hidden definition in no module");
Reader.HiddenNamesMap[Reader.getSubmodule(SubmoduleID)].push_back(
@@ -3813,7 +3822,13 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
case UPD_DECL_EXPORTED:
unsigned SubmoduleID = readSubmoduleID(Record, Idx);
Module *Owner = SubmoduleID ? Reader.getSubmodule(SubmoduleID) : nullptr;
- if (Owner && Owner->NameVisibility != Module::AllVisible) {
+ if (Reader.getContext().getLangOpts().ModulesLocalVisibility) {
+ // FIXME: This doesn't send the right notifications if there are
+ // ASTMutationListeners other than an ASTWriter.
+ Reader.getContext().mergeDefinitionIntoModule(cast<NamedDecl>(D), Owner,
+ /*NotifyListeners*/false);
+ Reader.PendingMergedDefinitionsToDeduplicate.insert(cast<NamedDecl>(D));
+ } else if (Owner && Owner->NameVisibility != Module::AllVisible) {
// If Owner is made visible at some later point, make this declaration
// visible too.
Reader.HiddenNamesMap[Owner].push_back(D);
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 1e7fc5cdb6a..2963b32857a 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5746,6 +5746,8 @@ void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {
assert(!WritingAST && "Already writing the AST!");
assert(D->isHidden() && "expected a hidden declaration");
- assert(D->isFromASTFile() && "hidden decl not from AST file");
+ if (!D->isFromASTFile())
+ return;
+
DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_EXPORTED, M));
}
OpenPOWER on IntegriCloud