xref: /freebsd/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenDecl.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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
emitAutoVarAlloca(const VarDecl & d)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.
isTrivialInitializer(const Expr * init)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 
emitAutoVarInit(const CIRGenFunction::AutoVarEmission & emission)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 
emitAutoVarCleanups(const CIRGenFunction::AutoVarEmission & emission)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.
emitAutoVarDecl(const VarDecl & d)199 void CIRGenFunction::emitAutoVarDecl(const VarDecl &d) {
200   CIRGenFunction::AutoVarEmission emission = emitAutoVarAlloca(d);
201   emitAutoVarInit(emission);
202   emitAutoVarCleanups(emission);
203 }
204 
emitVarDecl(const VarDecl & d)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 
getStaticDeclName(CIRGenModule & cgm,const VarDecl & d)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
getOrCreateStaticVarDecl(const VarDecl & d,cir::GlobalLinkageKind linkage)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.
addInitializerToStaticVarDecl(const VarDecl & d,cir::GlobalOp gv,cir::GetGlobalOp gvAddr)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 
emitStaticVarDecl(const VarDecl & d,cir::GlobalLinkageKind linkage)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 
emitScalarInit(const Expr * init,mlir::Location loc,LValue lvalue,bool capturedByInit)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 
emitExprAsInit(const Expr * init,const ValueDecl * d,LValue lvalue,bool capturedByInit)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 
emitDecl(const Decl & d)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 
emitNullabilityCheck(LValue lhs,mlir::Value rhs,SourceLocation loc)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