clang 22.0.0git
CIRGenModule.cpp
Go to the documentation of this file.
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"
16#include "CIRGenFunction.h"
17
19#include "clang/AST/DeclBase.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
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("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(*this)), genTypes(*this), vtables(*this) {
68
69 // Initialize cached types
70 VoidTy = cir::VoidType::get(&getMLIRContext());
71 VoidPtrTy = cir::PointerType::get(VoidTy);
72 SInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/true);
73 SInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/true);
74 SInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/true);
75 SInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/true);
76 SInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/true);
77 UInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/false);
78 UInt8PtrTy = cir::PointerType::get(UInt8Ty);
79 UInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/false);
80 UInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/false);
81 UInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/false);
82 UInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/false);
83 FP16Ty = cir::FP16Type::get(&getMLIRContext());
84 BFloat16Ty = cir::BF16Type::get(&getMLIRContext());
85 FloatTy = cir::SingleType::get(&getMLIRContext());
86 DoubleTy = cir::DoubleType::get(&getMLIRContext());
87 FP80Ty = cir::FP80Type::get(&getMLIRContext());
88 FP128Ty = cir::FP128Type::get(&getMLIRContext());
89
91 astContext
94 .getQuantity();
95
96 // TODO(CIR): Should be updated once TypeSizeInfoAttr is upstreamed
97 const unsigned sizeTypeSize =
98 astContext.getTypeSize(astContext.getSignedSizeType());
99 SizeAlignInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
100 // In CIRGenTypeCache, UIntPtrTy and SizeType are fields of the same union
101 UIntPtrTy =
102 cir::IntType::get(&getMLIRContext(), sizeTypeSize, /*isSigned=*/false);
103 PtrDiffTy =
104 cir::IntType::get(&getMLIRContext(), sizeTypeSize, /*isSigned=*/true);
105
106 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
107 if (sourceLanguage)
108 theModule->setAttr(
109 cir::CIRDialect::getSourceLanguageAttrName(),
110 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
111 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
112 builder.getStringAttr(getTriple().str()));
113
114 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
115 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
116 cir::OptInfoAttr::get(&mlirContext,
117 cgo.OptimizationLevel,
118 cgo.OptimizeSize));
119}
120
122
123/// FIXME: this could likely be a common helper and not necessarily related
124/// with codegen.
125/// Return the best known alignment for an unknown pointer to a
126/// particular class.
128 if (!rd->hasDefinition())
129 return CharUnits::One(); // Hopefully won't be used anywhere.
130
131 auto &layout = astContext.getASTRecordLayout(rd);
132
133 // If the class is final, then we know that the pointer points to an
134 // object of that type and can use the full alignment.
135 if (rd->isEffectivelyFinal())
136 return layout.getAlignment();
137
138 // Otherwise, we have to assume it could be a subclass.
139 return layout.getNonVirtualAlignment();
140}
141
143 LValueBaseInfo *baseInfo) {
145
146 // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown, but
147 // that doesn't return the information we need to compute baseInfo.
148
149 // Honor alignment typedef attributes even on incomplete types.
150 // We also honor them straight for C++ class types, even as pointees;
151 // there's an expressivity gap here.
152 if (const auto *tt = t->getAs<TypedefType>()) {
153 if (unsigned align = tt->getDecl()->getMaxAlignment()) {
154 if (baseInfo)
156 return astContext.toCharUnitsFromBits(align);
157 }
158 }
159
160 // Analyze the base element type, so we don't get confused by incomplete
161 // array types.
162 t = astContext.getBaseElementType(t);
163
164 if (t->isIncompleteType()) {
165 // We could try to replicate the logic from
166 // ASTContext::getTypeAlignIfKnown, but nothing uses the alignment if the
167 // type is incomplete, so it's impossible to test. We could try to reuse
168 // getTypeAlignIfKnown, but that doesn't return the information we need
169 // to set baseInfo. So just ignore the possibility that the alignment is
170 // greater than one.
171 if (baseInfo)
173 return CharUnits::One();
174 }
175
176 if (baseInfo)
178
179 CharUnits alignment;
180 if (t.getQualifiers().hasUnaligned()) {
181 alignment = CharUnits::One();
182 } else {
184 alignment = astContext.getTypeAlignInChars(t);
185 }
186
187 // Cap to the global maximum type alignment unless the alignment
188 // was somehow explicit on the type.
189 if (unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
190 if (alignment.getQuantity() > maxAlign &&
191 !astContext.isAlignmentRequired(t))
192 alignment = CharUnits::fromQuantity(maxAlign);
193 }
194 return alignment;
195}
196
198 if (theTargetCIRGenInfo)
199 return *theTargetCIRGenInfo;
200
201 const llvm::Triple &triple = getTarget().getTriple();
202 switch (triple.getArch()) {
203 default:
205
206 // Currently we just fall through to x86_64.
207 [[fallthrough]];
208
209 case llvm::Triple::x86_64: {
210 switch (triple.getOS()) {
211 default:
213
214 // Currently we just fall through to x86_64.
215 [[fallthrough]];
216
217 case llvm::Triple::Linux:
218 theTargetCIRGenInfo = createX8664TargetCIRGenInfo(genTypes);
219 return *theTargetCIRGenInfo;
220 }
221 }
222 }
223}
224
226 assert(cLoc.isValid() && "expected valid source location");
227 const SourceManager &sm = astContext.getSourceManager();
228 PresumedLoc pLoc = sm.getPresumedLoc(cLoc);
229 StringRef filename = pLoc.getFilename();
230 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
231 pLoc.getLine(), pLoc.getColumn());
232}
233
234mlir::Location CIRGenModule::getLoc(SourceRange cRange) {
235 assert(cRange.isValid() && "expected a valid source range");
236 mlir::Location begin = getLoc(cRange.getBegin());
237 mlir::Location end = getLoc(cRange.getEnd());
238 mlir::Attribute metadata;
239 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
240}
241
242mlir::Operation *
244 const Decl *d = gd.getDecl();
245
246 if (isa<CXXConstructorDecl>(d) || isa<CXXDestructorDecl>(d))
247 return getAddrOfCXXStructor(gd, /*FnInfo=*/nullptr, /*FnType=*/nullptr,
248 /*DontDefer=*/false, isForDefinition);
249
250 if (isa<CXXMethodDecl>(d)) {
251 const CIRGenFunctionInfo &fi =
252 getTypes().arrangeCXXMethodDeclaration(cast<CXXMethodDecl>(d));
253 cir::FuncType ty = getTypes().getFunctionType(fi);
254 return getAddrOfFunction(gd, ty, /*ForVTable=*/false, /*DontDefer=*/false,
255 isForDefinition);
256 }
257
258 if (isa<FunctionDecl>(d)) {
260 cir::FuncType ty = getTypes().getFunctionType(fi);
261 return getAddrOfFunction(gd, ty, /*ForVTable=*/false, /*DontDefer=*/false,
262 isForDefinition);
263 }
264
265 return getAddrOfGlobalVar(cast<VarDecl>(d), /*ty=*/nullptr, isForDefinition)
266 .getDefiningOp();
267}
268
270 // We call getAddrOfGlobal with isForDefinition set to ForDefinition in
271 // order to get a Value with exactly the type we need, not something that
272 // might have been created for another decl with the same mangled name but
273 // different type.
274 mlir::Operation *op = getAddrOfGlobal(d, ForDefinition);
275
276 // In case of different address spaces, we may still get a cast, even with
277 // IsForDefinition equal to ForDefinition. Query mangled names table to get
278 // GlobalValue.
279 if (!op)
281
282 assert(op && "expected a valid global op");
283
284 // Check to see if we've already emitted this. This is necessary for a
285 // couple of reasons: first, decls can end up in deferred-decls queue
286 // multiple times, and second, decls can end up with definitions in unusual
287 // ways (e.g. by an extern inline function acquiring a strong function
288 // redefinition). Just ignore those cases.
289 // TODO: Not sure what to map this to for MLIR
290 mlir::Operation *globalValueOp = op;
291 if (auto gv = dyn_cast<cir::GetGlobalOp>(op))
292 globalValueOp =
293 mlir::SymbolTable::lookupSymbolIn(getModule(), gv.getNameAttr());
294
295 if (auto cirGlobalValue =
296 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
297 if (!cirGlobalValue.isDeclaration())
298 return;
299
300 // If this is OpenMP, check if it is legal to emit this global normally.
302
303 // Otherwise, emit the definition and move on to the next one.
305}
306
308 // Emit code for any potentially referenced deferred decls. Since a previously
309 // unused static decl may become used during the generation of code for a
310 // static function, iterate until no changes are made.
311
315
316 // Stop if we're out of both deferred vtables and deferred declarations.
317 if (deferredDeclsToEmit.empty())
318 return;
319
320 // Grab the list of decls to emit. If emitGlobalDefinition schedules more
321 // work, it will not interfere with this.
322 std::vector<GlobalDecl> curDeclsToEmit;
323 curDeclsToEmit.swap(deferredDeclsToEmit);
324
325 for (const GlobalDecl &d : curDeclsToEmit) {
327
328 // If we found out that we need to emit more decls, do that recursively.
329 // This has the advantage that the decls are emitted in a DFS and related
330 // ones are close together, which is convenient for testing.
331 if (!deferredDeclsToEmit.empty()) {
332 emitDeferred();
333 assert(deferredDeclsToEmit.empty());
334 }
335 }
336}
337
339 if (const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.getDecl())) {
341 return;
342 }
343
344 const auto *global = cast<ValueDecl>(gd.getDecl());
345
346 if (const auto *fd = dyn_cast<FunctionDecl>(global)) {
347 // Update deferred annotations with the latest declaration if the function
348 // was already used or defined.
349 if (fd->hasAttr<AnnotateAttr>())
350 errorNYI(fd->getSourceRange(), "deferredAnnotations");
351 if (!fd->doesThisDeclarationHaveABody()) {
352 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
353 return;
354
355 errorNYI(fd->getSourceRange(),
356 "function declaration that forces code gen");
357 return;
358 }
359 } else {
360 const auto *vd = cast<VarDecl>(global);
361 assert(vd->isFileVarDecl() && "Cannot emit local var decl as global.");
362 if (vd->isThisDeclarationADefinition() != VarDecl::Definition &&
363 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
365 // If this declaration may have caused an inline variable definition to
366 // change linkage, make sure that it's emitted.
367 if (astContext.getInlineVariableDefinitionKind(vd) ==
370 // Otherwise, we can ignore this declaration. The variable will be emitted
371 // on its first use.
372 return;
373 }
374 }
375
376 // Defer code generation to first use when possible, e.g. if this is an inline
377 // function. If the global must always be emitted, do it eagerly if possible
378 // to benefit from cache locality. Deferring code generation is necessary to
379 // avoid adding initializers to external declarations.
380 if (mustBeEmitted(global) && mayBeEmittedEagerly(global)) {
381 // Emit the definition if it can't be deferred.
383 return;
384 }
385
386 // If we're deferring emission of a C++ variable with an initializer, remember
387 // the order in which it appeared on the file.
389
390 llvm::StringRef mangledName = getMangledName(gd);
391 if (getGlobalValue(mangledName) != nullptr) {
392 // The value has already been used and should therefore be emitted.
394 } else if (mustBeEmitted(global)) {
395 // The value must be emitted, but cannot be emitted eagerly.
396 assert(!mayBeEmittedEagerly(global));
398 } else {
399 // Otherwise, remember that we saw a deferred decl with this name. The first
400 // use of the mangled name will cause it to move into deferredDeclsToEmit.
401 deferredDecls[mangledName] = gd;
402 }
403}
404
406 mlir::Operation *op) {
407 auto const *funcDecl = cast<FunctionDecl>(gd.getDecl());
409 cir::FuncType funcType = getTypes().getFunctionType(fi);
410 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
411 if (!funcOp || funcOp.getFunctionType() != funcType) {
412 funcOp = getAddrOfFunction(gd, funcType, /*ForVTable=*/false,
413 /*DontDefer=*/true, ForDefinition);
414 }
415
416 // Already emitted.
417 if (!funcOp.isDeclaration())
418 return;
419
420 setFunctionLinkage(gd, funcOp);
421 setGVProperties(funcOp, funcDecl);
423 maybeSetTrivialComdat(*funcDecl, funcOp);
425
426 CIRGenFunction cgf(*this, builder);
427 curCGF = &cgf;
428 {
429 mlir::OpBuilder::InsertionGuard guard(builder);
430 cgf.generateCode(gd, funcOp, funcType);
431 }
432 curCGF = nullptr;
433
434 setNonAliasAttributes(gd, funcOp);
436
437 if (funcDecl->getAttr<ConstructorAttr>())
438 errorNYI(funcDecl->getSourceRange(), "constructor attribute");
439 if (funcDecl->getAttr<DestructorAttr>())
440 errorNYI(funcDecl->getSourceRange(), "destructor attribute");
441
442 if (funcDecl->getAttr<AnnotateAttr>())
443 errorNYI(funcDecl->getSourceRange(), "deferredAnnotations");
444}
445
448 if (dk == VarDecl::Definition && vd->hasAttr<DLLImportAttr>())
449 return;
450
452 // If we have a definition, this might be a deferred decl. If the
453 // instantiation is explicit, make sure we emit it at the end.
456
458}
459
460mlir::Operation *CIRGenModule::getGlobalValue(StringRef name) {
461 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
462}
463
465 mlir::Location loc, StringRef name,
466 mlir::Type t, bool isConstant,
467 mlir::Operation *insertPoint) {
468 cir::GlobalOp g;
469 CIRGenBuilderTy &builder = cgm.getBuilder();
470
471 {
472 mlir::OpBuilder::InsertionGuard guard(builder);
473
474 // If an insertion point is provided, we're replacing an existing global,
475 // otherwise, create the new global immediately after the last gloabl we
476 // emitted.
477 if (insertPoint) {
478 builder.setInsertionPoint(insertPoint);
479 } else {
480 // Group global operations together at the top of the module.
481 if (cgm.lastGlobalOp)
482 builder.setInsertionPointAfter(cgm.lastGlobalOp);
483 else
484 builder.setInsertionPointToStart(cgm.getModule().getBody());
485 }
486
487 g = builder.create<cir::GlobalOp>(loc, name, t, isConstant);
488 if (!insertPoint)
489 cgm.lastGlobalOp = g;
490
491 // Default to private until we can judge based on the initializer,
492 // since MLIR doesn't allow public declarations.
493 mlir::SymbolTable::setSymbolVisibility(
494 g, mlir::SymbolTable::Visibility::Private);
495 }
496 return g;
497}
498
499void CIRGenModule::setCommonAttributes(GlobalDecl gd, mlir::Operation *gv) {
500 const Decl *d = gd.getDecl();
501 if (isa_and_nonnull<NamedDecl>(d))
502 setGVProperties(gv, dyn_cast<NamedDecl>(d));
505}
506
507void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
508 setCommonAttributes(gd, op);
509
514
516}
517
518std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage() const {
519 using ClangStd = clang::LangStandard;
520 using CIRLang = cir::SourceLanguage;
521 auto opts = getLangOpts();
522
523 if (opts.CPlusPlus)
524 return CIRLang::CXX;
525 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
526 opts.LangStd == ClangStd::lang_c89 ||
527 opts.LangStd == ClangStd::lang_gnu89)
528 return CIRLang::C;
529
530 // TODO(cir): support remaining source languages.
532 errorNYI("CIR does not yet support the given source language");
533 return std::nullopt;
534}
535
536static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd) {
537 // Set linkage and visibility in case we never see a definition.
539 // Don't set internal linkage on declarations.
540 // "extern_weak" is overloaded in LLVM; we probably should have
541 // separate linkage types for this.
543 (nd->hasAttr<WeakAttr>() || nd->isWeakImported()))
544 gv.setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
545}
546
547/// If the specified mangled name is not in the module,
548/// create and return an mlir GlobalOp with the specified type (TODO(cir):
549/// address space).
550///
551/// TODO(cir):
552/// 1. If there is something in the module with the specified name, return
553/// it potentially bitcasted to the right type.
554///
555/// 2. If \p d is non-null, it specifies a decl that correspond to this. This
556/// is used to set the attributes on the global when it is first created.
557///
558/// 3. If \p isForDefinition is true, it is guaranteed that an actual global
559/// with type \p ty will be returned, not conversion of a variable with the same
560/// mangled name but some other type.
561cir::GlobalOp
562CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
563 LangAS langAS, const VarDecl *d,
564 ForDefinition_t isForDefinition) {
565 // Lookup the entry, lazily creating it if necessary.
566 cir::GlobalOp entry;
567 if (mlir::Operation *v = getGlobalValue(mangledName)) {
568 if (!isa<cir::GlobalOp>(v))
569 errorNYI(d->getSourceRange(), "global with non-GlobalOp type");
570 entry = cast<cir::GlobalOp>(v);
571 }
572
573 if (entry) {
576
579
580 if (entry.getSymType() == ty)
581 return entry;
582
583 // If there are two attempts to define the same mangled name, issue an
584 // error.
585 //
586 // TODO(cir): look at mlir::GlobalValue::isDeclaration for all aspects of
587 // recognizing the global as a declaration, for now only check if
588 // initializer is present.
589 if (isForDefinition && !entry.isDeclaration()) {
590 errorNYI(d->getSourceRange(), "global with conflicting type");
591 }
592
593 // Address space check removed because it is unnecessary because CIR records
594 // address space info in types.
595
596 // (If global is requested for a definition, we always need to create a new
597 // global, not just return a bitcast.)
598 if (!isForDefinition)
599 return entry;
600 }
601
602 mlir::Location loc = getLoc(d->getSourceRange());
603
604 // mlir::SymbolTable::Visibility::Public is the default, no need to explicitly
605 // mark it as such.
606 cir::GlobalOp gv =
607 CIRGenModule::createGlobalOp(*this, loc, mangledName, ty, false,
608 /*insertPoint=*/entry.getOperation());
609
610 // This is the first use or definition of a mangled name. If there is a
611 // deferred decl with this name, remember that we need to emit it at the end
612 // of the file.
613 auto ddi = deferredDecls.find(mangledName);
614 if (ddi != deferredDecls.end()) {
615 // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
616 // list, and remove it from DeferredDecls (since we don't need it anymore).
617 addDeferredDeclToEmit(ddi->second);
618 deferredDecls.erase(ddi);
619 }
620
621 // Handle things which are present even on external declarations.
622 if (d) {
623 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
624 errorNYI(d->getSourceRange(), "OpenMP target global variable");
625
626 gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
628
629 setLinkageForGV(gv, d);
630
631 if (d->getTLSKind())
632 errorNYI(d->getSourceRange(), "thread local global variable");
633
634 setGVProperties(gv, d);
635
636 // If required by the ABI, treat declarations of static data members with
637 // inline initializers as definitions.
638 if (astContext.isMSStaticDataMemberInlineDefinition(d))
639 errorNYI(d->getSourceRange(), "MS static data member inline definition");
640
642 gv.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(d));
643
644 // Handle XCore specific ABI requirements.
645 if (getTriple().getArch() == llvm::Triple::xcore)
646 errorNYI(d->getSourceRange(), "XCore specific ABI requirements");
647
648 // Check if we a have a const declaration with an initializer, we may be
649 // able to emit it as available_externally to expose it's value to the
650 // optimizer.
651 if (getLangOpts().CPlusPlus && gv.isPublic() &&
652 d->getType().isConstQualified() && gv.isDeclaration() &&
653 !d->hasDefinition() && d->hasInit() && !d->hasAttr<DLLImportAttr>())
655 "external const declaration with initializer");
656 }
657
658 return gv;
659}
660
661cir::GlobalOp
663 ForDefinition_t isForDefinition) {
664 assert(d->hasGlobalStorage() && "Not a global variable");
665 QualType astTy = d->getType();
666 if (!ty)
667 ty = getTypes().convertTypeForMem(astTy);
668
669 StringRef mangledName = getMangledName(d);
670 return getOrCreateCIRGlobal(mangledName, ty, astTy.getAddressSpace(), d,
671 isForDefinition);
672}
673
674/// Return the mlir::Value for the address of the given global variable. If
675/// \p ty is non-null and if the global doesn't exist, then it will be created
676/// with the specified type instead of whatever the normal requested type would
677/// be. If \p isForDefinition is true, it is guaranteed that an actual global
678/// with type \p ty will be returned, not conversion of a variable with the same
679/// mangled name but some other type.
680mlir::Value CIRGenModule::getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty,
681 ForDefinition_t isForDefinition) {
682 assert(d->hasGlobalStorage() && "Not a global variable");
683 QualType astTy = d->getType();
684 if (!ty)
685 ty = getTypes().convertTypeForMem(astTy);
686
688
689 cir::GlobalOp g = getOrCreateCIRGlobal(d, ty, isForDefinition);
690 mlir::Type ptrTy = builder.getPointerTo(g.getSymType());
691 return builder.create<cir::GetGlobalOp>(getLoc(d->getSourceRange()), ptrTy,
692 g.getSymName());
693}
694
695cir::GlobalViewAttr CIRGenModule::getAddrOfGlobalVarAttr(const VarDecl *d) {
696 assert(d->hasGlobalStorage() && "Not a global variable");
697 mlir::Type ty = getTypes().convertTypeForMem(d->getType());
698
699 cir::GlobalOp globalOp = getOrCreateCIRGlobal(d, ty, NotForDefinition);
701 cir::PointerType ptrTy = builder.getPointerTo(globalOp.getSymType());
702 return builder.getGlobalViewAttr(ptrTy, globalOp);
703}
704
706 bool isTentative) {
707 if (getLangOpts().OpenCL || getLangOpts().OpenMPIsTargetDevice) {
708 errorNYI(vd->getSourceRange(), "emit OpenCL/OpenMP global variable");
709 return;
710 }
711
712 // Whether the definition of the variable is available externally.
713 // If yes, we shouldn't emit the GloablCtor and GlobalDtor for the variable
714 // since this is the job for its original source.
715 bool isDefinitionAvailableExternally =
718
719 // It is useless to emit the definition for an available_externally variable
720 // which can't be marked as const.
721 if (isDefinitionAvailableExternally &&
723 // TODO: Update this when we have interface to check constexpr
724 // destructor.
725 vd->needsDestruction(astContext) ||
726 !vd->getType().isConstantStorage(astContext, true, true)))
727 return;
728
729 mlir::Attribute init;
730 const VarDecl *initDecl;
731 const Expr *initExpr = vd->getAnyInitializer(initDecl);
732
733 std::optional<ConstantEmitter> emitter;
734
736
737 if (vd->hasAttr<LoaderUninitializedAttr>()) {
738 errorNYI(vd->getSourceRange(), "loader uninitialized attribute");
739 return;
740 } else if (!initExpr) {
741 // This is a tentative definition; tentative definitions are
742 // implicitly initialized with { 0 }.
743 //
744 // Note that tentative definitions are only emitted at the end of
745 // a translation unit, so they should never have incomplete
746 // type. In addition, EmitTentativeDefinition makes sure that we
747 // never attempt to emit a tentative definition if a real one
748 // exists. A use may still exists, however, so we still may need
749 // to do a RAUW.
750 assert(!vd->getType()->isIncompleteType() && "Unexpected incomplete type");
751 init = builder.getZeroInitAttr(convertType(vd->getType()));
752 } else {
753 emitter.emplace(*this);
754 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
755 if (!initializer) {
756 QualType qt = initExpr->getType();
757 if (vd->getType()->isReferenceType())
758 qt = vd->getType();
759
760 if (getLangOpts().CPlusPlus) {
761 if (initDecl->hasFlexibleArrayInit(astContext))
762 errorNYI(vd->getSourceRange(), "flexible array initializer");
763 init = builder.getZeroInitAttr(convertType(qt));
765 errorNYI(vd->getSourceRange(), "global constructor");
766 } else {
767 errorNYI(vd->getSourceRange(), "static initializer");
768 }
769 } else {
770 init = initializer;
771 // We don't need an initializer, so remove the entry for the delayed
772 // initializer position (just in case this entry was delayed) if we
773 // also don't need to register a destructor.
774 if (vd->needsDestruction(astContext) == QualType::DK_cxx_destructor)
775 errorNYI(vd->getSourceRange(), "delayed destructor");
776 }
777 }
778
779 mlir::Type initType;
780 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
781 errorNYI(vd->getSourceRange(), "global initializer is a symbol reference");
782 return;
783 } else {
784 assert(mlir::isa<mlir::TypedAttr>(init) && "This should have a type");
785 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
786 initType = typedInitAttr.getType();
787 }
788 assert(!mlir::isa<mlir::NoneType>(initType) && "Should have a type by now");
789
790 cir::GlobalOp gv =
791 getOrCreateCIRGlobal(vd, initType, ForDefinition_t(!isTentative));
792 // TODO(cir): Strip off pointer casts from Entry if we get them?
793
794 if (!gv || gv.getSymType() != initType) {
795 errorNYI(vd->getSourceRange(), "global initializer with type mismatch");
796 return;
797 }
798
800
801 if (vd->hasAttr<AnnotateAttr>()) {
802 errorNYI(vd->getSourceRange(), "annotate global variable");
803 }
804
805 if (langOpts.CUDA) {
806 errorNYI(vd->getSourceRange(), "CUDA global variable");
807 }
808
809 // Set initializer and finalize emission
811 if (emitter)
812 emitter->finalize(gv);
813
814 // Set CIR's linkage type as appropriate.
815 cir::GlobalLinkageKind linkage =
816 getCIRLinkageVarDefinition(vd, /*IsConstant=*/false);
817
818 // Set CIR linkage and DLL storage class.
819 gv.setLinkage(linkage);
820 // FIXME(cir): setLinkage should likely set MLIR's visibility automatically.
821 gv.setVisibility(getMLIRVisibilityFromCIRLinkage(linkage));
823 if (linkage == cir::GlobalLinkageKind::CommonLinkage)
824 errorNYI(initExpr->getSourceRange(), "common linkage");
825
826 setNonAliasAttributes(vd, gv);
827
829
830 maybeSetTrivialComdat(*vd, gv);
831}
832
834 mlir::Operation *op) {
835 const auto *decl = cast<ValueDecl>(gd.getDecl());
836 if (const auto *fd = dyn_cast<FunctionDecl>(decl)) {
837 // TODO(CIR): Skip generation of CIR for functions with available_externally
838 // linkage at -O0.
839
840 if (const auto *method = dyn_cast<CXXMethodDecl>(decl)) {
841 // Make sure to emit the definition(s) before we emit the thunks. This is
842 // necessary for the generation of certain thunks.
843 if (isa<CXXConstructorDecl>(method) || isa<CXXDestructorDecl>(method))
844 abi->emitCXXStructor(gd);
845 else if (fd->isMultiVersion())
846 errorNYI(method->getSourceRange(), "multiversion functions");
847 else
849
850 if (method->isVirtual())
852
853 return;
854 }
855
856 if (fd->isMultiVersion())
857 errorNYI(fd->getSourceRange(), "multiversion functions");
859 return;
860 }
861
862 if (const auto *vd = dyn_cast<VarDecl>(decl))
863 return emitGlobalVarDefinition(vd, !vd->hasDefinition());
864
865 llvm_unreachable("Invalid argument to CIRGenModule::emitGlobalDefinition");
866}
867
868mlir::Attribute
870 assert(!e->getType()->isPointerType() && "Strings are always arrays");
871
872 // Don't emit it as the address of the string, emit the string data itself
873 // as an inline array.
874 if (e->getCharByteWidth() == 1) {
875 SmallString<64> str(e->getString());
876
877 // Resize the string to the right size, which is indicated by its type.
878 const ConstantArrayType *cat =
879 astContext.getAsConstantArrayType(e->getType());
880 uint64_t finalSize = cat->getZExtSize();
881 str.resize(finalSize);
882
883 mlir::Type eltTy = convertType(cat->getElementType());
884 return builder.getString(str, eltTy, finalSize);
885 }
886
888 "getConstantArrayFromStringLiteral: wide characters");
889 return mlir::Attribute();
890}
891
893 return getTriple().supportsCOMDAT();
894}
895
896static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d) {
897 if (!cgm.supportsCOMDAT())
898 return false;
899
900 if (d.hasAttr<SelectAnyAttr>())
901 return true;
902
903 GVALinkage linkage;
904 if (auto *vd = dyn_cast<VarDecl>(&d))
905 linkage = cgm.getASTContext().GetGVALinkageForVariable(vd);
906 else
907 linkage =
908 cgm.getASTContext().GetGVALinkageForFunction(cast<FunctionDecl>(&d));
909
910 switch (linkage) {
914 return false;
917 return true;
918 }
919 llvm_unreachable("No such linkage");
920}
921
922void CIRGenModule::maybeSetTrivialComdat(const Decl &d, mlir::Operation *op) {
923 if (!shouldBeInCOMDAT(*this, d))
924 return;
925 if (auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
926 globalOp.setComdat(true);
927 } else {
928 auto funcOp = cast<cir::FuncOp>(op);
929 funcOp.setComdat(true);
930 }
931}
932
934 // Make sure that this type is translated.
935 genTypes.updateCompletedType(td);
936}
937
938void CIRGenModule::addReplacement(StringRef name, mlir::Operation *op) {
939 replacements[name] = op;
940}
941
942void CIRGenModule::replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF) {
943 std::optional<mlir::SymbolTable::UseRange> optionalUseRange =
944 oldF.getSymbolUses(theModule);
945 if (!optionalUseRange)
946 return;
947
948 for (const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
949 // CallTryOp only shows up after FlattenCFG.
950 auto call = mlir::dyn_cast<cir::CallOp>(u.getUser());
951 if (!call)
952 continue;
953
954 for (const auto [argOp, fnArgType] :
955 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
956 if (argOp.getType() == fnArgType)
957 continue;
958
959 // The purpose of this entire function is to insert bitcasts in the case
960 // where these types don't match, but I haven't seen a case where that
961 // happens.
962 errorNYI(call.getLoc(), "replace call with mismatched types");
963 }
964 }
965}
966
967void CIRGenModule::applyReplacements() {
968 for (auto &i : replacements) {
969 StringRef mangledName = i.first();
970 mlir::Operation *replacement = i.second;
971 mlir::Operation *entry = getGlobalValue(mangledName);
972 if (!entry)
973 continue;
974 assert(isa<cir::FuncOp>(entry) && "expected function");
975 auto oldF = cast<cir::FuncOp>(entry);
976 auto newF = dyn_cast<cir::FuncOp>(replacement);
977 if (!newF) {
978 // In classic codegen, this can be a global alias, a bitcast, or a GEP.
979 errorNYI(replacement->getLoc(), "replacement is not a function");
980 continue;
981 }
982
983 // LLVM has opaque pointer but CIR not. So we may have to handle these
984 // different pointer types when performing replacement.
985 replacePointerTypeArgs(oldF, newF);
986
987 // Replace old with new, but keep the old order.
988 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
989 llvm_unreachable("internal error, cannot RAUW symbol");
990 if (newF) {
991 newF->moveBefore(oldF);
992 oldF->erase();
993 }
994 }
995}
996
998 mlir::Location loc, StringRef name, mlir::Type ty,
999 cir::GlobalLinkageKind linkage, clang::CharUnits alignment) {
1000 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
1001 mlir::SymbolTable::lookupSymbolIn(theModule, name));
1002
1003 if (gv) {
1004 // There should be handling added here to check the type as assert that
1005 // gv was a declaration if the type doesn't match and handling below
1006 // to replace the variable if it was a declaration.
1007 errorNYI(loc, "createOrReplaceCXXRuntimeVariable: already exists");
1008 return gv;
1009 }
1010
1011 // Create a new variable.
1012 gv = createGlobalOp(*this, loc, name, ty);
1013
1014 // Set up extra information and add to the module
1015 gv.setLinkageAttr(
1016 cir::GlobalLinkageKindAttr::get(&getMLIRContext(), linkage));
1017 mlir::SymbolTable::setSymbolVisibility(gv,
1019
1020 if (supportsCOMDAT() && cir::isWeakForLinker(linkage) &&
1021 !gv.hasAvailableExternallyLinkage()) {
1022 gv.setComdat(true);
1023 }
1024
1025 gv.setAlignmentAttr(getSize(alignment));
1026 setDSOLocal(static_cast<mlir::Operation *>(gv));
1027 return gv;
1028}
1029
1030// TODO(CIR): this could be a common method between LLVM codegen.
1031static bool isVarDeclStrongDefinition(const ASTContext &astContext,
1032 CIRGenModule &cgm, const VarDecl *vd,
1033 bool noCommon) {
1034 // Don't give variables common linkage if -fno-common was specified unless it
1035 // was overridden by a NoCommon attribute.
1036 if ((noCommon || vd->hasAttr<NoCommonAttr>()) && !vd->hasAttr<CommonAttr>())
1037 return true;
1038
1039 // C11 6.9.2/2:
1040 // A declaration of an identifier for an object that has file scope without
1041 // an initializer, and without a storage-class specifier or with the
1042 // storage-class specifier static, constitutes a tentative definition.
1043 if (vd->getInit() || vd->hasExternalStorage())
1044 return true;
1045
1046 // A variable cannot be both common and exist in a section.
1047 if (vd->hasAttr<SectionAttr>())
1048 return true;
1049
1050 // A variable cannot be both common and exist in a section.
1051 // We don't try to determine which is the right section in the front-end.
1052 // If no specialized section name is applicable, it will resort to default.
1053 if (vd->hasAttr<PragmaClangBSSSectionAttr>() ||
1054 vd->hasAttr<PragmaClangDataSectionAttr>() ||
1055 vd->hasAttr<PragmaClangRelroSectionAttr>() ||
1056 vd->hasAttr<PragmaClangRodataSectionAttr>())
1057 return true;
1058
1059 // Thread local vars aren't considered common linkage.
1060 if (vd->getTLSKind())
1061 return true;
1062
1063 // Tentative definitions marked with WeakImportAttr are true definitions.
1064 if (vd->hasAttr<WeakImportAttr>())
1065 return true;
1066
1067 // A variable cannot be both common and exist in a comdat.
1068 if (shouldBeInCOMDAT(cgm, *vd))
1069 return true;
1070
1071 // Declarations with a required alignment do not have common linkage in MSVC
1072 // mode.
1073 if (astContext.getTargetInfo().getCXXABI().isMicrosoft()) {
1074 if (vd->hasAttr<AlignedAttr>())
1075 return true;
1076 QualType varType = vd->getType();
1077 if (astContext.isAlignmentRequired(varType))
1078 return true;
1079
1080 if (const auto *rd = varType->getAsRecordDecl()) {
1081 for (const FieldDecl *fd : rd->fields()) {
1082 if (fd->isBitField())
1083 continue;
1084 if (fd->hasAttr<AlignedAttr>())
1085 return true;
1086 if (astContext.isAlignmentRequired(fd->getType()))
1087 return true;
1088 }
1089 }
1090 }
1091
1092 // Microsoft's link.exe doesn't support alignments greater than 32 bytes for
1093 // common symbols, so symbols with greater alignment requirements cannot be
1094 // common.
1095 // Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
1096 // alignments for common symbols via the aligncomm directive, so this
1097 // restriction only applies to MSVC environments.
1098 if (astContext.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
1099 astContext.getTypeAlignIfKnown(vd->getType()) >
1100 astContext.toBits(CharUnits::fromQuantity(32)))
1101 return true;
1102
1103 return false;
1104}
1105
1107 const DeclaratorDecl *dd, GVALinkage linkage, bool isConstantVariable) {
1108 if (linkage == GVA_Internal)
1109 return cir::GlobalLinkageKind::InternalLinkage;
1110
1111 if (dd->hasAttr<WeakAttr>()) {
1112 if (isConstantVariable)
1113 return cir::GlobalLinkageKind::WeakODRLinkage;
1114 return cir::GlobalLinkageKind::WeakAnyLinkage;
1115 }
1116
1117 if (const auto *fd = dd->getAsFunction())
1118 if (fd->isMultiVersion() && linkage == GVA_AvailableExternally)
1119 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1120
1121 // We are guaranteed to have a strong definition somewhere else,
1122 // so we can use available_externally linkage.
1123 if (linkage == GVA_AvailableExternally)
1124 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1125
1126 // Note that Apple's kernel linker doesn't support symbol
1127 // coalescing, so we need to avoid linkonce and weak linkages there.
1128 // Normally, this means we just map to internal, but for explicit
1129 // instantiations we'll map to external.
1130
1131 // In C++, the compiler has to emit a definition in every translation unit
1132 // that references the function. We should use linkonce_odr because
1133 // a) if all references in this translation unit are optimized away, we
1134 // don't need to codegen it. b) if the function persists, it needs to be
1135 // merged with other definitions. c) C++ has the ODR, so we know the
1136 // definition is dependable.
1137 if (linkage == GVA_DiscardableODR)
1138 return !astContext.getLangOpts().AppleKext
1139 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1140 : cir::GlobalLinkageKind::InternalLinkage;
1141
1142 // An explicit instantiation of a template has weak linkage, since
1143 // explicit instantiations can occur in multiple translation units
1144 // and must all be equivalent. However, we are not allowed to
1145 // throw away these explicit instantiations.
1146 //
1147 // CUDA/HIP: For -fno-gpu-rdc case, device code is limited to one TU,
1148 // so say that CUDA templates are either external (for kernels) or internal.
1149 // This lets llvm perform aggressive inter-procedural optimizations. For
1150 // -fgpu-rdc case, device function calls across multiple TU's are allowed,
1151 // therefore we need to follow the normal linkage paradigm.
1152 if (linkage == GVA_StrongODR) {
1153 if (getLangOpts().AppleKext)
1154 return cir::GlobalLinkageKind::ExternalLinkage;
1155 if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice &&
1156 !getLangOpts().GPURelocatableDeviceCode)
1157 return dd->hasAttr<CUDAGlobalAttr>()
1158 ? cir::GlobalLinkageKind::ExternalLinkage
1159 : cir::GlobalLinkageKind::InternalLinkage;
1160 return cir::GlobalLinkageKind::WeakODRLinkage;
1161 }
1162
1163 // C++ doesn't have tentative definitions and thus cannot have common
1164 // linkage.
1165 if (!getLangOpts().CPlusPlus && isa<VarDecl>(dd) &&
1166 !isVarDeclStrongDefinition(astContext, *this, cast<VarDecl>(dd),
1167 getCodeGenOpts().NoCommon)) {
1168 errorNYI(dd->getBeginLoc(), "common linkage", dd->getDeclKindName());
1169 return cir::GlobalLinkageKind::CommonLinkage;
1170 }
1171
1172 // selectany symbols are externally visible, so use weak instead of
1173 // linkonce. MSVC optimizes away references to const selectany globals, so
1174 // all definitions should be the same and ODR linkage should be used.
1175 // http://msdn.microsoft.com/en-us/library/5tkz6s71.aspx
1176 if (dd->hasAttr<SelectAnyAttr>())
1177 return cir::GlobalLinkageKind::WeakODRLinkage;
1178
1179 // Otherwise, we have strong external linkage.
1180 assert(linkage == GVA_StrongExternal);
1181 return cir::GlobalLinkageKind::ExternalLinkage;
1182}
1183
1184/// This function is called when we implement a function with no prototype, e.g.
1185/// "int foo() {}". If there are existing call uses of the old function in the
1186/// module, this adjusts them to call the new function directly.
1187///
1188/// This is not just a cleanup: the always_inline pass requires direct calls to
1189/// functions to be able to inline them. If there is a bitcast in the way, it
1190/// won't inline them. Instcombine normally deletes these calls, but it isn't
1191/// run at -O0.
1193 mlir::Operation *old, cir::FuncOp newFn) {
1194 // If we're redefining a global as a function, don't transform it.
1195 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1196 if (!oldFn)
1197 return;
1198
1199 // TODO(cir): this RAUW ignores the features below.
1203 if (oldFn->getAttrs().size() <= 1)
1204 errorNYI(old->getLoc(),
1205 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1206
1207 // Mark new function as originated from a no-proto declaration.
1208 newFn.setNoProto(oldFn.getNoProto());
1209
1210 // Iterate through all calls of the no-proto function.
1211 std::optional<mlir::SymbolTable::UseRange> symUses =
1212 oldFn.getSymbolUses(oldFn->getParentOp());
1213 for (const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1214 mlir::OpBuilder::InsertionGuard guard(builder);
1215
1216 if (auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1217 builder.setInsertionPoint(noProtoCallOp);
1218
1219 // Patch call type with the real function type.
1220 cir::CallOp realCallOp = builder.createCallOp(
1221 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1222
1223 // Replace old no proto call with fixed call.
1224 noProtoCallOp.replaceAllUsesWith(realCallOp);
1225 noProtoCallOp.erase();
1226 } else if (auto getGlobalOp =
1227 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1228 // Replace type
1229 getGlobalOp.getAddr().setType(
1230 cir::PointerType::get(newFn.getFunctionType()));
1231 } else {
1232 errorNYI(use.getUser()->getLoc(),
1233 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use");
1234 }
1235 }
1236}
1237
1238cir::GlobalLinkageKind
1240 assert(!isConstant && "constant variables NYI");
1241 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
1242 return getCIRLinkageForDeclarator(vd, linkage, isConstant);
1243}
1244
1246 const auto *d = cast<FunctionDecl>(gd.getDecl());
1247
1248 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
1249
1250 if (const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
1251 return getCXXABI().getCXXDestructorLinkage(linkage, dtor, gd.getDtorType());
1252
1253 return getCIRLinkageForDeclarator(d, linkage, /*isConstantVariable=*/false);
1254}
1255
1256static cir::GlobalOp
1257generateStringLiteral(mlir::Location loc, mlir::TypedAttr c,
1258 cir::GlobalLinkageKind lt, CIRGenModule &cgm,
1259 StringRef globalName, CharUnits alignment) {
1261
1262 // Create a global variable for this string
1263 // FIXME(cir): check for insertion point in module level.
1264 cir::GlobalOp gv = CIRGenModule::createGlobalOp(
1265 cgm, loc, globalName, c.getType(), !cgm.getLangOpts().WritableStrings);
1266
1267 // Set up extra information and add to the module
1268 gv.setAlignmentAttr(cgm.getSize(alignment));
1269 gv.setLinkageAttr(
1270 cir::GlobalLinkageKindAttr::get(cgm.getBuilder().getContext(), lt));
1274 if (gv.isWeakForLinker()) {
1275 assert(cgm.supportsCOMDAT() && "Only COFF uses weak string literals");
1276 gv.setComdat(true);
1277 }
1278 cgm.setDSOLocal(static_cast<mlir::Operation *>(gv));
1279 return gv;
1280}
1281
1282// LLVM IR automatically uniques names when new llvm::GlobalVariables are
1283// created. This is handy, for example, when creating globals for string
1284// literals. Since we don't do that when creating cir::GlobalOp's, we need
1285// a mechanism to generate a unique name in advance.
1286//
1287// For now, this mechanism is only used in cases where we know that the
1288// name is compiler-generated, so we don't use the MLIR symbol table for
1289// the lookup.
1290std::string CIRGenModule::getUniqueGlobalName(const std::string &baseName) {
1291 // If this is the first time we've generated a name for this basename, use
1292 // it as is and start a counter for this base name.
1293 auto it = cgGlobalNames.find(baseName);
1294 if (it == cgGlobalNames.end()) {
1295 cgGlobalNames[baseName] = 1;
1296 return baseName;
1297 }
1298
1299 std::string result =
1300 baseName + "." + std::to_string(cgGlobalNames[baseName]++);
1301 // There should not be any symbol with this name in the module.
1302 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1303 return result;
1304}
1305
1306/// Return a pointer to a constant array for the given string literal.
1308 StringRef name) {
1309 CharUnits alignment =
1310 astContext.getAlignOfGlobalVarInChars(s->getType(), /*VD=*/nullptr);
1311
1312 mlir::Attribute c = getConstantArrayFromStringLiteral(s);
1313
1314 if (getLangOpts().WritableStrings) {
1315 errorNYI(s->getSourceRange(),
1316 "getGlobalForStringLiteral: Writable strings");
1317 }
1318
1319 // Mangle the string literal if that's how the ABI merges duplicate strings.
1320 // Don't do it if they are writable, since we don't want writes in one TU to
1321 // affect strings in another.
1322 if (getCXXABI().getMangleContext().shouldMangleStringLiteral(s) &&
1323 !getLangOpts().WritableStrings) {
1324 errorNYI(s->getSourceRange(),
1325 "getGlobalForStringLiteral: mangle string literals");
1326 }
1327
1328 // Unlike LLVM IR, CIR doesn't automatically unique names for globals, so
1329 // we need to do that explicitly.
1330 std::string uniqueName = getUniqueGlobalName(name.str());
1331 mlir::Location loc = getLoc(s->getSourceRange());
1332 auto typedC = llvm::cast<mlir::TypedAttr>(c);
1333 cir::GlobalOp gv =
1334 generateStringLiteral(loc, typedC, cir::GlobalLinkageKind::PrivateLinkage,
1335 *this, uniqueName, alignment);
1336 setDSOLocal(static_cast<mlir::Operation *>(gv));
1337
1339
1340 return gv;
1341}
1342
1343/// Return a pointer to a constant array for the given string literal.
1344cir::GlobalViewAttr
1346 StringRef name) {
1347 cir::GlobalOp gv = getGlobalForStringLiteral(s, name);
1348 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
1349 assert(arrayTy && "String literal must be array");
1351 cir::PointerType ptrTy = getBuilder().getPointerTo(arrayTy.getElementType());
1352
1353 return builder.getGlobalViewAttr(ptrTy, gv);
1354}
1355
1357 CIRGenFunction *cgf) {
1358 if (cgf && e->getType()->isVariablyModifiedType())
1360
1362 "emitExplicitCastExprType");
1363}
1364
1366 for (Decl *decl : dc->decls()) {
1367 // Unlike other DeclContexts, the contents of an ObjCImplDecl at TU scope
1368 // are themselves considered "top-level", so EmitTopLevelDecl on an
1369 // ObjCImplDecl does not recursively visit them. We need to do that in
1370 // case they're nested inside another construct (LinkageSpecDecl /
1371 // ExportDecl) that does stop them from being considered "top-level".
1372 if (auto *oid = dyn_cast<ObjCImplDecl>(decl))
1373 errorNYI(oid->getSourceRange(), "emitDeclConext: ObjCImplDecl");
1374
1376 }
1377}
1378
1379// Emit code for a single top level declaration.
1381
1382 // Ignore dependent declarations.
1383 if (decl->isTemplated())
1384 return;
1385
1386 switch (decl->getKind()) {
1387 default:
1388 errorNYI(decl->getBeginLoc(), "declaration of kind",
1389 decl->getDeclKindName());
1390 break;
1391
1392 case Decl::CXXConversion:
1393 case Decl::CXXMethod:
1394 case Decl::Function: {
1395 auto *fd = cast<FunctionDecl>(decl);
1396 // Consteval functions shouldn't be emitted.
1397 if (!fd->isConsteval())
1398 emitGlobal(fd);
1399 break;
1400 }
1401
1402 case Decl::Var:
1403 case Decl::Decomposition:
1404 case Decl::VarTemplateSpecialization: {
1405 auto *vd = cast<VarDecl>(decl);
1406 if (isa<DecompositionDecl>(decl)) {
1407 errorNYI(decl->getSourceRange(), "global variable decompositions");
1408 break;
1409 }
1410 emitGlobal(vd);
1411 break;
1412 }
1413 case Decl::OpenACCRoutine:
1414 emitGlobalOpenACCDecl(cast<OpenACCRoutineDecl>(decl));
1415 break;
1416 case Decl::OpenACCDeclare:
1417 emitGlobalOpenACCDecl(cast<OpenACCDeclareDecl>(decl));
1418 break;
1419 case Decl::Enum:
1420 case Decl::Using: // using X; [C++]
1421 case Decl::UsingDirective: // using namespace X; [C++]
1422 case Decl::UsingEnum: // using enum X; [C++]
1423 case Decl::NamespaceAlias:
1424 case Decl::Typedef:
1425 case Decl::TypeAlias: // using foo = bar; [C++11]
1426 case Decl::Record:
1428 break;
1429
1430 // No code generation needed.
1431 case Decl::ClassTemplate:
1432 case Decl::Concept:
1433 case Decl::CXXDeductionGuide:
1434 case Decl::Empty:
1435 case Decl::FunctionTemplate:
1436 case Decl::StaticAssert:
1437 case Decl::TypeAliasTemplate:
1438 case Decl::UsingShadow:
1439 case Decl::VarTemplate:
1440 case Decl::VarTemplatePartialSpecialization:
1441 break;
1442
1443 case Decl::CXXConstructor:
1444 getCXXABI().emitCXXConstructors(cast<CXXConstructorDecl>(decl));
1445 break;
1446 case Decl::CXXDestructor:
1447 getCXXABI().emitCXXDestructors(cast<CXXDestructorDecl>(decl));
1448 break;
1449
1450 // C++ Decls
1451 case Decl::LinkageSpec:
1452 case Decl::Namespace:
1454 break;
1455
1456 case Decl::ClassTemplateSpecialization:
1457 case Decl::CXXRecord:
1460 break;
1461
1462 case Decl::FileScopeAsm:
1463 // File-scope asm is ignored during device-side CUDA compilation.
1464 if (langOpts.CUDA && langOpts.CUDAIsDevice)
1465 break;
1466 // File-scope asm is ignored during device-side OpenMP compilation.
1467 if (langOpts.OpenMPIsTargetDevice)
1468 break;
1469 // File-scope asm is ignored during device-side SYCL compilation.
1470 if (langOpts.SYCLIsDevice)
1471 break;
1472 auto *file_asm = cast<FileScopeAsmDecl>(decl);
1473 std::string line = file_asm->getAsmString();
1474 globalScopeAsm.push_back(builder.getStringAttr(line));
1475 break;
1476 }
1477}
1478
1479void CIRGenModule::setInitializer(cir::GlobalOp &op, mlir::Attribute value) {
1480 // Recompute visibility when updating initializer.
1481 op.setInitialValueAttr(value);
1483}
1484
1485std::pair<cir::FuncType, cir::FuncOp> CIRGenModule::getAddrAndTypeOfCXXStructor(
1486 GlobalDecl gd, const CIRGenFunctionInfo *fnInfo, cir::FuncType fnType,
1487 bool dontDefer, ForDefinition_t isForDefinition) {
1488 auto *md = cast<CXXMethodDecl>(gd.getDecl());
1489
1490 if (isa<CXXDestructorDecl>(md)) {
1491 // Always alias equivalent complete destructors to base destructors in the
1492 // MS ABI.
1493 if (getTarget().getCXXABI().isMicrosoft() &&
1494 gd.getDtorType() == Dtor_Complete &&
1495 md->getParent()->getNumVBases() == 0)
1496 errorNYI(md->getSourceRange(),
1497 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
1498 }
1499
1500 if (!fnType) {
1501 if (!fnInfo)
1503 fnType = getTypes().getFunctionType(*fnInfo);
1504 }
1505
1506 auto fn = getOrCreateCIRFunction(getMangledName(gd), fnType, gd,
1507 /*ForVtable=*/false, dontDefer,
1508 /*IsThunk=*/false, isForDefinition);
1509
1510 return {fnType, fn};
1511}
1512
1514 mlir::Type funcType, bool forVTable,
1515 bool dontDefer,
1516 ForDefinition_t isForDefinition) {
1517 assert(!cast<FunctionDecl>(gd.getDecl())->isConsteval() &&
1518 "consteval function should never be emitted");
1519
1520 if (!funcType) {
1521 const auto *fd = cast<FunctionDecl>(gd.getDecl());
1522 funcType = convertType(fd->getType());
1523 }
1524
1525 // Devirtualized destructor calls may come through here instead of via
1526 // getAddrOfCXXStructor. Make sure we use the MS ABI base destructor instead
1527 // of the complete destructor when necessary.
1528 if (const auto *dd = dyn_cast<CXXDestructorDecl>(gd.getDecl())) {
1529 if (getTarget().getCXXABI().isMicrosoft() &&
1530 gd.getDtorType() == Dtor_Complete &&
1531 dd->getParent()->getNumVBases() == 0)
1532 errorNYI(dd->getSourceRange(),
1533 "getAddrOfFunction: MS ABI complete destructor");
1534 }
1535
1536 StringRef mangledName = getMangledName(gd);
1537 cir::FuncOp func =
1538 getOrCreateCIRFunction(mangledName, funcType, gd, forVTable, dontDefer,
1539 /*isThunk=*/false, isForDefinition);
1540 return func;
1541}
1542
1543static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd,
1544 const NamedDecl *nd) {
1545 SmallString<256> buffer;
1546
1547 llvm::raw_svector_ostream out(buffer);
1549
1551
1552 if (mc.shouldMangleDeclName(nd)) {
1553 mc.mangleName(gd.getWithDecl(nd), out);
1554 } else {
1555 IdentifierInfo *ii = nd->getIdentifier();
1556 assert(ii && "Attempt to mangle unnamed decl.");
1557
1558 const auto *fd = dyn_cast<FunctionDecl>(nd);
1559 if (fd &&
1560 fd->getType()->castAs<FunctionType>()->getCallConv() == CC_X86RegCall) {
1561 cgm.errorNYI(nd->getSourceRange(), "getMangledName: X86RegCall");
1562 } else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
1564 cgm.errorNYI(nd->getSourceRange(), "getMangledName: CUDA device stub");
1565 }
1566 out << ii->getName();
1567 }
1568
1569 // Check if the module name hash should be appended for internal linkage
1570 // symbols. This should come before multi-version target suffixes are
1571 // appendded. This is to keep the name and module hash suffix of the internal
1572 // linkage function together. The unique suffix should only be added when name
1573 // mangling is done to make sure that the final name can be properly
1574 // demangled. For example, for C functions without prototypes, name mangling
1575 // is not done and the unique suffix should not be appended then.
1577
1578 if (const auto *fd = dyn_cast<FunctionDecl>(nd)) {
1579 if (fd->isMultiVersion()) {
1580 cgm.errorNYI(nd->getSourceRange(),
1581 "getMangledName: multi-version functions");
1582 }
1583 }
1584 if (cgm.getLangOpts().GPURelocatableDeviceCode) {
1585 cgm.errorNYI(nd->getSourceRange(),
1586 "getMangledName: GPU relocatable device code");
1587 }
1588
1589 return std::string(out.str());
1590}
1591
1593 GlobalDecl canonicalGd = gd.getCanonicalDecl();
1594
1595 // Some ABIs don't have constructor variants. Make sure that base and complete
1596 // constructors get mangled the same.
1597 if (const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.getDecl())) {
1598 if (!getTarget().getCXXABI().hasConstructorVariants()) {
1599 errorNYI(cd->getSourceRange(),
1600 "getMangledName: C++ constructor without variants");
1601 return cast<NamedDecl>(gd.getDecl())->getIdentifier()->getName();
1602 }
1603 }
1604
1605 // Keep the first result in the case of a mangling collision.
1606 const auto *nd = cast<NamedDecl>(gd.getDecl());
1607 std::string mangledName = getMangledNameImpl(*this, gd, nd);
1608
1609 auto result = manglings.insert(std::make_pair(mangledName, gd));
1610 return mangledDeclNames[canonicalGd] = result.first->first();
1611}
1612
1614 assert(!d->getInit() && "Cannot emit definite definitions here!");
1615
1616 StringRef mangledName = getMangledName(d);
1617 mlir::Operation *gv = getGlobalValue(mangledName);
1618
1619 // If we already have a definition, not declaration, with the same mangled
1620 // name, emitting of declaration is not required (and would actually overwrite
1621 // the emitted definition).
1622 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
1623 return;
1624
1625 // If we have not seen a reference to this variable yet, place it into the
1626 // deferred declarations table to be emitted if needed later.
1627 if (!mustBeEmitted(d) && !gv) {
1628 deferredDecls[mangledName] = d;
1629 return;
1630 }
1631
1632 // The tentative definition is the only definition.
1634}
1635
1637 // Never defer when EmitAllDecls is specified.
1638 if (langOpts.EmitAllDecls)
1639 return true;
1640
1641 const auto *vd = dyn_cast<VarDecl>(global);
1642 if (vd &&
1643 ((codeGenOpts.KeepPersistentStorageVariables &&
1644 (vd->getStorageDuration() == SD_Static ||
1645 vd->getStorageDuration() == SD_Thread)) ||
1646 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() == SD_Static &&
1647 vd->getType().isConstQualified())))
1648 return true;
1649
1650 return getASTContext().DeclMustBeEmitted(global);
1651}
1652
1654 // In OpenMP 5.0 variables and function may be marked as
1655 // device_type(host/nohost) and we should not emit them eagerly unless we sure
1656 // that they must be emitted on the host/device. To be sure we need to have
1657 // seen a declare target with an explicit mentioning of the function, we know
1658 // we have if the level of the declare target attribute is -1. Note that we
1659 // check somewhere else if we should emit this at all.
1660 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
1661 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
1662 OMPDeclareTargetDeclAttr::getActiveAttr(global);
1663 if (!activeAttr || (*activeAttr)->getLevel() != (unsigned)-1)
1664 return false;
1665 }
1666
1667 const auto *fd = dyn_cast<FunctionDecl>(global);
1668 if (fd) {
1669 // Implicit template instantiations may change linkage if they are later
1670 // explicitly instantiated, so they should not be emitted eagerly.
1671 if (fd->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
1672 return false;
1673 // Defer until all versions have been semantically checked.
1674 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
1675 return false;
1676 if (langOpts.SYCLIsDevice) {
1677 errorNYI(fd->getSourceRange(), "mayBeEmittedEagerly: SYCL");
1678 return false;
1679 }
1680 }
1681 const auto *vd = dyn_cast<VarDecl>(global);
1682 if (vd)
1683 if (astContext.getInlineVariableDefinitionKind(vd) ==
1685 // A definition of an inline constexpr static data member may change
1686 // linkage later if it's redeclared outside the class.
1687 return false;
1688
1689 // If OpenMP is enabled and threadprivates must be generated like TLS, delay
1690 // codegen for global variables, because they may be marked as threadprivate.
1691 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
1692 astContext.getTargetInfo().isTLSSupported() && isa<VarDecl>(global) &&
1693 !global->getType().isConstantStorage(astContext, false, false) &&
1694 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
1695 return false;
1696
1697 assert((fd || vd) &&
1698 "Only FunctionDecl and VarDecl should hit this path so far.");
1699 return true;
1700}
1701
1702static bool shouldAssumeDSOLocal(const CIRGenModule &cgm,
1703 cir::CIRGlobalValueInterface gv) {
1704 if (gv.hasLocalLinkage())
1705 return true;
1706
1707 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
1708 return true;
1709
1710 // DLLImport explicitly marks the GV as external.
1711 // so it shouldn't be dso_local
1712 // But we don't have the info set now
1714
1715 const llvm::Triple &tt = cgm.getTriple();
1716 const CodeGenOptions &cgOpts = cgm.getCodeGenOpts();
1717 if (tt.isOSCygMing()) {
1718 // In MinGW and Cygwin, variables without DLLImport can still be
1719 // automatically imported from a DLL by the linker; don't mark variables
1720 // that potentially could come from another DLL as DSO local.
1721
1722 // With EmulatedTLS, TLS variables can be autoimported from other DLLs
1723 // (and this actually happens in the public interface of libstdc++), so
1724 // such variables can't be marked as DSO local. (Native TLS variables
1725 // can't be dllimported at all, though.)
1726 cgm.errorNYI("shouldAssumeDSOLocal: MinGW");
1727 }
1728
1729 // On COFF, don't mark 'extern_weak' symbols as DSO local. If these symbols
1730 // remain unresolved in the link, they can be resolved to zero, which is
1731 // outside the current DSO.
1732 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
1733 return false;
1734
1735 // Every other GV is local on COFF.
1736 // Make an exception for windows OS in the triple: Some firmware builds use
1737 // *-win32-macho triples. This (accidentally?) produced windows relocations
1738 // without GOT tables in older clang versions; Keep this behaviour.
1739 // FIXME: even thread local variables?
1740 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
1741 return true;
1742
1743 // Only handle COFF and ELF for now.
1744 if (!tt.isOSBinFormatELF())
1745 return false;
1746
1747 llvm::Reloc::Model rm = cgOpts.RelocationModel;
1748 const LangOptions &lOpts = cgm.getLangOpts();
1749 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
1750 // On ELF, if -fno-semantic-interposition is specified and the target
1751 // supports local aliases, there will be neither CC1
1752 // -fsemantic-interposition nor -fhalf-no-semantic-interposition. Set
1753 // dso_local on the function if using a local alias is preferable (can avoid
1754 // PLT indirection).
1755 if (!(isa<cir::FuncOp>(gv) && gv.canBenefitFromLocalAlias()))
1756 return false;
1757 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
1758 }
1759
1760 // A definition cannot be preempted from an executable.
1761 if (!gv.isDeclarationForLinker())
1762 return true;
1763
1764 // Most PIC code sequences that assume that a symbol is local cannot produce a
1765 // 0 if it turns out the symbol is undefined. While this is ABI and relocation
1766 // depended, it seems worth it to handle it here.
1767 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
1768 return false;
1769
1770 // PowerPC64 prefers TOC indirection to avoid copy relocations.
1771 if (tt.isPPC64())
1772 return false;
1773
1774 if (cgOpts.DirectAccessExternalData) {
1775 // If -fdirect-access-external-data (default for -fno-pic), set dso_local
1776 // for non-thread-local variables. If the symbol is not defined in the
1777 // executable, a copy relocation will be needed at link time. dso_local is
1778 // excluded for thread-local variables because they generally don't support
1779 // copy relocations.
1780 if (auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
1781 // Assume variables are not thread-local until that support is added.
1783 return true;
1784 }
1785
1786 // -fno-pic sets dso_local on a function declaration to allow direct
1787 // accesses when taking its address (similar to a data symbol). If the
1788 // function is not defined in the executable, a canonical PLT entry will be
1789 // needed at link time. -fno-direct-access-external-data can avoid the
1790 // canonical PLT entry. We don't generalize this condition to -fpie/-fpic as
1791 // it could just cause trouble without providing perceptible benefits.
1792 if (isa<cir::FuncOp>(gv) && !cgOpts.NoPLT && rm == llvm::Reloc::Static)
1793 return true;
1794 }
1795
1796 // If we can use copy relocations we can assume it is local.
1797
1798 // Otherwise don't assume it is local.
1799
1800 return false;
1801}
1802
1803void CIRGenModule::setGlobalVisibility(mlir::Operation *gv,
1804 const NamedDecl *d) const {
1806}
1807
1808void CIRGenModule::setDSOLocal(cir::CIRGlobalValueInterface gv) const {
1809 gv.setDSOLocal(shouldAssumeDSOLocal(*this, gv));
1810}
1811
1812void CIRGenModule::setDSOLocal(mlir::Operation *op) const {
1813 if (auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
1814 setDSOLocal(globalValue);
1815}
1816
1817void CIRGenModule::setGVProperties(mlir::Operation *op,
1818 const NamedDecl *d) const {
1820 setGVPropertiesAux(op, d);
1821}
1822
1823void CIRGenModule::setGVPropertiesAux(mlir::Operation *op,
1824 const NamedDecl *d) const {
1825 setGlobalVisibility(op, d);
1826 setDSOLocal(op);
1828}
1829
1831 cir::FuncOp func,
1832 bool isIncompleteFunction,
1833 bool isThunk) {
1834 // NOTE(cir): Original CodeGen checks if this is an intrinsic. In CIR we
1835 // represent them in dedicated ops. The correct attributes are ensured during
1836 // translation to LLVM. Thus, we don't need to check for them here.
1837
1840
1841 // TODO(cir): This needs a lot of work to better match CodeGen. That
1842 // ultimately ends up in setGlobalVisibility, which already has the linkage of
1843 // the LLVM GV (corresponding to our FuncOp) computed, so it doesn't have to
1844 // recompute it here. This is a minimal fix for now.
1845 if (!isLocalLinkage(getFunctionLinkage(globalDecl))) {
1846 const Decl *decl = globalDecl.getDecl();
1847 func.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(decl));
1848 }
1849}
1850
1852 StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable,
1853 bool dontDefer, bool isThunk, ForDefinition_t isForDefinition,
1854 mlir::ArrayAttr extraAttrs) {
1855 const Decl *d = gd.getDecl();
1856
1857 if (isThunk)
1858 errorNYI(d->getSourceRange(), "getOrCreateCIRFunction: thunk");
1859
1860 // In what follows, we continue past 'errorNYI' as if nothing happened because
1861 // the rest of the implementation is better than doing nothing.
1862
1863 if (const auto *fd = cast_or_null<FunctionDecl>(d)) {
1864 // For the device mark the function as one that should be emitted.
1865 if (getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
1866 !isForDefinition)
1867 errorNYI(fd->getSourceRange(),
1868 "getOrCreateCIRFunction: OpenMP target function");
1869
1870 // Any attempts to use a MultiVersion function should result in retrieving
1871 // the iFunc instead. Name mangling will handle the rest of the changes.
1872 if (fd->isMultiVersion())
1873 errorNYI(fd->getSourceRange(), "getOrCreateCIRFunction: multi-version");
1874 }
1875
1876 // Lookup the entry, lazily creating it if necessary.
1877 mlir::Operation *entry = getGlobalValue(mangledName);
1878 if (entry) {
1879 assert(mlir::isa<cir::FuncOp>(entry));
1880
1882
1883 // Handle dropped DLL attributes.
1884 if (d && !d->hasAttr<DLLImportAttr>() && !d->hasAttr<DLLExportAttr>()) {
1886 setDSOLocal(entry);
1887 }
1888
1889 // If there are two attempts to define the same mangled name, issue an
1890 // error.
1891 auto fn = cast<cir::FuncOp>(entry);
1892 if (isForDefinition && fn && !fn.isDeclaration()) {
1893 errorNYI(d->getSourceRange(), "Duplicate function definition");
1894 }
1895 if (fn && fn.getFunctionType() == funcType) {
1896 return fn;
1897 }
1898
1899 if (!isForDefinition) {
1900 return fn;
1901 }
1902
1903 // TODO(cir): classic codegen checks here if this is a llvm::GlobalAlias.
1904 // How will we support this?
1905 }
1906
1907 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.getDecl());
1908 bool invalidLoc = !funcDecl ||
1909 funcDecl->getSourceRange().getBegin().isInvalid() ||
1910 funcDecl->getSourceRange().getEnd().isInvalid();
1911 cir::FuncOp funcOp = createCIRFunction(
1912 invalidLoc ? theModule->getLoc() : getLoc(funcDecl->getSourceRange()),
1913 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
1914
1915 // If we already created a function with the same mangled name (but different
1916 // type) before, take its name and add it to the list of functions to be
1917 // replaced with F at the end of CodeGen.
1918 //
1919 // This happens if there is a prototype for a function (e.g. "int f()") and
1920 // then a definition of a different type (e.g. "int f(int x)").
1921 if (entry) {
1922
1923 // Fetch a generic symbol-defining operation and its uses.
1924 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
1925
1926 // This might be an implementation of a function without a prototype, in
1927 // which case, try to do special replacement of calls which match the new
1928 // prototype. The really key thing here is that we also potentially drop
1929 // arguments from the call site so as to make a direct call, which makes the
1930 // inliner happier and suppresses a number of optimizer warnings (!) about
1931 // dropping arguments.
1932 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
1934
1935 // Obliterate no-proto declaration.
1936 entry->erase();
1937 }
1938
1939 if (d)
1940 setFunctionAttributes(gd, funcOp, /*isIncompleteFunction=*/false, isThunk);
1941
1942 // 'dontDefer' actually means don't move this to the deferredDeclsToEmit list.
1943 if (dontDefer) {
1944 // TODO(cir): This assertion will need an additional condition when we
1945 // support incomplete functions.
1946 assert(funcOp.getFunctionType() == funcType);
1947 return funcOp;
1948 }
1949
1950 // All MSVC dtors other than the base dtor are linkonce_odr and delegate to
1951 // each other bottoming out wiht the base dtor. Therefore we emit non-base
1952 // dtors on usage, even if there is no dtor definition in the TU.
1953 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
1954 getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(d),
1955 gd.getDtorType()))
1956 errorNYI(d->getSourceRange(), "getOrCreateCIRFunction: dtor");
1957
1958 // This is the first use or definition of a mangled name. If there is a
1959 // deferred decl with this name, remember that we need to emit it at the end
1960 // of the file.
1961 auto ddi = deferredDecls.find(mangledName);
1962 if (ddi != deferredDecls.end()) {
1963 // Move the potentially referenced deferred decl to the
1964 // DeferredDeclsToEmit list, and remove it from DeferredDecls (since we
1965 // don't need it anymore).
1966 addDeferredDeclToEmit(ddi->second);
1967 deferredDecls.erase(ddi);
1968
1969 // Otherwise, there are cases we have to worry about where we're using a
1970 // declaration for which we must emit a definition but where we might not
1971 // find a top-level definition.
1972 // - member functions defined inline in their classes
1973 // - friend functions defined inline in some class
1974 // - special member functions with implicit definitions
1975 // If we ever change our AST traversal to walk into class methods, this
1976 // will be unnecessary.
1977 //
1978 // We also don't emit a definition for a function if it's going to be an
1979 // entry in a vtable, unless it's already marked as used.
1980 } else if (getLangOpts().CPlusPlus && d) {
1981 // Look for a declaration that's lexically in a record.
1982 for (const auto *fd = cast<FunctionDecl>(d)->getMostRecentDecl(); fd;
1983 fd = fd->getPreviousDecl()) {
1984 if (isa<CXXRecordDecl>(fd->getLexicalDeclContext())) {
1985 if (fd->doesThisDeclarationHaveABody()) {
1987 break;
1988 }
1989 }
1990 }
1991 }
1992
1993 return funcOp;
1994}
1995
1996cir::FuncOp
1997CIRGenModule::createCIRFunction(mlir::Location loc, StringRef name,
1998 cir::FuncType funcType,
1999 const clang::FunctionDecl *funcDecl) {
2000 cir::FuncOp func;
2001 {
2002 mlir::OpBuilder::InsertionGuard guard(builder);
2003
2004 // Some global emissions are triggered while emitting a function, e.g.
2005 // void s() { x.method() }
2006 //
2007 // Be sure to insert a new function before a current one.
2008 CIRGenFunction *cgf = this->curCGF;
2009 if (cgf)
2010 builder.setInsertionPoint(cgf->curFn);
2011
2012 func = builder.create<cir::FuncOp>(loc, name, funcType);
2013
2015
2016 if (funcDecl && !funcDecl->hasPrototype())
2017 func.setNoProto(true);
2018
2019 assert(func.isDeclaration() && "expected empty body");
2020
2021 // A declaration gets private visibility by default, but external linkage
2022 // as the default linkage.
2023 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2024 &getMLIRContext(), cir::GlobalLinkageKind::ExternalLinkage));
2025 mlir::SymbolTable::setSymbolVisibility(
2026 func, mlir::SymbolTable::Visibility::Private);
2027
2029
2030 if (!cgf)
2031 theModule.push_back(func);
2032 }
2033 return func;
2034}
2035
2036mlir::SymbolTable::Visibility
2038 // MLIR doesn't accept public symbols declarations (only
2039 // definitions).
2040 if (op.isDeclaration())
2041 return mlir::SymbolTable::Visibility::Private;
2042 return getMLIRVisibilityFromCIRLinkage(op.getLinkage());
2043}
2044
2045mlir::SymbolTable::Visibility
2047 switch (glk) {
2048 case cir::GlobalLinkageKind::InternalLinkage:
2049 case cir::GlobalLinkageKind::PrivateLinkage:
2050 return mlir::SymbolTable::Visibility::Private;
2051 case cir::GlobalLinkageKind::ExternalLinkage:
2052 case cir::GlobalLinkageKind::ExternalWeakLinkage:
2053 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
2054 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
2055 case cir::GlobalLinkageKind::CommonLinkage:
2056 case cir::GlobalLinkageKind::WeakAnyLinkage:
2057 case cir::GlobalLinkageKind::WeakODRLinkage:
2058 return mlir::SymbolTable::Visibility::Public;
2059 default: {
2060 llvm::errs() << "visibility not implemented for '"
2061 << stringifyGlobalLinkageKind(glk) << "'\n";
2062 assert(0 && "not implemented");
2063 }
2064 }
2065 llvm_unreachable("linkage should be handled above!");
2066}
2067
2069 clang::VisibilityAttr::VisibilityType visibility) {
2070 switch (visibility) {
2071 case clang::VisibilityAttr::VisibilityType::Default:
2072 return cir::VisibilityKind::Default;
2073 case clang::VisibilityAttr::VisibilityType::Hidden:
2074 return cir::VisibilityKind::Hidden;
2075 case clang::VisibilityAttr::VisibilityType::Protected:
2076 return cir::VisibilityKind::Protected;
2077 }
2078 llvm_unreachable("unexpected visibility value");
2079}
2080
2081cir::VisibilityAttr
2083 const clang::VisibilityAttr *va = decl->getAttr<clang::VisibilityAttr>();
2084 cir::VisibilityAttr cirVisibility =
2085 cir::VisibilityAttr::get(&getMLIRContext());
2086 if (va) {
2087 cirVisibility = cir::VisibilityAttr::get(
2088 &getMLIRContext(),
2089 getGlobalVisibilityKindFromClangVisibility(va->getVisibility()));
2090 }
2091 return cirVisibility;
2092}
2093
2095 emitDeferred();
2096 applyReplacements();
2097
2098 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
2099 builder.getArrayAttr(globalScopeAsm));
2100
2101 // There's a lot of code that is not implemented yet.
2103}
2104
2105void CIRGenModule::emitAliasForGlobal(StringRef mangledName,
2106 mlir::Operation *op, GlobalDecl aliasGD,
2107 cir::FuncOp aliasee,
2108 cir::GlobalLinkageKind linkage) {
2109
2110 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.getDecl());
2111 assert(aliasFD && "expected FunctionDecl");
2112
2113 // The aliasee function type is different from the alias one, this difference
2114 // is specific to CIR because in LLVM the ptr types are already erased at this
2115 // point.
2116 const CIRGenFunctionInfo &fnInfo =
2118 cir::FuncType fnType = getTypes().getFunctionType(fnInfo);
2119
2120 cir::FuncOp alias =
2122 mangledName, fnType, aliasFD);
2123 alias.setAliasee(aliasee.getName());
2124 alias.setLinkage(linkage);
2125 // Declarations cannot have public MLIR visibility, just mark them private
2126 // but this really should have no meaning since CIR should not be using
2127 // this information to derive linkage information.
2128 mlir::SymbolTable::setSymbolVisibility(
2129 alias, mlir::SymbolTable::Visibility::Private);
2130
2131 // Alias constructors and destructors are always unnamed_addr.
2133
2134 // Switch any previous uses to the alias.
2135 if (op) {
2136 errorNYI(aliasFD->getSourceRange(), "emitAliasForGlobal: previous uses");
2137 } else {
2138 // Name already set by createCIRFunction
2139 }
2140
2141 // Finally, set up the alias with its proper name and attributes.
2142 setCommonAttributes(aliasGD, alias);
2143}
2144
2146 return genTypes.convertType(type);
2147}
2148
2150 // Verify the module after we have finished constructing it, this will
2151 // check the structural properties of the IR and invoke any specific
2152 // verifiers we have on the CIR operations.
2153 return mlir::verify(theModule).succeeded();
2154}
2155
2156mlir::Attribute CIRGenModule::getAddrOfRTTIDescriptor(mlir::Location loc,
2157 QualType ty, bool forEh) {
2158 // Return a bogus pointer if RTTI is disabled, unless it's for EH.
2159 // FIXME: should we even be calling this method if RTTI is disabled
2160 // and it's not for EH?
2161 if (!shouldEmitRTTI(forEh))
2162 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
2163
2164 errorNYI(loc, "getAddrOfRTTIDescriptor");
2165 return mlir::Attribute();
2166}
2167
2168// TODO(cir): this can be shared with LLVM codegen.
2170 const CXXRecordDecl *derivedClass,
2171 llvm::iterator_range<CastExpr::path_const_iterator> path) {
2172 CharUnits offset = CharUnits::Zero();
2173
2174 const ASTContext &astContext = getASTContext();
2175 const CXXRecordDecl *rd = derivedClass;
2176
2177 for (const CXXBaseSpecifier *base : path) {
2178 assert(!base->isVirtual() && "Should not see virtual bases here!");
2179
2180 // Get the layout.
2181 const ASTRecordLayout &layout = astContext.getASTRecordLayout(rd);
2182
2183 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
2184
2185 // Add the offset.
2186 offset += layout.getBaseClassOffset(baseDecl);
2187
2188 rd = baseDecl;
2189 }
2190
2191 return offset;
2192}
2193
2195 llvm::StringRef feature) {
2196 unsigned diagID = diags.getCustomDiagID(
2197 DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0");
2198 return diags.Report(loc, diagID) << feature;
2199}
2200
2202 llvm::StringRef feature) {
2203 return errorNYI(loc.getBegin(), feature) << loc;
2204}
Defines the clang::ASTContext interface.
static bool shouldAssumeDSOLocal(const CIRGenModule &cgm, cir::CIRGlobalValueInterface gv)
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, const NamedDecl *nd)
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
static CIRGenCXXABI * createCXXABI(CIRGenModule &cgm)
static bool isVarDeclStrongDefinition(const ASTContext &astContext, CIRGenModule &cgm, const VarDecl *vd, bool noCommon)
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd)
This file defines OpenACC nodes for declarative directives.
Defines the SourceManager interface.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
mlir::TypedAttr getConstNullPtrAttr(mlir::Type t)
cir::GlobalViewAttr getGlobalViewAttr(cir::PointerType type, cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::PointerType getPointerTo(mlir::Type ty)
cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee, mlir::Type returnType, mlir::ValueRange operands, llvm::ArrayRef< mlir::NamedAttribute > attrs={})
mlir::TypedAttr getZeroInitAttr(mlir::Type ty)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
SourceManager & getSourceManager()
Definition: ASTContext.h:801
const ConstantArrayType * getAsConstantArrayType(QualType T) const
Definition: ASTContext.h:3056
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
@ WeakUnknown
Weak for now, might become strong later in this TU.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const
Returns true if this is an inline-initialized static data member which is treated as a definition for...
const LangOptions & getLangOpts() const
Definition: ASTContext.h:894
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
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.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const
Return the alignment in characters that should be given to a global variable with type T.
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2625
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:859
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
Definition: ASTContext.cpp:884
QualType getSignedSizeType() const
Return the unique signed counterpart of the integer type corresponding to size_t.
InlineVariableDefinitionKind getInlineVariableDefinitionKind(const VarDecl *VD) const
Determine whether a definition of this inline variable should be treated as a weak or strong definiti...
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:38
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
Definition: RecordLayout.h:183
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:250
cir::PointerType getUInt8PtrTy()
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, std::optional< size_t > size)
Get a cir::ConstArrayAttr for a string literal.
Definition: CIRGenBuilder.h:38
Implements C++ ABI-specific code generation functions.
Definition: CIRGenCXXABI.h:26
virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d)=0
Emit constructor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d)=0
Emit dtor variants required by this ABI.
clang::MangleContext & getMangleContext()
Gets the mangle context.
Definition: CIRGenCXXABI.h:164
virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
cir::FuncOp curFn
The function for which code is currently being generated.
This class organizes the cross-function state that is used while generating CIR code.
Definition: CIRGenModule.h:56
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
llvm::StringRef getMangledName(clang::GlobalDecl gd)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
void setGlobalVisibility(mlir::Operation *op, const NamedDecl *d) const
Set the visibility for the given global.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
void emitDeferred()
Emit any needed decls for which code generation was deferred.
clang::ASTContext & getASTContext() const
Definition: CIRGenModule.h:102
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Definition: CIRGenModule.h:240
void emitTopLevelDecl(clang::Decl *decl)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
bool shouldEmitRTTI(bool forEH=false)
Definition: CIRGenModule.h:304
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
bool mustBeEmitted(const clang::ValueDecl *d)
Determine whether the definition must be emitted; if this returns false, the definition can be emitte...
mlir::IntegerAttr getSize(CharUnits size)
Definition: CIRGenModule.h:389
CIRGenBuilderTy & getBuilder()
Definition: CIRGenModule.h:101
void setDSOLocal(mlir::Operation *op) const
std::string getUniqueGlobalName(const std::string &baseName)
std::pair< cir::FuncType, cir::FuncOp > getAddrAndTypeOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
cir::GlobalOp getOrCreateCIRGlobal(llvm::StringRef mangledName, mlir::Type ty, LangAS langAS, const VarDecl *d, ForDefinition_t isForDefinition)
If the specified mangled name is not in the module, create and return an mlir::GlobalOp value.
clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd)
Return the best known alignment for an unknown pointer to a particular class.
void handleCXXStaticMemberVarInstantiation(VarDecl *vd)
Tell the consumer that this variable has been instantiated.
void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo)
FIXME: this could likely be a common helper and not necessarily related with codegen.
void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f, bool isIncompleteFunction, bool isThunk)
Set function attributes for a function declaration.
static mlir::SymbolTable::Visibility getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK)
const clang::TargetInfo & getTarget() const
Definition: CIRGenModule.h:103
static mlir::SymbolTable::Visibility getMLIRVisibility(cir::GlobalOp op)
const llvm::Triple & getTriple() const
Definition: CIRGenModule.h:399
void emitTentativeDefinition(const VarDecl *d)
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
void emitGlobalDecl(const clang::GlobalDecl &d)
Helper for emitDeferred to apply actual codegen.
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, bool dontDefer=false, bool isThunk=false, ForDefinition_t isForDefinition=NotForDefinition, mlir::ArrayAttr extraAttrs={})
void emitGlobalVarDefinition(const clang::VarDecl *vd, bool isTentative=false)
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd)
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
std::map< llvm::StringRef, clang::GlobalDecl > deferredDecls
This contains all the decls which have definitions but which are deferred for emission and therefore ...
Definition: CIRGenModule.h:268
mlir::Value getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty={}, ForDefinition_t isForDefinition=NotForDefinition)
Return the mlir::Value for the address of the given global variable.
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
void updateCompletedType(const clang::TagDecl *td)
const clang::CodeGenOptions & getCodeGenOpts() const
Definition: CIRGenModule.h:104
const clang::LangOptions & getLangOpts() const
Definition: CIRGenModule.h:107
void addDeferredDeclToEmit(clang::GlobalDecl GD)
Definition: CIRGenModule.h:273
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType funcType, const clang::FunctionDecl *funcDecl)
const TargetCIRGenInfo & getTargetCIRGenInfo()
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
mlir::Operation * lastGlobalOp
Definition: CIRGenModule.h:122
static cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility(clang::VisibilityAttr::VisibilityType visibility)
llvm::StringMap< unsigned > cgGlobalNames
Definition: CIRGenModule.h:156
mlir::Operation * getGlobalValue(llvm::StringRef ref)
mlir::ModuleOp getModule() const
Definition: CIRGenModule.h:100
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage, bool isConstantVariable)
mlir::MLIRContext & getMLIRContext()
Definition: CIRGenModule.h:110
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::Operation *insertPoint=nullptr)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
CIRGenCXXABI & getCXXABI() const
Definition: CIRGenModule.h:109
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
void emitDeclContext(const DeclContext *dc)
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant)
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
CIRGenVTables & getVTables()
Definition: CIRGenModule.h:255
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
Definition: CIRGenModule.h:418
std::vector< clang::GlobalDecl > deferredDeclsToEmit
Definition: CIRGenModule.h:272
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl)
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCXXMethodDeclaration(const clang::CXXMethodDecl *md)
C++ methods have some special rules and also have implicit parameters.
Definition: CIRGenCall.cpp:396
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
Definition: CIRGenCall.cpp:179
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
Definition: CIRGenCall.cpp:50
void updateCompletedType(const clang::TagDecl *td)
UpdateCompletedType - when we find the full definition for a TagDecl, replace the 'opaque' type we pr...
mlir::Type convertType(clang::QualType type)
Convert a Clang type into a mlir::Type.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
Definition: DeclCXX.cpp:2325
bool hasDefinition() const
Definition: DeclCXX.h:561
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition: CharUnits.h:58
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Definition: CharUnits.h:53
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::Reloc::Model RelocationModel
The name of the relocation model to use.
Represents the canonical version of C arrays with a specified constant size.
Definition: TypeBase.h:3776
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1449
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2373
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
Definition: DeclBase.cpp:848
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:251
static DeclContext * castToDeclContext(const Decl *)
Definition: DeclBase.cpp:1063
const char * getDeclKindName() const
Definition: DeclBase.cpp:147
bool hasAttr() const
Definition: DeclBase.h:577
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:427
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:779
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:830
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:1233
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:231
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1529
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:904
ExplicitCastExpr - An explicit cast written in the source code.
Definition: Expr.h:3864
This represents one expression.
Definition: Expr.h:112
QualType getType() const
Definition: Expr.h:144
Represents a member of a struct/union/class.
Definition: Decl.h:3157
Represents a function declaration or definition.
Definition: Decl.h:1999
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
Definition: Decl.h:2442
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: TypeBase.h:4478
CallingConv getCallConv() const
Definition: TypeBase.h:4833
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:57
GlobalDecl getCanonicalDecl() const
Definition: GlobalDecl.h:97
KernelReferenceKind getKernelReferenceKind() const
Definition: GlobalDecl.h:135
GlobalDecl getWithDecl(const Decl *D)
Definition: GlobalDecl.h:172
CXXDtorType getDtorType() const
Definition: GlobalDecl.h:113
const Decl * getDecl() const
Definition: GlobalDecl.h:106
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:434
void setLinkage(Linkage L)
Definition: Visibility.h:92
Linkage getLinkage() const
Definition: Visibility.h:88
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
Definition: Mangle.h:52
bool shouldMangleDeclName(const NamedDecl *D)
Definition: Mangle.cpp:121
void mangleName(GlobalDecl GD, raw_ostream &)
Definition: Mangle.cpp:155
This represents a decl that may have a name.
Definition: Decl.h:273
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:294
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
Definition: Decl.cpp:1226
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
Definition: TypeBase.h:937
LangAS getAddressSpace() const
Return the address space of this type.
Definition: TypeBase.h:8469
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: TypeBase.h:8383
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: TypeBase.h:8416
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
Definition: TypeBase.h:1036
bool hasUnaligned() const
Definition: TypeBase.h:511
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
bool isValid() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1801
StringRef getString() const
Definition: Expr.h:1869
unsigned getCharByteWidth() const
Definition: Expr.h:1912
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3714
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
Definition: TargetCXXABI.h:136
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:1288
bool isTLSSupported() const
Whether the target supports thread-local storage.
Definition: TargetInfo.h:1616
uint64_t getPointerAlign(LangAS AddrSpace) const
Definition: TargetInfo.h:490
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
Definition: TargetInfo.h:1360
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.h:41
bool isPointerType() const
Definition: TypeBase.h:8580
bool isReferenceType() const
Definition: TypeBase.h:8604
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition: TypeBase.h:2818
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2440
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:711
QualType getType() const
Definition: Decl.h:722
Represents a variable declaration or definition.
Definition: Decl.h:925
TLSKind getTLSKind() const
Definition: Decl.cpp:2168
bool hasInit() const
Definition: Decl.cpp:2398
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:2260
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2190
bool hasFlexibleArrayInit(const ASTContext &Ctx) const
Whether this variable has a flexible array member initialized with one or more elements.
Definition: Decl.cpp:2862
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1225
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
Definition: Decl.cpp:2648
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
Definition: Decl.cpp:2366
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
Definition: Decl.cpp:2851
const Expr * getInit() const
Definition: Decl.h:1367
bool hasExternalStorage() const
Returns true if a variable has extern or private_extern storage.
Definition: Decl.h:1216
@ Definition
This declaration is definitely a definition.
Definition: Decl.h:1300
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
Definition: Decl.cpp:2375
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
Definition: Decl.cpp:2779
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Definition: Decl.h:1357
static LLVM_ATTRIBUTE_UNUSED bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
Definition: CIROpsEnums.h:102
@ AttributedType
The l-value was considered opaque, so the alignment was determined from a type, but that type was an ...
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
std::unique_ptr< TargetCIRGenInfo > createX8664TargetCIRGenInfo(CIRGenTypes &cgt)
Definition: TargetInfo.cpp:57
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
@ OpenCL
Definition: LangStandard.h:65
@ CPlusPlus
Definition: LangStandard.h:55
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
@ SD_Thread
Thread storage duration.
Definition: Specifiers.h:342
@ SD_Static
Static storage duration.
Definition: Specifiers.h:343
@ Dtor_Complete
Complete object dtor.
Definition: ABI.h:35
LangAS
Defines the address space values used by the address space qualifier of QualType.
Definition: AddressSpaces.h:25
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition: Specifiers.h:188
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:206
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:194
@ CC_X86RegCall
Definition: Specifiers.h:287
bool isExternallyVisible(Linkage L)
Definition: Linkage.h:90
static bool alignCXXRecordDecl()
static bool weakRefReference()
static bool opGlobalSection()
static bool opGlobalConstant()
static bool addressSpace()
static bool opGlobalUnnamedAddr()
static bool needsGlobalCtorDtor()
static bool cgmRelease()
static bool opGlobalThreadLocal()
static bool sourceLanguageCases()
static bool cxxRecordStaticMembers()
static bool opFuncAstDeclAttr()
static bool opGlobalUsedOrCompilerUsed()
static bool sanitizers()
static bool moduleNameHash()
static bool opGlobalVisibility()
static bool setFunctionAttributes()
static bool setDLLStorageClass()
static bool opFuncParameterAttributes()
static bool targetCIRGenInfoArch()
static bool opFuncExtraAttrs()
static bool opFuncSection()
static bool opFuncAttributesForDefinition()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool opGlobalWeakRef()
static bool setTargetAttributes()
static bool deferredCXXGlobalInit()
static bool opFuncOperandBundles()
static bool defaultVisibility()
static bool opFuncExceptions()
static bool deferredVtables()
static bool cudaSupport()
static bool opFuncMaybeHandleStaticInExternC()
static bool generateDebugInfo()
static bool targetCIRGenInfoOS()
static bool opFuncCPUAndFeaturesAttributes()
static bool maybeHandleStaticInExternC()
static bool setLLVMFunctionFEnvAttributes()
cir::PointerType VoidPtrTy
void* in address space 0
unsigned char SizeAlignInBytes
The alignment of size_t.
LangStandard - Information about the properties of a particular language standard.
Definition: LangStandard.h:71