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