Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
213799 views
1
//===----------------------------------------------------------------------===//
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 contains code to emit Decl nodes as CIR code.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "CIRGenConstantEmitter.h"
14
#include "CIRGenFunction.h"
15
#include "mlir/IR/Location.h"
16
#include "clang/AST/Attr.h"
17
#include "clang/AST/Decl.h"
18
#include "clang/AST/DeclOpenACC.h"
19
#include "clang/AST/Expr.h"
20
#include "clang/AST/ExprCXX.h"
21
#include "clang/CIR/MissingFeatures.h"
22
23
using namespace clang;
24
using namespace clang::CIRGen;
25
26
CIRGenFunction::AutoVarEmission
27
CIRGenFunction::emitAutoVarAlloca(const VarDecl &d) {
28
QualType ty = d.getType();
29
if (ty.getAddressSpace() != LangAS::Default)
30
cgm.errorNYI(d.getSourceRange(), "emitAutoVarAlloca: address space");
31
32
mlir::Location loc = getLoc(d.getSourceRange());
33
34
CIRGenFunction::AutoVarEmission emission(d);
35
emission.IsEscapingByRef = d.isEscapingByref();
36
if (emission.IsEscapingByRef)
37
cgm.errorNYI(d.getSourceRange(),
38
"emitAutoVarDecl: decl escaping by reference");
39
40
CharUnits alignment = getContext().getDeclAlign(&d);
41
42
// If the type is variably-modified, emit all the VLA sizes for it.
43
if (ty->isVariablyModifiedType())
44
cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: variably modified type");
45
46
Address address = Address::invalid();
47
if (!ty->isConstantSizeType())
48
cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: non-constant size type");
49
50
// A normal fixed sized variable becomes an alloca in the entry block,
51
mlir::Type allocaTy = convertTypeForMem(ty);
52
// Create the temp alloca and declare variable using it.
53
address = createTempAlloca(allocaTy, alignment, loc, d.getName());
54
declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()), alignment);
55
56
emission.Addr = address;
57
setAddrOfLocalVar(&d, address);
58
59
return emission;
60
}
61
62
/// Determine whether the given initializer is trivial in the sense
63
/// that it requires no code to be generated.
64
bool CIRGenFunction::isTrivialInitializer(const Expr *init) {
65
if (!init)
66
return true;
67
68
if (const CXXConstructExpr *construct = dyn_cast<CXXConstructExpr>(init))
69
if (CXXConstructorDecl *constructor = construct->getConstructor())
70
if (constructor->isTrivial() && constructor->isDefaultConstructor() &&
71
!construct->requiresZeroInitialization())
72
return true;
73
74
return false;
75
}
76
77
void CIRGenFunction::emitAutoVarInit(
78
const CIRGenFunction::AutoVarEmission &emission) {
79
assert(emission.Variable && "emission was not valid!");
80
81
// If this was emitted as a global constant, we're done.
82
if (emission.wasEmittedAsGlobal())
83
return;
84
85
const VarDecl &d = *emission.Variable;
86
87
QualType type = d.getType();
88
89
// If this local has an initializer, emit it now.
90
const Expr *init = d.getInit();
91
92
// Initialize the variable here if it doesn't have a initializer and it is a
93
// C struct that is non-trivial to initialize or an array containing such a
94
// struct.
95
if (!init && type.isNonTrivialToPrimitiveDefaultInitialize() ==
96
QualType::PDIK_Struct) {
97
cgm.errorNYI(d.getSourceRange(),
98
"emitAutoVarInit: non-trivial to default initialize");
99
return;
100
}
101
102
const Address addr = emission.Addr;
103
104
// Check whether this is a byref variable that's potentially
105
// captured and moved by its own initializer. If so, we'll need to
106
// emit the initializer first, then copy into the variable.
107
assert(!cir::MissingFeatures::opAllocaCaptureByInit());
108
109
// Note: constexpr already initializes everything correctly.
110
LangOptions::TrivialAutoVarInitKind trivialAutoVarInit =
111
(d.isConstexpr()
112
? LangOptions::TrivialAutoVarInitKind::Uninitialized
113
: (d.getAttr<UninitializedAttr>()
114
? LangOptions::TrivialAutoVarInitKind::Uninitialized
115
: getContext().getLangOpts().getTrivialAutoVarInit()));
116
117
auto initializeWhatIsTechnicallyUninitialized = [&](Address addr) {
118
if (trivialAutoVarInit ==
119
LangOptions::TrivialAutoVarInitKind::Uninitialized)
120
return;
121
122
cgm.errorNYI(d.getSourceRange(), "emitAutoVarInit: trivial initialization");
123
};
124
125
if (isTrivialInitializer(init)) {
126
initializeWhatIsTechnicallyUninitialized(addr);
127
return;
128
}
129
130
mlir::Attribute constant;
131
if (emission.IsConstantAggregate ||
132
d.mightBeUsableInConstantExpressions(getContext())) {
133
// FIXME: Differently from LLVM we try not to emit / lower too much
134
// here for CIR since we are interested in seeing the ctor in some
135
// analysis later on. So CIR's implementation of ConstantEmitter will
136
// frequently return an empty Attribute, to signal we want to codegen
137
// some trivial ctor calls and whatnots.
138
constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(d);
139
if (constant && !mlir::isa<cir::ZeroAttr>(constant) &&
140
(trivialAutoVarInit !=
141
LangOptions::TrivialAutoVarInitKind::Uninitialized)) {
142
cgm.errorNYI(d.getSourceRange(), "emitAutoVarInit: constant aggregate");
143
return;
144
}
145
}
146
147
// NOTE(cir): In case we have a constant initializer, we can just emit a
148
// store. But, in CIR, we wish to retain any ctor calls, so if it is a
149
// CXX temporary object creation, we ensure the ctor call is used deferring
150
// its removal/optimization to the CIR lowering.
151
if (!constant || isa<CXXTemporaryObjectExpr>(init)) {
152
initializeWhatIsTechnicallyUninitialized(addr);
153
LValue lv = makeAddrLValue(addr, type, AlignmentSource::Decl);
154
emitExprAsInit(init, &d, lv);
155
// In case lv has uses it means we indeed initialized something
156
// out of it while trying to build the expression, mark it as such.
157
mlir::Value val = lv.getAddress().getPointer();
158
assert(val && "Should have an address");
159
auto allocaOp = dyn_cast_or_null<cir::AllocaOp>(val.getDefiningOp());
160
assert(allocaOp && "Address should come straight out of the alloca");
161
162
if (!allocaOp.use_empty())
163
allocaOp.setInitAttr(mlir::UnitAttr::get(&getMLIRContext()));
164
return;
165
}
166
167
// FIXME(cir): migrate most of this file to use mlir::TypedAttr directly.
168
auto typedConstant = mlir::dyn_cast<mlir::TypedAttr>(constant);
169
assert(typedConstant && "expected typed attribute");
170
if (!emission.IsConstantAggregate) {
171
// For simple scalar/complex initialization, store the value directly.
172
LValue lv = makeAddrLValue(addr, type);
173
assert(init && "expected initializer");
174
mlir::Location initLoc = getLoc(init->getSourceRange());
175
// lv.setNonGC(true);
176
return emitStoreThroughLValue(
177
RValue::get(builder.getConstant(initLoc, typedConstant)), lv);
178
}
179
}
180
181
void CIRGenFunction::emitAutoVarCleanups(
182
const CIRGenFunction::AutoVarEmission &emission) {
183
const VarDecl &d = *emission.Variable;
184
185
// Check the type for a cleanup.
186
if (d.needsDestruction(getContext()))
187
cgm.errorNYI(d.getSourceRange(), "emitAutoVarCleanups: type cleanup");
188
189
assert(!cir::MissingFeatures::opAllocaPreciseLifetime());
190
191
// Handle the cleanup attribute.
192
if (d.hasAttr<CleanupAttr>())
193
cgm.errorNYI(d.getSourceRange(), "emitAutoVarCleanups: CleanupAttr");
194
}
195
196
/// Emit code and set up symbol table for a variable declaration with auto,
197
/// register, or no storage class specifier. These turn into simple stack
198
/// objects, globals depending on target.
199
void CIRGenFunction::emitAutoVarDecl(const VarDecl &d) {
200
CIRGenFunction::AutoVarEmission emission = emitAutoVarAlloca(d);
201
emitAutoVarInit(emission);
202
emitAutoVarCleanups(emission);
203
}
204
205
void CIRGenFunction::emitVarDecl(const VarDecl &d) {
206
// If the declaration has external storage, don't emit it now, allow it to be
207
// emitted lazily on its first use.
208
if (d.hasExternalStorage())
209
return;
210
211
if (d.getStorageDuration() != SD_Automatic) {
212
// Static sampler variables translated to function calls.
213
if (d.getType()->isSamplerT()) {
214
// Nothing needs to be done here, but let's flag it as an error until we
215
// have a test. It requires OpenCL support.
216
cgm.errorNYI(d.getSourceRange(), "emitVarDecl static sampler type");
217
return;
218
}
219
220
cir::GlobalLinkageKind linkage =
221
cgm.getCIRLinkageVarDefinition(&d, /*IsConstant=*/false);
222
223
// FIXME: We need to force the emission/use of a guard variable for
224
// some variables even if we can constant-evaluate them because
225
// we can't guarantee every translation unit will constant-evaluate them.
226
227
return emitStaticVarDecl(d, linkage);
228
}
229
230
if (d.getType().getAddressSpace() == LangAS::opencl_local)
231
cgm.errorNYI(d.getSourceRange(), "emitVarDecl openCL address space");
232
233
assert(d.hasLocalStorage());
234
235
CIRGenFunction::VarDeclContext varDeclCtx{*this, &d};
236
return emitAutoVarDecl(d);
237
}
238
239
static std::string getStaticDeclName(CIRGenModule &cgm, const VarDecl &d) {
240
if (cgm.getLangOpts().CPlusPlus)
241
return cgm.getMangledName(&d).str();
242
243
// If this isn't C++, we don't need a mangled name, just a pretty one.
244
assert(!d.isExternallyVisible() && "name shouldn't matter");
245
std::string contextName;
246
const DeclContext *dc = d.getDeclContext();
247
if (auto *cd = dyn_cast<CapturedDecl>(dc))
248
dc = cast<DeclContext>(cd->getNonClosureContext());
249
if (const auto *fd = dyn_cast<FunctionDecl>(dc))
250
contextName = std::string(cgm.getMangledName(fd));
251
else if (isa<BlockDecl>(dc))
252
cgm.errorNYI(d.getSourceRange(), "block decl context for static var");
253
else if (isa<ObjCMethodDecl>(dc))
254
cgm.errorNYI(d.getSourceRange(), "ObjC decl context for static var");
255
else
256
cgm.errorNYI(d.getSourceRange(), "Unknown context for static var decl");
257
258
contextName += "." + d.getNameAsString();
259
return contextName;
260
}
261
262
// TODO(cir): LLVM uses a Constant base class. Maybe CIR could leverage an
263
// interface for all constants?
264
cir::GlobalOp
265
CIRGenModule::getOrCreateStaticVarDecl(const VarDecl &d,
266
cir::GlobalLinkageKind linkage) {
267
// In general, we don't always emit static var decls once before we reference
268
// them. It is possible to reference them before emitting the function that
269
// contains them, and it is possible to emit the containing function multiple
270
// times.
271
if (cir::GlobalOp existingGV = getStaticLocalDeclAddress(&d))
272
return existingGV;
273
274
QualType ty = d.getType();
275
assert(ty->isConstantSizeType() && "VLAs can't be static");
276
277
// Use the label if the variable is renamed with the asm-label extension.
278
if (d.hasAttr<AsmLabelAttr>())
279
errorNYI(d.getSourceRange(), "getOrCreateStaticVarDecl: asm label");
280
281
std::string name = getStaticDeclName(*this, d);
282
283
mlir::Type lty = getTypes().convertTypeForMem(ty);
284
assert(!cir::MissingFeatures::addressSpace());
285
286
if (d.hasAttr<LoaderUninitializedAttr>() || d.hasAttr<CUDASharedAttr>())
287
errorNYI(d.getSourceRange(),
288
"getOrCreateStaticVarDecl: LoaderUninitializedAttr");
289
assert(!cir::MissingFeatures::addressSpace());
290
291
mlir::Attribute init = builder.getZeroInitAttr(convertType(ty));
292
293
cir::GlobalOp gv = builder.createVersionedGlobal(
294
getModule(), getLoc(d.getLocation()), name, lty, linkage);
295
// TODO(cir): infer visibility from linkage in global op builder.
296
gv.setVisibility(getMLIRVisibilityFromCIRLinkage(linkage));
297
gv.setInitialValueAttr(init);
298
gv.setAlignment(getASTContext().getDeclAlign(&d).getAsAlign().value());
299
300
if (supportsCOMDAT() && gv.isWeakForLinker())
301
gv.setComdat(true);
302
303
assert(!cir::MissingFeatures::opGlobalThreadLocal());
304
305
setGVProperties(gv, &d);
306
307
// OG checks if the expected address space, denoted by the type, is the
308
// same as the actual address space indicated by attributes. If they aren't
309
// the same, an addrspacecast is emitted when this variable is accessed.
310
// In CIR however, cir.get_global already carries that information in
311
// !cir.ptr type - if this global is in OpenCL local address space, then its
312
// type would be !cir.ptr<..., addrspace(offload_local)>. Therefore we don't
313
// need an explicit address space cast in CIR: they will get emitted when
314
// lowering to LLVM IR.
315
316
// Ensure that the static local gets initialized by making sure the parent
317
// function gets emitted eventually.
318
const Decl *dc = cast<Decl>(d.getDeclContext());
319
320
// We can't name blocks or captured statements directly, so try to emit their
321
// parents.
322
if (isa<BlockDecl>(dc) || isa<CapturedDecl>(dc)) {
323
dc = dc->getNonClosureContext();
324
// FIXME: Ensure that global blocks get emitted.
325
if (!dc)
326
errorNYI(d.getSourceRange(), "non-closure context");
327
}
328
329
GlobalDecl gd;
330
if (isa<CXXConstructorDecl>(dc))
331
errorNYI(d.getSourceRange(), "C++ constructors static var context");
332
else if (isa<CXXDestructorDecl>(dc))
333
errorNYI(d.getSourceRange(), "C++ destructors static var context");
334
else if (const auto *fd = dyn_cast<FunctionDecl>(dc))
335
gd = GlobalDecl(fd);
336
else {
337
// Don't do anything for Obj-C method decls or global closures. We should
338
// never defer them.
339
assert(isa<ObjCMethodDecl>(dc) && "unexpected parent code decl");
340
}
341
if (gd.getDecl() && cir::MissingFeatures::openMP()) {
342
// Disable emission of the parent function for the OpenMP device codegen.
343
errorNYI(d.getSourceRange(), "OpenMP");
344
}
345
346
return gv;
347
}
348
349
/// Add the initializer for 'd' to the global variable that has already been
350
/// created for it. If the initializer has a different type than gv does, this
351
/// may free gv and return a different one. Otherwise it just returns gv.
352
cir::GlobalOp CIRGenFunction::addInitializerToStaticVarDecl(
353
const VarDecl &d, cir::GlobalOp gv, cir::GetGlobalOp gvAddr) {
354
ConstantEmitter emitter(*this);
355
mlir::TypedAttr init =
356
mlir::cast<mlir::TypedAttr>(emitter.tryEmitForInitializer(d));
357
358
// If constant emission failed, then this should be a C++ static
359
// initializer.
360
if (!init) {
361
cgm.errorNYI(d.getSourceRange(), "static var without initializer");
362
return gv;
363
}
364
365
// TODO(cir): There should be debug code here to assert that the decl size
366
// matches the CIR data layout type alloc size, but the code for calculating
367
// the type alloc size is not implemented yet.
368
assert(!cir::MissingFeatures::dataLayoutTypeAllocSize());
369
370
// The initializer may differ in type from the global. Rewrite
371
// the global to match the initializer. (We have to do this
372
// because some types, like unions, can't be completely represented
373
// in the LLVM type system.)
374
if (gv.getSymType() != init.getType()) {
375
gv.setSymType(init.getType());
376
377
// Normally this should be done with a call to cgm.replaceGlobal(oldGV, gv),
378
// but since at this point the current block hasn't been really attached,
379
// there's no visibility into the GetGlobalOp corresponding to this Global.
380
// Given those constraints, thread in the GetGlobalOp and update it
381
// directly.
382
assert(!cir::MissingFeatures::addressSpace());
383
gvAddr.getAddr().setType(builder.getPointerTo(init.getType()));
384
}
385
386
bool needsDtor =
387
d.needsDestruction(getContext()) == QualType::DK_cxx_destructor;
388
389
assert(!cir::MissingFeatures::opGlobalConstant());
390
gv.setInitialValueAttr(init);
391
392
emitter.finalize(gv);
393
394
if (needsDtor) {
395
// We have a constant initializer, but a nontrivial destructor. We still
396
// need to perform a guarded "initialization" in order to register the
397
// destructor.
398
cgm.errorNYI(d.getSourceRange(), "C++ guarded init");
399
}
400
401
return gv;
402
}
403
404
void CIRGenFunction::emitStaticVarDecl(const VarDecl &d,
405
cir::GlobalLinkageKind linkage) {
406
// Check to see if we already have a global variable for this
407
// declaration. This can happen when double-emitting function
408
// bodies, e.g. with complete and base constructors.
409
cir::GlobalOp globalOp = cgm.getOrCreateStaticVarDecl(d, linkage);
410
// TODO(cir): we should have a way to represent global ops as values without
411
// having to emit a get global op. Sometimes these emissions are not used.
412
mlir::Value addr = builder.createGetGlobal(globalOp);
413
auto getAddrOp = mlir::cast<cir::GetGlobalOp>(addr.getDefiningOp());
414
415
CharUnits alignment = getContext().getDeclAlign(&d);
416
417
// Store into LocalDeclMap before generating initializer to handle
418
// circular references.
419
mlir::Type elemTy = convertTypeForMem(d.getType());
420
setAddrOfLocalVar(&d, Address(addr, elemTy, alignment));
421
422
// We can't have a VLA here, but we can have a pointer to a VLA,
423
// even though that doesn't really make any sense.
424
// Make sure to evaluate VLA bounds now so that we have them for later.
425
if (d.getType()->isVariablyModifiedType()) {
426
cgm.errorNYI(d.getSourceRange(),
427
"emitStaticVarDecl: variably modified type");
428
}
429
430
// Save the type in case adding the initializer forces a type change.
431
mlir::Type expectedType = addr.getType();
432
433
cir::GlobalOp var = globalOp;
434
435
assert(!cir::MissingFeatures::cudaSupport());
436
437
// If this value has an initializer, emit it.
438
if (d.getInit())
439
var = addInitializerToStaticVarDecl(d, var, getAddrOp);
440
441
var.setAlignment(alignment.getAsAlign().value());
442
443
// There are a lot of attributes that need to be handled here. Until
444
// we start to support them, we just report an error if there are any.
445
if (d.hasAttrs())
446
cgm.errorNYI(d.getSourceRange(), "static var with attrs");
447
448
if (cgm.getCodeGenOpts().KeepPersistentStorageVariables)
449
cgm.errorNYI(d.getSourceRange(), "static var keep persistent storage");
450
451
// From traditional codegen:
452
// We may have to cast the constant because of the initializer
453
// mismatch above.
454
//
455
// FIXME: It is really dangerous to store this in the map; if anyone
456
// RAUW's the GV uses of this constant will be invalid.
457
mlir::Value castedAddr =
458
builder.createBitcast(getAddrOp.getAddr(), expectedType);
459
localDeclMap.find(&d)->second = Address(castedAddr, elemTy, alignment);
460
cgm.setStaticLocalDeclAddress(&d, var);
461
462
assert(!cir::MissingFeatures::sanitizers());
463
assert(!cir::MissingFeatures::generateDebugInfo());
464
}
465
466
void CIRGenFunction::emitScalarInit(const Expr *init, mlir::Location loc,
467
LValue lvalue, bool capturedByInit) {
468
assert(!cir::MissingFeatures::objCLifetime());
469
470
SourceLocRAIIObject locRAII{*this, loc};
471
mlir::Value value = emitScalarExpr(init);
472
if (capturedByInit) {
473
cgm.errorNYI(init->getSourceRange(), "emitScalarInit: captured by init");
474
return;
475
}
476
assert(!cir::MissingFeatures::emitNullabilityCheck());
477
emitStoreThroughLValue(RValue::get(value), lvalue, true);
478
}
479
480
void CIRGenFunction::emitExprAsInit(const Expr *init, const ValueDecl *d,
481
LValue lvalue, bool capturedByInit) {
482
SourceLocRAIIObject loc{*this, getLoc(init->getSourceRange())};
483
if (capturedByInit) {
484
cgm.errorNYI(init->getSourceRange(), "emitExprAsInit: captured by init");
485
return;
486
}
487
488
QualType type = d->getType();
489
490
if (type->isReferenceType()) {
491
RValue rvalue = emitReferenceBindingToExpr(init);
492
if (capturedByInit)
493
cgm.errorNYI(init->getSourceRange(), "emitExprAsInit: captured by init");
494
emitStoreThroughLValue(rvalue, lvalue);
495
return;
496
}
497
switch (CIRGenFunction::getEvaluationKind(type)) {
498
case cir::TEK_Scalar:
499
emitScalarInit(init, getLoc(d->getSourceRange()), lvalue);
500
return;
501
case cir::TEK_Complex: {
502
mlir::Value complex = emitComplexExpr(init);
503
if (capturedByInit)
504
cgm.errorNYI(init->getSourceRange(),
505
"emitExprAsInit: complex type captured by init");
506
mlir::Location loc = getLoc(init->getExprLoc());
507
emitStoreOfComplex(loc, complex, lvalue,
508
/*isInit*/ true);
509
return;
510
}
511
case cir::TEK_Aggregate:
512
// The overlap flag here should be calculated.
513
assert(!cir::MissingFeatures::aggValueSlotMayOverlap());
514
emitAggExpr(init,
515
AggValueSlot::forLValue(lvalue, AggValueSlot::IsDestructed,
516
AggValueSlot::IsNotAliased,
517
AggValueSlot::MayOverlap));
518
return;
519
}
520
llvm_unreachable("bad evaluation kind");
521
}
522
523
void CIRGenFunction::emitDecl(const Decl &d) {
524
switch (d.getKind()) {
525
case Decl::BuiltinTemplate:
526
case Decl::TranslationUnit:
527
case Decl::ExternCContext:
528
case Decl::Namespace:
529
case Decl::UnresolvedUsingTypename:
530
case Decl::ClassTemplateSpecialization:
531
case Decl::ClassTemplatePartialSpecialization:
532
case Decl::VarTemplateSpecialization:
533
case Decl::VarTemplatePartialSpecialization:
534
case Decl::TemplateTypeParm:
535
case Decl::UnresolvedUsingValue:
536
case Decl::NonTypeTemplateParm:
537
case Decl::CXXDeductionGuide:
538
case Decl::CXXMethod:
539
case Decl::CXXConstructor:
540
case Decl::CXXDestructor:
541
case Decl::CXXConversion:
542
case Decl::Field:
543
case Decl::MSProperty:
544
case Decl::IndirectField:
545
case Decl::ObjCIvar:
546
case Decl::ObjCAtDefsField:
547
case Decl::ParmVar:
548
case Decl::ImplicitParam:
549
case Decl::ClassTemplate:
550
case Decl::VarTemplate:
551
case Decl::FunctionTemplate:
552
case Decl::TypeAliasTemplate:
553
case Decl::TemplateTemplateParm:
554
case Decl::ObjCMethod:
555
case Decl::ObjCCategory:
556
case Decl::ObjCProtocol:
557
case Decl::ObjCInterface:
558
case Decl::ObjCCategoryImpl:
559
case Decl::ObjCImplementation:
560
case Decl::ObjCProperty:
561
case Decl::ObjCCompatibleAlias:
562
case Decl::PragmaComment:
563
case Decl::PragmaDetectMismatch:
564
case Decl::AccessSpec:
565
case Decl::LinkageSpec:
566
case Decl::Export:
567
case Decl::ObjCPropertyImpl:
568
case Decl::FileScopeAsm:
569
case Decl::Friend:
570
case Decl::FriendTemplate:
571
case Decl::Block:
572
case Decl::OutlinedFunction:
573
case Decl::Captured:
574
case Decl::UsingShadow:
575
case Decl::ConstructorUsingShadow:
576
case Decl::ObjCTypeParam:
577
case Decl::Binding:
578
case Decl::UnresolvedUsingIfExists:
579
case Decl::HLSLBuffer:
580
case Decl::HLSLRootSignature:
581
llvm_unreachable("Declaration should not be in declstmts!");
582
583
case Decl::Function: // void X();
584
case Decl::EnumConstant: // enum ? { X = ? }
585
case Decl::StaticAssert: // static_assert(X, ""); [C++0x]
586
case Decl::Label: // __label__ x;
587
case Decl::Import:
588
case Decl::MSGuid: // __declspec(uuid("..."))
589
case Decl::TemplateParamObject:
590
case Decl::OMPThreadPrivate:
591
case Decl::OMPAllocate:
592
case Decl::OMPCapturedExpr:
593
case Decl::OMPRequires:
594
case Decl::Empty:
595
case Decl::Concept:
596
case Decl::LifetimeExtendedTemporary:
597
case Decl::RequiresExprBody:
598
case Decl::UnnamedGlobalConstant:
599
// None of these decls require codegen support.
600
return;
601
602
case Decl::Enum: // enum X;
603
case Decl::Record: // struct/union/class X;
604
case Decl::CXXRecord: // struct/union/class X; [C++]
605
case Decl::NamespaceAlias:
606
case Decl::Using: // using X; [C++]
607
case Decl::UsingEnum: // using enum X; [C++]
608
case Decl::UsingDirective: // using namespace X; [C++]
609
assert(!cir::MissingFeatures::generateDebugInfo());
610
return;
611
case Decl::Var: {
612
const VarDecl &vd = cast<VarDecl>(d);
613
assert(vd.isLocalVarDecl() &&
614
"Should not see file-scope variables inside a function!");
615
emitVarDecl(vd);
616
return;
617
}
618
case Decl::OpenACCDeclare:
619
emitOpenACCDeclare(cast<OpenACCDeclareDecl>(d));
620
return;
621
case Decl::OpenACCRoutine:
622
emitOpenACCRoutine(cast<OpenACCRoutineDecl>(d));
623
return;
624
case Decl::Typedef: // typedef int X;
625
case Decl::TypeAlias: { // using X = int; [C++0x]
626
QualType ty = cast<TypedefNameDecl>(d).getUnderlyingType();
627
assert(!cir::MissingFeatures::generateDebugInfo());
628
if (ty->isVariablyModifiedType())
629
cgm.errorNYI(d.getSourceRange(), "emitDecl: variably modified type");
630
return;
631
}
632
case Decl::ImplicitConceptSpecialization:
633
case Decl::TopLevelStmt:
634
case Decl::UsingPack:
635
case Decl::Decomposition: // This could be moved to join Decl::Var
636
case Decl::OMPDeclareReduction:
637
case Decl::OMPDeclareMapper:
638
cgm.errorNYI(d.getSourceRange(),
639
std::string("emitDecl: unhandled decl type: ") +
640
d.getDeclKindName());
641
}
642
}
643
644
void CIRGenFunction::emitNullabilityCheck(LValue lhs, mlir::Value rhs,
645
SourceLocation loc) {
646
if (!sanOpts.has(SanitizerKind::NullabilityAssign))
647
return;
648
649
assert(!cir::MissingFeatures::sanitizers());
650
}
651
652