/// Get the linkage from a semantic point of view. Entities in
/// anonymous namespaces are external (in c++98).
- Linkage getFormalLinkage() const {
- return clang::getFormalLinkage(getLinkageInternal());
- }
+ Linkage getFormalLinkage() const;
/// True if this decl has external linkage.
bool hasExternalFormalLinkage() const {
}
static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
- // C++ [basic.link]p4.8:
- // - if the declaration of the name is attached to a named module and is not
- // exported
- // the name has module linkage;
- //
- // [basic.namespace.general]/p2
- // A namespace is never attached to a named module and never has a name with
- // module linkage.
- if (isInModulePurview(D) &&
- !isExportedFromModuleInterfaceUnit(
- cast<NamedDecl>(D->getCanonicalDecl())) &&
- !isa<NamespaceDecl>(D))
- return LinkageInfo(ModuleLinkage, DefaultVisibility, false);
-
return LinkageInfo::external();
}
.getLinkage();
}
+/// Get the linkage from a semantic point of view. Entities in
+/// anonymous namespaces are external (in c++98).
+Linkage NamedDecl::getFormalLinkage() const {
+ Linkage InternalLinkage = getLinkageInternal();
+
+ // C++ [basic.link]p4.8:
+ // - if the declaration of the name is attached to a named module and is not
+ // exported
+ // the name has module linkage;
+ //
+ // [basic.namespace.general]/p2
+ // A namespace is never attached to a named module and never has a name with
+ // module linkage.
+ if (isInModulePurview(this) &&
+ InternalLinkage == ExternalLinkage &&
+ !isExportedFromModuleInterfaceUnit(
+ cast<NamedDecl>(this->getCanonicalDecl())) &&
+ !isa<NamespaceDecl>(this))
+ InternalLinkage = ModuleLinkage;
+
+ return clang::getFormalLinkage(InternalLinkage);
+}
+
LinkageInfo NamedDecl::getLinkageAndVisibility() const {
return LinkageComputer{}.getDeclLinkageAndVisibility(this);
}
--- /dev/null
+// RUN: rm -fr %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/m-a.pcm
+// RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-module-interface -o %t/m-b.pcm \
+// RUN: -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/m.cppm -emit-module-interface -o %t/m.pcm \
+// RUN: -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/use.cppm -fprebuilt-module-path=%t -emit-obj
+
+//--- a.cppm
+export module m:a;
+namespace n {
+export class a {
+public:
+ virtual ~a() {}
+};
+}
+
+//--- b.cppm
+export module m:b;
+namespace n {
+class a;
+}
+
+//--- m.cppm
+export module m;
+export import :a;
+export import :b;
+
+//--- use.cppm
+// expected-no-diagnostics
+export module u;
+export import m;
+
+struct aa : public n::a {
+ aa() {}
+};
+auto foo(n::a*) {
+ return;
+}
+
+void use() {
+ n::a _;
+}
const auto *f = selectFirst<FunctionDecl>(
"f", match(functionDecl(hasName("f")).bind("f"), Ctx));
- EXPECT_EQ(a->getLinkageInternal(), InternalLinkage);
- EXPECT_EQ(f->getLinkageInternal(), InternalLinkage);
+ EXPECT_EQ(a->getFormalLinkage(), InternalLinkage);
+ EXPECT_EQ(f->getFormalLinkage(), InternalLinkage);
const auto *b =
selectFirst<VarDecl>("b", match(varDecl(hasName("b")).bind("b"), Ctx));
const auto *g = selectFirst<FunctionDecl>(
"g", match(functionDecl(hasName("g")).bind("g"), Ctx));
- EXPECT_EQ(b->getLinkageInternal(), ModuleLinkage);
- EXPECT_EQ(g->getLinkageInternal(), ModuleLinkage);
+ EXPECT_EQ(b->getFormalLinkage(), ModuleLinkage);
+ EXPECT_EQ(g->getFormalLinkage(), ModuleLinkage);
AST = tooling::buildASTFromCodeWithArgs(
Code.code(), /*Args=*/{"-std=c++20"});
f = selectFirst<FunctionDecl>(
"f", match(functionDecl(hasName("f")).bind("f"), CtxTS));
- EXPECT_EQ(a->getLinkageInternal(), InternalLinkage);
- EXPECT_EQ(f->getLinkageInternal(), InternalLinkage);
+ EXPECT_EQ(a->getFormalLinkage(), InternalLinkage);
+ EXPECT_EQ(f->getFormalLinkage(), InternalLinkage);
b = selectFirst<VarDecl>("b", match(varDecl(hasName("b")).bind("b"), CtxTS));
g = selectFirst<FunctionDecl>(
"g", match(functionDecl(hasName("g")).bind("g"), CtxTS));
- EXPECT_EQ(b->getLinkageInternal(), ModuleLinkage);
- EXPECT_EQ(g->getLinkageInternal(), ModuleLinkage);
+ EXPECT_EQ(b->getFormalLinkage(), ModuleLinkage);
+ EXPECT_EQ(g->getFormalLinkage(), ModuleLinkage);
}
TEST(Decl, GetNonTransparentDeclContext) {