summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-02-10 06:50:24 +0000
committerJohn McCall <rjmccall@apple.com>2011-02-10 06:50:24 +0000
commitf768aa7613f0705bc32e226f12fe58be9fb5b0b7 (patch)
tree84ea1b7ad66bf5402dcc103a88c95205e6203124 /clang/lib
parent6b657aed3365d6bf77b0eda4020eeea5661535e7 (diff)
downloadbcm5719-llvm-f768aa7613f0705bc32e226f12fe58be9fb5b0b7.tar.gz
bcm5719-llvm-f768aa7613f0705bc32e226f12fe58be9fb5b0b7.zip
Move the check that gives functions with unique-external types unique-external
linkage into Decl.cpp. Disable this logic for extern "C" functions, because the operative rule there is weaker. Fixes rdar://problem/8898466 llvm-svn: 125268
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp4
-rw-r--r--clang/lib/AST/Decl.cpp13
2 files changed, 13 insertions, 4 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index d6c89c947ce..6b267432586 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5859,10 +5859,6 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) {
GVALinkage External = GVA_StrongExternal;
Linkage L = FD->getLinkage();
- if (L == ExternalLinkage && getLangOptions().CPlusPlus &&
- FD->getType()->getLinkage() == UniqueExternalLinkage)
- L = UniqueExternalLinkage;
-
switch (L) {
case NoLinkage:
case InternalLinkage:
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 11614df5003..9aeb04fa448 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -392,6 +392,14 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
}
}
+ // In C++, then if the type of the function uses a type with
+ // unique-external linkage, it's not legally usable from outside
+ // this translation unit. However, we should use the C linkage
+ // rules instead for extern "C" declarations.
+ if (Context.getLangOptions().CPlusPlus && !Function->isExternC() &&
+ Function->getType()->getLinkage() == UniqueExternalLinkage)
+ return LinkageInfo::uniqueExternal();
+
if (FunctionTemplateSpecializationInfo *SpecInfo
= Function->getTemplateSpecializationInfo()) {
LV.merge(getLVForDecl(SpecInfo->getTemplate(),
@@ -512,6 +520,11 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
return LinkageInfo::uniqueExternal();
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ // If the type of the function uses a type with unique-external
+ // linkage, it's not legally usable from outside this translation unit.
+ if (MD->getType()->getLinkage() == UniqueExternalLinkage)
+ return LinkageInfo::uniqueExternal();
+
TemplateSpecializationKind TSK = TSK_Undeclared;
// If this is a method template specialization, use the linkage for
OpenPOWER on IntegriCloud