llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Morris Hafner (mmha) <details> <summary>Changes</summary> This change implements variable linkage types in ClangIR except for common linkage which requires Comdat support. --- Patch is 37.19 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/129072.diff 19 Files Affected: - (modified) clang/include/clang/CIR/Dialect/IR/CIRDialect.h (+2) - (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+79-4) - (added) clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h (+119) - (modified) clang/include/clang/CIR/Dialect/IR/CMakeLists.txt (+3-1) - (added) clang/include/clang/CIR/Interfaces/CIROpInterfaces.h (+29) - (added) clang/include/clang/CIR/Interfaces/CIROpInterfaces.td (+63) - (modified) clang/include/clang/CIR/Interfaces/CMakeLists.txt (+9) - (modified) clang/include/clang/CIR/MissingFeatures.h (+4) - (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+201-1) - (modified) clang/lib/CIR/CodeGen/CIRGenModule.h (+12) - (modified) clang/lib/CIR/CodeGen/CMakeLists.txt (+1) - (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+7-1) - (modified) clang/lib/CIR/Dialect/IR/CMakeLists.txt (+2-1) - (modified) clang/lib/CIR/FrontendAction/CMakeLists.txt (+4) - (added) clang/lib/CIR/Interfaces/CIROpInterfaces.cpp (+22) - (modified) clang/lib/CIR/Interfaces/CMakeLists.txt (+3-1) - (modified) clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt (+5) - (modified) clang/test/CIR/global-var-simple.cpp (+32-32) - (added) clang/test/CIR/global_var_linkage.cpp (+11) ``````````diff diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h index 683176b139ca4..0684cf5034f5d 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h @@ -28,6 +28,8 @@ #include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIROpsDialect.h.inc" +#include "clang/CIR/Dialect/IR/CIROpsEnums.h" +#include "clang/CIR/Interfaces/CIROpInterfaces.h" // TableGen'erated files for MLIR dialects require that a macro be defined when // they are included. GET_OP_CLASSES tells the file to define the classes for diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index f9ce38588e436..7c5d339130ec5 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -18,6 +18,8 @@ include "clang/CIR/Dialect/IR/CIRDialect.td" include "clang/CIR/Dialect/IR/CIRTypes.td" include "clang/CIR/Dialect/IR/CIRAttrs.td" +include "clang/CIR/Interfaces/CIROpInterfaces.td" + include "mlir/IR/BuiltinAttributeInterfaces.td" include "mlir/IR/EnumAttr.td" include "mlir/IR/SymbolInterfaces.td" @@ -278,6 +280,59 @@ def ScopeOp : CIR_Op<"scope", [ // GlobalOp //===----------------------------------------------------------------------===// +// Linkage types. This is currently a replay of llvm/IR/GlobalValue.h, this is +// currently handy as part of forwarding appropriate linkage types for LLVM +// lowering, specially useful for C++ support. + +// Externally visible function +def Global_ExternalLinkage : + I32EnumAttrCase<"ExternalLinkage", 0, "external">; +// Available for inspection, not emission. +def Global_AvailableExternallyLinkage : + I32EnumAttrCase<"AvailableExternallyLinkage", 1, "available_externally">; +// Keep one copy of function when linking (inline) +def Global_LinkOnceAnyLinkage : + I32EnumAttrCase<"LinkOnceAnyLinkage", 2, "linkonce">; +// Same, but only replaced by something equivalent. +def Global_LinkOnceODRLinkage : + I32EnumAttrCase<"LinkOnceODRLinkage", 3, "linkonce_odr">; +// Keep one copy of named function when linking (weak) +def Global_WeakAnyLinkage : + I32EnumAttrCase<"WeakAnyLinkage", 4, "weak">; +// Same, but only replaced by something equivalent. +def Global_WeakODRLinkage : + I32EnumAttrCase<"WeakODRLinkage", 5, "weak_odr">; +// TODO: should we add something like appending linkage too? +// Special purpose, only applies to global arrays +// def Global_AppendingLinkage : +// I32EnumAttrCase<"AppendingLinkage", 6, "appending">; +// Rename collisions when linking (static functions). +def Global_InternalLinkage : + I32EnumAttrCase<"InternalLinkage", 7, "internal">; +// Like Internal, but omit from symbol table, prefix it with +// "cir_" to prevent clash with MLIR's symbol "private". +def Global_PrivateLinkage : + I32EnumAttrCase<"PrivateLinkage", 8, "cir_private">; +// ExternalWeak linkage description. +def Global_ExternalWeakLinkage : + I32EnumAttrCase<"ExternalWeakLinkage", 9, "extern_weak">; +// Tentative definitions. +def Global_CommonLinkage : + I32EnumAttrCase<"CommonLinkage", 10, "common">; + +/// An enumeration for the kinds of linkage for global values. +def GlobalLinkageKind : I32EnumAttr< + "GlobalLinkageKind", + "Linkage type/kind", + [Global_ExternalLinkage, Global_AvailableExternallyLinkage, + Global_LinkOnceAnyLinkage, Global_LinkOnceODRLinkage, + Global_WeakAnyLinkage, Global_WeakODRLinkage, + Global_InternalLinkage, Global_PrivateLinkage, + Global_ExternalWeakLinkage, Global_CommonLinkage + ]> { + let cppNamespace = "::cir"; +} + // TODO(CIR): For starters, cir.global has only name and type. The other // properties of a global variable will be added over time as more of ClangIR // is upstreamed. @@ -289,12 +344,19 @@ def GlobalOp : CIR_Op<"global"> { The backing memory for the variable is allocated statically and is described by the type of the variable. + + The `linkage` tracks C/C++ linkage types, currently very similar to LLVM's. }]; - let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type, - OptionalAttr<AnyAttr>:$initial_value); + let arguments = (ins SymbolNameAttr:$sym_name, + TypeAttr:$sym_type, + Arg<GlobalLinkageKind, "linkage type">:$linkage, + OptionalAttr<AnyAttr>:$initial_value, + UnitAttr:$dsolocal); let assemblyFormat = [{ + $linkage + (`dsolocal` $dsolocal^)? $sym_name custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value) attr-dict @@ -303,12 +365,25 @@ def GlobalOp : CIR_Op<"global"> { let extraClassDeclaration = [{ bool isDeclaration() { return !getInitialValue(); } bool hasInitializer() { return !isDeclaration(); } + bool hasAvailableExternallyLinkage() { + return cir::isAvailableExternallyLinkage(getLinkage()); + } + bool hasInternalLinkage() { + return cir::isInternalLinkage(getLinkage()); + } + /// Whether the definition of this global may be replaced at link time. + bool isWeakForLinker() { return cir::isWeakForLinker(getLinkage()); } + bool isDSOLocal() { return getDsolocal(); } }]; let skipDefaultBuilders = 1; - let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name, - "mlir::Type":$sym_type)>]; + let builders = [OpBuilder<(ins + "llvm::StringRef":$sym_name, + "mlir::Type":$sym_type, + // CIR defaults to external linkage. + CArg<"cir::GlobalLinkageKind", + "cir::GlobalLinkageKind::ExternalLinkage">:$linkage)>]; let hasVerifier = 1; } diff --git a/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h b/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h new file mode 100644 index 0000000000000..a1e32209555f3 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h @@ -0,0 +1,119 @@ +//===- CIROpsEnumsDialect.h - MLIR Dialect for CIR ----------------------*- C++ +//-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the Target dialect for CIR in MLIR. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_DIALECT_CIR_CIROPSENUMS_H_ +#define MLIR_DIALECT_CIR_CIROPSENUMS_H_ + +#include "mlir/IR/BuiltinAttributes.h" +#include "clang/CIR/Dialect/IR/CIROpsEnums.h.inc" + +namespace cir { + +static bool isExternalLinkage(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::ExternalLinkage; +} +static bool isAvailableExternallyLinkage(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::AvailableExternallyLinkage; +} +static bool isLinkOnceAnyLinkage(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::LinkOnceAnyLinkage; +} +static bool isLinkOnceODRLinkage(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::LinkOnceODRLinkage; +} +static bool isLinkOnceLinkage(GlobalLinkageKind linkage) { + return isLinkOnceAnyLinkage(linkage) || isLinkOnceODRLinkage(linkage); +} +static bool isWeakAnyLinkage(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::WeakAnyLinkage; +} +static bool isWeakODRLinkage(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::WeakODRLinkage; +} +static bool isWeakLinkage(GlobalLinkageKind linkage) { + return isWeakAnyLinkage(linkage) || isWeakODRLinkage(linkage); +} +static bool isInternalLinkage(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::InternalLinkage; +} +static bool isPrivateLinkage(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::PrivateLinkage; +} +static bool isLocalLinkage(GlobalLinkageKind linkage) { + return isInternalLinkage(linkage) || isPrivateLinkage(linkage); +} +static bool isExternalWeakLinkage(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::ExternalWeakLinkage; +} +LLVM_ATTRIBUTE_UNUSED static bool isCommonLinkage(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::CommonLinkage; +} +LLVM_ATTRIBUTE_UNUSED static bool +isValidDeclarationLinkage(GlobalLinkageKind linkage) { + return isExternalWeakLinkage(linkage) || isExternalLinkage(linkage); +} + +/// Whether the definition of this global may be replaced by something +/// non-equivalent at link time. For example, if a function has weak linkage +/// then the code defining it may be replaced by different code. +LLVM_ATTRIBUTE_UNUSED static bool +isInterposableLinkage(GlobalLinkageKind linkage) { + switch (linkage) { + case GlobalLinkageKind::WeakAnyLinkage: + case GlobalLinkageKind::LinkOnceAnyLinkage: + case GlobalLinkageKind::CommonLinkage: + case GlobalLinkageKind::ExternalWeakLinkage: + return true; + + case GlobalLinkageKind::AvailableExternallyLinkage: + case GlobalLinkageKind::LinkOnceODRLinkage: + case GlobalLinkageKind::WeakODRLinkage: + // The above three cannot be overridden but can be de-refined. + + case GlobalLinkageKind::ExternalLinkage: + case GlobalLinkageKind::InternalLinkage: + case GlobalLinkageKind::PrivateLinkage: + return false; + } + llvm_unreachable("Fully covered switch above!"); +} + +/// Whether the definition of this global may be discarded if it is not used +/// in its compilation unit. +LLVM_ATTRIBUTE_UNUSED static bool +isDiscardableIfUnused(GlobalLinkageKind linkage) { + return isLinkOnceLinkage(linkage) || isLocalLinkage(linkage) || + isAvailableExternallyLinkage(linkage); +} + +/// Whether the definition of this global may be replaced at link time. NB: +/// Using this method outside of the code generators is almost always a +/// mistake: when working at the IR level use isInterposable instead as it +/// knows about ODR semantics. +LLVM_ATTRIBUTE_UNUSED static bool isWeakForLinker(GlobalLinkageKind linkage) { + return linkage == GlobalLinkageKind::WeakAnyLinkage || + linkage == GlobalLinkageKind::WeakODRLinkage || + linkage == GlobalLinkageKind::LinkOnceAnyLinkage || + linkage == GlobalLinkageKind::LinkOnceODRLinkage || + linkage == GlobalLinkageKind::CommonLinkage || + linkage == GlobalLinkageKind::ExternalWeakLinkage; +} + +LLVM_ATTRIBUTE_UNUSED static bool isValidLinkage(GlobalLinkageKind gl) { + return isExternalLinkage(gl) || isLocalLinkage(gl) || isWeakLinkage(gl) || + isLinkOnceLinkage(gl); +} + +} // namespace cir + +#endif // MLIR_DIALECT_CIR_CIROPSENUMS_H_ diff --git a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt index 1fdbc24ba6b4a..39292fb541daa 100644 --- a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt +++ b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt @@ -16,4 +16,6 @@ add_dependencies(mlir-headers MLIRCIROpsIncGen) mlir_tablegen(CIROpsAttributes.h.inc -gen-attrdef-decls) mlir_tablegen(CIROpsAttributes.cpp.inc -gen-attrdef-defs) -add_public_tablegen_target(MLIRCIRAttrsEnumsGen) +mlir_tablegen(CIROpsEnums.h.inc -gen-enum-decls) +mlir_tablegen(CIROpsEnums.cpp.inc -gen-enum-defs) +add_public_tablegen_target(MLIRCIREnumsGen) diff --git a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.h b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.h new file mode 100644 index 0000000000000..86064619af7db --- /dev/null +++ b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.h @@ -0,0 +1,29 @@ +//===- CIROpInterfaces.h - CIR Op Interfaces --------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_INTERFACES_CIR_OP_H_ +#define MLIR_INTERFACES_CIR_OP_H_ + +#include "mlir/IR/Attributes.h" +#include "mlir/IR/Operation.h" +#include "mlir/IR/Value.h" +#include "mlir/Interfaces/CallInterfaces.h" + +#include "clang/AST/Attr.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/Mangle.h" +#include "clang/CIR/Dialect/IR/CIROpsEnums.h" + +namespace cir {} // namespace cir + +/// Include the generated interface declarations. +#include "clang/CIR/Interfaces/CIROpInterfaces.h.inc" + +namespace cir {} // namespace cir + +#endif // MLIR_INTERFACES_CIR_OP_H_ diff --git a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td new file mode 100644 index 0000000000000..b765a3e65f70b --- /dev/null +++ b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td @@ -0,0 +1,63 @@ +//===- CIROpInterfaces.td - CIR Op Interface Definitions --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_CIR_OP_INTERFACES +#define MLIR_CIR_OP_INTERFACES + +include "mlir/IR/OpBase.td" + +let cppNamespace = "::cir" in { + def CIRGlobalValueInterface + : OpInterface<"CIRGlobalValueInterface"> { + + let methods = [ + InterfaceMethod<"", + "bool", "hasAvailableExternallyLinkage", (ins), [{}], + /*defaultImplementation=*/[{ return false; }] + >, + InterfaceMethod<"", + "bool", "hasLocalLinkage", (ins), [{}], + /*defaultImplementation=*/[{ + return cir::isLocalLinkage($_op.getLinkage()); + }] + >, + InterfaceMethod<"", + "bool", "hasExternalWeakLinkage", (ins), [{}], + /*defaultImplementation=*/[{ + return cir::isExternalWeakLinkage($_op.getLinkage()); + }] + >, + InterfaceMethod<"", + "bool", "isExternalLinkage", (ins), [{}], + /*defaultImplementation=*/[{ + return cir::isExternalLinkage($_op.getLinkage()); + }] + >, + InterfaceMethod<"", + "bool", "isDeclarationForLinker", (ins), [{}], + /*defaultImplementation=*/[{ + if ($_op.hasAvailableExternallyLinkage()) + return true; + return $_op.isDeclaration(); + }] + >, + InterfaceMethod<"", + "void", "setDSOLocal", (ins "bool":$val), [{}], + /*defaultImplementation=*/[{ + $_op.setDsolocal(val); + }] + >, + ]; + let extraClassDeclaration = [{ + bool canBenefitFromLocalAlias(); + }]; + } + +} // namespace cir + +#endif // MLIR_CIR_OP_INTERFACES diff --git a/clang/include/clang/CIR/Interfaces/CMakeLists.txt b/clang/include/clang/CIR/Interfaces/CMakeLists.txt index 1c90b6b5a23cb..e9929f6964605 100644 --- a/clang/include/clang/CIR/Interfaces/CMakeLists.txt +++ b/clang/include/clang/CIR/Interfaces/CMakeLists.txt @@ -3,6 +3,14 @@ # directory which is not the case for CIR (and also FIR, both have similar # workarounds). +function(add_clang_mlir_op_interface interface) + set(LLVM_TARGET_DEFINITIONS ${interface}.td) + mlir_tablegen(${interface}.h.inc -gen-op-interface-decls) + mlir_tablegen(${interface}.cpp.inc -gen-op-interface-defs) + add_public_tablegen_target(MLIR${interface}IncGen) + add_dependencies(mlir-generic-headers MLIR${interface}IncGen) +endfunction() + function(add_clang_mlir_type_interface interface) set(LLVM_TARGET_DEFINITIONS ${interface}.td) mlir_tablegen(${interface}.h.inc -gen-type-interface-decls) @@ -11,4 +19,5 @@ function(add_clang_mlir_type_interface interface) add_dependencies(mlir-generic-headers MLIR${interface}IncGen) endfunction() +add_clang_mlir_op_interface(CIROpInterfaces) add_clang_mlir_type_interface(CIRFPTypeInterface) diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index d4fcd52e7e6e3..0d0083850eb70 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -36,6 +36,10 @@ struct MissingFeatures { static bool opGlobalConstant() { return false; } static bool opGlobalAlignment() { return false; } static bool opGlobalLinkage() { return false; } + + static bool supportIFuncAttr() { return false; } + static bool supportVisibility() { return false; } + static bool supportComdat() { return false; } }; } // namespace cir diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index d8acc99e550ad..8eb08228075ef 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -18,6 +18,7 @@ #include "clang/AST/GlobalDecl.h" #include "clang/Basic/SourceManager.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/MissingFeatures.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Location.h" @@ -31,7 +32,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, const clang::CodeGenOptions &cgo, DiagnosticsEngine &diags) : builder(mlirContext, *this), astContext(astContext), - langOpts(astContext.getLangOpts()), + langOpts(astContext.getLangOpts()), codeGenOpts(cgo), theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&mlirContext))}, diags(diags), target(astContext.getTargetInfo()), genTypes(*this) { @@ -176,6 +177,18 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd, } varOp.setInitialValueAttr(initializer); } + + // Set CIR's linkage type as appropriate. + cir::GlobalLinkageKind linkage = + getCIRLinkageVarDefinition(vd, /*IsConstant=*/false); + + // Set CIR linkage and DLL storage class. + varOp.setLinkage(linkage); + + if (linkage == cir::GlobalLinkageKind::CommonLinkage) { + errorNYI(initExpr->getSourceRange(), "common linkage"); + } + theModule.push_back(varOp); } else { errorNYI(vd->getSourceRange().getBegin(), @@ -210,6 +223,193 @@ void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd, llvm_unreachable("Invalid argument to CIRGenModule::emitGlobalDefinition"); } +static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d) { + assert(!cir::MissingFeatures::supportComdat()); + + if (d.hasAttr<SelectAnyAttr>()) + return true; + + GVALinkage linkage; + if (auto *vd = dyn_cast<VarDecl>(&d)) + linkage = cgm.getASTContext().GetGVALinkageForVariable(vd); + else + linkage = + cgm.getASTContext().GetGVALinkageForFunction(cast<FunctionDecl>(&d)); + + switch (linkage) { + case clang::GVA_Internal: + case clang::GVA_AvailableExternally: + case clang::GVA_StrongExternal: + return false; + case clang::GVA_DiscardableODR: + case clang::GVA_StrongODR: + return true; + } + llvm_unreachable("No such linkage"); +} + +// TODO(CIR): this could be a common method between LLVM codegen. +static bool isVarDeclStrongDefinition(const ASTContext &astContext, + CIRGenModule &cgm, const VarDecl *vd, + bool noCommon) { + // Don't give variables common linkage if -fno-common was specified unless it + // was overridden by a NoCommon attribute. + if ((noCommon || vd->hasAttr<NoCommonAttr>()) && !vd->hasAttr<CommonAttr>()) + return true; + + // C11 6.9.2/2: + // A declaration of an identifier for an object that has file scope without + // an initializer, and without a storage-class specifier or with the + // storage-class specifier static, constitutes a tentative definition. + if (vd->getInit() || vd->hasExternalStorage()) + return true; + + // A variable cannot be both common and exist in a section. + if (vd->hasAttr<SectionAttr>()) + return true; + + // A variable cannot be both common and exist in a section. + // We don't try to determine which is the right section in the front-end. + // If no specialized section name is applicable, it will resort to default. + if (vd->hasAttr<PragmaClangBSSSectionAttr>() || + vd->hasAttr<PragmaClangDataSectionAttr>() || + vd->hasAttr<PragmaClangRelroSectionAttr>() || + vd->hasAttr<PragmaClangRodataSectionAttr>()) + return true; + + // Thread local vars aren't considered common linkage. + if (... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/129072 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits