1//===- CIRGenModule.cpp - Per-Module state for CIR generation -------------===//
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// This is the internal per-translation-unit state used for CIR translation.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenModule.h"
14#include "CIRGenCXXABI.h"
15#include "CIRGenConstantEmitter.h"
16#include "CIRGenFunction.h"
17
18#include "clang/AST/ASTContext.h"
19#include "clang/AST/DeclBase.h"
20#include "clang/AST/DeclOpenACC.h"
21#include "clang/AST/GlobalDecl.h"
22#include "clang/AST/RecordLayout.h"
23#include "clang/Basic/SourceManager.h"
24#include "clang/CIR/Dialect/IR/CIRDialect.h"
25#include "clang/CIR/Interfaces/CIROpInterfaces.h"
26#include "clang/CIR/MissingFeatures.h"
27
28#include "CIRGenFunctionInfo.h"
29#include "mlir/IR/BuiltinOps.h"
30#include "mlir/IR/Location.h"
31#include "mlir/IR/MLIRContext.h"
32#include "mlir/IR/Verifier.h"
33
34using namespace clang;
35using namespace clang::CIRGen;
36
37static CIRGenCXXABI *createCXXABI(CIRGenModule &cgm) {
38 switch (cgm.getASTContext().getCXXABIKind()) {
39 case TargetCXXABI::GenericItanium:
40 case TargetCXXABI::GenericAArch64:
41 case TargetCXXABI::AppleARM64:
42 return CreateCIRGenItaniumCXXABI(cgm);
43
44 case TargetCXXABI::Fuchsia:
45 case TargetCXXABI::GenericARM:
46 case TargetCXXABI::iOS:
47 case TargetCXXABI::WatchOS:
48 case TargetCXXABI::GenericMIPS:
49 case TargetCXXABI::WebAssembly:
50 case TargetCXXABI::XL:
51 case TargetCXXABI::Microsoft:
52 cgm.errorNYI(feature: "C++ ABI kind not yet implemented");
53 return nullptr;
54 }
55
56 llvm_unreachable("invalid C++ ABI kind");
57}
58
59CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
60 clang::ASTContext &astContext,
61 const clang::CodeGenOptions &cgo,
62 DiagnosticsEngine &diags)
63 : builder(mlirContext, *this), astContext(astContext),
64 langOpts(astContext.getLangOpts()), codeGenOpts(cgo),
65 theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&mlirContext))},
66 diags(diags), target(astContext.getTargetInfo()),
67 abi(createCXXABI(cgm&: *this)), genTypes(*this) {
68
69 // Initialize cached types
70 VoidTy = cir::VoidType::get(&getMLIRContext());
71 SInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/true);
72 SInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/true);
73 SInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/true);
74 SInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/true);
75 SInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/true);
76 UInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/false);
77 UInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/false);
78 UInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/false);
79 UInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/false);
80 UInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/false);
81 FP16Ty = cir::FP16Type::get(&getMLIRContext());
82 BFloat16Ty = cir::BF16Type::get(&getMLIRContext());
83 FloatTy = cir::SingleType::get(&getMLIRContext());
84 DoubleTy = cir::DoubleType::get(&getMLIRContext());
85 FP80Ty = cir::FP80Type::get(&getMLIRContext());
86 FP128Ty = cir::FP128Type::get(&getMLIRContext());
87
88 PointerAlignInBytes =
89 astContext
90 .toCharUnitsFromBits(
91 BitSize: astContext.getTargetInfo().getPointerAlign(AddrSpace: LangAS::Default))
92 .getQuantity();
93
94 // TODO(CIR): Should be updated once TypeSizeInfoAttr is upstreamed
95 const unsigned sizeTypeSize =
96 astContext.getTypeSize(T: astContext.getSignedSizeType());
97 PtrDiffTy =
98 cir::IntType::get(&getMLIRContext(), sizeTypeSize, /*isSigned=*/true);
99
100 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
101 builder.getStringAttr(getTriple().str()));
102}
103
104CIRGenModule::~CIRGenModule() = default;
105
106/// FIXME: this could likely be a common helper and not necessarily related
107/// with codegen.
108/// Return the best known alignment for an unknown pointer to a
109/// particular class.
110CharUnits CIRGenModule::getClassPointerAlignment(const CXXRecordDecl *rd) {
111 if (!rd->hasDefinition())
112 return CharUnits::One(); // Hopefully won't be used anywhere.
113
114 auto &layout = astContext.getASTRecordLayout(rd);
115
116 // If the class is final, then we know that the pointer points to an
117 // object of that type and can use the full alignment.
118 if (rd->isEffectivelyFinal())
119 return layout.getAlignment();
120
121 // Otherwise, we have to assume it could be a subclass.
122 return layout.getNonVirtualAlignment();
123}
124
125CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t,
126 LValueBaseInfo *baseInfo) {
127 assert(!cir::MissingFeatures::opTBAA());
128
129 // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown, but
130 // that doesn't return the information we need to compute baseInfo.
131
132 // Honor alignment typedef attributes even on incomplete types.
133 // We also honor them straight for C++ class types, even as pointees;
134 // there's an expressivity gap here.
135 if (const auto *tt = t->getAs<TypedefType>()) {
136 if (unsigned align = tt->getDecl()->getMaxAlignment()) {
137 if (baseInfo)
138 *baseInfo = LValueBaseInfo(AlignmentSource::AttributedType);
139 return astContext.toCharUnitsFromBits(BitSize: align);
140 }
141 }
142
143 // Analyze the base element type, so we don't get confused by incomplete
144 // array types.
145 t = astContext.getBaseElementType(QT: t);
146
147 if (t->isIncompleteType()) {
148 // We could try to replicate the logic from
149 // ASTContext::getTypeAlignIfKnown, but nothing uses the alignment if the
150 // type is incomplete, so it's impossible to test. We could try to reuse
151 // getTypeAlignIfKnown, but that doesn't return the information we need
152 // to set baseInfo. So just ignore the possibility that the alignment is
153 // greater than one.
154 if (baseInfo)
155 *baseInfo = LValueBaseInfo(AlignmentSource::Type);
156 return CharUnits::One();
157 }
158
159 if (baseInfo)
160 *baseInfo = LValueBaseInfo(AlignmentSource::Type);
161
162 CharUnits alignment;
163 if (t.getQualifiers().hasUnaligned()) {
164 alignment = CharUnits::One();
165 } else {
166 assert(!cir::MissingFeatures::alignCXXRecordDecl());
167 alignment = astContext.getTypeAlignInChars(T: t);
168 }
169
170 // Cap to the global maximum type alignment unless the alignment
171 // was somehow explicit on the type.
172 if (unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
173 if (alignment.getQuantity() > maxAlign &&
174 !astContext.isAlignmentRequired(T: t))
175 alignment = CharUnits::fromQuantity(Quantity: maxAlign);
176 }
177 return alignment;
178}
179
180const TargetCIRGenInfo &CIRGenModule::getTargetCIRGenInfo() {
181 if (theTargetCIRGenInfo)
182 return *theTargetCIRGenInfo;
183
184 const llvm::Triple &triple = getTarget().getTriple();
185 switch (triple.getArch()) {
186 default:
187 assert(!cir::MissingFeatures::targetCIRGenInfoArch());
188
189 // Currently we just fall through to x86_64.
190 [[fallthrough]];
191
192 case llvm::Triple::x86_64: {
193 switch (triple.getOS()) {
194 default:
195 assert(!cir::MissingFeatures::targetCIRGenInfoOS());
196
197 // Currently we just fall through to x86_64.
198 [[fallthrough]];
199
200 case llvm::Triple::Linux:
201 theTargetCIRGenInfo = createX8664TargetCIRGenInfo(genTypes);
202 return *theTargetCIRGenInfo;
203 }
204 }
205 }
206}
207
208mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) {
209 assert(cLoc.isValid() && "expected valid source location");
210 const SourceManager &sm = astContext.getSourceManager();
211 PresumedLoc pLoc = sm.getPresumedLoc(Loc: cLoc);
212 StringRef filename = pLoc.getFilename();
213 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
214 pLoc.getLine(), pLoc.getColumn());
215}
216
217mlir::Location CIRGenModule::getLoc(SourceRange cRange) {
218 assert(cRange.isValid() && "expected a valid source range");
219 mlir::Location begin = getLoc(cRange.getBegin());
220 mlir::Location end = getLoc(cRange.getEnd());
221 mlir::Attribute metadata;
222 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
223}
224
225mlir::Operation *
226CIRGenModule::getAddrOfGlobal(GlobalDecl gd, ForDefinition_t isForDefinition) {
227 const Decl *d = gd.getDecl();
228
229 if (isa<CXXConstructorDecl>(Val: d) || isa<CXXDestructorDecl>(Val: d)) {
230 errorNYI(d->getSourceRange(),
231 "getAddrOfGlobal: C++ constructor/destructor");
232 return nullptr;
233 }
234
235 if (isa<CXXMethodDecl>(Val: d)) {
236 const CIRGenFunctionInfo &fi =
237 getTypes().arrangeCXXMethodDeclaration(md: cast<CXXMethodDecl>(Val: d));
238 cir::FuncType ty = getTypes().getFunctionType(fi);
239 return getAddrOfFunction(gd, ty, /*ForVTable=*/false, /*DontDefer=*/false,
240 isForDefinition);
241 }
242
243 if (isa<FunctionDecl>(Val: d)) {
244 const CIRGenFunctionInfo &fi = getTypes().arrangeGlobalDeclaration(gd);
245 cir::FuncType ty = getTypes().getFunctionType(fi);
246 return getAddrOfFunction(gd, ty, /*ForVTable=*/false, /*DontDefer=*/false,
247 isForDefinition);
248 }
249
250 return getAddrOfGlobalVar(cast<VarDecl>(d), /*ty=*/nullptr, isForDefinition)
251 .getDefiningOp();
252}
253
254void CIRGenModule::emitGlobalDecl(const clang::GlobalDecl &d) {
255 // We call getAddrOfGlobal with isForDefinition set to ForDefinition in
256 // order to get a Value with exactly the type we need, not something that
257 // might have been created for another decl with the same mangled name but
258 // different type.
259 mlir::Operation *op = getAddrOfGlobal(d, ForDefinition);
260
261 // In case of different address spaces, we may still get a cast, even with
262 // IsForDefinition equal to ForDefinition. Query mangled names table to get
263 // GlobalValue.
264 if (!op)
265 op = getGlobalValue(getMangledName(d));
266
267 assert(op && "expected a valid global op");
268
269 // Check to see if we've already emitted this. This is necessary for a
270 // couple of reasons: first, decls can end up in deferred-decls queue
271 // multiple times, and second, decls can end up with definitions in unusual
272 // ways (e.g. by an extern inline function acquiring a strong function
273 // redefinition). Just ignore those cases.
274 // TODO: Not sure what to map this to for MLIR
275 mlir::Operation *globalValueOp = op;
276 if (auto gv = dyn_cast<cir::GetGlobalOp>(op))
277 globalValueOp =
278 mlir::SymbolTable::lookupSymbolIn(getModule(), gv.getNameAttr());
279
280 if (auto cirGlobalValue =
281 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
282 if (!cirGlobalValue.isDeclaration())
283 return;
284
285 // If this is OpenMP, check if it is legal to emit this global normally.
286 assert(!cir::MissingFeatures::openMP());
287
288 // Otherwise, emit the definition and move on to the next one.
289 emitGlobalDefinition(d, op);
290}
291
292void CIRGenModule::emitDeferred() {
293 // Emit code for any potentially referenced deferred decls. Since a previously
294 // unused static decl may become used during the generation of code for a
295 // static function, iterate until no changes are made.
296
297 assert(!cir::MissingFeatures::openMP());
298 assert(!cir::MissingFeatures::deferredVtables());
299 assert(!cir::MissingFeatures::cudaSupport());
300
301 // Stop if we're out of both deferred vtables and deferred declarations.
302 if (deferredDeclsToEmit.empty())
303 return;
304
305 // Grab the list of decls to emit. If emitGlobalDefinition schedules more
306 // work, it will not interfere with this.
307 std::vector<GlobalDecl> curDeclsToEmit;
308 curDeclsToEmit.swap(x&: deferredDeclsToEmit);
309
310 for (const GlobalDecl &d : curDeclsToEmit) {
311 emitGlobalDecl(d);
312
313 // If we found out that we need to emit more decls, do that recursively.
314 // This has the advantage that the decls are emitted in a DFS and related
315 // ones are close together, which is convenient for testing.
316 if (!deferredDeclsToEmit.empty()) {
317 emitDeferred();
318 assert(deferredDeclsToEmit.empty());
319 }
320 }
321}
322
323void CIRGenModule::emitGlobal(clang::GlobalDecl gd) {
324 if (const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(Val: gd.getDecl())) {
325 emitGlobalOpenACCDecl(cd);
326 return;
327 }
328
329 const auto *global = cast<ValueDecl>(Val: gd.getDecl());
330
331 if (const auto *fd = dyn_cast<FunctionDecl>(Val: global)) {
332 // Update deferred annotations with the latest declaration if the function
333 // was already used or defined.
334 if (fd->hasAttr<AnnotateAttr>())
335 errorNYI(fd->getSourceRange(), "deferredAnnotations");
336 if (!fd->doesThisDeclarationHaveABody()) {
337 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
338 return;
339
340 errorNYI(fd->getSourceRange(),
341 "function declaration that forces code gen");
342 return;
343 }
344 } else {
345 const auto *vd = cast<VarDecl>(Val: global);
346 assert(vd->isFileVarDecl() && "Cannot emit local var decl as global.");
347 if (vd->isThisDeclarationADefinition() != VarDecl::Definition &&
348 !astContext.isMSStaticDataMemberInlineDefinition(VD: vd)) {
349 assert(!cir::MissingFeatures::openMP());
350 // If this declaration may have caused an inline variable definition to
351 // change linkage, make sure that it's emitted.
352 if (astContext.getInlineVariableDefinitionKind(vd) ==
353 ASTContext::InlineVariableDefinitionKind::Strong)
354 getAddrOfGlobalVar(vd);
355 // Otherwise, we can ignore this declaration. The variable will be emitted
356 // on its first use.
357 return;
358 }
359 }
360
361 // Defer code generation to first use when possible, e.g. if this is an inline
362 // function. If the global must always be emitted, do it eagerly if possible
363 // to benefit from cache locality. Deferring code generation is necessary to
364 // avoid adding initializers to external declarations.
365 if (mustBeEmitted(d: global) && mayBeEmittedEagerly(d: global)) {
366 // Emit the definition if it can't be deferred.
367 emitGlobalDefinition(gd);
368 return;
369 }
370
371 // If we're deferring emission of a C++ variable with an initializer, remember
372 // the order in which it appeared on the file.
373 assert(!cir::MissingFeatures::deferredCXXGlobalInit());
374
375 llvm::StringRef mangledName = getMangledName(gd);
376 if (getGlobalValue(mangledName) != nullptr) {
377 // The value has already been used and should therefore be emitted.
378 addDeferredDeclToEmit(GD: gd);
379 } else if (mustBeEmitted(d: global)) {
380 // The value must be emitted, but cannot be emitted eagerly.
381 assert(!mayBeEmittedEagerly(global));
382 addDeferredDeclToEmit(GD: gd);
383 } else {
384 // Otherwise, remember that we saw a deferred decl with this name. The first
385 // use of the mangled name will cause it to move into deferredDeclsToEmit.
386 deferredDecls[mangledName] = gd;
387 }
388}
389
390void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd,
391 mlir::Operation *op) {
392 auto const *funcDecl = cast<FunctionDecl>(Val: gd.getDecl());
393 if (funcDecl->getIdentifier() == nullptr) {
394 errorNYI(funcDecl->getSourceRange().getBegin(),
395 "function definition with a non-identifier for a name");
396 return;
397 }
398
399 const CIRGenFunctionInfo &fi = getTypes().arrangeGlobalDeclaration(gd);
400 cir::FuncType funcType = getTypes().getFunctionType(fi);
401 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
402 if (!funcOp || funcOp.getFunctionType() != funcType) {
403 funcOp = getAddrOfFunction(gd, funcType, /*ForVTable=*/false,
404 /*DontDefer=*/true, ForDefinition);
405 }
406
407 CIRGenFunction cgf(*this, builder);
408 curCGF = &cgf;
409 {
410 mlir::OpBuilder::InsertionGuard guard(builder);
411 cgf.generateCode(gd, funcOp, funcType);
412 }
413 curCGF = nullptr;
414}
415
416mlir::Operation *CIRGenModule::getGlobalValue(StringRef name) {
417 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
418}
419
420cir::GlobalOp CIRGenModule::createGlobalOp(CIRGenModule &cgm,
421 mlir::Location loc, StringRef name,
422 mlir::Type t,
423 mlir::Operation *insertPoint) {
424 cir::GlobalOp g;
425 CIRGenBuilderTy &builder = cgm.getBuilder();
426
427 {
428 mlir::OpBuilder::InsertionGuard guard(builder);
429
430 // If an insertion point is provided, we're replacing an existing global,
431 // otherwise, create the new global immediately after the last gloabl we
432 // emitted.
433 if (insertPoint) {
434 builder.setInsertionPoint(insertPoint);
435 } else {
436 // Group global operations together at the top of the module.
437 if (cgm.lastGlobalOp)
438 builder.setInsertionPointAfter(cgm.lastGlobalOp);
439 else
440 builder.setInsertionPointToStart(cgm.getModule().getBody());
441 }
442
443 g = builder.create<cir::GlobalOp>(loc, name, t);
444 if (!insertPoint)
445 cgm.lastGlobalOp = g;
446
447 // Default to private until we can judge based on the initializer,
448 // since MLIR doesn't allow public declarations.
449 mlir::SymbolTable::setSymbolVisibility(
450 g, mlir::SymbolTable::Visibility::Private);
451 }
452 return g;
453}
454
455void CIRGenModule::setCommonAttributes(GlobalDecl gd, mlir::Operation *gv) {
456 const Decl *d = gd.getDecl();
457 if (isa_and_nonnull<NamedDecl>(d))
458 setGVProperties(gv, dyn_cast<NamedDecl>(d));
459 assert(!cir::MissingFeatures::defaultVisibility());
460 assert(!cir::MissingFeatures::opGlobalUsedOrCompilerUsed());
461}
462
463void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
464 setCommonAttributes(gd, op);
465
466 assert(!cir::MissingFeatures::opGlobalUsedOrCompilerUsed());
467 assert(!cir::MissingFeatures::opGlobalSection());
468 assert(!cir::MissingFeatures::opFuncCPUAndFeaturesAttributes());
469 assert(!cir::MissingFeatures::opFuncSection());
470
471 assert(!cir::MissingFeatures::setTargetAttributes());
472}
473
474static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd) {
475 // Set linkage and visibility in case we never see a definition.
476 LinkageInfo lv = nd->getLinkageAndVisibility();
477 // Don't set internal linkage on declarations.
478 // "extern_weak" is overloaded in LLVM; we probably should have
479 // separate linkage types for this.
480 if (isExternallyVisible(lv.getLinkage()) &&
481 (nd->hasAttr<WeakAttr>() || nd->isWeakImported()))
482 gv.setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
483}
484
485/// If the specified mangled name is not in the module,
486/// create and return an mlir GlobalOp with the specified type (TODO(cir):
487/// address space).
488///
489/// TODO(cir):
490/// 1. If there is something in the module with the specified name, return
491/// it potentially bitcasted to the right type.
492///
493/// 2. If \p d is non-null, it specifies a decl that correspond to this. This
494/// is used to set the attributes on the global when it is first created.
495///
496/// 3. If \p isForDefinition is true, it is guaranteed that an actual global
497/// with type \p ty will be returned, not conversion of a variable with the same
498/// mangled name but some other type.
499cir::GlobalOp
500CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
501 LangAS langAS, const VarDecl *d,
502 ForDefinition_t isForDefinition) {
503 // Lookup the entry, lazily creating it if necessary.
504 cir::GlobalOp entry;
505 if (mlir::Operation *v = getGlobalValue(mangledName)) {
506 if (!isa<cir::GlobalOp>(v))
507 errorNYI(d->getSourceRange(), "global with non-GlobalOp type");
508 entry = cast<cir::GlobalOp>(v);
509 }
510
511 if (entry) {
512 assert(!cir::MissingFeatures::addressSpace());
513 assert(!cir::MissingFeatures::opGlobalWeakRef());
514
515 assert(!cir::MissingFeatures::setDLLStorageClass());
516 assert(!cir::MissingFeatures::openMP());
517
518 if (entry.getSymType() == ty)
519 return entry;
520
521 // If there are two attempts to define the same mangled name, issue an
522 // error.
523 //
524 // TODO(cir): look at mlir::GlobalValue::isDeclaration for all aspects of
525 // recognizing the global as a declaration, for now only check if
526 // initializer is present.
527 if (isForDefinition && !entry.isDeclaration()) {
528 errorNYI(d->getSourceRange(), "global with conflicting type");
529 }
530
531 // Address space check removed because it is unnecessary because CIR records
532 // address space info in types.
533
534 // (If global is requested for a definition, we always need to create a new
535 // global, not just return a bitcast.)
536 if (!isForDefinition)
537 return entry;
538 }
539
540 mlir::Location loc = getLoc(d->getSourceRange());
541
542 // mlir::SymbolTable::Visibility::Public is the default, no need to explicitly
543 // mark it as such.
544 cir::GlobalOp gv =
545 CIRGenModule::createGlobalOp(*this, loc, mangledName, ty,
546 /*insertPoint=*/entry.getOperation());
547
548 // This is the first use or definition of a mangled name. If there is a
549 // deferred decl with this name, remember that we need to emit it at the end
550 // of the file.
551 auto ddi = deferredDecls.find(x: mangledName);
552 if (ddi != deferredDecls.end()) {
553 // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
554 // list, and remove it from DeferredDecls (since we don't need it anymore).
555 addDeferredDeclToEmit(GD: ddi->second);
556 deferredDecls.erase(position: ddi);
557 }
558
559 // Handle things which are present even on external declarations.
560 if (d) {
561 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
562 errorNYI(d->getSourceRange(), "OpenMP target global variable");
563
564 gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
565 assert(!cir::MissingFeatures::opGlobalConstant());
566
567 setLinkageForGV(gv, d);
568
569 if (d->getTLSKind())
570 errorNYI(d->getSourceRange(), "thread local global variable");
571
572 setGVProperties(gv, d);
573
574 // If required by the ABI, treat declarations of static data members with
575 // inline initializers as definitions.
576 if (astContext.isMSStaticDataMemberInlineDefinition(VD: d))
577 errorNYI(d->getSourceRange(), "MS static data member inline definition");
578
579 assert(!cir::MissingFeatures::opGlobalSection());
580 gv.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(d));
581
582 // Handle XCore specific ABI requirements.
583 if (getTriple().getArch() == llvm::Triple::xcore)
584 errorNYI(d->getSourceRange(), "XCore specific ABI requirements");
585
586 // Check if we a have a const declaration with an initializer, we may be
587 // able to emit it as available_externally to expose it's value to the
588 // optimizer.
589 if (getLangOpts().CPlusPlus && gv.isPublic() &&
590 d->getType().isConstQualified() && gv.isDeclaration() &&
591 !d->hasDefinition() && d->hasInit() && !d->hasAttr<DLLImportAttr>())
592 errorNYI(d->getSourceRange(),
593 "external const declaration with initializer");
594 }
595
596 return gv;
597}
598
599cir::GlobalOp
600CIRGenModule::getOrCreateCIRGlobal(const VarDecl *d, mlir::Type ty,
601 ForDefinition_t isForDefinition) {
602 assert(d->hasGlobalStorage() && "Not a global variable");
603 QualType astTy = d->getType();
604 if (!ty)
605 ty = getTypes().convertTypeForMem(astTy);
606
607 StringRef mangledName = getMangledName(gd: d);
608 return getOrCreateCIRGlobal(mangledName, ty, astTy.getAddressSpace(), d,
609 isForDefinition);
610}
611
612/// Return the mlir::Value for the address of the given global variable. If
613/// \p ty is non-null and if the global doesn't exist, then it will be created
614/// with the specified type instead of whatever the normal requested type would
615/// be. If \p isForDefinition is true, it is guaranteed that an actual global
616/// with type \p ty will be returned, not conversion of a variable with the same
617/// mangled name but some other type.
618mlir::Value CIRGenModule::getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty,
619 ForDefinition_t isForDefinition) {
620 assert(d->hasGlobalStorage() && "Not a global variable");
621 QualType astTy = d->getType();
622 if (!ty)
623 ty = getTypes().convertTypeForMem(astTy);
624
625 assert(!cir::MissingFeatures::opGlobalThreadLocal());
626
627 cir::GlobalOp g = getOrCreateCIRGlobal(d, ty, isForDefinition);
628 mlir::Type ptrTy = builder.getPointerTo(g.getSymType());
629 return builder.create<cir::GetGlobalOp>(getLoc(d->getSourceRange()), ptrTy,
630 g.getSymName());
631}
632
633void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
634 bool isTentative) {
635 const QualType astTy = vd->getType();
636
637 if (getLangOpts().OpenCL || getLangOpts().OpenMPIsTargetDevice) {
638 errorNYI(vd->getSourceRange(), "emit OpenCL/OpenMP global variable");
639 return;
640 }
641
642 // Whether the definition of the variable is available externally.
643 // If yes, we shouldn't emit the GloablCtor and GlobalDtor for the variable
644 // since this is the job for its original source.
645 bool isDefinitionAvailableExternally =
646 astContext.GetGVALinkageForVariable(VD: vd) == GVA_AvailableExternally;
647 assert(!cir::MissingFeatures::needsGlobalCtorDtor());
648
649 // It is useless to emit the definition for an available_externally variable
650 // which can't be marked as const.
651 if (isDefinitionAvailableExternally &&
652 (!vd->hasConstantInitialization() ||
653 // TODO: Update this when we have interface to check constexpr
654 // destructor.
655 vd->needsDestruction(Ctx: astContext) ||
656 !vd->getType().isConstantStorage(astContext, true, true)))
657 return;
658
659 mlir::Attribute init;
660 const VarDecl *initDecl;
661 const Expr *initExpr = vd->getAnyInitializer(D&: initDecl);
662
663 std::optional<ConstantEmitter> emitter;
664
665 assert(!cir::MissingFeatures::cudaSupport());
666
667 if (vd->hasAttr<LoaderUninitializedAttr>()) {
668 errorNYI(vd->getSourceRange(), "loader uninitialized attribute");
669 return;
670 } else if (!initExpr) {
671 // This is a tentative definition; tentative definitions are
672 // implicitly initialized with { 0 }.
673 //
674 // Note that tentative definitions are only emitted at the end of
675 // a translation unit, so they should never have incomplete
676 // type. In addition, EmitTentativeDefinition makes sure that we
677 // never attempt to emit a tentative definition if a real one
678 // exists. A use may still exists, however, so we still may need
679 // to do a RAUW.
680 assert(!astTy->isIncompleteType() && "Unexpected incomplete type");
681 init = builder.getZeroInitAttr(convertType(type: vd->getType()));
682 } else {
683 emitter.emplace(args&: *this);
684 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
685 if (!initializer) {
686 QualType qt = initExpr->getType();
687 if (vd->getType()->isReferenceType())
688 qt = vd->getType();
689
690 if (getLangOpts().CPlusPlus) {
691 if (initDecl->hasFlexibleArrayInit(Ctx: astContext))
692 errorNYI(vd->getSourceRange(), "flexible array initializer");
693 init = builder.getZeroInitAttr(convertType(qt));
694 if (astContext.GetGVALinkageForVariable(VD: vd) != GVA_AvailableExternally)
695 errorNYI(vd->getSourceRange(), "global constructor");
696 } else {
697 errorNYI(vd->getSourceRange(), "static initializer");
698 }
699 } else {
700 init = initializer;
701 // We don't need an initializer, so remove the entry for the delayed
702 // initializer position (just in case this entry was delayed) if we
703 // also don't need to register a destructor.
704 if (vd->needsDestruction(Ctx: astContext) == QualType::DK_cxx_destructor)
705 errorNYI(vd->getSourceRange(), "delayed destructor");
706 }
707 }
708
709 mlir::Type initType;
710 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
711 errorNYI(vd->getSourceRange(), "global initializer is a symbol reference");
712 return;
713 } else {
714 assert(mlir::isa<mlir::TypedAttr>(init) && "This should have a type");
715 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
716 initType = typedInitAttr.getType();
717 }
718 assert(!mlir::isa<mlir::NoneType>(initType) && "Should have a type by now");
719
720 cir::GlobalOp gv =
721 getOrCreateCIRGlobal(vd, initType, ForDefinition_t(!isTentative));
722 // TODO(cir): Strip off pointer casts from Entry if we get them?
723
724 if (!gv || gv.getSymType() != initType) {
725 errorNYI(vd->getSourceRange(), "global initializer with type mismatch");
726 return;
727 }
728
729 assert(!cir::MissingFeatures::maybeHandleStaticInExternC());
730
731 if (vd->hasAttr<AnnotateAttr>()) {
732 errorNYI(vd->getSourceRange(), "annotate global variable");
733 }
734
735 if (langOpts.CUDA) {
736 errorNYI(vd->getSourceRange(), "CUDA global variable");
737 }
738
739 // Set initializer and finalize emission
740 CIRGenModule::setInitializer(gv, init);
741 if (emitter)
742 emitter->finalize(gv);
743
744 // Set CIR's linkage type as appropriate.
745 cir::GlobalLinkageKind linkage =
746 getCIRLinkageVarDefinition(vd, /*IsConstant=*/false);
747
748 // Set CIR linkage and DLL storage class.
749 gv.setLinkage(linkage);
750 // FIXME(cir): setLinkage should likely set MLIR's visibility automatically.
751 gv.setVisibility(getMLIRVisibilityFromCIRLinkage(linkage));
752 assert(!cir::MissingFeatures::opGlobalDLLImportExport());
753 if (linkage == cir::GlobalLinkageKind::CommonLinkage)
754 errorNYI(initExpr->getSourceRange(), "common linkage");
755
756 setNonAliasAttributes(vd, gv);
757
758 assert(!cir::MissingFeatures::opGlobalThreadLocal());
759
760 maybeSetTrivialComdat(*vd, gv);
761}
762
763void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd,
764 mlir::Operation *op) {
765 const auto *decl = cast<ValueDecl>(Val: gd.getDecl());
766 if (const auto *fd = dyn_cast<FunctionDecl>(Val: decl)) {
767 // TODO(CIR): Skip generation of CIR for functions with available_externally
768 // linkage at -O0.
769
770 if (const auto *method = dyn_cast<CXXMethodDecl>(Val: decl)) {
771 // Make sure to emit the definition(s) before we emit the thunks. This is
772 // necessary for the generation of certain thunks.
773 if (isa<CXXConstructorDecl>(Val: method) || isa<CXXDestructorDecl>(Val: method))
774 errorNYI(method->getSourceRange(), "C++ ctor/dtor");
775 else if (fd->isMultiVersion())
776 errorNYI(method->getSourceRange(), "multiversion functions");
777 else
778 emitGlobalFunctionDefinition(gd, op);
779
780 if (method->isVirtual())
781 errorNYI(method->getSourceRange(), "virtual member function");
782
783 return;
784 }
785
786 if (fd->isMultiVersion())
787 errorNYI(fd->getSourceRange(), "multiversion functions");
788 emitGlobalFunctionDefinition(gd, op);
789 return;
790 }
791
792 if (const auto *vd = dyn_cast<VarDecl>(Val: decl))
793 return emitGlobalVarDefinition(vd, isTentative: !vd->hasDefinition());
794
795 llvm_unreachable("Invalid argument to CIRGenModule::emitGlobalDefinition");
796}
797
798mlir::Attribute
799CIRGenModule::getConstantArrayFromStringLiteral(const StringLiteral *e) {
800 assert(!e->getType()->isPointerType() && "Strings are always arrays");
801
802 // Don't emit it as the address of the string, emit the string data itself
803 // as an inline array.
804 if (e->getCharByteWidth() == 1) {
805 SmallString<64> str(e->getString());
806
807 // Resize the string to the right size, which is indicated by its type.
808 const ConstantArrayType *cat =
809 astContext.getAsConstantArrayType(T: e->getType());
810 uint64_t finalSize = cat->getZExtSize();
811 str.resize(N: finalSize);
812
813 mlir::Type eltTy = convertType(cat->getElementType());
814 return builder.getString(str, eltTy, finalSize);
815 }
816
817 errorNYI(e->getSourceRange(),
818 "getConstantArrayFromStringLiteral: wide characters");
819 return mlir::Attribute();
820}
821
822bool CIRGenModule::supportsCOMDAT() const {
823 return getTriple().supportsCOMDAT();
824}
825
826static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d) {
827 if (!cgm.supportsCOMDAT())
828 return false;
829
830 if (d.hasAttr<SelectAnyAttr>())
831 return true;
832
833 GVALinkage linkage;
834 if (auto *vd = dyn_cast<VarDecl>(Val: &d))
835 linkage = cgm.getASTContext().GetGVALinkageForVariable(VD: vd);
836 else
837 linkage =
838 cgm.getASTContext().GetGVALinkageForFunction(FD: cast<FunctionDecl>(Val: &d));
839
840 switch (linkage) {
841 case clang::GVA_Internal:
842 case clang::GVA_AvailableExternally:
843 case clang::GVA_StrongExternal:
844 return false;
845 case clang::GVA_DiscardableODR:
846 case clang::GVA_StrongODR:
847 return true;
848 }
849 llvm_unreachable("No such linkage");
850}
851
852void CIRGenModule::maybeSetTrivialComdat(const Decl &d, mlir::Operation *op) {
853 if (!shouldBeInCOMDAT(cgm&: *this, d))
854 return;
855 if (auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op))
856 globalOp.setComdat(true);
857
858 assert(!cir::MissingFeatures::opFuncSetComdat());
859}
860
861void CIRGenModule::updateCompletedType(const TagDecl *td) {
862 // Make sure that this type is translated.
863 genTypes.updateCompletedType(td);
864}
865
866// TODO(CIR): this could be a common method between LLVM codegen.
867static bool isVarDeclStrongDefinition(const ASTContext &astContext,
868 CIRGenModule &cgm, const VarDecl *vd,
869 bool noCommon) {
870 // Don't give variables common linkage if -fno-common was specified unless it
871 // was overridden by a NoCommon attribute.
872 if ((noCommon || vd->hasAttr<NoCommonAttr>()) && !vd->hasAttr<CommonAttr>())
873 return true;
874
875 // C11 6.9.2/2:
876 // A declaration of an identifier for an object that has file scope without
877 // an initializer, and without a storage-class specifier or with the
878 // storage-class specifier static, constitutes a tentative definition.
879 if (vd->getInit() || vd->hasExternalStorage())
880 return true;
881
882 // A variable cannot be both common and exist in a section.
883 if (vd->hasAttr<SectionAttr>())
884 return true;
885
886 // A variable cannot be both common and exist in a section.
887 // We don't try to determine which is the right section in the front-end.
888 // If no specialized section name is applicable, it will resort to default.
889 if (vd->hasAttr<PragmaClangBSSSectionAttr>() ||
890 vd->hasAttr<PragmaClangDataSectionAttr>() ||
891 vd->hasAttr<PragmaClangRelroSectionAttr>() ||
892 vd->hasAttr<PragmaClangRodataSectionAttr>())
893 return true;
894
895 // Thread local vars aren't considered common linkage.
896 if (vd->getTLSKind())
897 return true;
898
899 // Tentative definitions marked with WeakImportAttr are true definitions.
900 if (vd->hasAttr<WeakImportAttr>())
901 return true;
902
903 // A variable cannot be both common and exist in a comdat.
904 if (shouldBeInCOMDAT(cgm, *vd))
905 return true;
906
907 // Declarations with a required alignment do not have common linkage in MSVC
908 // mode.
909 if (astContext.getTargetInfo().getCXXABI().isMicrosoft()) {
910 if (vd->hasAttr<AlignedAttr>())
911 return true;
912 QualType varType = vd->getType();
913 if (astContext.isAlignmentRequired(T: varType))
914 return true;
915
916 if (const auto *rt = varType->getAs<RecordType>()) {
917 const RecordDecl *rd = rt->getDecl();
918 for (const FieldDecl *fd : rd->fields()) {
919 if (fd->isBitField())
920 continue;
921 if (fd->hasAttr<AlignedAttr>())
922 return true;
923 if (astContext.isAlignmentRequired(fd->getType()))
924 return true;
925 }
926 }
927 }
928
929 // Microsoft's link.exe doesn't support alignments greater than 32 bytes for
930 // common symbols, so symbols with greater alignment requirements cannot be
931 // common.
932 // Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
933 // alignments for common symbols via the aligncomm directive, so this
934 // restriction only applies to MSVC environments.
935 if (astContext.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
936 astContext.getTypeAlignIfKnown(T: vd->getType()) >
937 astContext.toBits(CharSize: CharUnits::fromQuantity(Quantity: 32)))
938 return true;
939
940 return false;
941}
942
943cir::GlobalLinkageKind CIRGenModule::getCIRLinkageForDeclarator(
944 const DeclaratorDecl *dd, GVALinkage linkage, bool isConstantVariable) {
945 if (linkage == GVA_Internal)
946 return cir::GlobalLinkageKind::InternalLinkage;
947
948 if (dd->hasAttr<WeakAttr>()) {
949 if (isConstantVariable)
950 return cir::GlobalLinkageKind::WeakODRLinkage;
951 return cir::GlobalLinkageKind::WeakAnyLinkage;
952 }
953
954 if (const auto *fd = dd->getAsFunction())
955 if (fd->isMultiVersion() && linkage == GVA_AvailableExternally)
956 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
957
958 // We are guaranteed to have a strong definition somewhere else,
959 // so we can use available_externally linkage.
960 if (linkage == GVA_AvailableExternally)
961 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
962
963 // Note that Apple's kernel linker doesn't support symbol
964 // coalescing, so we need to avoid linkonce and weak linkages there.
965 // Normally, this means we just map to internal, but for explicit
966 // instantiations we'll map to external.
967
968 // In C++, the compiler has to emit a definition in every translation unit
969 // that references the function. We should use linkonce_odr because
970 // a) if all references in this translation unit are optimized away, we
971 // don't need to codegen it. b) if the function persists, it needs to be
972 // merged with other definitions. c) C++ has the ODR, so we know the
973 // definition is dependable.
974 if (linkage == GVA_DiscardableODR)
975 return !astContext.getLangOpts().AppleKext
976 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
977 : cir::GlobalLinkageKind::InternalLinkage;
978
979 // An explicit instantiation of a template has weak linkage, since
980 // explicit instantiations can occur in multiple translation units
981 // and must all be equivalent. However, we are not allowed to
982 // throw away these explicit instantiations.
983 //
984 // CUDA/HIP: For -fno-gpu-rdc case, device code is limited to one TU,
985 // so say that CUDA templates are either external (for kernels) or internal.
986 // This lets llvm perform aggressive inter-procedural optimizations. For
987 // -fgpu-rdc case, device function calls across multiple TU's are allowed,
988 // therefore we need to follow the normal linkage paradigm.
989 if (linkage == GVA_StrongODR) {
990 if (getLangOpts().AppleKext)
991 return cir::GlobalLinkageKind::ExternalLinkage;
992 if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice &&
993 !getLangOpts().GPURelocatableDeviceCode)
994 return dd->hasAttr<CUDAGlobalAttr>()
995 ? cir::GlobalLinkageKind::ExternalLinkage
996 : cir::GlobalLinkageKind::InternalLinkage;
997 return cir::GlobalLinkageKind::WeakODRLinkage;
998 }
999
1000 // C++ doesn't have tentative definitions and thus cannot have common
1001 // linkage.
1002 if (!getLangOpts().CPlusPlus && isa<VarDecl>(Val: dd) &&
1003 !isVarDeclStrongDefinition(astContext, cgm&: *this, vd: cast<VarDecl>(Val: dd),
1004 noCommon: getCodeGenOpts().NoCommon)) {
1005 errorNYI(dd->getBeginLoc(), "common linkage", dd->getDeclKindName());
1006 return cir::GlobalLinkageKind::CommonLinkage;
1007 }
1008
1009 // selectany symbols are externally visible, so use weak instead of
1010 // linkonce. MSVC optimizes away references to const selectany globals, so
1011 // all definitions should be the same and ODR linkage should be used.
1012 // http://msdn.microsoft.com/en-us/library/5tkz6s71.aspx
1013 if (dd->hasAttr<SelectAnyAttr>())
1014 return cir::GlobalLinkageKind::WeakODRLinkage;
1015
1016 // Otherwise, we have strong external linkage.
1017 assert(linkage == GVA_StrongExternal);
1018 return cir::GlobalLinkageKind::ExternalLinkage;
1019}
1020
1021cir::GlobalLinkageKind
1022CIRGenModule::getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant) {
1023 assert(!isConstant && "constant variables NYI");
1024 GVALinkage linkage = astContext.GetGVALinkageForVariable(VD: vd);
1025 return getCIRLinkageForDeclarator(vd, linkage, isConstant);
1026}
1027
1028static cir::GlobalOp
1029generateStringLiteral(mlir::Location loc, mlir::TypedAttr c,
1030 cir::GlobalLinkageKind lt, CIRGenModule &cgm,
1031 StringRef globalName, CharUnits alignment) {
1032 assert(!cir::MissingFeatures::addressSpace());
1033
1034 // Create a global variable for this string
1035 // FIXME(cir): check for insertion point in module level.
1036 cir::GlobalOp gv =
1037 CIRGenModule::createGlobalOp(cgm, loc, globalName, c.getType());
1038
1039 // Set up extra information and add to the module
1040 gv.setAlignmentAttr(cgm.getSize(alignment));
1041 gv.setLinkageAttr(
1042 cir::GlobalLinkageKindAttr::get(cgm.getBuilder().getContext(), lt));
1043 assert(!cir::MissingFeatures::opGlobalThreadLocal());
1044 assert(!cir::MissingFeatures::opGlobalUnnamedAddr());
1045 CIRGenModule::setInitializer(gv, c);
1046 if (gv.isWeakForLinker()) {
1047 assert(cgm.supportsCOMDAT() && "Only COFF uses weak string literals");
1048 gv.setComdat(true);
1049 }
1050 cgm.setDSOLocal(static_cast<mlir::Operation *>(gv));
1051 return gv;
1052}
1053
1054// LLVM IR automatically uniques names when new llvm::GlobalVariables are
1055// created. This is handy, for example, when creating globals for string
1056// literals. Since we don't do that when creating cir::GlobalOp's, we need
1057// a mechanism to generate a unique name in advance.
1058//
1059// For now, this mechanism is only used in cases where we know that the
1060// name is compiler-generated, so we don't use the MLIR symbol table for
1061// the lookup.
1062std::string CIRGenModule::getUniqueGlobalName(const std::string &baseName) {
1063 // If this is the first time we've generated a name for this basename, use
1064 // it as is and start a counter for this base name.
1065 auto it = cgGlobalNames.find(Key: baseName);
1066 if (it == cgGlobalNames.end()) {
1067 cgGlobalNames[baseName] = 1;
1068 return baseName;
1069 }
1070
1071 std::string result =
1072 baseName + "." + std::to_string(val: cgGlobalNames[baseName]++);
1073 // There should not be any symbol with this name in the module.
1074 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1075 return result;
1076}
1077
1078/// Return a pointer to a constant array for the given string literal.
1079cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
1080 StringRef name) {
1081 CharUnits alignment =
1082 astContext.getAlignOfGlobalVarInChars(T: s->getType(), /*VD=*/nullptr);
1083
1084 mlir::Attribute c = getConstantArrayFromStringLiteral(s);
1085
1086 if (getLangOpts().WritableStrings) {
1087 errorNYI(s->getSourceRange(),
1088 "getGlobalForStringLiteral: Writable strings");
1089 }
1090
1091 // Mangle the string literal if that's how the ABI merges duplicate strings.
1092 // Don't do it if they are writable, since we don't want writes in one TU to
1093 // affect strings in another.
1094 if (getCXXABI().getMangleContext().shouldMangleStringLiteral(SL: s) &&
1095 !getLangOpts().WritableStrings) {
1096 errorNYI(s->getSourceRange(),
1097 "getGlobalForStringLiteral: mangle string literals");
1098 }
1099
1100 // Unlike LLVM IR, CIR doesn't automatically unique names for globals, so
1101 // we need to do that explicitly.
1102 std::string uniqueName = getUniqueGlobalName(baseName: name.str());
1103 mlir::Location loc = getLoc(s->getSourceRange());
1104 auto typedC = llvm::cast<mlir::TypedAttr>(c);
1105 cir::GlobalOp gv =
1106 generateStringLiteral(loc, typedC, cir::GlobalLinkageKind::PrivateLinkage,
1107 *this, uniqueName, alignment);
1108 setDSOLocal(static_cast<mlir::Operation *>(gv));
1109
1110 assert(!cir::MissingFeatures::sanitizers());
1111
1112 return gv;
1113}
1114
1115void CIRGenModule::emitDeclContext(const DeclContext *dc) {
1116 for (Decl *decl : dc->decls()) {
1117 // Unlike other DeclContexts, the contents of an ObjCImplDecl at TU scope
1118 // are themselves considered "top-level", so EmitTopLevelDecl on an
1119 // ObjCImplDecl does not recursively visit them. We need to do that in
1120 // case they're nested inside another construct (LinkageSpecDecl /
1121 // ExportDecl) that does stop them from being considered "top-level".
1122 if (auto *oid = dyn_cast<ObjCImplDecl>(Val: decl))
1123 errorNYI(oid->getSourceRange(), "emitDeclConext: ObjCImplDecl");
1124
1125 emitTopLevelDecl(decl);
1126 }
1127}
1128
1129// Emit code for a single top level declaration.
1130void CIRGenModule::emitTopLevelDecl(Decl *decl) {
1131
1132 // Ignore dependent declarations.
1133 if (decl->isTemplated())
1134 return;
1135
1136 switch (decl->getKind()) {
1137 default:
1138 errorNYI(loc: decl->getBeginLoc(), feature: "declaration of kind",
1139 name: decl->getDeclKindName());
1140 break;
1141
1142 case Decl::CXXMethod:
1143 case Decl::Function: {
1144 auto *fd = cast<FunctionDecl>(Val: decl);
1145 // Consteval functions shouldn't be emitted.
1146 if (!fd->isConsteval())
1147 emitGlobal(gd: fd);
1148 break;
1149 }
1150
1151 case Decl::Var: {
1152 auto *vd = cast<VarDecl>(Val: decl);
1153 emitGlobal(gd: vd);
1154 break;
1155 }
1156 case Decl::OpenACCRoutine:
1157 emitGlobalOpenACCDecl(cast<OpenACCRoutineDecl>(Val: decl));
1158 break;
1159 case Decl::OpenACCDeclare:
1160 emitGlobalOpenACCDecl(cast<OpenACCDeclareDecl>(Val: decl));
1161 break;
1162 case Decl::Enum:
1163 case Decl::Using: // using X; [C++]
1164 case Decl::UsingDirective: // using namespace X; [C++]
1165 case Decl::Typedef:
1166 case Decl::TypeAlias: // using foo = bar; [C++11]
1167 case Decl::Record:
1168 assert(!cir::MissingFeatures::generateDebugInfo());
1169 break;
1170
1171 // No code generation needed.
1172 case Decl::UsingShadow:
1173 case Decl::Empty:
1174 break;
1175
1176 // C++ Decls
1177 case Decl::LinkageSpec:
1178 case Decl::Namespace:
1179 emitDeclContext(dc: Decl::castToDeclContext(decl));
1180 break;
1181
1182 case Decl::ClassTemplateSpecialization:
1183 case Decl::CXXRecord:
1184 assert(!cir::MissingFeatures::generateDebugInfo());
1185 assert(!cir::MissingFeatures::cxxRecordStaticMembers());
1186 break;
1187 }
1188}
1189
1190void CIRGenModule::setInitializer(cir::GlobalOp &op, mlir::Attribute value) {
1191 // Recompute visibility when updating initializer.
1192 op.setInitialValueAttr(value);
1193 assert(!cir::MissingFeatures::opGlobalVisibility());
1194}
1195
1196std::pair<cir::FuncType, cir::FuncOp> CIRGenModule::getAddrAndTypeOfCXXStructor(
1197 GlobalDecl gd, const CIRGenFunctionInfo *fnInfo, cir::FuncType fnType,
1198 bool dontDefer, ForDefinition_t isForDefinition) {
1199 auto *md = cast<CXXMethodDecl>(Val: gd.getDecl());
1200
1201 if (isa<CXXDestructorDecl>(Val: md)) {
1202 // Always alias equivalent complete destructors to base destructors in the
1203 // MS ABI.
1204 if (getTarget().getCXXABI().isMicrosoft() &&
1205 gd.getDtorType() == Dtor_Complete &&
1206 md->getParent()->getNumVBases() == 0)
1207 errorNYI(md->getSourceRange(),
1208 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
1209 }
1210
1211 if (!fnType) {
1212 if (!fnInfo)
1213 fnInfo = &getTypes().arrangeCXXStructorDeclaration(gd);
1214 fnType = getTypes().getFunctionType(*fnInfo);
1215 }
1216
1217 auto fn = getOrCreateCIRFunction(getMangledName(gd), fnType, gd,
1218 /*ForVtable=*/false, dontDefer,
1219 /*IsThunk=*/false, isForDefinition);
1220
1221 return {fnType, fn};
1222}
1223
1224cir::FuncOp CIRGenModule::getAddrOfFunction(clang::GlobalDecl gd,
1225 mlir::Type funcType, bool forVTable,
1226 bool dontDefer,
1227 ForDefinition_t isForDefinition) {
1228 assert(!cast<FunctionDecl>(gd.getDecl())->isConsteval() &&
1229 "consteval function should never be emitted");
1230
1231 if (!funcType) {
1232 const auto *fd = cast<FunctionDecl>(Val: gd.getDecl());
1233 funcType = convertType(type: fd->getType());
1234 }
1235
1236 StringRef mangledName = getMangledName(gd);
1237 cir::FuncOp func =
1238 getOrCreateCIRFunction(mangledName, funcType, gd, forVTable, dontDefer,
1239 /*isThunk=*/false, isForDefinition);
1240 return func;
1241}
1242
1243static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd,
1244 const NamedDecl *nd) {
1245 SmallString<256> buffer;
1246
1247 llvm::raw_svector_ostream out(buffer);
1248 MangleContext &mc = cgm.getCXXABI().getMangleContext();
1249
1250 assert(!cir::MissingFeatures::moduleNameHash());
1251
1252 if (mc.shouldMangleDeclName(D: nd)) {
1253 mc.mangleName(GD: gd.getWithDecl(nd), out);
1254 } else {
1255 IdentifierInfo *ii = nd->getIdentifier();
1256 assert(ii && "Attempt to mangle unnamed decl.");
1257
1258 const auto *fd = dyn_cast<FunctionDecl>(Val: nd);
1259 if (fd &&
1260 fd->getType()->castAs<FunctionType>()->getCallConv() == CC_X86RegCall) {
1261 cgm.errorNYI(nd->getSourceRange(), "getMangledName: X86RegCall");
1262 } else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
1263 gd.getKernelReferenceKind() == KernelReferenceKind::Stub) {
1264 cgm.errorNYI(nd->getSourceRange(), "getMangledName: CUDA device stub");
1265 }
1266 out << ii->getName();
1267 }
1268
1269 // Check if the module name hash should be appended for internal linkage
1270 // symbols. This should come before multi-version target suffixes are
1271 // appendded. This is to keep the name and module hash suffix of the internal
1272 // linkage function together. The unique suffix should only be added when name
1273 // mangling is done to make sure that the final name can be properly
1274 // demangled. For example, for C functions without prototypes, name mangling
1275 // is not done and the unique suffix should not be appended then.
1276 assert(!cir::MissingFeatures::moduleNameHash());
1277
1278 if (const auto *fd = dyn_cast<FunctionDecl>(Val: nd)) {
1279 if (fd->isMultiVersion()) {
1280 cgm.errorNYI(nd->getSourceRange(),
1281 "getMangledName: multi-version functions");
1282 }
1283 }
1284 if (cgm.getLangOpts().GPURelocatableDeviceCode) {
1285 cgm.errorNYI(nd->getSourceRange(),
1286 "getMangledName: GPU relocatable device code");
1287 }
1288
1289 return std::string(out.str());
1290}
1291
1292StringRef CIRGenModule::getMangledName(GlobalDecl gd) {
1293 GlobalDecl canonicalGd = gd.getCanonicalDecl();
1294
1295 // Some ABIs don't have constructor variants. Make sure that base and complete
1296 // constructors get mangled the same.
1297 if (const auto *cd = dyn_cast<CXXConstructorDecl>(Val: canonicalGd.getDecl())) {
1298 if (!getTarget().getCXXABI().hasConstructorVariants()) {
1299 errorNYI(cd->getSourceRange(),
1300 "getMangledName: C++ constructor without variants");
1301 return cast<NamedDecl>(Val: gd.getDecl())->getIdentifier()->getName();
1302 }
1303 }
1304
1305 // Keep the first result in the case of a mangling collision.
1306 const auto *nd = cast<NamedDecl>(Val: gd.getDecl());
1307 std::string mangledName = getMangledNameImpl(cgm&: *this, gd, nd);
1308
1309 auto result = manglings.insert(KV: std::make_pair(x&: mangledName, y&: gd));
1310 return mangledDeclNames[canonicalGd] = result.first->first();
1311}
1312
1313void CIRGenModule::emitTentativeDefinition(const VarDecl *d) {
1314 assert(!d->getInit() && "Cannot emit definite definitions here!");
1315
1316 StringRef mangledName = getMangledName(gd: d);
1317 mlir::Operation *gv = getGlobalValue(mangledName);
1318
1319 // If we already have a definition, not declaration, with the same mangled
1320 // name, emitting of declaration is not required (and would actually overwrite
1321 // the emitted definition).
1322 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
1323 return;
1324
1325 // If we have not seen a reference to this variable yet, place it into the
1326 // deferred declarations table to be emitted if needed later.
1327 if (!mustBeEmitted(d) && !gv) {
1328 deferredDecls[mangledName] = d;
1329 return;
1330 }
1331
1332 // The tentative definition is the only definition.
1333 emitGlobalVarDefinition(vd: d);
1334}
1335
1336bool CIRGenModule::mustBeEmitted(const ValueDecl *global) {
1337 // Never defer when EmitAllDecls is specified.
1338 if (langOpts.EmitAllDecls)
1339 return true;
1340
1341 const auto *vd = dyn_cast<VarDecl>(Val: global);
1342 if (vd &&
1343 ((codeGenOpts.KeepPersistentStorageVariables &&
1344 (vd->getStorageDuration() == SD_Static ||
1345 vd->getStorageDuration() == SD_Thread)) ||
1346 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() == SD_Static &&
1347 vd->getType().isConstQualified())))
1348 return true;
1349
1350 return getASTContext().DeclMustBeEmitted(global);
1351}
1352
1353bool CIRGenModule::mayBeEmittedEagerly(const ValueDecl *global) {
1354 // In OpenMP 5.0 variables and function may be marked as
1355 // device_type(host/nohost) and we should not emit them eagerly unless we sure
1356 // that they must be emitted on the host/device. To be sure we need to have
1357 // seen a declare target with an explicit mentioning of the function, we know
1358 // we have if the level of the declare target attribute is -1. Note that we
1359 // check somewhere else if we should emit this at all.
1360 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
1361 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
1362 OMPDeclareTargetDeclAttr::getActiveAttr(global);
1363 if (!activeAttr || (*activeAttr)->getLevel() != (unsigned)-1)
1364 return false;
1365 }
1366
1367 const auto *fd = dyn_cast<FunctionDecl>(Val: global);
1368 if (fd) {
1369 // Implicit template instantiations may change linkage if they are later
1370 // explicitly instantiated, so they should not be emitted eagerly.
1371 if (fd->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
1372 return false;
1373 // Defer until all versions have been semantically checked.
1374 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
1375 return false;
1376 if (langOpts.SYCLIsDevice) {
1377 errorNYI(fd->getSourceRange(), "mayBeEmittedEagerly: SYCL");
1378 return false;
1379 }
1380 }
1381 const auto *vd = dyn_cast<VarDecl>(Val: global);
1382 if (vd)
1383 if (astContext.getInlineVariableDefinitionKind(VD: vd) ==
1384 ASTContext::InlineVariableDefinitionKind::WeakUnknown)
1385 // A definition of an inline constexpr static data member may change
1386 // linkage later if it's redeclared outside the class.
1387 return false;
1388
1389 // If OpenMP is enabled and threadprivates must be generated like TLS, delay
1390 // codegen for global variables, because they may be marked as threadprivate.
1391 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
1392 astContext.getTargetInfo().isTLSSupported() && isa<VarDecl>(global) &&
1393 !global->getType().isConstantStorage(astContext, false, false) &&
1394 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
1395 return false;
1396
1397 assert((fd || vd) &&
1398 "Only FunctionDecl and VarDecl should hit this path so far.");
1399 return true;
1400}
1401
1402static bool shouldAssumeDSOLocal(const CIRGenModule &cgm,
1403 cir::CIRGlobalValueInterface gv) {
1404 if (gv.hasLocalLinkage())
1405 return true;
1406
1407 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
1408 return true;
1409
1410 // DLLImport explicitly marks the GV as external.
1411 // so it shouldn't be dso_local
1412 // But we don't have the info set now
1413 assert(!cir::MissingFeatures::opGlobalDLLImportExport());
1414
1415 const llvm::Triple &tt = cgm.getTriple();
1416 const CodeGenOptions &cgOpts = cgm.getCodeGenOpts();
1417 if (tt.isWindowsGNUEnvironment()) {
1418 // In MinGW, variables without DLLImport can still be automatically
1419 // imported from a DLL by the linker; don't mark variables that
1420 // potentially could come from another DLL as DSO local.
1421
1422 // With EmulatedTLS, TLS variables can be autoimported from other DLLs
1423 // (and this actually happens in the public interface of libstdc++), so
1424 // such variables can't be marked as DSO local. (Native TLS variables
1425 // can't be dllimported at all, though.)
1426 cgm.errorNYI(feature: "shouldAssumeDSOLocal: MinGW");
1427 }
1428
1429 // On COFF, don't mark 'extern_weak' symbols as DSO local. If these symbols
1430 // remain unresolved in the link, they can be resolved to zero, which is
1431 // outside the current DSO.
1432 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
1433 return false;
1434
1435 // Every other GV is local on COFF.
1436 // Make an exception for windows OS in the triple: Some firmware builds use
1437 // *-win32-macho triples. This (accidentally?) produced windows relocations
1438 // without GOT tables in older clang versions; Keep this behaviour.
1439 // FIXME: even thread local variables?
1440 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
1441 return true;
1442
1443 // Only handle COFF and ELF for now.
1444 if (!tt.isOSBinFormatELF())
1445 return false;
1446
1447 llvm::Reloc::Model rm = cgOpts.RelocationModel;
1448 const LangOptions &lOpts = cgm.getLangOpts();
1449 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
1450 // On ELF, if -fno-semantic-interposition is specified and the target
1451 // supports local aliases, there will be neither CC1
1452 // -fsemantic-interposition nor -fhalf-no-semantic-interposition. Set
1453 // dso_local on the function if using a local alias is preferable (can avoid
1454 // PLT indirection).
1455 if (!(isa<cir::FuncOp>(gv) && gv.canBenefitFromLocalAlias()))
1456 return false;
1457 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
1458 }
1459
1460 // A definition cannot be preempted from an executable.
1461 if (!gv.isDeclarationForLinker())
1462 return true;
1463
1464 // Most PIC code sequences that assume that a symbol is local cannot produce a
1465 // 0 if it turns out the symbol is undefined. While this is ABI and relocation
1466 // depended, it seems worth it to handle it here.
1467 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
1468 return false;
1469
1470 // PowerPC64 prefers TOC indirection to avoid copy relocations.
1471 if (tt.isPPC64())
1472 return false;
1473
1474 if (cgOpts.DirectAccessExternalData) {
1475 // If -fdirect-access-external-data (default for -fno-pic), set dso_local
1476 // for non-thread-local variables. If the symbol is not defined in the
1477 // executable, a copy relocation will be needed at link time. dso_local is
1478 // excluded for thread-local variables because they generally don't support
1479 // copy relocations.
1480 if (auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
1481 // Assume variables are not thread-local until that support is added.
1482 assert(!cir::MissingFeatures::opGlobalThreadLocal());
1483 return true;
1484 }
1485
1486 // -fno-pic sets dso_local on a function declaration to allow direct
1487 // accesses when taking its address (similar to a data symbol). If the
1488 // function is not defined in the executable, a canonical PLT entry will be
1489 // needed at link time. -fno-direct-access-external-data can avoid the
1490 // canonical PLT entry. We don't generalize this condition to -fpie/-fpic as
1491 // it could just cause trouble without providing perceptible benefits.
1492 if (isa<cir::FuncOp>(gv) && !cgOpts.NoPLT && rm == llvm::Reloc::Static)
1493 return true;
1494 }
1495
1496 // If we can use copy relocations we can assume it is local.
1497
1498 // Otherwise don't assume it is local.
1499
1500 return false;
1501}
1502
1503void CIRGenModule::setGlobalVisibility(mlir::Operation *gv,
1504 const NamedDecl *d) const {
1505 assert(!cir::MissingFeatures::opGlobalVisibility());
1506}
1507
1508void CIRGenModule::setDSOLocal(cir::CIRGlobalValueInterface gv) const {
1509 gv.setDSOLocal(shouldAssumeDSOLocal(*this, gv));
1510}
1511
1512void CIRGenModule::setDSOLocal(mlir::Operation *op) const {
1513 if (auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
1514 setDSOLocal(globalValue);
1515}
1516
1517void CIRGenModule::setGVProperties(mlir::Operation *op,
1518 const NamedDecl *d) const {
1519 assert(!cir::MissingFeatures::opGlobalDLLImportExport());
1520 setGVPropertiesAux(op, d);
1521}
1522
1523void CIRGenModule::setGVPropertiesAux(mlir::Operation *op,
1524 const NamedDecl *d) const {
1525 setGlobalVisibility(op, d);
1526 setDSOLocal(op);
1527 assert(!cir::MissingFeatures::opGlobalPartition());
1528}
1529
1530cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
1531 StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable,
1532 bool dontDefer, bool isThunk, ForDefinition_t isForDefinition,
1533 mlir::ArrayAttr extraAttrs) {
1534 const Decl *d = gd.getDecl();
1535
1536 if (isThunk)
1537 errorNYI(d->getSourceRange(), "getOrCreateCIRFunction: thunk");
1538
1539 // In what follows, we continue past 'errorNYI' as if nothing happened because
1540 // the rest of the implementation is better than doing nothing.
1541
1542 if (const auto *fd = cast_or_null<FunctionDecl>(Val: d)) {
1543 // For the device mark the function as one that should be emitted.
1544 if (getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
1545 !isForDefinition)
1546 errorNYI(fd->getSourceRange(),
1547 "getOrCreateCIRFunction: OpenMP target function");
1548
1549 // Any attempts to use a MultiVersion function should result in retrieving
1550 // the iFunc instead. Name mangling will handle the rest of the changes.
1551 if (fd->isMultiVersion())
1552 errorNYI(fd->getSourceRange(), "getOrCreateCIRFunction: multi-version");
1553 }
1554
1555 // Lookup the entry, lazily creating it if necessary.
1556 mlir::Operation *entry = getGlobalValue(mangledName);
1557 if (entry) {
1558 if (!isa<cir::FuncOp>(entry))
1559 errorNYI(d->getSourceRange(), "getOrCreateCIRFunction: non-FuncOp");
1560
1561 assert(!cir::MissingFeatures::weakRefReference());
1562
1563 // Handle dropped DLL attributes.
1564 if (d && !d->hasAttr<DLLImportAttr>() && !d->hasAttr<DLLExportAttr>()) {
1565 assert(!cir::MissingFeatures::setDLLStorageClass());
1566 setDSOLocal(entry);
1567 }
1568
1569 // If there are two attempts to define the same mangled name, issue an
1570 // error.
1571 auto fn = cast<cir::FuncOp>(entry);
1572 assert((!isForDefinition || !fn || !fn.isDeclaration()) &&
1573 "Duplicate function definition");
1574 if (fn && fn.getFunctionType() == funcType) {
1575 return fn;
1576 }
1577
1578 if (!isForDefinition) {
1579 return fn;
1580 }
1581
1582 // TODO(cir): classic codegen checks here if this is a llvm::GlobalAlias.
1583 // How will we support this?
1584 }
1585
1586 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(Val: gd.getDecl());
1587 bool invalidLoc = !funcDecl ||
1588 funcDecl->getSourceRange().getBegin().isInvalid() ||
1589 funcDecl->getSourceRange().getEnd().isInvalid();
1590 cir::FuncOp funcOp = createCIRFunction(
1591 invalidLoc ? theModule->getLoc() : getLoc(funcDecl->getSourceRange()),
1592 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
1593
1594 // 'dontDefer' actually means don't move this to the deferredDeclsToEmit list.
1595 if (dontDefer) {
1596 // TODO(cir): This assertion will need an additional condition when we
1597 // support incomplete functions.
1598 assert(funcOp.getFunctionType() == funcType);
1599 return funcOp;
1600 }
1601
1602 // All MSVC dtors other than the base dtor are linkonce_odr and delegate to
1603 // each other bottoming out wiht the base dtor. Therefore we emit non-base
1604 // dtors on usage, even if there is no dtor definition in the TU.
1605 if (isa_and_nonnull<CXXDestructorDecl>(Val: d))
1606 errorNYI(d->getSourceRange(), "getOrCreateCIRFunction: dtor");
1607
1608 // This is the first use or definition of a mangled name. If there is a
1609 // deferred decl with this name, remember that we need to emit it at the end
1610 // of the file.
1611 auto ddi = deferredDecls.find(x: mangledName);
1612 if (ddi != deferredDecls.end()) {
1613 // Move the potentially referenced deferred decl to the
1614 // DeferredDeclsToEmit list, and remove it from DeferredDecls (since we
1615 // don't need it anymore).
1616 addDeferredDeclToEmit(GD: ddi->second);
1617 deferredDecls.erase(position: ddi);
1618
1619 // Otherwise, there are cases we have to worry about where we're using a
1620 // declaration for which we must emit a definition but where we might not
1621 // find a top-level definition.
1622 // - member functions defined inline in their classes
1623 // - friend functions defined inline in some class
1624 // - special member functions with implicit definitions
1625 // If we ever change our AST traversal to walk into class methods, this
1626 // will be unnecessary.
1627 //
1628 // We also don't emit a definition for a function if it's going to be an
1629 // entry in a vtable, unless it's already marked as used.
1630 } else if (getLangOpts().CPlusPlus && d) {
1631 // Look for a declaration that's lexically in a record.
1632 for (const auto *fd = cast<FunctionDecl>(Val: d)->getMostRecentDecl(); fd;
1633 fd = fd->getPreviousDecl()) {
1634 if (isa<CXXRecordDecl>(fd->getLexicalDeclContext())) {
1635 if (fd->doesThisDeclarationHaveABody()) {
1636 addDeferredDeclToEmit(GD: gd.getWithDecl(D: fd));
1637 break;
1638 }
1639 }
1640 }
1641 }
1642
1643 return funcOp;
1644}
1645
1646cir::FuncOp
1647CIRGenModule::createCIRFunction(mlir::Location loc, StringRef name,
1648 cir::FuncType funcType,
1649 const clang::FunctionDecl *funcDecl) {
1650 cir::FuncOp func;
1651 {
1652 mlir::OpBuilder::InsertionGuard guard(builder);
1653
1654 // Some global emissions are triggered while emitting a function, e.g.
1655 // void s() { x.method() }
1656 //
1657 // Be sure to insert a new function before a current one.
1658 CIRGenFunction *cgf = this->curCGF;
1659 if (cgf)
1660 builder.setInsertionPoint(cgf->curFn);
1661
1662 func = builder.create<cir::FuncOp>(loc, name, funcType);
1663
1664 if (!cgf)
1665 theModule.push_back(func);
1666 }
1667 return func;
1668}
1669
1670mlir::SymbolTable::Visibility
1671CIRGenModule::getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind glk) {
1672 switch (glk) {
1673 case cir::GlobalLinkageKind::InternalLinkage:
1674 case cir::GlobalLinkageKind::PrivateLinkage:
1675 return mlir::SymbolTable::Visibility::Private;
1676 case cir::GlobalLinkageKind::ExternalLinkage:
1677 case cir::GlobalLinkageKind::ExternalWeakLinkage:
1678 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
1679 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
1680 case cir::GlobalLinkageKind::CommonLinkage:
1681 case cir::GlobalLinkageKind::WeakAnyLinkage:
1682 case cir::GlobalLinkageKind::WeakODRLinkage:
1683 return mlir::SymbolTable::Visibility::Public;
1684 default: {
1685 llvm::errs() << "visibility not implemented for '"
1686 << stringifyGlobalLinkageKind(glk) << "'\n";
1687 assert(0 && "not implemented");
1688 }
1689 }
1690 llvm_unreachable("linkage should be handled above!");
1691}
1692
1693cir::VisibilityKind CIRGenModule::getGlobalVisibilityKindFromClangVisibility(
1694 clang::VisibilityAttr::VisibilityType visibility) {
1695 switch (visibility) {
1696 case clang::VisibilityAttr::VisibilityType::Default:
1697 return cir::VisibilityKind::Default;
1698 case clang::VisibilityAttr::VisibilityType::Hidden:
1699 return cir::VisibilityKind::Hidden;
1700 case clang::VisibilityAttr::VisibilityType::Protected:
1701 return cir::VisibilityKind::Protected;
1702 }
1703 llvm_unreachable("unexpected visibility value");
1704}
1705
1706cir::VisibilityAttr
1707CIRGenModule::getGlobalVisibilityAttrFromDecl(const Decl *decl) {
1708 const clang::VisibilityAttr *va = decl->getAttr<clang::VisibilityAttr>();
1709 cir::VisibilityAttr cirVisibility =
1710 cir::VisibilityAttr::get(&getMLIRContext());
1711 if (va) {
1712 cirVisibility = cir::VisibilityAttr::get(
1713 &getMLIRContext(),
1714 getGlobalVisibilityKindFromClangVisibility(va->getVisibility()));
1715 }
1716 return cirVisibility;
1717}
1718
1719void CIRGenModule::release() {
1720 emitDeferred();
1721
1722 // There's a lot of code that is not implemented yet.
1723 assert(!cir::MissingFeatures::cgmRelease());
1724}
1725
1726mlir::Type CIRGenModule::convertType(QualType type) {
1727 return genTypes.convertType(type);
1728}
1729
1730bool CIRGenModule::verifyModule() const {
1731 // Verify the module after we have finished constructing it, this will
1732 // check the structural properties of the IR and invoke any specific
1733 // verifiers we have on the CIR operations.
1734 return mlir::verify(theModule).succeeded();
1735}
1736
1737// TODO(cir): this can be shared with LLVM codegen.
1738CharUnits CIRGenModule::computeNonVirtualBaseClassOffset(
1739 const CXXRecordDecl *derivedClass,
1740 llvm::iterator_range<CastExpr::path_const_iterator> path) {
1741 CharUnits offset = CharUnits::Zero();
1742
1743 const ASTContext &astContext = getASTContext();
1744 const CXXRecordDecl *rd = derivedClass;
1745
1746 for (const CXXBaseSpecifier *base : path) {
1747 assert(!base->isVirtual() && "Should not see virtual bases here!");
1748
1749 // Get the layout.
1750 const ASTRecordLayout &layout = astContext.getASTRecordLayout(rd);
1751
1752 const auto *baseDecl = cast<CXXRecordDecl>(
1753 Val: base->getType()->castAs<clang::RecordType>()->getDecl());
1754
1755 // Add the offset.
1756 offset += layout.getBaseClassOffset(Base: baseDecl);
1757
1758 rd = baseDecl;
1759 }
1760
1761 return offset;
1762}
1763
1764DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc,
1765 llvm::StringRef feature) {
1766 unsigned diagID = diags.getCustomDiagID(
1767 L: DiagnosticsEngine::Error, FormatString: "ClangIR code gen Not Yet Implemented: %0");
1768 return diags.Report(Loc: loc, DiagID: diagID) << feature;
1769}
1770
1771DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc,
1772 llvm::StringRef feature) {
1773 return errorNYI(loc: loc.getBegin(), feature) << loc;
1774}
1775

source code of clang/lib/CIR/CodeGen/CIRGenModule.cpp