clang 24.0.0git
ModuleUtils.cpp
Go to the documentation of this file.
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
10#include "clang/AST/Attr.h"
12#include "llvm/ADT/SetVector.h"
13
14namespace clang::CodeGenUtils {
15
17 const TargetInfo &Target) {
18 // OpenCL v1.2 s6.5.3: a string literal is in the constant address space.
19 if (LangOpts.OpenCL)
21 if (LangOpts.SYCLIsDevice)
23 if (LangOpts.HIP && LangOpts.CUDAIsDevice && Target.getTriple().isSPIRV())
24 // For HIPSPV map literals to cuda_device (maps to CrossWorkGroup in SPIR-V)
25 // instead of default AS (maps to Generic in SPIR-V). Otherwise, we end up
26 // with OpVariable instructions with Generic storage class which is not
27 // allowed (SPIR-V V1.6 s3.42.8). Also, mapping literals to SPIR-V
28 // UniformConstant storage class is not viable as pointers to it may not be
29 // casted to Generic pointers which are used to model HIP's "flat" pointers.
31 if (auto AS = Target.getConstantAddressSpace())
32 return *AS;
33 return LangAS::Default;
34}
35
36bool hasUnwindExceptions(const LangOptions &LangOpts) {
37 // If exceptions are completely disabled, obviously this is false.
38 if (!LangOpts.Exceptions)
39 return false;
40
41 // If C++ exceptions are enabled, this is true.
42 if (LangOpts.CXXExceptions)
43 return true;
44
45 // If ObjC exceptions are enabled, this depends on the ABI.
46 if (LangOpts.ObjCExceptions) {
47 return LangOpts.ObjCRuntime.hasUnwindExceptions();
48 }
49
50 return true;
51}
52
54 bool NoCommon) {
55 // Don't give variables common linkage if -fno-common was specified unless it
56 // was overridden by a NoCommon attribute.
57 if ((NoCommon || D->hasAttr<NoCommonAttr>()) && !D->hasAttr<CommonAttr>())
58 return true;
59
60 // C11 6.9.2/2:
61 // A declaration of an identifier for an object that has file scope without
62 // an initializer, and without a storage-class specifier or with the
63 // storage-class specifier static, constitutes a tentative definition.
64 if (D->getInit() || D->hasExternalStorage())
65 return true;
66
67 // A variable cannot be both common and exist in a section.
68 if (D->hasAttr<SectionAttr>())
69 return true;
70
71 // A variable cannot be both common and exist in a section.
72 // We don't try to determine which is the right section in the front-end.
73 // If no specialized section name is applicable, it will resort to default.
74 if (D->hasAttr<PragmaClangBSSSectionAttr>() ||
75 D->hasAttr<PragmaClangDataSectionAttr>() ||
76 D->hasAttr<PragmaClangRelroSectionAttr>() ||
77 D->hasAttr<PragmaClangRodataSectionAttr>())
78 return true;
79
80 // Thread local vars aren't considered common linkage.
81 if (D->getTLSKind())
82 return true;
83
84 // Tentative definitions marked with WeakImportAttr are true definitions.
85 if (D->hasAttr<WeakImportAttr>())
86 return true;
87
88 // A variable cannot be both common and exist in a comdat.
89 if (shouldBeInCOMDAT(Ctx, *D))
90 return true;
91
92 // Declarations with a required alignment do not have common linkage in MSVC
93 // mode.
94 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft()) {
95 if (D->hasAttr<AlignedAttr>())
96 return true;
97 QualType VarType = D->getType();
98 if (Ctx.isAlignmentRequired(VarType))
99 return true;
100
101 if (const auto *RD = VarType->getAsRecordDecl()) {
102 for (const FieldDecl *FD : RD->fields()) {
103 if (FD->isBitField())
104 continue;
105 if (FD->hasAttr<AlignedAttr>())
106 return true;
107 if (Ctx.isAlignmentRequired(FD->getType()))
108 return true;
109 }
110 }
111 }
112
113 // Microsoft's link.exe doesn't support alignments greater than 32 bytes for
114 // common symbols, so symbols with greater alignment requirements cannot be
115 // common.
116 // Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
117 // alignments for common symbols via the aligncomm directive, so this
118 // restriction only applies to MSVC environments.
119 if (Ctx.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
120 Ctx.getTypeAlignIfKnown(D->getType()) >
122 return true;
123
124 return false;
125}
126
127bool shouldBeInCOMDAT(const ASTContext &Ctx, const Decl &D) {
128 if (!Ctx.getTargetInfo().getTriple().supportsCOMDAT())
129 return false;
130
131 if (D.hasAttr<SelectAnyAttr>())
132 return true;
133
135 if (auto *VD = dyn_cast<VarDecl>(&D))
137 else
139
140 switch (Linkage) {
141 case GVA_Internal:
144 return false;
146 case GVA_StrongODR:
147 return true;
148 }
149 llvm_unreachable("No such linkage");
150}
151
154 llvm::ArrayRef<Module *> Imported) {
156 if (Primary && Primary->isInterfaceOrPartition()) {
157 // The modules the unit exports.
158 for (auto I : Primary->Exports)
159 Candidates.insert(I.first);
160 // The modules it only imports.
161 Candidates.insert_range(Primary->Imports);
162 // The modules it imports in the global module fragment or the private
163 // module fragment.
164 for (Module *SubM : Primary->submodules()) {
165 assert(
166 (SubM->isGlobalModule() || SubM->isPrivateModule()) &&
167 "The sub modules of C++20 module unit should only be global module "
168 "fragments or private module fragments.");
169 assert(SubM->Exports.empty() &&
170 "The global module fragments and the private module fragments are "
171 "not allowed to export import modules.");
172 Candidates.insert_range(SubM->Imports);
173 }
174 } else {
175 Candidates.insert_range(Imported);
176 }
177
179 for (Module *M : Candidates) {
180 // No Itanium initializer in header like modules.
181 if (M->isHeaderLikeModule())
182 continue;
183 // The initialization may be skipped when it is sure to do nothing.
184 if (!M->isNamedModuleInterfaceHasInit())
185 continue;
186 Result.push_back(M);
187 }
188 return Result;
189}
190
191} // namespace clang::CodeGenUtils
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:245
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const
unsigned getTypeAlignIfKnown(QualType T, bool NeedsPreferredAlignment=false) const
Return the alignment of a type, in bits, or 0 if the type is incomplete and we cannot determine the a...
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:971
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:58
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool hasAttr() const
Definition DeclBase.h:587
Represents a member of a struct/union/class.
Definition Decl.h:3299
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
Describes a module or submodule.
Definition Module.h:340
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
Definition Module.h:674
bool isInterfaceOrPartition() const
Definition Module.h:892
llvm::iterator_range< submodule_iterator > submodules()
Definition Module.h:1079
llvm::SmallVector< ModuleRef, 2 > Imports
The set of modules imported by this module, and on which this module depends.
Definition Module.h:661
bool hasUnwindExceptions() const
Does this runtime use zero-cost exceptions?
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
Exposes information about the current target.
Definition TargetInfo.h:228
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
QualType getType() const
Definition Decl.h:724
Represents a variable declaration or definition.
Definition Decl.h:933
TLSKind getTLSKind() const
Definition Decl.cpp:2148
const Expr * getInit() const
Definition Decl.h:1392
bool hasExternalStorage() const
Returns true if a variable has extern or private_extern storage.
Definition Decl.h:1239
Defines the clang::TargetInfo interface.
LangAS getGlobalConstantAddressSpace(const LangOptions &LangOpts, const TargetInfo &Target)
Determines whether the language options require us to model unwind exceptions.
bool isVarDeclStrongDefinition(const ASTContext &Ctx, const VarDecl *D, bool NoCommon)
Check whether D is a strong definition, and thus must not be given common linkage.
llvm::SmallVector< Module *, 8 > importedModulesToInitialize(Module *Primary, llvm::ArrayRef< Module * > Imported)
The C++20 named modules whose Itanium initializer function the global init function of a translation ...
bool hasUnwindExceptions(const LangOptions &LangOpts)
bool shouldBeInCOMDAT(const ASTContext &Ctx, const Decl &D)
Check whether D should be emitted into a COMDAT group.
GVALinkage
A more specific kind of linkage than enum Linkage.
Definition Linkage.h:72
@ GVA_StrongODR
Definition Linkage.h:77
@ GVA_StrongExternal
Definition Linkage.h:76
@ GVA_AvailableExternally
Definition Linkage.h:74
@ GVA_DiscardableODR
Definition Linkage.h:75
@ GVA_Internal
Definition Linkage.h:73
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
Definition Linkage.h:24
@ Result
The result type of a method or function.
Definition TypeBase.h:906
LangAS
Defines the address space values used by the address space qualifier of QualType.
U cast(CodeGen::Address addr)
Definition Address.h:327