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