clang: lib/CodeGen/CodeGenFunction.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

38#include "llvm/ADT/ArrayRef.h"

39#include "llvm/ADT/ScopeExit.h"

40#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"

41#include "llvm/IR/DataLayout.h"

42#include "llvm/IR/Dominators.h"

43#include "llvm/IR/FPEnv.h"

44#include "llvm/IR/Instruction.h"

45#include "llvm/IR/IntrinsicInst.h"

46#include "llvm/IR/Intrinsics.h"

47#include "llvm/IR/MDBuilder.h"

48#include "llvm/Support/CRC.h"

49#include "llvm/Support/xxhash.h"

50#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"

51#include "llvm/Transforms/Utils/PromoteMemToReg.h"

52#include

53

54using namespace clang;

56

57namespace llvm {

59}

60

61

62

65 if (CGOpts.DisableLifetimeMarkers)

66 return false;

67

68

69 if (CGOpts.SanitizeAddressUseAfterScope ||

70 LangOpts.Sanitize.has(SanitizerKind::HWAddress) ||

71 LangOpts.Sanitize.has(SanitizerKind::Memory))

72 return true;

73

74

75 return CGOpts.OptimizationLevel != 0;

76}

77

78CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)

83 DebugInfo(CGM.getModuleDebugInfo()),

85 ShouldEmitLifetimeMarkers(

87 if (!suppressNewContext)

88 CGM.getCXXABI().getMangleContext().startNewFunction();

90

92}

93

97 "missed to deactivate a cleanup");

98

100 CGM.getOpenMPRuntime().functionFinished(*this);

101

102

103

104

105

106

107 if (CGM.getLangOpts().OpenMPIRBuilder && CurFn)

108 CGM.getOpenMPRuntime().getOMPBuilder().finalize(CurFn);

109}

110

111

112

113llvm::fp::ExceptionBehavior

115

116 switch (Kind) {

120 default:

121 llvm_unreachable("Unsupported FP Exception Behavior");

122 }

123}

124

126 llvm::FastMathFlags FMF;

127 FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());

128 FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());

129 FMF.setNoInfs(FPFeatures.getNoHonorInfs());

130 FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());

131 FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());

132 FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());

134 Builder.setFastMathFlags(FMF);

135}

136

138 const Expr *E)

139 : CGF(CGF) {

141}

142

145 : CGF(CGF) {

146 ConstructorHelper(FPFeatures);

147}

148

149void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(FPOptions FPFeatures) {

150 OldFPFeatures = CGF.CurFPFeatures;

151 CGF.CurFPFeatures = FPFeatures;

152

153 OldExcept = CGF.Builder.getDefaultConstrainedExcept();

154 OldRounding = CGF.Builder.getDefaultConstrainedRounding();

155

156 if (OldFPFeatures == FPFeatures)

157 return;

158

159 FMFGuard.emplace(CGF.Builder);

160

161 llvm::RoundingMode NewRoundingBehavior = FPFeatures.getRoundingMode();

162 CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);

163 auto NewExceptionBehavior =

165 CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);

166

167 CGF.SetFastMathFlags(FPFeatures);

168

169 assert((CGF.CurFuncDecl == nullptr || CGF.Builder.getIsFPConstrained() ||

172 (NewExceptionBehavior == llvm::fp::ebIgnore &&

173 NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&

174 "FPConstrained should be enabled on entire function");

175

176 auto mergeFnAttrValue = [&](StringRef Name, bool Value) {

177 auto OldValue =

178 CGF.CurFn->getFnAttribute(Name).getValueAsBool();

179 auto NewValue = OldValue & Value;

180 if (OldValue != NewValue)

181 CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue));

182 };

183 mergeFnAttrValue("no-infs-fp-math", FPFeatures.getNoHonorInfs());

184 mergeFnAttrValue("no-nans-fp-math", FPFeatures.getNoHonorNaNs());

185 mergeFnAttrValue("no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());

186}

187

189 CGF.CurFPFeatures = OldFPFeatures;

190 CGF.Builder.setDefaultConstrainedExcept(OldExcept);

191 CGF.Builder.setDefaultConstrainedRounding(OldRounding);

192}

193

203 MightBeSigned

205 nullptr, IsKnownNonNull)

208}

209

210LValue

213 return ::makeNaturalAlignAddrLValue(V, T, false,

214 true, *this,

215 IsKnownNonNull);

216}

217

220 return ::makeNaturalAlignAddrLValue(V, T, true,

221 true, *this);

222}

223

226 return ::makeNaturalAlignAddrLValue(V, T, false,

227 false, *this);

228}

229

232 return ::makeNaturalAlignAddrLValue(V, T, true,

233 false, *this);

234}

235

237 return CGM.getTypes().ConvertTypeForMem(T);

238}

239

241 return CGM.getTypes().ConvertType(T);

242}

243

245 llvm::Type *LLVMTy) {

246 return CGM.getTypes().convertTypeForLoadStore(ASTTy, LLVMTy);

247}

248

250 type = type.getCanonicalType();

251 while (true) {

252 switch (type->getTypeClass()) {

253#define TYPE(name, parent)

254#define ABSTRACT_TYPE(name, parent)

255#define NON_CANONICAL_TYPE(name, parent) case Type:๐Ÿ“›

256#define DEPENDENT_TYPE(name, parent) case Type:๐Ÿ“›

257#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type:๐Ÿ“›

258#include "clang/AST/TypeNodes.inc"

259 llvm_unreachable("non-canonical or dependent type in IR-generation");

260

261 case Type::Auto:

262 case Type::DeducedTemplateSpecialization:

263 llvm_unreachable("undeduced type in IR-generation");

264

265

266 case Type::Builtin:

267 case Type::Pointer:

268 case Type::BlockPointer:

269 case Type::LValueReference:

270 case Type::RValueReference:

271 case Type::MemberPointer:

272 case Type::Vector:

273 case Type::ExtVector:

274 case Type::ConstantMatrix:

275 case Type::FunctionProto:

276 case Type::FunctionNoProto:

277 case Type::Enum:

278 case Type::ObjCObjectPointer:

279 case Type::Pipe:

280 case Type::BitInt:

281 case Type::HLSLAttributedResource:

282 case Type::HLSLInlineSpirv:

284

285

286 case Type::Complex:

288

289

290 case Type::ConstantArray:

291 case Type::IncompleteArray:

292 case Type::VariableArray:

293 case Type::Record:

294 case Type::ObjCObject:

295 case Type::ObjCInterface:

296 case Type::ArrayParameter:

298

299

300 case Type::Atomic:

302 continue;

303 }

304 llvm_unreachable("unknown type kind!");

305 }

306}

307

309

310

311 llvm::BasicBlock *CurBB = Builder.GetInsertBlock();

312

313 if (CurBB) {

314 assert(!CurBB->getTerminator() && "Unexpected terminated block.");

315

316

317

318 if (CurBB->empty() || ReturnBlock.getBlock()->use_empty()) {

319 ReturnBlock.getBlock()->replaceAllUsesWith(CurBB);

322 } else

324 return llvm::DebugLoc();

325 }

326

327

328

329

330 if (ReturnBlock.getBlock()->hasOneUse()) {

331 llvm::BranchInst *BI =

332 dyn_castllvm::BranchInst(*ReturnBlock.getBlock()->user_begin());

333 if (BI && BI->isUnconditional() &&

334 BI->getSuccessor(0) == ReturnBlock.getBlock()) {

335

336

337 llvm::DebugLoc Loc = BI->getDebugLoc();

338 Builder.SetInsertPoint(BI->getParent());

339 BI->eraseFromParent();

342 return Loc;

343 }

344 }

345

346

347

348

349

351 return llvm::DebugLoc();

352}

353

355 if (!BB) return;

356 if (!BB->use_empty()) {

357 CGF.CurFn->insert(CGF.CurFn->end(), BB);

358 return;

359 }

360 delete BB;

361}

362

364 assert(BreakContinueStack.empty() &&

365 "mismatched push/pop in break/continue stack!");

367 "mismatched push/pop of cleanups in EHStack!");

369 "mismatched activate/deactivate of cleanups!");

370

371 if (CGM.shouldEmitConvergenceTokens()) {

374 "mismatched push/pop in convergence stack!");

375 }

376

377 bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0

378 && NumSimpleReturnExprs == NumReturnExprs

380

381

382

383

384

385

386

387

388

389

390

391

393 if (OnlySimpleReturnStmts)

394 DI->EmitLocation(Builder, LastStopPoint);

395 else

396 DI->EmitLocation(Builder, EndLoc);

397 }

398

399

400

401

402

404 bool HasOnlyNoopCleanups =

406 bool EmitRetDbgLoc = !HasCleanups || HasOnlyNoopCleanups;

407

408 std::optional OAL;

409 if (HasCleanups) {

410

411

413 if (OnlySimpleReturnStmts)

414 DI->EmitLocation(Builder, EndLoc);

415 else

416

417

419 }

420

422 }

423

424

426

428 if (CGM.getCodeGenOpts().InstrumentFunctions)

429 CurFn->addFnAttr("instrument-function-exit", "__cyg_profile_func_exit");

430 if (CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining)

431 CurFn->addFnAttr("instrument-function-exit-inlined",

432 "__cyg_profile_func_exit");

433 }

434

435

438

439

440

441 uint64_t RetKeyInstructionsAtomGroup = Loc ? Loc->getAtomGroup() : 0;

444 RetKeyInstructionsAtomGroup);

446

447 assert(EHStack.empty() &&

448 "did not remove all scopes from cleanup stack!");

449

450

451

452 if (IndirectBranch) {

453 EmitBlock(IndirectBranch->getParent());

454 Builder.ClearInsertionPoint();

455 }

456

457

458

459 if (!EscapedLocals.empty()) {

460

461

463 EscapeArgs.resize(EscapedLocals.size());

464 for (auto &Pair : EscapedLocals)

465 EscapeArgs[Pair.second] = Pair.first;

466 llvm::Function *FrameEscapeFn = llvm::Intrinsic::getOrInsertDeclaration(

467 &CGM.getModule(), llvm::Intrinsic::localescape);

469 }

470

471

474 Ptr->eraseFromParent();

475

476

477

478 if (PostAllocaInsertPt) {

479 llvm::Instruction *PostPtr = PostAllocaInsertPt;

480 PostAllocaInsertPt = nullptr;

481 PostPtr->eraseFromParent();

482 }

483

484

485

486 if (IndirectBranch) {

488 if (PN->getNumIncomingValues() == 0) {

489 PN->replaceAllUsesWith(llvm::PoisonValue::get(PN->getType()));

490 PN->eraseFromParent();

491 }

492 }

493

495 EmitIfUsed(*this, TerminateLandingPad);

498

499 for (const auto &FuncletAndParent : TerminateFunclets)

500 EmitIfUsed(*this, FuncletAndParent.second);

501

502 if (CGM.getCodeGenOpts().EmitDeclMetadata)

503 EmitDeclMetadata();

504

505 for (const auto &R : DeferredReplacements) {

506 if (llvm::Value *Old = R.first) {

507 Old->replaceAllUsesWith(R.second);

509 }

510 }

511 DeferredReplacements.clear();

512

513

514

515

516

517

518

520 llvm::DominatorTree DT(*CurFn);

521 llvm::PromoteMemToReg(

524 }

525

526

527 for (llvm::Argument &A : CurFn->args())

528 if (auto *VT = dyn_castllvm::VectorType(A.getType()))

529 LargestVectorWidth =

530 std::max((uint64_t)LargestVectorWidth,

531 VT->getPrimitiveSizeInBits().getKnownMinValue());

532

533

534 if (auto *VT = dyn_castllvm::VectorType(CurFn->getReturnType()))

535 LargestVectorWidth =

536 std::max((uint64_t)LargestVectorWidth,

537 VT->getPrimitiveSizeInBits().getKnownMinValue());

538

539 if (CurFnInfo->getMaxVectorWidth() > LargestVectorWidth)

540 LargestVectorWidth = CurFnInfo->getMaxVectorWidth();

541

542

543

544

545

546

547

548

549 if (getContext().getTargetInfo().getTriple().isX86())

550 CurFn->addFnAttr("min-legal-vector-width",

551 llvm::utostr(LargestVectorWidth));

552

553

555 Builder.ClearInsertionPoint();

556 ReturnBlock.getBlock()->eraseFromParent();

557 }

559 auto *RetAlloca =

560 dyn_castllvm::AllocaInst(ReturnValue.emitRawPointer(*this));

561 if (RetAlloca && RetAlloca->use_empty()) {

562 RetAlloca->eraseFromParent();

564 }

565 }

566}

567

568

569

571 if (CGM.getCodeGenOpts().InstrumentFunctions &&

572 CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining &&

573 CGM.getCodeGenOpts().InstrumentFunctionEntryBare)

574 return false;

576 return false;

577 return true;

578}

579

582 return false;

583 return CurFuncDecl->hasAttr();

584}

585

586

587

589 return CGM.getCodeGenOpts().XRayInstrumentFunctions;

590}

591

592

593

595 return CGM.getCodeGenOpts().XRayInstrumentFunctions &&

596 (CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents ||

597 CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==

599}

600

602 return CGM.getCodeGenOpts().XRayInstrumentFunctions &&

603 (CGM.getCodeGenOpts().XRayAlwaysEmitTypedEvents ||

604 CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==

606}

607

608llvm::ConstantInt *

610

611

614 std::string Mangled;

615 llvm::raw_string_ostream Out(Mangled);

616 CGM.getCXXABI().getMangleContext().mangleCanonicalTypeName(Ty, Out, false);

617 return llvm::ConstantInt::get(

618 CGM.Int32Ty, static_cast<uint32_t>(llvm::xxh3_64bits(Mangled)));

619}

620

621void CodeGenFunction::EmitKernelMetadata(const FunctionDecl *FD,

622 llvm::Function *Fn) {

623 if (!FD->hasAttr() && !FD->hasAttr())

624 return;

625

627

629

632 getContext().getTargetInfo().getTriple().isSPIRV())))

633 return;

634

635 if (const VecTypeHintAttr *A = FD->getAttr()) {

636 QualType HintQTy = A->getTypeHint();

638 bool IsSignedInteger =

640 (HintEltQTy && HintEltQTy->getElementType()->isSignedIntegerType());

641 llvm::Metadata *AttrMDArgs[] = {

642 llvm::ConstantAsMetadata::get(llvm::PoisonValue::get(

644 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(

645 llvm::IntegerType::get(Context, 32),

646 llvm::APInt(32, (uint64_t)(IsSignedInteger ? 1 : 0))))};

647 Fn->setMetadata("vec_type_hint", llvm::MDNode::get(Context, AttrMDArgs));

648 }

649

650 if (const WorkGroupSizeHintAttr *A = FD->getAttr()) {

651 auto Eval = [&](Expr *E) {

652 return E->EvaluateKnownConstInt(FD->getASTContext()).getExtValue();

653 };

654 llvm::Metadata *AttrMDArgs[] = {

655 llvm::ConstantAsMetadata::get(Builder.getInt32(Eval(A->getXDim()))),

656 llvm::ConstantAsMetadata::get(Builder.getInt32(Eval(A->getYDim()))),

657 llvm::ConstantAsMetadata::get(Builder.getInt32(Eval(A->getZDim())))};

658 Fn->setMetadata("work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs));

659 }

660

661 if (const ReqdWorkGroupSizeAttr *A = FD->getAttr()) {

662 auto Eval = [&](Expr *E) {

663 return E->EvaluateKnownConstInt(FD->getASTContext()).getExtValue();

664 };

665 llvm::Metadata *AttrMDArgs[] = {

666 llvm::ConstantAsMetadata::get(Builder.getInt32(Eval(A->getXDim()))),

667 llvm::ConstantAsMetadata::get(Builder.getInt32(Eval(A->getYDim()))),

668 llvm::ConstantAsMetadata::get(Builder.getInt32(Eval(A->getZDim())))};

669 Fn->setMetadata("reqd_work_group_size", llvm::MDNode::get(Context, AttrMDArgs));

670 }

671

672 if (const OpenCLIntelReqdSubGroupSizeAttr *A =

673 FD->getAttr()) {

674 llvm::Metadata *AttrMDArgs[] = {

675 llvm::ConstantAsMetadata::get(Builder.getInt32(A->getSubGroupSize()))};

676 Fn->setMetadata("intel_reqd_sub_group_size",

677 llvm::MDNode::get(Context, AttrMDArgs));

678 }

679}

680

681

683 const Stmt *Body = nullptr;

684 if (auto *FD = dyn_cast_or_null(F))

686 else if (auto *OMD = dyn_cast_or_null(F))

687 Body = OMD->getBody();

688

689 if (auto *CS = dyn_cast_or_null(Body)) {

690 auto LastStmt = CS->body_rbegin();

691 if (LastStmt != CS->body_rend())

693 }

694 return false;

695}

696

698 if (SanOpts.has(SanitizerKind::Thread)) {

699 Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");

700 Fn->removeFnAttr(llvm::Attribute::SanitizeThread);

701 }

702}

703

704

705bool CodeGenFunction::requiresReturnValueCheck() const {

706 return requiresReturnValueNullabilityCheck() ||

709}

710

712 auto *MD = dyn_cast_or_null(D);

713 if (!MD || !MD->getDeclName().getAsIdentifierInfo() ||

714 !MD->getDeclName().getAsIdentifierInfo()->isStr("allocate") ||

715 (MD->getNumParams() != 1 && MD->getNumParams() != 2))

716 return false;

717

719 return false;

720

721 if (MD->getNumParams() == 2) {

722 auto *PT = MD->parameters()[1]->getType()->getAs<PointerType>();

723 if (!PT || !PT->isVoidPointerType() ||

724 !PT->getPointeeType().isConstQualified())

725 return false;

726 }

727

728 return true;

729}

730

731bool CodeGenFunction::isInAllocaArgument(CGCXXABI &ABI, QualType Ty) {

734}

735

736bool CodeGenFunction::hasInAllocaArg(const CXXMethodDecl *MD) {

739 llvm::any_of(MD->parameters(), [&](ParmVarDecl *P) {

740 return isInAllocaArgument(CGM.getCXXABI(), P->getType());

741 });

742}

743

744

747 if (const auto *MD = dyn_cast(FD))

749 return nullptr;

751}

752

754 llvm::Function *Fn,

760 "Do not use a CodeGenFunction object for more than one function");

761

763

764 DidCallStackSave = false;

766 const FunctionDecl *FD = dyn_cast_or_null(D);

773 assert(CurFn->isDeclaration() && "Function already has body?");

774

775

776

777 do {

778#define SANITIZER(NAME, ID) \

779 if (SanOpts.empty()) \

780 break; \

781 if (SanOpts.has(SanitizerKind::ID)) \

782 if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \

783 SanOpts.set(SanitizerKind::ID, false);

784

785#include "clang/Basic/Sanitizers.def"

786#undef SANITIZER

787 } while (false);

788

789 if (D) {

790 const bool SanitizeBounds = SanOpts.hasOneOf(SanitizerKind::Bounds);

792 bool NoSanitizeCoverage = false;

793

795 no_sanitize_mask |= Attr->getMask();

796

797 if (Attr->hasCoverage())

798 NoSanitizeCoverage = true;

799 }

800

801

802 SanOpts.Mask &= ~no_sanitize_mask;

803 if (no_sanitize_mask & SanitizerKind::Address)

804 SanOpts.set(SanitizerKind::KernelAddress, false);

805 if (no_sanitize_mask & SanitizerKind::KernelAddress)

806 SanOpts.set(SanitizerKind::Address, false);

807 if (no_sanitize_mask & SanitizerKind::HWAddress)

808 SanOpts.set(SanitizerKind::KernelHWAddress, false);

809 if (no_sanitize_mask & SanitizerKind::KernelHWAddress)

810 SanOpts.set(SanitizerKind::HWAddress, false);

811

812 if (SanitizeBounds && SanOpts.hasOneOf(SanitizerKind::Bounds))

813 Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds);

814

815 if (NoSanitizeCoverage && CGM.getCodeGenOpts().hasSanitizeCoverage())

816 Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage);

817

818

819 if (CGM.getCodeGenOpts().hasSanitizeBinaryMetadata()) {

820 if (no_sanitize_mask & SanitizerKind::Thread)

821 Fn->addFnAttr("no_sanitize_thread");

822 }

823 }

824

826 CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);

827 } else {

828

829 if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))

830 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);

831 if (SanOpts.hasOneOf(SanitizerKind::HWAddress |

832 SanitizerKind::KernelHWAddress))

833 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);

834 if (SanOpts.has(SanitizerKind::MemtagStack))

835 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);

836 if (SanOpts.has(SanitizerKind::Thread))

837 Fn->addFnAttr(llvm::Attribute::SanitizeThread);

838 if (SanOpts.has(SanitizerKind::Type))

839 Fn->addFnAttr(llvm::Attribute::SanitizeType);

840 if (SanOpts.has(SanitizerKind::NumericalStability))

841 Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);

842 if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))

843 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);

844 if (SanOpts.has(SanitizerKind::AllocToken))

845 Fn->addFnAttr(llvm::Attribute::SanitizeAllocToken);

846 }

847 if (SanOpts.has(SanitizerKind::SafeStack))

848 Fn->addFnAttr(llvm::Attribute::SafeStack);

849 if (SanOpts.has(SanitizerKind::ShadowCallStack))

850 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);

851

852 if (SanOpts.has(SanitizerKind::Realtime))

856 Fn->addFnAttr(llvm::Attribute::SanitizeRealtime);

858 Fn->addFnAttr(llvm::Attribute::SanitizeRealtimeBlocking);

859 }

860

861

862 if (SanOpts.hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink))

863 Fn->addFnAttr(llvm::Attribute::OptForFuzzing);

864

865

866

867 if (SanOpts.has(SanitizerKind::Thread)) {

868 if (const auto *OMD = dyn_cast_or_null(D)) {

869 const IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);

870 if (OMD->getMethodFamily() == OMF_dealloc ||

872 (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) {

874 }

875 }

876 }

877

878

879

880

881 if (D && SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {

884 }

885

886

887

888

889 if (D && SanOpts.has(SanitizerKind::Null))

890 if (FD && FD->getBody() &&

893

894

895 bool AlwaysXRayAttr = false;

896 if (const auto *XRayAttr = D ? D->getAttr() : nullptr) {

897 if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(

899 CGM.getCodeGenOpts().XRayInstrumentationBundle.has(

902 Fn->addFnAttr("function-instrument", "xray-always");

903 AlwaysXRayAttr = true;

904 }

905 if (XRayAttr->neverXRayInstrument())

906 Fn->addFnAttr("function-instrument", "xray-never");

907 if (const auto *LogArgs = D->getAttr())

909 Fn->addFnAttr("xray-log-args",

910 llvm::utostr(LogArgs->getArgumentCount()));

911 }

912 } else {

914 Fn->addFnAttr(

915 "xray-instruction-threshold",

916 llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));

917 }

918

920 if (CGM.getCodeGenOpts().XRayIgnoreLoops)

921 Fn->addFnAttr("xray-ignore-loops");

922

923 if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(

925 Fn->addFnAttr("xray-skip-exit");

926

927 if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(

929 Fn->addFnAttr("xray-skip-entry");

930

931 auto FuncGroups = CGM.getCodeGenOpts().XRayTotalFunctionGroups;

932 if (FuncGroups > 1) {

934 CurFn->getName().bytes_end());

935 auto Group = crc32(FuncName) % FuncGroups;

936 if (Group != CGM.getCodeGenOpts().XRaySelectedFunctionGroup &&

937 !AlwaysXRayAttr)

938 Fn->addFnAttr("function-instrument", "xray-never");

939 }

940 }

941

942 if (CGM.getCodeGenOpts().getProfileInstr() !=

943 llvm::driver::ProfileInstrKind::ProfileNone) {

944 switch (CGM.isFunctionBlockedFromProfileInstr(Fn, Loc)) {

946 Fn->addFnAttr(llvm::Attribute::SkipProfile);

947 break;

949 Fn->addFnAttr(llvm::Attribute::NoProfile);

950 break;

952 break;

953 }

954 }

955

956 unsigned Count, Offset;

957 StringRef Section;

958 if (const auto *Attr =

959 D ? D->getAttr() : nullptr) {

960 Count = Attr->getCount();

961 Offset = Attr->getOffset();

962 Section = Attr->getSection();

963 } else {

964 Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount;

965 Offset = CGM.getCodeGenOpts().PatchableFunctionEntryOffset;

966 }

967 if (Section.empty())

968 Section = CGM.getCodeGenOpts().PatchableFunctionEntrySection;

969 if (Count && Offset <= Count) {

970 Fn->addFnAttr("patchable-function-entry", std::to_string(Count - Offset));

971 if (Offset)

972 Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset));

973 if (!Section.empty())

974 Fn->addFnAttr("patchable-function-entry-section", Section);

975 }

976

977

978

979

980 if (CGM.getCodeGenOpts().HotPatch &&

981 getContext().getTargetInfo().getTriple().isX86() &&

982 getContext().getTargetInfo().getTriple().getEnvironment() !=

983 llvm::Triple::CODE16)

984 Fn->addFnAttr("patchable-function", "prologue-short-redirect");

985

986

987 if (CGM.getCodeGenOpts().NoUseJumpTables)

988 Fn->addFnAttr("no-jump-tables", "true");

989

990

991 if (CGM.getCodeGenOpts().NoInlineLineTables)

992 Fn->addFnAttr("no-inline-line-tables");

993

994

995 if (CGM.getCodeGenOpts().ProfileSampleAccurate)

996 Fn->addFnAttr("profile-sample-accurate");

997

998 if (CGM.getCodeGenOpts().SampleProfileFile.empty())

999 Fn->addFnAttr("use-sample-profile");

1000

1001 if (D && D->hasAttr())

1002 Fn->addFnAttr("cfi-canonical-jump-table");

1003

1004 if (D && D->hasAttr())

1005 Fn->addFnAttr(llvm::Attribute::NoProfile);

1006

1007 if (D && D->hasAttr())

1008 Fn->addFnAttr(llvm::Attribute::HybridPatchable);

1009

1010 if (D) {

1011

1012 if (auto *A = D->getAttr()) {

1013 switch (A->getThunkType()) {

1014 case FunctionReturnThunksAttr::Kind::Keep:

1015 break;

1016 case FunctionReturnThunksAttr::Kind::Extern:

1017 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);

1018 break;

1019 }

1020 } else if (CGM.getCodeGenOpts().FunctionReturnThunks)

1021 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);

1022 }

1023

1026 getContext().getTargetInfo().getTriple().isSPIRV()) ||

1029

1030 EmitKernelMetadata(FD, Fn);

1031 }

1032

1033 if (FD && FD->hasAttr()) {

1034 Fn->setMetadata("clspv_libclc_builtin",

1036 }

1037

1038

1039

1040 if (FD && SanOpts.has(SanitizerKind::Function)) {

1042 llvm::LLVMContext &Ctx = Fn->getContext();

1043 llvm::MDBuilder MDB(Ctx);

1044 Fn->setMetadata(

1045 llvm::LLVMContext::MD_func_sanitize,

1046 MDB.createRTTIPointerPrologue(

1048 }

1049 }

1050

1051

1052

1053 if (SanOpts.has(SanitizerKind::NullabilityReturn)) {

1054 auto Nullability = FnRetTy->getNullability();

1056 FnRetTy->isRecordType()) {

1057 if (!(SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) &&

1059 RetValNullabilityPrecondition =

1061 }

1062 }

1063

1064

1065

1066

1067

1068

1069

1070

1071

1072

1073

1074

1075

1076

1077

1078 if (FD &&

1082 Fn->addFnAttr(llvm::Attribute::NoRecurse);

1083

1085 llvm::fp::ExceptionBehavior FPExceptionBehavior =

1087 Builder.setDefaultConstrainedRounding(RM);

1088 Builder.setDefaultConstrainedExcept(FPExceptionBehavior);

1090 (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||

1091 RM != llvm::RoundingMode::NearestTiesToEven))) {

1092 Builder.setIsFPConstrained(true);

1093 Fn->addFnAttr(llvm::Attribute::StrictFP);

1094 }

1095

1096

1097

1099 CGM.getCodeGenOpts().StackAlignment))

1100 Fn->addFnAttr("stackrealign");

1101

1102

1103 if (FD && FD->isMain())

1104 Fn->removeFnAttr("zero-call-used-regs");

1105

1106

1107 llvm::StringMap FeatureMap;

1109 if (FD) {

1112 if (T->getAArch64SMEAttributes() &

1115

1118 }

1119 std::optional<std::pair<unsigned, unsigned>> VScaleRange =

1121 &FeatureMap);

1122 if (VScaleRange) {

1123 CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(

1124 getLLVMContext(), VScaleRange->first, VScaleRange->second));

1125 }

1126

1128

1129

1130

1131

1132 llvm::Value *Poison = llvm::PoisonValue::get(Int32Ty);

1134

1136

1137 Builder.SetInsertPoint(EntryBB);

1138

1139

1140

1141 if (requiresReturnValueCheck()) {

1143 Builder.CreateStore(llvm::ConstantPointerNull::get(Int8PtrTy),

1144 ReturnLocation);

1145 }

1146

1147

1149

1150

1151

1152 DI->emitFunctionStart(GD, Loc, StartLoc,

1153 DI->getFunctionType(FD, RetTy, Args), CurFn,

1155 }

1156

1158 if (CGM.getCodeGenOpts().InstrumentFunctions)

1159 CurFn->addFnAttr("instrument-function-entry", "__cyg_profile_func_enter");

1160 if (CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining)

1161 CurFn->addFnAttr("instrument-function-entry-inlined",

1162 "__cyg_profile_func_enter");

1163 if (CGM.getCodeGenOpts().InstrumentFunctionEntryBare)

1164 CurFn->addFnAttr("instrument-function-entry-inlined",

1165 "__cyg_profile_func_enter_bare");

1166 }

1167

1168

1169

1170

1171

1172 if (CGM.getCodeGenOpts().InstrumentForProfiling) {

1173

1174

1176 if (CGM.getCodeGenOpts().CallFEntry)

1177 Fn->addFnAttr("fentry-call", "true");

1178 else {

1179 Fn->addFnAttr("instrument-function-entry-inlined",

1181 }

1182 if (CGM.getCodeGenOpts().MNopMCount) {

1183 if (CGM.getCodeGenOpts().CallFEntry)

1184 CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)

1185 << "-mnop-mcount" << "-mfentry";

1186 Fn->addFnAttr("mnop-mcount");

1187 }

1188

1189 if (CGM.getCodeGenOpts().RecordMCount) {

1190 if (CGM.getCodeGenOpts().CallFEntry)

1191 CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)

1192 << "-mrecord-mcount" << "-mfentry";

1193 Fn->addFnAttr("mrecord-mcount");

1194 }

1195 }

1196 }

1197

1198 if (CGM.getCodeGenOpts().PackedStack) {

1199 if (getContext().getTargetInfo().getTriple().getArch() !=

1200 llvm::Triple::systemz)

1201 CGM.getDiags().Report(diag::err_opt_not_valid_on_target)

1202 << "-mpacked-stack";

1203 Fn->addFnAttr("packed-stack");

1204 }

1205

1206 if (CGM.getCodeGenOpts().WarnStackSize != UINT_MAX &&

1207 CGM.getDiags().isIgnored(diag::warn_fe_backend_frame_larger_than, Loc))

1208 Fn->addFnAttr("warn-stack-size",

1209 std::to_string(CGM.getCodeGenOpts().WarnStackSize));

1210

1212

1214

1215

1217 ++NumReturnExprs;

1219

1220

1221 auto AI = CurFn->arg_begin();

1222 if (CurFnInfo->getReturnInfo().isSRetAfterThis())

1223 ++AI;

1225 &*AI, RetTy, CurFnInfo->getReturnInfo().getIndirectAlign(), false,

1227 if (CurFnInfo->getReturnInfo().getIndirectByVal()) {

1232 }

1235

1236 unsigned Idx = CurFnInfo->getReturnInfo().getInAllocaFieldIndex();

1237 llvm::Function::arg_iterator EI = CurFn->arg_end();

1238 --EI;

1239 llvm::Value *Addr = Builder.CreateStructGEP(

1240 CurFnInfo->getArgStruct(), &*EI, Idx);

1241 llvm::Type *Ty =

1247 } else {

1249

1250

1251

1252

1254 CurFnInfo->isReturnsRetained() &&

1257 }

1258

1260

1262

1263

1265 CGM.getOpenMPRuntime().emitFunctionProlog(*this, CurCodeDecl);

1266

1268

1269 if (FD->hasAttr()) {

1270 CGM.getHLSLRuntime().emitEntryFunction(FD, Fn);

1271 }

1272 }

1273

1275

1276 if (const CXXMethodDecl *MD = dyn_cast_if_present(D);

1278 bool IsInLambda =

1281 CGM.getCXXABI().EmitInstanceFunctionProlog(*this);

1282 if (IsInLambda) {

1283

1287

1288

1289

1290

1291

1292

1295

1296

1297 CXXThisValue = ThisFieldLValue.getPointer(*this);

1298 } else {

1299

1300

1301 CXXThisValue =

1303 }

1304 }

1306 if (FD->hasCapturedVLAType()) {

1309 auto VAT = FD->getCapturedVLAType();

1310 VLASizeMap[VAT->getSizeExpr()] = ExprArg;

1311 }

1312 }

1314

1315

1316

1317 CXXThisValue = CXXABIThisValue;

1318 }

1319

1320

1321 if (CXXABIThisValue) {

1323 SkippedChecks.set(SanitizerKind::ObjectSize, true);

1325

1326

1327

1328

1330 SkippedChecks.set(SanitizerKind::Null, true);

1331

1334 Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks);

1335 }

1336 }

1337

1338

1339

1340

1341 if (!FD || !FD->hasAttr()) {

1342 for (const VarDecl *VD : Args) {

1343

1344

1345

1347 if (const ParmVarDecl *PVD = dyn_cast(VD))

1348 Ty = PVD->getOriginalType();

1349 else

1350 Ty = VD->getType();

1351

1354 }

1355 }

1356

1358 DI->EmitLocation(Builder, StartLoc);

1359

1360

1362 if (const auto *VecWidth = CurFuncDecl->getAttr())

1363 LargestVectorWidth = VecWidth->getVectorWidth();

1364

1365 if (CGM.shouldEmitConvergenceTokens())

1367}

1368

1372 if (const CompoundStmt *S = dyn_cast(Body))

1374 else

1376}

1377

1378

1379

1380

1381

1383 const Stmt *S) {

1384 llvm::BasicBlock *SkipCountBB = nullptr;

1385

1386

1387 if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr() &&

1389

1390

1391

1394 }

1399 if (SkipCountBB)

1401}

1402

1403

1404

1405

1407

1408

1409 if (F->isInterposable()) return;

1410

1411 for (llvm::BasicBlock &BB : *F)

1412 for (llvm::Instruction &I : BB)

1413 if (I.mayThrow())

1414 return;

1415

1416 F->setDoesNotThrow();

1417}

1418

1423

1424 const CXXMethodDecl *MD = dyn_cast(FD);

1426 if (CGM.getCXXABI().HasThisReturn(GD))

1428 else if (CGM.getCXXABI().hasMostDerivedReturn(GD))

1429 ResTy = CGM.getContext().VoidPtrTy;

1430 CGM.getCXXABI().buildThisParam(*this, Args);

1431 }

1432

1433

1434

1435

1436 bool PassedParams = true;

1437 if (const CXXConstructorDecl *CD = dyn_cast(FD))

1438 if (auto Inherited = CD->getInheritedConstructor())

1439 PassedParams =

1441

1442 if (PassedParams) {

1443 for (auto *Param : FD->parameters()) {

1444 Args.push_back(Param);

1445 if (!Param->hasAttr())

1446 continue;

1447

1449 getContext(), Param->getDeclContext(), Param->getLocation(),

1451 SizeArguments[Param] = Implicit;

1453 }

1454 }

1455

1457 CGM.getCXXABI().addImplicitStructorParams(*this, ResTy, Args);

1458

1459 return ResTy;

1460}

1461

1464 assert(Fn && "generating code for null Function");

1467

1470

1471 CGM.getTargetCodeGenInfo().checkFunctionABI(CGM, FD);

1472

1474

1475

1476

1477 std::string FDInlineName = (Fn->getName() + ".inline").str();

1478 llvm::Module *M = Fn->getParent();

1479 llvm::Function *Clone = M->getFunction(FDInlineName);

1480 if (!Clone) {

1481 Clone = llvm::Function::Create(Fn->getFunctionType(),

1482 llvm::GlobalValue::InternalLinkage,

1483 Fn->getAddressSpace(), FDInlineName, M);

1484 Clone->addFnAttr(llvm::Attribute::AlwaysInline);

1485 }

1486 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);

1487 Fn = Clone;

1488 } else {

1489

1490

1491

1492

1493

1496 if (LLVM_UNLIKELY(PD->isInlineBuiltinDeclaration())) {

1497 std::string FDInlineName = (Fn->getName() + ".inline").str();

1498 llvm::Module *M = Fn->getParent();

1499 if (llvm::Function *Clone = M->getFunction(FDInlineName)) {

1500 Clone->replaceAllUsesWith(Fn);

1501 Clone->eraseFromParent();

1502 }

1503 break;

1504 }

1505 }

1506 }

1507

1508

1509 if (FD->hasAttr()) {

1510

1511

1512 Fn->setSubprogram(nullptr);

1513

1514 DebugInfo = nullptr;

1515 }

1516

1517 auto Cleanup = llvm::make_scope_exit([this] {

1519 DI->completeFunction();

1520 });

1521

1522

1523

1526 BodyRange = Body->getSourceRange();

1527 else

1529 CurEHLocation = BodyRange.getEnd();

1530

1531

1532

1533

1534

1535

1537

1538

1539

1541 if (SpecDecl->hasBody(SpecDecl))

1542 Loc = SpecDecl->getLocation();

1543

1545

1546 if (Body) {

1547

1549 ShouldEmitLifetimeMarkers = true;

1550

1551

1552

1553 if (ShouldEmitLifetimeMarkers)

1555 }

1556

1557

1558 StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin());

1559

1560

1561 if (Body && isa_and_nonnull(Body))

1563

1564

1565

1566

1567

1569 CurFn->addFnAttr(llvm::Attribute::MustProgress);

1570

1571

1572 PGO->assignRegionCounters(GD, CurFn);

1579 FD->hasAttr())

1580 CGM.getCUDARuntime().emitDeviceStub(*this, Args);

1583

1584

1591

1592

1593

1594

1595

1600

1601

1603 } else if (DeviceKernelAttr::isOpenCLSpelling(

1604 FD->getAttr()) &&

1607 for (unsigned i = 0; i < Args.size(); ++i) {

1609 QualType ArgQualType = Args[i]->getType();

1611 CallArgs.add(ArgRValue, ArgQualType);

1612 }

1615 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FT);

1616 const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionCall(

1617 CallArgs, FT, false);

1618 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FnInfo);

1619 llvm::Constant *GDStubFunctionPointer =

1620 CGM.getRawFunctionPointer(GDStub, FTy);

1623 Loc);

1624 } else if (Body) {

1626 } else

1627 llvm_unreachable("no definition for emitted function");

1628

1629

1630

1631

1632

1633

1634

1637 bool ShouldEmitUnreachable =

1638 CGM.getCodeGenOpts().StrictReturn ||

1640 if (SanOpts.has(SanitizerKind::Return)) {

1641 auto CheckOrdinal = SanitizerKind::SO_Return;

1642 auto CheckHandler = SanitizerHandler::MissingReturn;

1644 llvm::Value *IsFalse = Builder.getFalse();

1645 EmitCheck(std::make_pair(IsFalse, CheckOrdinal), CheckHandler,

1647 } else if (ShouldEmitUnreachable) {

1648 if (CGM.getCodeGenOpts().OptimizationLevel == 0)

1650 }

1651 if (SanOpts.has(SanitizerKind::Return) || ShouldEmitUnreachable) {

1652 Builder.CreateUnreachable();

1653 Builder.ClearInsertionPoint();

1654 }

1655 }

1656

1657

1659

1660 PGO->verifyCounterMap();

1661

1662

1663

1664 if (CurFn->doesNotThrow())

1666}

1667

1668

1669

1670

1672

1673 if (!S) return false;

1674

1675

1676

1677

1678

1679

1681 return true;

1682

1683

1684

1686 return true;

1687

1688

1690 IgnoreCaseStmts = true;

1691

1692

1695 return true;

1696

1697 return false;

1698}

1699

1700

1701

1702

1704

1705 if (!S) return false;

1706

1707

1708

1711 return false;

1712

1714 return true;

1715

1716

1719 return true;

1720

1721 return false;

1722}

1723

1725 if (!S) return false;

1726

1727

1728

1729

1730

1735 return false;

1736

1738 return true;

1739

1742 return true;

1743

1744 return false;

1745}

1746

1747

1748

1749

1751 bool &ResultBool,

1752 bool AllowLabels) {

1753

1754

1755

1756 if (!AllowLabels && CGM.getCodeGenOpts().hasProfileClangInstr() &&

1757 CGM.getCodeGenOpts().MCDCCoverage)

1758 return false;

1759

1760 llvm::APSInt ResultInt;

1762 return false;

1763

1764 ResultBool = ResultInt.getBoolValue();

1765 return true;

1766}

1767

1768

1769

1770

1772 llvm::APSInt &ResultInt,

1773 bool AllowLabels) {

1774

1775

1778 return false;

1779

1780 llvm::APSInt Int = Result.Val.getInt();

1782 return false;

1783

1784 PGO->markStmtMaybeUsed(Cond);

1785 ResultInt = Int;

1786 return true;

1787}

1788

1789

1791 while (const UnaryOperator *Op = dyn_cast(C->IgnoreParens())) {

1792 if (Op->getOpcode() != UO_LNot)

1793 break;

1794 C = Op->getSubExpr();

1795 }

1796 return C->IgnoreParens();

1797}

1798

1799

1800

1805

1806

1807

1808

1809

1812 llvm::BasicBlock *FalseBlock, uint64_t TrueCount ,

1814

1815 bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();

1818

1819 const Stmt *CntrStmt = (CntrIdx ? CntrIdx : Cond);

1820

1821 llvm::BasicBlock *ThenBlock = nullptr;

1822 llvm::BasicBlock *ElseBlock = nullptr;

1823 llvm::BasicBlock *NextBlock = nullptr;

1824

1825

1826 llvm::BasicBlock *CounterIncrBlock = createBasicBlock("lop.rhscnt");

1827

1828

1829

1830

1831

1832

1833

1834

1835

1836

1837

1838

1839

1840 if (LOp == BO_LAnd) {

1841 ThenBlock = CounterIncrBlock;

1842 ElseBlock = FalseBlock;

1843 NextBlock = TrueBlock;

1844 }

1845

1846

1847

1848

1849

1850

1851

1852

1853

1854

1855

1856

1857

1858 else if (LOp == BO_LOr) {

1859 ThenBlock = TrueBlock;

1860 ElseBlock = CounterIncrBlock;

1861 NextBlock = FalseBlock;

1862 } else {

1863 llvm_unreachable("Expected Opcode must be that of a Logical Operator");

1864 }

1865

1866

1868

1869

1871

1872

1874

1875

1877}

1878

1879

1880

1881

1882

1883

1884

1885

1887 const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock,

1889 const VarDecl *ConditionalDecl) {

1890 Cond = Cond->IgnoreParens();

1891

1892 if (const BinaryOperator *CondBOp = dyn_cast(Cond)) {

1893

1894 if (CondBOp->getOpcode() == BO_LAnd) {

1896

1897

1898

1899 bool ConstantBool = false;

1901 ConstantBool) {

1902

1905 FalseBlock, TrueCount, LH);

1907 return;

1908 }

1909

1910

1911

1913 ConstantBool) {

1914

1916 FalseBlock, TrueCount, LH, CondBOp);

1918 return;

1919 }

1920

1921

1922

1923 llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true");

1924

1925

1927

1929 {

1931

1932

1933

1937 }

1938

1941

1942

1943 eval.begin(*this);

1945 FalseBlock, TrueCount, LH);

1946 eval.end(*this);

1948 return;

1949 }

1950

1951 if (CondBOp->getOpcode() == BO_LOr) {

1953

1954

1955

1956 bool ConstantBool = false;

1958 !ConstantBool) {

1959

1962 FalseBlock, TrueCount, LH);

1964 return;

1965 }

1966

1967

1968

1970 !ConstantBool) {

1971

1973 FalseBlock, TrueCount, LH, CondBOp);

1975 return;

1976 }

1977

1978

1979 llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false");

1980

1981

1982

1983 uint64_t LHSCount =

1985 uint64_t RHSCount = TrueCount - LHSCount;

1986

1988 {

1989

1990

1991

1996 }

1997

2000

2001

2002 eval.begin(*this);

2004 RHSCount, LH);

2005

2006 eval.end(*this);

2008 return;

2009 }

2010 }

2011

2012 if (const UnaryOperator *CondUOp = dyn_cast(Cond)) {

2013

2014

2015

2016

2017 bool MCDCCondition = CGM.getCodeGenOpts().hasProfileClangInstr() &&

2018 CGM.getCodeGenOpts().MCDCCoverage &&

2020 if (CondUOp->getOpcode() == UO_LNot && !MCDCCondition) {

2021

2023

2025

2027 FalseCount, LH);

2028 }

2029 }

2030

2032

2034 llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");

2035

2036

2037

2041

2042

2043

2044

2045

2046

2047 uint64_t LHSScaledTrueCount = 0;

2048 if (TrueCount) {

2049 double LHSRatio =

2051 LHSScaledTrueCount = TrueCount * LHSRatio;

2052 }

2053

2054 cond.begin(*this);

2057 {

2060 LHSScaledTrueCount, LH, CondOp);

2061 }

2062 cond.end(*this);

2063

2064 cond.begin(*this);

2067 TrueCount - LHSScaledTrueCount, LH, CondOp);

2068 cond.end(*this);

2069

2070 return;

2071 }

2072

2073 if (const CXXThrowExpr *Throw = dyn_cast(Cond)) {

2074

2075

2076

2077

2078

2080 return;

2081 }

2082

2083

2084 llvm::Value *CondV;

2085 {

2088 }

2089

2091

2092

2093

2095 const Expr *MCDCBaseExpr = Cond;

2096

2097

2098

2099

2100

2101 if (ConditionalOp)

2102 MCDCBaseExpr = ConditionalOp;

2103

2105 }

2106

2107 llvm::MDNode *Weights = nullptr;

2108 llvm::MDNode *Unpredictable = nullptr;

2109

2110

2111

2112

2113 auto *Call = dyn_cast(Cond->IgnoreImpCasts());

2114 if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) {

2115 auto *FD = dyn_cast_or_null(Call->getCalleeDecl());

2116 if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {

2118 Unpredictable = MDHelper.createUnpredictable();

2119 }

2120 }

2121

2122

2123

2124 llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH);

2125 if (CondV != NewCondV)

2126 CondV = NewCondV;

2127 else {

2128

2130 Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount);

2131 }

2132

2133 llvm::Instruction *BrInst = Builder.CreateCondBr(CondV, TrueBlock, FalseBlock,

2134 Weights, Unpredictable);

2136

2138 case HLSLControlFlowHintAttr::Microsoft_branch:

2139 case HLSLControlFlowHintAttr::Microsoft_flatten: {

2140 llvm::MDBuilder MDHelper(CGM.getLLVMContext());

2141

2142 llvm::ConstantInt *BranchHintConstant =

2144 HLSLControlFlowHintAttr::Spelling::Microsoft_branch

2145 ? llvm::ConstantInt::get(CGM.Int32Ty, 1)

2146 : llvm::ConstantInt::get(CGM.Int32Ty, 2);

2147

2149 {MDHelper.createString("hlsl.controlflow.hint"),

2150 MDHelper.createConstant(BranchHintConstant)});

2151 BrInst->setMetadata("hlsl.controlflow.hint",

2152 llvm::MDNode::get(CGM.getLLVMContext(), Vals));

2153 break;

2154 }

2155

2156 case HLSLControlFlowHintAttr::SpellingNotCalculated:

2157 break;

2158 }

2159}

2160

2162 unsigned Idx,

2164 llvm::Value *Arg = nullptr;

2165 if ((ICEArguments & (1 << Idx)) == 0) {

2167 } else {

2168

2169

2170 std::optionalllvm::APSInt Result =

2172 assert(Result && "Expected argument to be a constant");

2174 }

2175 return Arg;

2176}

2177

2178

2179

2181 CGM.ErrorUnsupported(S, Type);

2182}

2183

2184

2185

2186

2187

2188

2189

2190

2193 llvm::Value *sizeInChars) {

2195

2197 llvm::Value *baseSizeInChars

2199

2201 llvm::Value *end = Builder.CreateInBoundsGEP(begin.getElementType(),

2203 sizeInChars, "vla.end");

2204

2205 llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock();

2206 llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop");

2207 llvm::BasicBlock *contBB = CGF.createBasicBlock("vla-init.cont");

2208

2209

2210

2212

2213 llvm::PHINode *cur = Builder.CreatePHI(begin.getType(), 2, "vla.cur");

2214 cur->addIncoming(begin.emitRawPointer(CGF), originBB);

2215

2218

2219

2220 Builder.CreateMemCpy(Address(cur, CGF.Int8Ty, curAlign), src, baseSizeInChars,

2221 false);

2222

2223

2224 llvm::Value *next =

2225 Builder.CreateInBoundsGEP(CGF.Int8Ty, cur, baseSizeInChars, "vla.next");

2226

2227

2228 llvm::Value *done = Builder.CreateICmpEQ(next, end, "vla-init.isdone");

2229 Builder.CreateCondBr(done, contBB, loopBB);

2230 cur->addIncoming(next, loopBB);

2231

2233}

2234

2235void

2237

2240 return;

2241

2244

2245

2247

2248 llvm::Value *SizeVal;

2250

2251

2252 if (size.isZero()) {

2253

2255 dyn_cast_or_null(

2258 SizeVal = VlaSize.NumElts;

2260 if (!eltSize.isOne())

2261 SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(eltSize));

2262 vla = vlaType;

2263 } else {

2264 return;

2265 }

2266 } else {

2267 SizeVal = CGM.getSize(size);

2268 vla = nullptr;

2269 }

2270

2271

2272

2273

2274

2275 if (CGM.getTypes().isZeroInitializable(Ty)) {

2276

2278

2279 llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty);

2280

2281 llvm::GlobalVariable *NullVariable =

2282 new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(),

2283 true,

2284 llvm::GlobalVariable::PrivateLinkage,

2285 NullConstant, Twine());

2287 NullVariable->setAlignment(NullAlign.getAsAlign());

2288 Address SrcPtr(NullVariable, Builder.getInt8Ty(), NullAlign);

2289

2290 if (vla) return emitNonZeroVLAInit(*this, Ty, DestPtr, SrcPtr, SizeVal);

2291

2292

2293 Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, false);

2294 return;

2295 }

2296

2297

2298

2299

2300 Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal, false);

2301}

2302

2304

2305 if (!IndirectBranch)

2307

2309

2310

2311 IndirectBranch->addDestination(BB);

2312 return llvm::BlockAddress::get(CurFn->getType(), BB);

2313}

2314

2316

2317 if (IndirectBranch) return IndirectBranch->getParent();

2318

2320

2321

2322 llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, 0,

2323 "indirect.goto.dest");

2324

2325

2326 IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);

2327 return IndirectBranch->getParent();

2328}

2329

2330

2331

2336

2337

2338

2339 llvm::Value *numVLAElements = nullptr;

2342

2343

2344

2345 do {

2348

2349

2351 baseType = elementType;

2352 return numVLAElements;

2353 }

2355

2356

2357

2358 }

2359

2360

2361

2362

2364

2365

2366 llvm::ConstantInt *zero = Builder.getInt32(0);

2367 gepIndices.push_back(zero);

2368

2369 uint64_t countFromCLAs = 1;

2371

2372 llvm::ArrayType *llvmArrayType =

2374 while (llvmArrayType) {

2377 llvmArrayType->getNumElements());

2378

2379 gepIndices.push_back(zero);

2380 countFromCLAs *= llvmArrayType->getNumElements();

2381 eltType = arrayType->getElementType();

2382

2383 llvmArrayType =

2384 dyn_castllvm::ArrayType(llvmArrayType->getElementType());

2386 assert((!llvmArrayType || arrayType) &&

2387 "LLVM and Clang types are out-of-synch");

2388 }

2389

2391

2392

2393

2396 eltType = arrayType->getElementType();

2398 }

2399

2400 llvm::Type *baseType = ConvertType(eltType);

2402 } else {

2403

2406 gepIndices, "array.begin"),

2408 }

2409

2410 baseType = eltType;

2411

2412 llvm::Value *numElements

2413 = llvm::ConstantInt::get(SizeTy, countFromCLAs);

2414

2415

2416 if (numVLAElements)

2417 numElements = Builder.CreateNUWMul(numVLAElements, numElements);

2418

2419 return numElements;

2420}

2421

2424 assert(vla && "type was not a variable array type!");

2426}

2427

2430

2431 llvm::Value *numElements = nullptr;

2432

2434 do {

2435 elementType = type->getElementType();

2436 llvm::Value *vlaSize = VLASizeMap[type->getSizeExpr()];

2437 assert(vlaSize && "no size for VLA!");

2438 assert(vlaSize->getType() == SizeTy);

2439

2440 if (!numElements) {

2441 numElements = vlaSize;

2442 } else {

2443

2444

2445 numElements = Builder.CreateNUWMul(numElements, vlaSize);

2446 }

2447 } while ((type = getContext().getAsVariableArrayType(elementType)));

2448

2449 return { numElements, elementType };

2450}

2451

2455 assert(vla && "type was not a variable array type!");

2457}

2458

2461 llvm::Value *VlaSize = VLASizeMap[Vla->getSizeExpr()];

2462 assert(VlaSize && "no size for VLA!");

2463 assert(VlaSize->getType() == SizeTy);

2465}

2466

2468 assert(type->isVariablyModifiedType() &&

2469 "Must pass variably modified type to EmitVLASizes!");

2470

2472

2473

2474

2475 do {

2476 assert(type->isVariablyModifiedType());

2477

2478 const Type *ty = type.getTypePtr();

2480

2481#define TYPE(Class, Base)

2482#define ABSTRACT_TYPE(Class, Base)

2483#define NON_CANONICAL_TYPE(Class, Base)

2484#define DEPENDENT_TYPE(Class, Base) case Type::Class:

2485#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)

2486#include "clang/AST/TypeNodes.inc"

2487 llvm_unreachable("unexpected dependent type!");

2488

2489

2490 case Type::Builtin:

2491 case Type::Complex:

2492 case Type::Vector:

2493 case Type::ExtVector:

2494 case Type::ConstantMatrix:

2495 case Type::Record:

2496 case Type::Enum:

2497 case Type::Using:

2498 case Type::TemplateSpecialization:

2499 case Type::ObjCTypeParam:

2500 case Type::ObjCObject:

2501 case Type::ObjCInterface:

2502 case Type::ObjCObjectPointer:

2503 case Type::BitInt:

2504 case Type::HLSLInlineSpirv:

2505 case Type::PredefinedSugar:

2506 llvm_unreachable("type class is never variably-modified!");

2507

2508 case Type::Adjusted:

2510 break;

2511

2512 case Type::Decayed:

2514 break;

2515

2516 case Type::Pointer:

2518 break;

2519

2520 case Type::BlockPointer:

2522 break;

2523

2524 case Type::LValueReference:

2525 case Type::RValueReference:

2527 break;

2528

2529 case Type::MemberPointer:

2531 break;

2532

2533 case Type::ArrayParameter:

2534 case Type::ConstantArray:

2535 case Type::IncompleteArray:

2536

2538 break;

2539

2540 case Type::VariableArray: {

2541

2543

2544

2545

2547

2548

2549 llvm::Value *&entry = VLASizeMap[sizeExpr];

2550 if (!entry) {

2552

2553

2554

2555

2556

2557 if (SanOpts.has(SanitizerKind::VLABound)) {

2558 auto CheckOrdinal = SanitizerKind::SO_VLABound;

2559 auto CheckHandler = SanitizerHandler::VLABoundNotPositive;

2561 llvm::Value *Zero = llvm::Constant::getNullValue(size->getType());

2563 llvm::Value *CheckCondition =

2567 llvm::Constant *StaticArgs[] = {

2570 EmitCheck(std::make_pair(CheckCondition, CheckOrdinal),

2571 CheckHandler, StaticArgs, size);

2572 }

2573

2574

2575

2576

2577 entry = Builder.CreateIntCast(size, SizeTy, false);

2578 }

2579 }

2581 break;

2582 }

2583

2584 case Type::FunctionProto:

2585 case Type::FunctionNoProto:

2587 break;

2588

2589 case Type::Paren:

2590 case Type::TypeOf:

2591 case Type::UnaryTransform:

2592 case Type::Attributed:

2593 case Type::BTFTagAttributed:

2594 case Type::HLSLAttributedResource:

2595 case Type::SubstTemplateTypeParm:

2596 case Type::MacroQualified:

2597 case Type::CountAttributed:

2598

2600 break;

2601

2602 case Type::Typedef:

2603 case Type::Decltype:

2604 case Type::Auto:

2605 case Type::DeducedTemplateSpecialization:

2606 case Type::PackIndexing:

2607

2608 return;

2609

2610 case Type::TypeOfExpr:

2611

2613 return;

2614

2615 case Type::Atomic:

2617 break;

2618

2619 case Type::Pipe:

2621 break;

2622 }

2623 } while (type->isVariablyModifiedType());

2624}

2625

2627 if (getContext().getBuiltinVaListType()->isArrayType())

2630}

2631

2635

2638 assert(Init.hasValue() && "Invalid DeclRefExpr initializer!");

2640 if (CGM.getCodeGenOpts().hasReducedDebugInfo())

2641 Dbg->EmitGlobalVariable(E->getDecl(), Init);

2642}

2643

2646

2647

2648

2649

2653

2654

2656 llvm::Instruction *inst = new llvm::BitCastInst(value, value->getType(), "",

2657 Builder.GetInsertBlock());

2658

2660 protection.Inst = inst;

2661 return protection;

2662}

2663

2665 if (!protection.Inst) return;

2666

2667

2668 protection.Inst->eraseFromParent();

2669}

2670

2674 llvm::Value *Alignment,

2675 llvm::Value *OffsetValue) {

2676 if (Alignment->getType() != IntPtrTy)

2677 Alignment =

2678 Builder.CreateIntCast(Alignment, IntPtrTy, false, "casted.align");

2679 if (OffsetValue && OffsetValue->getType() != IntPtrTy)

2680 OffsetValue =

2681 Builder.CreateIntCast(OffsetValue, IntPtrTy, true, "casted.offset");

2682 llvm::Value *TheCheck = nullptr;

2683 if (SanOpts.has(SanitizerKind::Alignment)) {

2684 llvm::Value *PtrIntValue =

2686

2687 if (OffsetValue) {

2688 bool IsOffsetZero = false;

2689 if (const auto *CI = dyn_castllvm::ConstantInt(OffsetValue))

2690 IsOffsetZero = CI->isZero();

2691

2692 if (!IsOffsetZero)

2693 PtrIntValue = Builder.CreateSub(PtrIntValue, OffsetValue, "offsetptr");

2694 }

2695

2696 llvm::Value *Zero = llvm::ConstantInt::get(IntPtrTy, 0);

2697 llvm::Value *Mask =

2698 Builder.CreateSub(Alignment, llvm::ConstantInt::get(IntPtrTy, 1));

2699 llvm::Value *MaskedPtr = Builder.CreateAnd(PtrIntValue, Mask, "maskedptr");

2700 TheCheck = Builder.CreateICmpEQ(MaskedPtr, Zero, "maskcond");

2701 }

2702 llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(

2703 CGM.getDataLayout(), PtrValue, Alignment, OffsetValue);

2704

2705 if (SanOpts.has(SanitizerKind::Alignment))

2706 return;

2708 OffsetValue, TheCheck, Assumption);

2709}

2710

2712 const Expr *E,

2714 llvm::Value *Alignment,

2715 llvm::Value *OffsetValue) {

2718

2720 OffsetValue);

2721}

2722

2724 llvm::Value *AnnotatedVal,

2725 StringRef AnnotationStr,

2727 const AnnotateAttr *Attr) {

2729 AnnotatedVal,

2730 CGM.EmitAnnotationString(AnnotationStr),

2731 CGM.EmitAnnotationUnit(Location),

2732 CGM.EmitAnnotationLineNo(Location),

2733 };

2735 Args.push_back(CGM.EmitAnnotationArgs(Attr));

2736 return Builder.CreateCall(AnnotationFn, Args);

2737}

2738

2740 assert(D->hasAttr() && "no annotate attribute");

2741 for (const auto *I : D->specific_attrs())

2743 {V->getType(), CGM.ConstGlobalsPtrTy}),

2744 V, I->getAnnotation(), D->getLocation(), I);

2745}

2746

2749 assert(D->hasAttr() && "no annotate attribute");

2750 llvm::Value *V = Addr.emitRawPointer(*this);

2751 llvm::Type *VTy = V->getType();

2752 auto *PTy = dyn_castllvm::PointerType(VTy);

2753 unsigned AS = PTy ? PTy->getAddressSpace() : 0;

2754 llvm::PointerType *IntrinTy =

2755 llvm::PointerType::get(CGM.getLLVMContext(), AS);

2756 llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,

2757 {IntrinTy, CGM.ConstGlobalsPtrTy});

2758

2759 for (const auto *I : D->specific_attrs()) {

2760

2761

2762

2763 if (VTy != IntrinTy)

2764 V = Builder.CreateBitCast(V, IntrinTy);

2766 V = Builder.CreateBitCast(V, VTy);

2767 }

2768

2769 return Address(V, Addr.getElementType(), Addr.getAlignment());

2770}

2771

2773

2775 : CGF(CGF) {

2776 assert(!CGF->IsSanitizerScope);

2777 CGF->IsSanitizerScope = true;

2778}

2779

2781 CGF->IsSanitizerScope = false;

2782}

2783

2785 const llvm::Twine &Name,

2786 llvm::BasicBlock::iterator InsertPt) const {

2789 I->setNoSanitizeMetadata();

2790}

2791

2793 llvm::Instruction *I, const llvm::Twine &Name,

2794 llvm::BasicBlock::iterator InsertPt) const {

2795 llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, InsertPt);

2796 if (CGF)

2797 CGF->InsertHelper(I, Name, InsertPt);

2798}

2799

2800

2801

2804

2805

2806 if (CGM.getContext().getTargetInfo().getTriple().isX86()) {

2807 unsigned BuiltinID = TargetDecl->getBuiltinID();

2808 if (BuiltinID == X86::BI__builtin_ia32_cmpps ||

2809 BuiltinID == X86::BI__builtin_ia32_cmpss ||

2810 BuiltinID == X86::BI__builtin_ia32_cmppd ||

2811 BuiltinID == X86::BI__builtin_ia32_cmpsd) {

2813 llvm::StringMap TargetFetureMap;

2814 CGM.getContext().getFunctionFeatureMap(TargetFetureMap, FD);

2815 llvm::APSInt Result =

2816 *(E->getArg(2)->getIntegerConstantExpr(CGM.getContext()));

2817 if (Result.getSExtValue() > 7 && !TargetFetureMap.lookup("avx"))

2818 CGM.getDiags().Report(E->getBeginLoc(), diag::err_builtin_needs_feature)

2820 }

2821 }

2823}

2824

2825

2826

2829

2830 if (!TargetDecl)

2831 return;

2832

2833

2834

2836 if (!FD)

2837 return;

2838

2839 bool IsAlwaysInline = TargetDecl->hasAttr();

2840 bool IsFlatten = FD && FD->hasAttr();

2841

2842

2843

2844

2845 unsigned BuiltinID = TargetDecl->getBuiltinID();

2846 std::string MissingFeature;

2847 llvm::StringMap CallerFeatureMap;

2848 CGM.getContext().getFunctionFeatureMap(CallerFeatureMap, FD);

2849

2850

2851

2852

2854 if (BuiltinID) {

2855 StringRef FeatureList(CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID));

2857 FeatureList, CallerFeatureMap) && !IsHipStdPar) {

2858 CGM.getDiags().Report(Loc, diag::err_builtin_needs_feature)

2860 << FeatureList;

2861 }

2863 TargetDecl->hasAttr()) {

2864

2865

2866 const TargetAttr *TD = TargetDecl->getAttr();

2868 CGM.getContext().filterFunctionTargetAttrs(TD);

2869

2871 llvm::StringMap CalleeFeatureMap;

2872 CGM.getContext().getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);

2873

2874 for (const auto &F : ParsedAttr.Features) {

2875 if (F[0] == '+' && CalleeFeatureMap.lookup(F.substr(1)))

2876 ReqFeatures.push_back(StringRef(F).substr(1));

2877 }

2878

2879 for (const auto &F : CalleeFeatureMap) {

2880

2881 if (F.getValue())

2882 ReqFeatures.push_back(F.getKey());

2883 }

2884 if (!llvm::all_of(ReqFeatures,

2885 [&](StringRef Feature) {

2886 if (!CallerFeatureMap.lookup(Feature)) {

2887 MissingFeature = Feature.str();

2888 return false;

2889 }

2890 return true;

2891 }) &&

2892 !IsHipStdPar) {

2893 if (IsAlwaysInline)

2894 CGM.getDiags().Report(Loc, diag::err_function_needs_feature)

2896 else if (IsFlatten)

2897 CGM.getDiags().Report(Loc, diag::err_flatten_function_needs_feature)

2899 }

2900

2902 llvm::StringMap CalleeFeatureMap;

2903 CGM.getContext().getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);

2904

2905 for (const auto &F : CalleeFeatureMap) {

2906 if (F.getValue() &&

2907 (!CallerFeatureMap.lookup(F.getKey()) ||

2908 !CallerFeatureMap.find(F.getKey())->getValue()) &&

2909 !IsHipStdPar) {

2910 if (IsAlwaysInline)

2911 CGM.getDiags().Report(Loc, diag::err_function_needs_feature)

2913 else if (IsFlatten)

2914 CGM.getDiags().Report(Loc, diag::err_flatten_function_needs_feature)

2916 }

2917 }

2918 }

2919}

2920

2922 if (CGM.getCodeGenOpts().SanitizeStats)

2923 return;

2924

2925 llvm::IRBuilder<> IRB(Builder.GetInsertBlock(), Builder.GetInsertPoint());

2926 IRB.SetCurrentDebugLocation(Builder.getCurrentDebugLocation());

2927 CGM.getSanStats().create(IRB, SSK);

2928}

2929

2932 const CGCalleeInfo &CI = Callee.getAbstractInfo();

2934 if (!FP)

2935 return;

2936

2937 StringRef Salt;

2939 Salt = Info.CFISalt;

2940

2941 Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(FP->desugar(), Salt));

2942}

2943

2944llvm::Value *

2945CodeGenFunction::FormAArch64ResolverCondition(const FMVResolverOption &RO) {

2946 return RO.Features.empty() ? nullptr : EmitAArch64CpuSupports(RO.Features);

2947}

2948

2949llvm::Value *

2950CodeGenFunction::FormX86ResolverCondition(const FMVResolverOption &RO) {

2951 llvm::Value *Condition = nullptr;

2952

2953 if (RO.Architecture) {

2954 StringRef Arch = *RO.Architecture;

2955

2956

2957 if (Arch.starts_with("x86-64"))

2959 else

2961 }

2962

2963 if (!RO.Features.empty()) {

2964 llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Features);

2967 }

2969}

2970

2972 llvm::Function *Resolver,

2974 llvm::Function *FuncToReturn,

2975 bool SupportsIFunc) {

2976 if (SupportsIFunc) {

2977 Builder.CreateRet(FuncToReturn);

2978 return;

2979 }

2980

2982 llvm::make_pointer_range(Resolver->args()));

2983

2984 llvm::CallInst *Result = Builder.CreateCall(FuncToReturn, Args);

2985 Result->setTailCallKind(llvm::CallInst::TCK_MustTail);

2986

2987 if (Resolver->getReturnType()->isVoidTy())

2988 Builder.CreateRetVoid();

2989 else

2990 Builder.CreateRet(Result);

2991}

2992

2995

2996 llvm::Triple::ArchType ArchType =

2998

2999 switch (ArchType) {

3000 case llvm::Triple::x86:

3001 case llvm::Triple::x86_64:

3003 return;

3004 case llvm::Triple::aarch64:

3006 return;

3007 case llvm::Triple::riscv32:

3008 case llvm::Triple::riscv64:

3010 return;

3011

3012 default:

3013 assert(false && "Only implemented for x86, AArch64 and RISC-V targets");

3014 }

3015}

3016

3019

3020 if (getContext().getTargetInfo().getTriple().getOS() !=

3021 llvm::Triple::OSType::Linux) {

3022 CGM.getDiags().Report(diag::err_os_unsupport_riscv_fmv);

3023 return;

3024 }

3025

3026 llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);

3027 Builder.SetInsertPoint(CurBlock);

3029

3031 bool HasDefault = false;

3032 unsigned DefaultIndex = 0;

3033

3034

3035 for (unsigned Index = 0; Index < Options.size(); Index++) {

3036

3037 if (Options[Index].Features.empty()) {

3038 HasDefault = true;

3039 DefaultIndex = Index;

3040 continue;

3041 }

3042

3043 Builder.SetInsertPoint(CurBlock);

3044

3045

3046

3047

3048

3049

3050

3051

3052

3053

3054

3055

3056

3057

3058

3059

3060

3061

3062

3063

3064

3065

3068

3069 for (StringRef Feat : Options[Index].Features) {

3070 std::vectorstd::string FeatStr =

3072

3073 assert(FeatStr.size() == 1 && "Feature string not delimited");

3074

3075 std::string &CurrFeat = FeatStr.front();

3076 if (CurrFeat[0] == '+')

3077 TargetAttrFeats.push_back(CurrFeat.substr(1));

3078 }

3079

3080 if (TargetAttrFeats.empty())

3081 continue;

3082

3083 for (std::string &Feat : TargetAttrFeats)

3084 CurrTargetAttrFeats.push_back(Feat);

3085

3086 Builder.SetInsertPoint(CurBlock);

3088

3089 llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);

3090 CGBuilderTy RetBuilder(*this, RetBlock);

3092 Options[Index].Function, SupportsIFunc);

3093 llvm::BasicBlock *ElseBlock = createBasicBlock("resolver_else", Resolver);

3094

3095 Builder.SetInsertPoint(CurBlock);

3096 Builder.CreateCondBr(FeatsCondition, RetBlock, ElseBlock);

3097

3098 CurBlock = ElseBlock;

3099 }

3100

3101

3102 if (HasDefault) {

3103 Builder.SetInsertPoint(CurBlock);

3105 CGM, Resolver, Builder, Options[DefaultIndex].Function, SupportsIFunc);

3106 return;

3107 }

3108

3109

3110 Builder.SetInsertPoint(CurBlock);

3111 llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);

3112 TrapCall->setDoesNotReturn();

3113 TrapCall->setDoesNotThrow();

3114 Builder.CreateUnreachable();

3115 Builder.ClearInsertionPoint();

3116}

3117

3120 assert(!Options.empty() && "No multiversion resolver options found");

3121 assert(Options.back().Features.size() == 0 && "Default case must be last");

3123 assert(SupportsIFunc &&

3124 "Multiversion resolver requires target IFUNC support");

3125 bool AArch64CpuInitialized = false;

3126 llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);

3127

3129 Builder.SetInsertPoint(CurBlock);

3130 llvm::Value *Condition = FormAArch64ResolverCondition(RO);

3131

3132

3135 SupportsIFunc);

3136 return;

3137 }

3138

3139 if (!AArch64CpuInitialized) {

3140 Builder.SetInsertPoint(CurBlock, CurBlock->begin());

3141 EmitAArch64CpuInit();

3142 AArch64CpuInitialized = true;

3143 Builder.SetInsertPoint(CurBlock);

3144 }

3145

3146 llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);

3147 CGBuilderTy RetBuilder(*this, RetBlock);

3149 SupportsIFunc);

3152 }

3153

3154

3155 Builder.SetInsertPoint(CurBlock);

3156 llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);

3157 TrapCall->setDoesNotReturn();

3158 TrapCall->setDoesNotThrow();

3159 Builder.CreateUnreachable();

3160 Builder.ClearInsertionPoint();

3161}

3162

3165

3167

3168

3169 llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);

3170 Builder.SetInsertPoint(CurBlock);

3171 EmitX86CpuInit();

3172

3174 Builder.SetInsertPoint(CurBlock);

3175 llvm::Value *Condition = FormX86ResolverCondition(RO);

3176

3177

3179 assert(&RO == Options.end() - 1 &&

3180 "Default or Generic case must be last");

3182 SupportsIFunc);

3183 return;

3184 }

3185

3186 llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);

3187 CGBuilderTy RetBuilder(*this, RetBlock);

3189 SupportsIFunc);

3192 }

3193

3194

3195 Builder.SetInsertPoint(CurBlock);

3196 llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);

3197 TrapCall->setDoesNotReturn();

3198 TrapCall->setDoesNotThrow();

3199 Builder.CreateUnreachable();

3200 Builder.ClearInsertionPoint();

3201}

3202

3203

3204

3205

3206

3207

3208

3211 SourceLocation SecondaryLoc, llvm::Value *Alignment,

3212 llvm::Value *OffsetValue, llvm::Value *TheCheck,

3213 llvm::Instruction *Assumption) {

3214 assert(isa_and_nonnullllvm::CallInst(Assumption) &&

3216 llvm::Intrinsic::getOrInsertDeclaration(

3217 Builder.GetInsertBlock()->getParent()->getParent(),

3218 llvm::Intrinsic::assume) &&

3219 "Assumption should be a call to llvm.assume().");

3220 assert(&(Builder.GetInsertBlock()->back()) == Assumption &&

3221 "Assumption should be the last instruction of the basic block, "

3222 "since the basic block is still being generated.");

3223

3224 if (SanOpts.has(SanitizerKind::Alignment))

3225 return;

3226

3227

3228

3230 return;

3231

3232

3233

3234 Assumption->removeFromParent();

3235

3236 {

3237 auto CheckOrdinal = SanitizerKind::SO_Alignment;

3238 auto CheckHandler = SanitizerHandler::AlignmentAssumption;

3240

3241 if (!OffsetValue)

3242 OffsetValue = Builder.getInt1(false);

3243

3247 llvm::Value *DynamicData[] = {Ptr, Alignment, OffsetValue};

3248 EmitCheck({std::make_pair(TheCheck, CheckOrdinal)}, CheckHandler,

3249 StaticData, DynamicData);

3250 }

3251

3252

3253

3254 Builder.Insert(Assumption);

3255

3256}

3257

3260 return DI->SourceLocToDebugLoc(Location);

3261

3262 return llvm::DebugLoc();

3263}

3264

3265llvm::Value *

3266CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,

3268 switch (LH) {

3270 return Cond;

3273

3274

3276 return Cond;

3277 llvm::Type *CondTy = Cond->getType();

3278 assert(CondTy->isIntegerTy(1) && "expecting condition to be a boolean");

3279 llvm::Function *FnExpect =

3281 llvm::Value *ExpectedValueOfCond =

3282 llvm::ConstantInt::getBool(CondTy, LH == Stmt::LH_Likely);

3283 return Builder.CreateCall(FnExpect, {Cond, ExpectedValueOfCond},

3284 Cond->getName() + ".expval");

3285 }

3286 llvm_unreachable("Unknown Likelihood");

3287}

3288

3290 unsigned NumElementsDst,

3291 const llvm::Twine &Name) {

3293 unsigned NumElementsSrc = SrcTy->getNumElements();

3294 if (NumElementsSrc == NumElementsDst)

3295 return SrcVec;

3296

3297 std::vector ShuffleMask(NumElementsDst, -1);

3298 for (unsigned MaskIdx = 0;

3299 MaskIdx < std::min<>(NumElementsDst, NumElementsSrc); ++MaskIdx)

3300 ShuffleMask[MaskIdx] = MaskIdx;

3301

3302 return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name);

3303}

3304

3308 if (!PointerAuth.isSigned())

3309 return;

3310

3311 auto *Key = Builder.getInt32(PointerAuth.getKey());

3312

3313 llvm::Value *Discriminator = PointerAuth.getDiscriminator();

3314 if (!Discriminator)

3315 Discriminator = Builder.getSize(0);

3316

3317 llvm::Value *Args[] = {Key, Discriminator};

3318 Bundles.emplace_back("ptrauth", Args);

3319}

3320

3324 unsigned IntrinsicID) {

3325 if (!PointerAuth)

3327

3328 auto Key = CGF.Builder.getInt32(PointerAuth.getKey());

3329

3330 llvm::Value *Discriminator = PointerAuth.getDiscriminator();

3331 if (!Discriminator) {

3333 }

3334

3335

3336 auto OrigType = Pointer->getType();

3338

3339

3342

3343

3346}

3347

3348llvm::Value *

3354 llvm::Intrinsic::ptrauth_sign);

3355}

3356

3360 auto StripIntrinsic = CGF.CGM.getIntrinsic(llvm::Intrinsic::ptrauth_strip);

3361

3362 auto Key = CGF.Builder.getInt32(PointerAuth.getKey());

3363

3364 auto OrigType = Pointer->getType();

3367 return CGF.Builder.CreateIntToPtr(Pointer, OrigType);

3368}

3369

3370llvm::Value *

3375 }

3378 }

3379

3381 llvm::Intrinsic::ptrauth_auth);

3382}

3383

3385 llvm::Instruction *KeyInstruction, llvm::Value *Backup) {

3387 DI->addInstToCurrentSourceAtom(KeyInstruction, Backup);

3388}

3389

3391 llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom) {

3393 DI->addInstToSpecificSourceAtom(KeyInstruction, Backup, Atom);

3394}

3395

3397 llvm::Value *Backup) {

3400 DI->addInstToCurrentSourceAtom(KeyInstruction, Backup);

3401 }

3402}

Defines the clang::ASTContext interface.

This file provides some common utility functions for processing Lambda related AST Constructs.

Defines enum values for all the target-independent builtin functions.

static llvm::Value * EmitPointerAuthCommon(CodeGenFunction &CGF, const CGPointerAuthInfo &PointerAuth, llvm::Value *Pointer, unsigned IntrinsicID)

Definition CodeGenFunction.cpp:3321

static void CreateMultiVersionResolverReturn(CodeGenModule &CGM, llvm::Function *Resolver, CGBuilderTy &Builder, llvm::Function *FuncToReturn, bool SupportsIFunc)

Definition CodeGenFunction.cpp:2971

static llvm::Value * EmitStrip(CodeGenFunction &CGF, const CGPointerAuthInfo &PointerAuth, llvm::Value *Pointer)

Definition CodeGenFunction.cpp:3357

static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, Address dest, Address src, llvm::Value *sizeInChars)

emitNonZeroVLAInit - Emit the "zero" initialization of a variable-length array whose elements have a ...

Definition CodeGenFunction.cpp:2191

static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB)

Definition CodeGenFunction.cpp:354

static LValue makeNaturalAlignAddrLValue(llvm::Value *V, QualType T, bool ForPointeeType, bool MightBeSigned, CodeGenFunction &CGF, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

Definition CodeGenFunction.cpp:195

static void TryMarkNoThrow(llvm::Function *F)

Tries to mark the given function nounwind based on the non-existence of any throwing calls within it.

Definition CodeGenFunction.cpp:1406

static llvm::Constant * getPrologueSignature(CodeGenModule &CGM, const FunctionDecl *FD)

Return the UBSan prologue signature for FD if one is available.

Definition CodeGenFunction.cpp:745

static bool endsWithReturn(const Decl *F)

Determine whether the function F ends with a return stmt.

Definition CodeGenFunction.cpp:682

static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts, const LangOptions &LangOpts)

shouldEmitLifetimeMarkers - Decide whether we need emit the life-time markers.

Definition CodeGenFunction.cpp:63

static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx)

Definition CodeGenFunction.cpp:711

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the Objective-C statement AST node classes.

Enumerates target-specific builtins in their own namespaces within namespace clang.

APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const

Get a function type and produce the equivalent function type with the specified exception specificati...

QualType getBaseElementType(const ArrayType *VAT) const

Return the innermost element type of an array type.

bool hasAnyFunctionEffects() const

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

CharUnits getTypeSizeInChars(QualType T) const

Return the size of the specified (complete) type T, in characters.

static bool hasSameType(QualType T1, QualType T2)

Determine whether the given types T1 and T2 are equivalent.

const VariableArrayType * getAsVariableArrayType(QualType T) const

QualType getSizeType() const

Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.

const TargetInfo & getTargetInfo() const

void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const

Represents an array type, per C99 6.7.5.2 - Array Declarators.

QualType getElementType() const

Attr - This represents one attribute.

A builtin binary operation expression such as "x + y" or "x <= y".

static bool isLogicalOp(Opcode Opc)

BinaryOperatorKind Opcode

Represents a C++ constructor within a class.

Represents a static or instance method of a struct/union/class.

bool isImplicitObjectMemberFunction() const

[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...

const CXXRecordDecl * getParent() const

Return the parent of this method declaration, which is the class in which this method is defined.

QualType getThisType() const

Return the type of the this pointer.

bool isLambda() const

Determine whether this class describes a lambda function object.

void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const

For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...

bool isCapturelessLambda() const

bool isEmpty() const

Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).

A C++ throw-expression (C++ [except.throw]).

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

Expr * getArg(unsigned Arg)

getArg - Return the specified argument.

SourceLocation getBeginLoc() const

CharUnits - This is an opaque type for sizes expressed in character units.

bool isZero() const

isZero - Test whether the quantity equals zero.

llvm::Align getAsAlign() const

getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

CharUnits alignmentOfArrayElement(CharUnits elementSize) const

Given that this is the alignment of the first element of an array, return the minimum alignment of an...

bool isOne() const

isOne - Test whether the quantity equals one.

CodeGenOptions - Track various options which control how the code is optimized and passed to the back...

@ InAlloca

InAlloca - Pass the argument directly using the LLVM inalloca attribute.

@ Indirect

Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...

Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...

llvm::Value * emitRawPointer(CodeGenFunction &CGF) const

Return the pointer contained in this class after authenticating it and adding offset to it if necessa...

CharUnits getAlignment() const

llvm::Type * getElementType() const

Return the type of the values stored in this address.

Address withElementType(llvm::Type *ElemTy) const

Return address with different element type, but same pointer and alignment.

llvm::PointerType * getType() const

Return the type of the pointer value.

A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.

A scoped helper to set the current debug location to the specified location or preferred location of ...

static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)

Apply TemporaryLocation if it is valid.

void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const override

This forwards to CodeGenFunction::InsertHelper.

Definition CodeGenFunction.cpp:2792

llvm::ConstantInt * getSize(CharUnits N)

@ RAA_DirectInMemory

Pass it on the stack using its defined layout.

virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0

Returns how an argument of the given record type should be passed.

Abstract information about a function or function prototype.

const FunctionProtoType * getCalleeFunctionProtoType() const

All available information about a concrete callee.

static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())

This class gathers all debug information during compilation and is responsible for emitting to llvm g...

CGFunctionInfo - Class to encapsulate the information about a function definition.

bool isDelegateCall() const

llvm::Value * getDiscriminator() const

CallArgList - Type for representing both the value and type of arguments in a call.

void add(RValue rvalue, QualType type)

virtual ~CGCapturedStmtInfo()

Definition CodeGenFunction.cpp:2772

~CGFPOptionsRAII()

Definition CodeGenFunction.cpp:188

CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures)

Definition CodeGenFunction.cpp:143

An object to manage conditionally-evaluated expressions.

void begin(CodeGenFunction &CGF)

void end(CodeGenFunction &CGF)

An object which temporarily prevents a value from being destroyed by aggressive peephole optimization...

~SanitizerScope()

Definition CodeGenFunction.cpp:2780

SanitizerScope(CodeGenFunction *CGF)

Definition CodeGenFunction.cpp:2774

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

void EmitRISCVMultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)

Definition CodeGenFunction.cpp:3017

GlobalDecl CurGD

CurGD - The GlobalDecl for the current function being compiled.

void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)

EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.

Definition CodeGenFunction.cpp:1886

void setCurrentProfileCount(uint64_t Count)

Set the profiler's current count.

llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")

Definition CodeGenFunction.cpp:3289

void EmitAArch64MultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)

Definition CodeGenFunction.cpp:3118

JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)

The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...

llvm::Value * EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx, const CallExpr *E)

Definition CodeGenFunction.cpp:2161

SanitizerSet SanOpts

Sanitizers enabled for this function.

void EmitNullInitialization(Address DestPtr, QualType Ty)

EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...

Definition CodeGenFunction.cpp:2236

RawAddress CreateIRTemp(QualType T, const Twine &Name="tmp")

CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.

void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl)

Definition CodeGenFunction.cpp:2802

static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)

ContainsLabel - Return true if the statement contains a label in it.

Definition CodeGenFunction.cpp:1671

bool ShouldSkipSanitizerInstrumentation()

ShouldSkipSanitizerInstrumentation - Return true if the current function should not be instrumented w...

Definition CodeGenFunction.cpp:580

llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)

Definition CodeGenFunction.cpp:2303

llvm::Value * EmitRISCVCpuSupports(const CallExpr *E)

llvm::Value * EmitRISCVCpuInit()

static bool hasScalarEvaluationKind(QualType T)

llvm::Type * ConvertType(QualType T)

Definition CodeGenFunction.cpp:240

void GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo)

Definition CodeGenFunction.cpp:1462

void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)

Definition CodeGenFunction.cpp:2921

void addInstToNewSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)

Add KeyInstruction and an optional Backup instruction to a new atom group (See ApplyAtomGroup for mor...

Definition CodeGenFunction.cpp:3396

FieldDecl * LambdaThisCaptureField

PeepholeProtection protectFromPeepholes(RValue rvalue)

protectFromPeepholes - Protect a value that we're intending to store to the side, but which will prob...

Definition CodeGenFunction.cpp:2645

void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD)

bool CurFuncIsThunk

In C++, whether we are code generating a thunk.

LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T)

Given a value of type T* that may not be to a complete object, construct an l-value with the natural ...

Definition CodeGenFunction.cpp:219

JumpDest getJumpDestForLabel(const LabelDecl *S)

getBasicBlockForLabel - Return the LLVM basicblock that the specified label maps to.

void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)

SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack

Stack to track the controlled convergence tokens.

void unprotectFromPeepholes(PeepholeProtection protection)

Definition CodeGenFunction.cpp:2664

RValue convertTempToRValue(Address addr, QualType type, SourceLocation Loc)

Given the address of a temporary variable, produce an r-value of its type.

llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)

Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...

llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack

llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)

createBasicBlock - Create an LLVM basic block.

void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)

See CGDebugInfo::addInstToCurrentSourceAtom.

Definition CodeGenFunction.cpp:3384

const LangOptions & getLangOpts() const

void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom)

See CGDebugInfo::addInstToSpecificSourceAtom.

Definition CodeGenFunction.cpp:3390

LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

Definition CodeGenFunction.cpp:211

void EmitVarAnnotations(const VarDecl *D, llvm::Value *V)

Emit local annotations for the local variable V, declared by D.

Definition CodeGenFunction.cpp:2739

llvm::BasicBlock * EHResumeBlock

EHResumeBlock - Unified block containing a call to llvm.eh.resume.

Address EmitFieldAnnotations(const FieldDecl *D, Address V)

Emit field annotations for the given field & value.

Definition CodeGenFunction.cpp:2747

void EmitConstructorBody(FunctionArgList &Args)

EmitConstructorBody - Emits the body of the current constructor.

void EmitKCFIOperandBundle(const CGCallee &Callee, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)

Definition CodeGenFunction.cpp:2930

void EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init)

Definition CodeGenFunction.cpp:2636

Address makeNaturalAddressForPointer(llvm::Value *Ptr, QualType T, CharUnits Alignment=CharUnits::Zero(), bool ForPointeeType=false, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

Construct an address with the natural alignment of T.

LValue MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, QualType T)

Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known to be unsigned.

Definition CodeGenFunction.cpp:230

@ TCK_ConstructorCall

Checking the 'this' pointer for a constructor call.

@ TCK_MemberCall

Checking the 'this' pointer for a call to a non-static member function.

const Decl * CurCodeDecl

CurCodeDecl - This is the inner-most code context, which includes blocks.

llvm::AssertingVH< llvm::Instruction > AllocaInsertPt

AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...

void EmitFunctionBody(const Stmt *Body)

Definition CodeGenFunction.cpp:1369

JumpDest ReturnBlock

ReturnBlock - Unified return block.

llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)

Converts Location to a DebugLoc, if debug information is enabled.

Definition CodeGenFunction.cpp:3258

llvm::Constant * EmitCheckTypeDescriptor(QualType T)

Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.

llvm::DebugLoc EmitReturnBlock()

Emit the unified return block, trying to avoid its emission when possible.

Definition CodeGenFunction.cpp:308

RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")

CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...

const TargetInfo & getTarget() const

llvm::Value * EmitAnnotationCall(llvm::Function *AnnotationFn, llvm::Value *AnnotatedVal, StringRef AnnotationStr, SourceLocation Location, const AnnotateAttr *Attr)

Emit an annotation call (intrinsic).

Definition CodeGenFunction.cpp:2723

Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())

void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, std::initializer_list< llvm::Value ** > ValuesToReload={})

Takes the old cleanup stack size and emits the cleanup blocks that have been added.

void maybeCreateMCDCCondBitmap()

Allocate a temp value on the stack that MCDC can use to track condition results.

void EmitIgnoredExpr(const Expr *E)

EmitIgnoredExpr - Emit an expression in a context which ignores the result.

RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)

EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...

static bool isInstrumentedCondition(const Expr *C)

isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....

Definition CodeGenFunction.cpp:1801

~CodeGenFunction()

Definition CodeGenFunction.cpp:94

VlaSizePair getVLAElements1D(const VariableArrayType *vla)

Return the number of elements for a single dimension for the given array type.

Definition CodeGenFunction.cpp:2460

bool AlwaysEmitXRayCustomEvents() const

AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit XRay custom event handling c...

Definition CodeGenFunction.cpp:594

void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())

Emit code for the start of a function.

Definition CodeGenFunction.cpp:753

llvm::Value * EmitPointerAuthSign(const CGPointerAuthInfo &Info, llvm::Value *Pointer)

Definition CodeGenFunction.cpp:3349

void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn)

Annotate the function with an attribute that disables TSan checking at runtime.

Definition CodeGenFunction.cpp:697

llvm::Value * EvaluateExprAsBool(const Expr *E)

EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...

void EmitPointerAuthOperandBundle(const CGPointerAuthInfo &Info, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)

Definition CodeGenFunction.cpp:3305

void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)

Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...

void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const

CGBuilder insert helper.

Definition CodeGenFunction.cpp:2784

SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack

Stack to track the Logical Operator recursion nest for MC/DC.

llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)

emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...

Definition CodeGenFunction.cpp:2332

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

bool AlwaysEmitXRayTypedEvents() const

AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit XRay typed event handling ...

Definition CodeGenFunction.cpp:601

CGDebugInfo * getDebugInfo()

void EmitStartEHSpec(const Decl *D)

EmitStartEHSpec - Emit the start of the exception spec.

void EmitDestructorBody(FunctionArgList &Args)

EmitDestructorBody - Emits the body of the current destructor.

void EmitX86MultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)

Definition CodeGenFunction.cpp:3163

bool ShouldInstrumentFunction()

ShouldInstrumentFunction - Return true if the current function should be instrumented with __cyg_prof...

Definition CodeGenFunction.cpp:570

void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)

Update the MCDC temp value with the condition's evaluated result.

void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue, llvm::Value *TheCheck, llvm::Instruction *Assumption)

Definition CodeGenFunction.cpp:3209

RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)

EmitCall - Generate a call of the given function, expecting the given result type,...

llvm::ConstantInt * getUBSanFunctionTypeHash(QualType T) const

Return a type hash constant for a function instrumented by -fsanitize=function.

Definition CodeGenFunction.cpp:609

void EmitBranchToCounterBlock(const Expr *Cond, BinaryOperator::Opcode LOp, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount=0, Stmt::Likelihood LH=Stmt::LH_None, const Expr *CntrIdx=nullptr)

EmitBranchToCounterBlock - Emit a conditional branch to a new block that increments a profile counter...

Definition CodeGenFunction.cpp:1810

void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)

Increment the profiler's counter for the given statement by StepV.

VlaSizePair getVLASize(const VariableArrayType *vla)

Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...

Definition CodeGenFunction.cpp:2429

ASTContext & getContext() const

void EmitMultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)

Definition CodeGenFunction.cpp:2993

const Decl * CurFuncDecl

CurFuncDecl - Holds the Decl for the current outermost non-closure context.

static const Expr * stripCond(const Expr *C)

Ignore parentheses and logical-NOT to track conditions consistently.

Definition CodeGenFunction.cpp:1790

void EmitFunctionProlog(const CGFunctionInfo &FI, llvm::Function *Fn, const FunctionArgList &Args)

EmitFunctionProlog - Emit the target specific LLVM code to load the arguments for the given function.

void SetFastMathFlags(FPOptions FPFeatures)

Set the codegen fast-math flags.

Definition CodeGenFunction.cpp:125

llvm::SmallVector< char, 256 > LifetimeExtendedCleanupStack

Address EmitVAListRef(const Expr *E)

Definition CodeGenFunction.cpp:2626

void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD)

Address ReturnValuePointer

ReturnValuePointer - The temporary alloca to hold a pointer to sret.

static bool mightAddDeclToScope(const Stmt *S)

Determine if the given statement might introduce a declaration into the current scope,...

Definition CodeGenFunction.cpp:1724

void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})

EmitStmt - Emit the code for the statement.

llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields

bool AutoreleaseResult

In ARC, whether we should autorelease the return value.

llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

uint64_t getCurrentProfileCount()

Get the profiler's current count.

llvm::Type * ConvertTypeForMem(QualType T)

Definition CodeGenFunction.cpp:236

void EmitEndEHSpec(const Decl *D)

EmitEndEHSpec - Emit the end of the exception spec.

LValue EmitLValueForLambdaField(const FieldDecl *Field)

CodeGenTypes & getTypes() const

static TypeEvaluationKind getEvaluationKind(QualType T)

getEvaluationKind - Return the TypeEvaluationKind of QualType T.

Definition CodeGenFunction.cpp:249

bool IsSanitizerScope

True if CodeGen currently emits code implementing sanitizer checks.

static bool containsBreak(const Stmt *S)

containsBreak - Return true if the statement contains a break out of it.

Definition CodeGenFunction.cpp:1703

void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)

HLSLControlFlowHintAttr::Spelling HLSLControlFlowAttr

HLSL Branch attribute.

void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)

llvm::SmallVector< const ParmVarDecl *, 4 > FnArgs

Save Parameter Decl for coroutine.

const TargetInfo & Target

void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, SourceLocation EndLoc, uint64_t RetKeyInstructionsSourceAtom)

EmitFunctionEpilog - Emit the target specific LLVM code to return the given temporary.

Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...

void EmitBranch(llvm::BasicBlock *Block)

EmitBranch - Emit a branch to the specified basic block from the current insert block,...

RawAddress NormalCleanupDest

i32s containing the indexes of the cleanup destinations.

llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)

Definition CodeGenFunction.cpp:244

VarBypassDetector Bypasses

llvm::BasicBlock * GetIndirectGotoBlock()

Definition CodeGenFunction.cpp:2315

EHScopeStack::stable_iterator PrologueCleanupDepth

PrologueCleanupDepth - The cleanup depth enclosing all the cleanups associated with the parameters.

Address EmitMSVAListRef(const Expr *E)

Emit a "reference" to a __builtin_ms_va_list; this is always the value of the expression,...

Definition CodeGenFunction.cpp:2632

llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)

EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...

llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)

Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.

LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

Definition CodeGenFunction.cpp:363

const CGFunctionInfo * CurFnInfo

uint64_t getProfileCount(const Stmt *S)

Get the profiler's count for the given statement.

Address GetAddrOfLocalVar(const VarDecl *VD)

GetAddrOfLocalVar - Return the address of a local variable.

bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)

ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...

Definition CodeGenFunction.cpp:1750

void ErrorUnsupported(const Stmt *S, const char *Type)

ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.

Definition CodeGenFunction.cpp:2180

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

EmitLValue - Emit code to compute a designator that specifies the location of the expression.

bool ShouldXRayInstrumentFunction() const

ShouldXRayInstrument - Return true if the current function should be instrumented with XRay nop sleds...

Definition CodeGenFunction.cpp:588

void EnsureInsertPoint()

EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.

llvm::LLVMContext & getLLVMContext()

bool SawAsmBlock

Whether we processed a Microsoft-style asm block during CodeGen.

bool checkIfFunctionMustProgress()

Returns true if a function must make progress, which means the mustprogress attribute can be added.

void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)

Definition CodeGenFunction.cpp:2671

void EmitVariablyModifiedType(QualType Ty)

EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...

Definition CodeGenFunction.cpp:2467

void MaybeEmitDeferredVarDeclInit(const VarDecl *var)

void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S)

When instrumenting to collect profile data, the counts for some blocks such as switch cases need to n...

Definition CodeGenFunction.cpp:1382

void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)

Definition CodeGenFunction.cpp:224

QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)

Definition CodeGenFunction.cpp:1419

llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)

Definition CodeGenFunction.cpp:3371

This class organizes the cross-function state that is used while generating LLVM code.

CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)

CodeGenTypes & getTypes()

const TargetCodeGenInfo & getTargetCodeGenInfo()

const CodeGenOptions & getCodeGenOpts() const

void GenKernelArgMetadata(llvm::Function *FN, const FunctionDecl *FD=nullptr, CodeGenFunction *CGF=nullptr)

OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument information in the program executab...

llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})

llvm::Type * ConvertType(QualType T)

ConvertType - Convert type T into a llvm::Type.

bool inheritingCtorHasParams(const InheritedConstructor &Inherited, CXXCtorType Type)

Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...

FunctionArgList - Type for representing both the decl and type of parameters to a function.

LValue - This represents an lvalue references.

llvm::Value * getPointer(CodeGenFunction &CGF) const

Address getAddress() const

RValue - This trivial value class is used to represent the result of an expression that is evaluated.

llvm::Value * getScalarVal() const

getScalarVal() - Return the Value* of this scalar value.

ReturnValueSlot - Contains the address where the return value of a function can be stored,...

virtual llvm::Constant * getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const

Return a constant used by UBSan as a signature to identify functions possessing type information,...

CompoundStmt - This represents a group of statements like { stmt stmt }.

ConditionalOperator - The ?

A reference to a declared variable, function, enum, etc.

Decl - This represents one declaration (or definition), e.g.

ASTContext & getASTContext() const LLVM_READONLY

Decl * getNonClosureContext()

Find the innermost non-closure ancestor of this declaration, walking up through blocks,...

llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const

SourceLocation getLocation() const

This represents one expression.

FPOptions getFPFeaturesInEffect(const LangOptions &LO) const

Returns the set of floating point options that apply to this expression.

std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const

isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

ExtVectorType - Extended vector type.

LangOptions::FPExceptionModeKind getExceptionMode() const

bool allowFPContractAcrossStatement() const

RoundingMode getRoundingMode() const

Represents a member of a struct/union/class.

Represents a function declaration or definition.

bool isMultiVersion() const

True if this function is considered a multiversioned function.

Stmt * getBody(const FunctionDecl *&Definition) const

Retrieve the body (definition) of the function.

unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const

Returns a value indicating whether this function corresponds to a builtin function.

bool UsesFPIntrin() const

Determine whether the function was declared in source context that requires constrained FP intrinsics...

bool usesSEHTry() const

Indicates the function uses __try.

QualType getReturnType() const

ArrayRef< ParmVarDecl * > parameters() const

FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const

Retrieve the function declaration from which this function could be instantiated, if it is an instant...

FunctionEffectsRef getFunctionEffects() const

bool isMSVCRTEntryPoint() const

Determines whether this function is a MSVCRT user defined entry point.

bool isInlineBuiltinDeclaration() const

Determine if this function provides an inline implementation of a builtin.

bool hasImplicitReturnZero() const

Whether falling off this function implicitly returns null/zero.

bool isMain() const

Determines whether this function is "main", which is the entry point into an executable program.

bool isDefaulted() const

Whether this function is defaulted.

OverloadedOperatorKind getOverloadedOperator() const

getOverloadedOperator - Which C++ overloaded operator this function represents, if any.

FunctionDecl * getPreviousDecl()

Return the previous declaration of this declaration or NULL if this is the first declaration.

Represents a prototype with parameter type info, e.g.

FunctionTypeExtraAttributeInfo getExtraAttributeInfo() const

Return the extra attribute information.

FunctionType - C99 6.7.5.3 - Function Declarators.

@ SME_PStateSMCompatibleMask

GlobalDecl - represents a global declaration.

CXXCtorType getCtorType() const

KernelReferenceKind getKernelReferenceKind() const

const Decl * getDecl() const

One of these records is kept for each identifier that is lexed.

bool isStr(const char(&Str)[StrLen]) const

Return true if this is the identifier for the specified string.

static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)

Create implicit parameter.

Represents the declaration of a label.

FPExceptionModeKind

Possible floating point exception behavior.

@ FPE_Strict

Strictly preserve the floating-point exception semantics.

@ FPE_MayTrap

Transformations do not cause new exceptions but may hide some.

@ FPE_Ignore

Assume that floating-point exceptions are masked.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

SanitizerSet Sanitize

Set of enabled sanitizers.

RoundingMode getDefaultRoundingMode() const

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

Represents a parameter to a function.

ParsedAttr - Represents a syntactic attribute.

PointerType - C99 6.7.5.1 - Pointer Declarators.

@ Forbid

Profiling is forbidden using the noprofile attribute.

@ Skip

Profiling is skipped using the skipprofile attribute.

@ Allow

Profiling is allowed.

A (possibly-)qualified type.

bool isVolatileQualified() const

Determine whether this type is volatile-qualified.

field_range fields() const

Encodes a location in the source.

A trivial tuple used to represent a source range.

Stmt - This represents one statement.

StmtClass getStmtClass() const

Likelihood

The likelihood of a branch being taken.

@ LH_Unlikely

Branch has the [[unlikely]] attribute.

@ LH_None

No attribute set or branches of the IfStmt have the same attribute.

@ LH_Likely

Branch has the [[likely]] attribute.

bool isMicrosoft() const

Is this ABI an MSVC-compatible ABI?

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

virtual std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts, ArmStreamingKind Mode, llvm::StringMap< bool > *FeatureMap=nullptr) const

Returns target-specific min and max values VScale_Range.

bool supportsIFunc() const

Identify whether this target supports IFuncs.

TargetCXXABI getCXXABI() const

Get the C++ ABI currently in use.

virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const

bool isSignedIntegerType() const

Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isVariablyModifiedType() const

Whether this type is a variably-modified type (C99 6.7.5).

TypeClass getTypeClass() const

const T * getAs() const

Member-template getAs'.

bool isObjCRetainableType() const

bool isFunctionNoProtoType() const

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

Represents a variable declaration or definition.

Represents a C array with a specified size that is not an integer-constant-expression.

Expr * getSizeExpr() const

QualType getElementType() const

Defines the clang::TargetInfo interface.

bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)

Returns true if the required target features of a builtin function are enabled.

@ 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 ...

TypeEvaluationKind

The kind of evaluation to perform on values of a particular type.

CGBuilderInserter CGBuilderInserterTy

constexpr XRayInstrMask Typed

constexpr XRayInstrMask FunctionExit

constexpr XRayInstrMask FunctionEntry

constexpr XRayInstrMask Custom

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const AstTypeMatcher< ArrayType > arrayType

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

@ NonNull

Values of this type can never be null.

nullptr

This class represents a compute construct, representing a 'Kind' of โ€˜parallelโ€™, 'serial',...

bool isLambdaCallOperator(const CXXMethodDecl *MD)

@ Result

The result type of a method or function.

const FunctionProtoType * T

llvm::fp::ExceptionBehavior ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind)

Definition CodeGenFunction.cpp:114

U cast(CodeGen::Address addr)

bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)

Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.

@ Other

Other implicit parameter.

@ EST_None

no exception specification

@ Implicit

An implicit conversion.

Diagnostic wrappers for TextAPI types for error reporting.

cl::opt< bool > EnableSingleByteCoverage

A jump destination is an abstract label, branching to which may require a jump out through normal cle...

llvm::BasicBlock * getBlock() const

This structure provides a set of types that are commonly used during IR emission.

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

llvm::IntegerType * SizeTy

llvm::IntegerType * Int32Ty

llvm::IntegerType * IntPtrTy

llvm::PointerType * Int8PtrTy

CharUnits getPointerAlign() const

EvalResult is a struct with detailed info about an evaluated expression.

A FunctionEffect plus a potential boolean expression determining whether the effect is declared (e....

Contains information gathered from parsing the contents of TargetAttr.

std::vector< std::string > Features

void set(SanitizerMask K, bool Value)

Enable or disable a certain (single) sanitizer.

bool has(SanitizerMask K) const

Check if a certain (single) sanitizer is enabled.