Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 61 additions & 76 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2789,87 +2789,72 @@ static void addNamespaceMembers(Decl *decl,
if (declOwner && declOwner != redeclOwner->getTopLevelModule())
continue;
}
for (auto member : redecl->decls()) {
if (auto classTemplate = dyn_cast<clang::ClassTemplateDecl>(member)) {
// Add all specializations to a worklist so we don't accidentally mutate
// the list of decls we're iterating over.
llvm::SmallPtrSet<const clang::ClassTemplateSpecializationDecl *, 16> specWorklist;
for (auto spec : classTemplate->specializations())
specWorklist.insert(spec);
for (auto spec : specWorklist) {
if (auto import =
ctx.getClangModuleLoader()->importDeclDirectly(spec))
if (addedMembers.insert(import).second)
members.push_back(import);
}
}

std::function<void(clang::DeclContext *)> addDeclsFromContext =
[&](clang::DeclContext *declContext) {
for (auto member : declContext->decls()) {
if (auto classTemplate =
dyn_cast<clang::ClassTemplateDecl>(member)) {
// Add all specializations to a worklist so we don't accidentally
// mutate the list of decls we're iterating over.
llvm::SmallPtrSet<const clang::ClassTemplateSpecializationDecl *,
16>
specWorklist;
for (auto spec : classTemplate->specializations())
specWorklist.insert(spec);
for (auto spec : specWorklist) {
if (auto import =
ctx.getClangModuleLoader()->importDeclDirectly(spec))
if (addedMembers.insert(import).second)
members.push_back(import);
}
auto lookupAndAddMembers = [&](DeclName name) {
auto allResults = evaluateOrDefault(
ctx.evaluator, ClangDirectLookupRequest({decl, redecl, name}), {});

for (auto found : allResults) {
auto clangMember = cast<clang::NamedDecl *>(found);
if (auto importedDecl =
ctx.getClangModuleLoader()->importDeclDirectly(clangMember)) {
if (addedMembers.insert(importedDecl).second) {
members.push_back(importedDecl);

// Handle macro-expanded declarations.
importedDecl->visitAuxiliaryDecls([&](Decl *decl) {
auto valueDecl = dyn_cast<ValueDecl>(decl);
if (!valueDecl)
return;

// Bail out if the auxiliary decl was not produced by a macro.
auto module = decl->getDeclContext()->getParentModule();
auto *sf = module->getSourceFileContainingLocation(decl->getLoc());
if (!sf || sf->Kind != SourceFileKind::MacroExpansion)
return;

members.push_back(valueDecl);
});
}
}
}
};

auto lookupAndAddMembers = [&](clang::NamedDecl *namedDecl) {
auto name = ctx.getClangModuleLoader()->importName(namedDecl);
if (!name)
return;

auto allResults = evaluateOrDefault(
ctx.evaluator, ClangDirectLookupRequest({decl, redecl, name}),
{});

for (auto found : allResults) {
auto clangMember = cast<clang::NamedDecl *>(found);
if (auto importedDecl =
ctx.getClangModuleLoader()->importDeclDirectly(
clangMember)) {
if (addedMembers.insert(importedDecl).second) {
members.push_back(importedDecl);

// Handle macro-expanded declarations.
importedDecl->visitAuxiliaryDecls([&](Decl *decl) {
auto valueDecl = dyn_cast<ValueDecl>(decl);
if (!valueDecl)
return;

// Bail out if the auxiliary decl was not produced by a
// macro.
auto module = decl->getDeclContext()->getParentModule();
auto *sf = module->getSourceFileContainingLocation(
decl->getLoc());
if (!sf || sf->Kind != SourceFileKind::MacroExpansion)
return;

members.push_back(valueDecl);
});
}
}
}
};

// Look through `extern` blocks.
if (auto linkageSpecDecl = dyn_cast<clang::LinkageSpecDecl>(member))
addDeclsFromContext(linkageSpecDecl);

auto namedDecl = dyn_cast<clang::NamedDecl>(member);
if (!namedDecl)
auto namedDecl = dyn_cast<clang::NamedDecl>(member);
if (!namedDecl)
continue;
auto name = ctx.getClangModuleLoader()->importName(namedDecl);
if (!name)
continue;
lookupAndAddMembers(name);

// Unscoped enums could have their enumerators present
// in the parent namespace.
if (auto *ed = dyn_cast<clang::EnumDecl>(member)) {
if (!ed->isScoped()) {
for (const auto *ecd : ed->enumerators()) {
auto name = ctx.getClangModuleLoader()->importName(ecd);
if (!name)
continue;
lookupAndAddMembers(namedDecl);

// Unscoped enums could have their enumerators present
// in the parent namespace.
if (auto *ed = dyn_cast<clang::EnumDecl>(member)) {
if (!ed->isScoped()) {
for (auto *ecd : ed->enumerators()) {
lookupAndAddMembers(ecd);
}
}
}
lookupAndAddMembers(name);
}
};

addDeclsFromContext(redecl);
}
}
}
}
}

Expand Down
5 changes: 0 additions & 5 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5076,11 +5076,6 @@ static bool isDirectLookupMemberContext(const clang::Decl *foundClangDecl,
return firstDecl->getCanonicalDecl() == parent->getCanonicalDecl();
}
}
// Look through `extern` blocks.
if (auto linkageSpecDecl = dyn_cast<clang::LinkageSpecDecl>(memberContext)) {
if (auto parentDecl = dyn_cast<clang::Decl>(linkageSpecDecl->getParent()))
return isDirectLookupMemberContext(foundClangDecl, parentDecl, parent);
}
return false;
}

Expand Down
7 changes: 2 additions & 5 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1171,14 +1171,11 @@ namespace {
return nullptr;
// If this is a top-level namespace, don't put it in the module we're
// importing, put it in the "__ObjC" module that is implicitly imported.
auto clangDC = decl->getDeclContext();
while (isa<clang::LinkageSpecDecl>(clangDC))
clangDC = clangDC->getParent();
if (!clangDC->isNamespace())
if (!decl->getParent()->isNamespace())
dc = Impl.ImportedHeaderUnit;
else {
// This is a nested namespace, so just lookup it's parent normally.
auto parentNS = cast<clang::NamespaceDecl>(clangDC);
auto parentNS = cast<clang::NamespaceDecl>(decl->getParent());
auto parent =
Impl.importDecl(parentNS, getVersion(), /*UseCanonicalDecl*/ false);
// The parent namespace might not be imported if it's `swift_private`.
Expand Down
24 changes: 0 additions & 24 deletions lib/ClangImporter/SwiftLookupTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2034,30 +2034,6 @@ void importer::addEntryToLookupTable(SwiftLookupTable &table,
namedMember = def;
addEntryToLookupTable(table, namedMember, nameImporter);
}
if (auto linkageSpecDecl =
dyn_cast<clang::LinkageSpecDecl>(canonicalMember)) {
std::function<void(clang::DeclContext *)> addDeclsFromContext =
[&](clang::DeclContext *declContext) {
for (auto nestedDecl : declContext->decls()) {
if (auto namedMember = dyn_cast<clang::NamedDecl>(nestedDecl))
addEntryToLookupTable(table, namedMember, nameImporter);
else if (auto nestedLinkageSpecDecl =
dyn_cast<clang::LinkageSpecDecl>(nestedDecl))
addDeclsFromContext(nestedLinkageSpecDecl);
}
};

// HACK: libc++ redeclares lgamma_r in one of its headers, and that
// declaration hijacks lgamma_r from math.h where it is originally
// defined. This causes deserialization issues when loading the Darwin
// overlay on Apple platforms, because Swift cannot find lgamma_r in
// module _math.
bool shouldSkip = canonicalMember->getOwningModule() &&
canonicalMember->getOwningModule()->Name ==
"std_private_random_binomial_distribution";
if (!shouldSkip)
addDeclsFromContext(linkageSpecDecl);
}
}
}
if (auto usingDecl = dyn_cast<clang::UsingDecl>(named)) {
Expand Down
28 changes: 0 additions & 28 deletions test/Interop/Cxx/namespace/Inputs/extern-within-namespace.h

This file was deleted.

This file was deleted.

25 changes: 0 additions & 25 deletions test/Interop/Cxx/namespace/extern-within-namespace.swift

This file was deleted.