From e6a4b7dc8f2a8e64eda3a7818bd60ac2f3b83412 Mon Sep 17 00:00:00 2001 From: Artem Chikin Date: Fri, 25 Apr 2025 16:47:48 -0700 Subject: [PATCH] [clang] Allow parameterized 'isWeakImport' based on an enclosing platform version Similarly to 'CheckAvailability' and 'getAvailability', set 'Decl::isWeakImported' to allow querying using an external target platform version. In https://github.com/swiftlang/llvm-project/pull/7916 we have added support for configuring 'clang::CodeGenerator' with a differently-versioned target info, and this change adopts the code generator's target info in order to also determine weakly-imported linkage on declarations during code-gen. Before this change, they were relying on the 'ASTContext' to specify the target info, which may differ from code-gen's. --- clang/include/clang/AST/DeclBase.h | 2 +- clang/lib/AST/DeclBase.cpp | 4 ++-- clang/lib/CodeGen/CodeGenModule.cpp | 7 ++++--- clang/unittests/AST/DeclTest.cpp | 6 ++++++ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 04dbd1db6cba8..d4cb103852ab6 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -771,7 +771,7 @@ class alignas(8) Decl { /// 'weak_import' attribute, but may also be marked with an /// 'availability' attribute where we're targing a platform prior to /// the introduction of this feature. - bool isWeakImported() const; + bool isWeakImported(VersionTuple EnclosingVersion = VersionTuple()) const; /// Determines whether this symbol can be weak-imported, /// e.g., whether it would be well-formed to add the weak_import diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index bc3d01de78298..8479aa5d4037d 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -840,7 +840,7 @@ bool Decl::canBeWeakImported(bool &IsDefinition) const { return false; } -bool Decl::isWeakImported() const { +bool Decl::isWeakImported(VersionTuple EnclosingVersion) const { bool IsDefinition; if (!canBeWeakImported(IsDefinition)) return false; @@ -851,7 +851,7 @@ bool Decl::isWeakImported() const { if (const auto *Availability = dyn_cast(A)) { if (CheckAvailability(getASTContext(), Availability, nullptr, - VersionTuple()) == AR_NotYetIntroduced) + EnclosingVersion) == AR_NotYetIntroduced) return true; } else if (const auto *DA = dyn_cast(A)) { auto DomainName = DA->getDomain(); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 5507372424563..d8db38b7fae05 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2758,14 +2758,15 @@ void CodeGenModule::SetInternalFunctionAttributes(GlobalDecl GD, setNonAliasAttributes(GD, F); } -static void setLinkageForGV(llvm::GlobalValue *GV, const NamedDecl *ND) { +static void setLinkageForGV(llvm::GlobalValue *GV, const NamedDecl *ND, + VersionTuple EnclosingVersion = VersionTuple()) { // Set linkage and visibility in case we never see a definition. LinkageInfo LV = ND->getLinkageAndVisibility(); // Don't set internal linkage on declarations. // "extern_weak" is overloaded in LLVM; we probably should have // separate linkage types for this. if (isExternallyVisible(LV.getLinkage()) && - (ND->hasAttr() || ND->isWeakImported())) + (ND->hasAttr() || ND->isWeakImported(EnclosingVersion))) GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); } @@ -2870,7 +2871,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, // Only a few attributes are set on declarations; these may later be // overridden by a definition. - setLinkageForGV(F, FD); + setLinkageForGV(F, FD, Target.getTriple().getOSVersion()); setGVProperties(F, FD); // Setup target-specific attributes. diff --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp index fcc191957dad0..0f8cd680dbc14 100644 --- a/clang/unittests/AST/DeclTest.cpp +++ b/clang/unittests/AST/DeclTest.cpp @@ -108,6 +108,12 @@ TEST(Decl, Availability) { clang::AR_Unavailable) { setFailure("failed obsoleted"); } + if (Node.isWeakImported(clang::VersionTuple(10, 1)) != true) { + setFailure("failed not weak imported"); + } + if (Node.isWeakImported(clang::VersionTuple(10, 10)) != false) { + setFailure("failed weak imported"); + } if (Node.getAvailability() != clang::AR_Deprecated) setFailure("did not default to target OS version");