1//===--- ModuleUtils.cpp - Shared module emission queries -----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "clang/CodeGenUtils/ModuleUtils.h"
10#include "clang/AST/Attr.h"
11#include "clang/Basic/TargetInfo.h"
12
13namespace clang::CodeGenUtils {
14
15LangAS getGlobalConstantAddressSpace(const LangOptions &LangOpts,
16 const TargetInfo &Target) {
17 // OpenCL v1.2 s6.5.3: a string literal is in the constant address space.
18 if (LangOpts.OpenCL)
19 return LangAS::opencl_constant;
20 if (LangOpts.SYCLIsDevice)
21 return LangAS::sycl_global;
22 if (LangOpts.HIP && LangOpts.CUDAIsDevice && Target.getTriple().isSPIRV())
23 // For HIPSPV map literals to cuda_device (maps to CrossWorkGroup in SPIR-V)
24 // instead of default AS (maps to Generic in SPIR-V). Otherwise, we end up
25 // with OpVariable instructions with Generic storage class which is not
26 // allowed (SPIR-V V1.6 s3.42.8). Also, mapping literals to SPIR-V
27 // UniformConstant storage class is not viable as pointers to it may not be
28 // casted to Generic pointers which are used to model HIP's "flat" pointers.
29 return LangAS::cuda_device;
30 if (auto AS = Target.getConstantAddressSpace())
31 return *AS;
32 return LangAS::Default;
33}
34
35bool hasUnwindExceptions(const LangOptions &LangOpts) {
36 // If exceptions are completely disabled, obviously this is false.
37 if (!LangOpts.Exceptions)
38 return false;
39
40 // If C++ exceptions are enabled, this is true.
41 if (LangOpts.CXXExceptions)
42 return true;
43
44 // If ObjC exceptions are enabled, this depends on the ABI.
45 if (LangOpts.ObjCExceptions) {
46 return LangOpts.ObjCRuntime.hasUnwindExceptions();
47 }
48
49 return true;
50}
51
52bool isVarDeclStrongDefinition(const ASTContext &Ctx, const VarDecl *D,
53 bool NoCommon) {
54 // Don't give variables common linkage if -fno-common was specified unless it
55 // was overridden by a NoCommon attribute.
56 if ((NoCommon || D->hasAttr<NoCommonAttr>()) && !D->hasAttr<CommonAttr>())
57 return true;
58
59 // C11 6.9.2/2:
60 // A declaration of an identifier for an object that has file scope without
61 // an initializer, and without a storage-class specifier or with the
62 // storage-class specifier static, constitutes a tentative definition.
63 if (D->getInit() || D->hasExternalStorage())
64 return true;
65
66 // A variable cannot be both common and exist in a section.
67 if (D->hasAttr<SectionAttr>())
68 return true;
69
70 // A variable cannot be both common and exist in a section.
71 // We don't try to determine which is the right section in the front-end.
72 // If no specialized section name is applicable, it will resort to default.
73 if (D->hasAttr<PragmaClangBSSSectionAttr>() ||
74 D->hasAttr<PragmaClangDataSectionAttr>() ||
75 D->hasAttr<PragmaClangRelroSectionAttr>() ||
76 D->hasAttr<PragmaClangRodataSectionAttr>())
77 return true;
78
79 // Thread local vars aren't considered common linkage.
80 if (D->getTLSKind())
81 return true;
82
83 // Tentative definitions marked with WeakImportAttr are true definitions.
84 if (D->hasAttr<WeakImportAttr>())
85 return true;
86
87 // A variable cannot be both common and exist in a comdat.
88 if (shouldBeInCOMDAT(Ctx, D: *D))
89 return true;
90
91 // Declarations with a required alignment do not have common linkage in MSVC
92 // mode.
93 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft()) {
94 if (D->hasAttr<AlignedAttr>())
95 return true;
96 QualType VarType = D->getType();
97 if (Ctx.isAlignmentRequired(T: VarType))
98 return true;
99
100 if (const auto *RD = VarType->getAsRecordDecl()) {
101 for (const FieldDecl *FD : RD->fields()) {
102 if (FD->isBitField())
103 continue;
104 if (FD->hasAttr<AlignedAttr>())
105 return true;
106 if (Ctx.isAlignmentRequired(T: FD->getType()))
107 return true;
108 }
109 }
110 }
111
112 // Microsoft's link.exe doesn't support alignments greater than 32 bytes for
113 // common symbols, so symbols with greater alignment requirements cannot be
114 // common.
115 // Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
116 // alignments for common symbols via the aligncomm directive, so this
117 // restriction only applies to MSVC environments.
118 if (Ctx.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
119 Ctx.getTypeAlignIfKnown(T: D->getType()) >
120 Ctx.toBits(CharSize: CharUnits::fromQuantity(Quantity: 32)))
121 return true;
122
123 return false;
124}
125
126bool shouldBeInCOMDAT(const ASTContext &Ctx, const Decl &D) {
127 if (!Ctx.getTargetInfo().getTriple().supportsCOMDAT())
128 return false;
129
130 if (D.hasAttr<SelectAnyAttr>())
131 return true;
132
133 GVALinkage Linkage;
134 if (auto *VD = dyn_cast<VarDecl>(Val: &D))
135 Linkage = Ctx.GetGVALinkageForVariable(VD);
136 else
137 Linkage = Ctx.GetGVALinkageForFunction(FD: cast<FunctionDecl>(Val: &D));
138
139 switch (Linkage) {
140 case GVA_Internal:
141 case GVA_AvailableExternally:
142 case GVA_StrongExternal:
143 return false;
144 case GVA_DiscardableODR:
145 case GVA_StrongODR:
146 return true;
147 }
148 llvm_unreachable("No such linkage");
149}
150
151} // namespace clang::CodeGenUtils
152