Thanks to visit codestin.com
Credit goes to clang.llvm.org

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