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/Frontend/OpenMP/OMPIRBuilder.h"

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

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

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

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

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

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

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

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

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

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

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

51#include

52

53using namespace clang;

54using namespace CodeGen;

55

56namespace llvm {

58}

59

60

61

64 if (CGOpts.DisableLifetimeMarkers)

65 return false;

66

67

68 if (CGOpts.SanitizeAddressUseAfterScope ||

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

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

71 return true;

72

73

74 return CGOpts.OptimizationLevel != 0;

75}

76

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

79 Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),

81 SanOpts(CGM.getLangOpts().Sanitize), CurFPFeatures(CGM.getLangOpts()),

82 DebugInfo(CGM.getModuleDebugInfo()), PGO(cgm),

83 ShouldEmitLifetimeMarkers(

85 if (!suppressNewContext)

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

87 EHStack.setCGF(this);

88

89 SetFastMathFlags(CurFPFeatures);

90}

91

92CodeGenFunction::~CodeGenFunction() {

95 "missed to deactivate a cleanup");

96

99

100

101

102

103

104

107}

108

109

110

111llvm::fp::ExceptionBehavior

113

114 switch (Kind) {

118 default:

119 llvm_unreachable("Unsupported FP Exception Behavior");

120 }

121}

122

124 llvm::FastMathFlags FMF;

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

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

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

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

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

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

132 Builder.setFastMathFlags(FMF);

133}

134

137 : CGF(CGF) {

139}

140

143 : CGF(CGF) {

144 ConstructorHelper(FPFeatures);

145}

146

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

148 OldFPFeatures = CGF.CurFPFeatures;

149 CGF.CurFPFeatures = FPFeatures;

150

151 OldExcept = CGF.Builder.getDefaultConstrainedExcept();

152 OldRounding = CGF.Builder.getDefaultConstrainedRounding();

153

154 if (OldFPFeatures == FPFeatures)

155 return;

156

157 FMFGuard.emplace(CGF.Builder);

158

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

160 CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);

161 auto NewExceptionBehavior =

164 CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);

165

166 CGF.SetFastMathFlags(FPFeatures);

167

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

169 isa(CGF.CurFuncDecl) ||

170 isa(CGF.CurFuncDecl) ||

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

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

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

174

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

176 auto OldValue =

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

178 auto NewValue = OldValue & Value;

179 if (OldValue != NewValue)

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

181 };

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

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

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

185 mergeFnAttrValue(

186 "unsafe-fp-math",

187 FPFeatures.getAllowFPReassociate() && FPFeatures.getAllowReciprocal() &&

188 FPFeatures.getAllowApproxFunc() && FPFeatures.getNoSignedZero() &&

190}

191

193 CGF.CurFPFeatures = OldFPFeatures;

194 CGF.Builder.setDefaultConstrainedExcept(OldExcept);

195 CGF.Builder.setDefaultConstrainedRounding(OldRounding);

196}

197

207 MightBeSigned

209 nullptr, IsKnownNonNull)

212}

213

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

218 true, *this,

219 IsKnownNonNull);

220}

221

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

225 true, *this);

226}

227

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

231 false, *this);

232}

233

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

237 false, *this);

238}

239

242}

243

246}

247

249 llvm::Type *LLVMTy) {

251}

252

254 type = type.getCanonicalType();

255 while (true) {

256 switch (type->getTypeClass()) {

257#define TYPE(name, parent)

258#define ABSTRACT_TYPE(name, parent)

259#define NON_CANONICAL_TYPE(name, parent) case Type:📛

260#define DEPENDENT_TYPE(name, parent) case Type:📛

261#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type:📛

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

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

264

265 case Type::Auto:

266 case Type::DeducedTemplateSpecialization:

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

268

269

270 case Type::Builtin:

271 case Type::Pointer:

272 case Type::BlockPointer:

273 case Type::LValueReference:

274 case Type::RValueReference:

275 case Type::MemberPointer:

276 case Type::Vector:

277 case Type::ExtVector:

278 case Type::ConstantMatrix:

279 case Type::FunctionProto:

280 case Type::FunctionNoProto:

281 case Type::Enum:

282 case Type::ObjCObjectPointer:

283 case Type::Pipe:

284 case Type::BitInt:

285 case Type::HLSLAttributedResource:

287

288

289 case Type::Complex:

291

292

293 case Type::ConstantArray:

294 case Type::IncompleteArray:

295 case Type::VariableArray:

296 case Type::Record:

297 case Type::ObjCObject:

298 case Type::ObjCInterface:

299 case Type::ArrayParameter:

301

302

303 case Type::Atomic:

304 type = cast(type)->getValueType();

305 continue;

306 }

307 llvm_unreachable("unknown type kind!");

308 }

309}

310

312

313

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

315

316 if (CurBB) {

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

318

319

320

325 } else

327 return llvm::DebugLoc();

328 }

329

330

331

332

334 llvm::BranchInst *BI =

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

338

339

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

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

342 BI->eraseFromParent();

345 return Loc;

346 }

347 }

348

349

350

351

352

354 return llvm::DebugLoc();

355}

356

358 if (!BB) return;

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

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

361 return;

362 }

363 delete BB;

364}

365

367 assert(BreakContinueStack.empty() &&

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

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

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

373

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

378 }

379

380 bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0

381 && NumSimpleReturnExprs == NumReturnExprs

383

384

385

386

387

388

389

390

391

392

393

394

396 if (OnlySimpleReturnStmts)

397 DI->EmitLocation(Builder, LastStopPoint);

398 else

399 DI->EmitLocation(Builder, EndLoc);

400 }

401

402

403

404

405

407 bool HasOnlyLifetimeMarkers =

409 bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers;

410

411 std::optional OAL;

412 if (HasCleanups) {

413

414

416 if (OnlySimpleReturnStmts)

417 DI->EmitLocation(Builder, EndLoc);

418 else

419

420

422 }

423

425 }

426

427

429

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

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

435 "__cyg_profile_func_exit");

436 }

437

438

441

442

443

447

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

450

451

452

453 if (IndirectBranch) {

454 EmitBlock(IndirectBranch->getParent());

455 Builder.ClearInsertionPoint();

456 }

457

458

459

460 if (!EscapedLocals.empty()) {

461

462

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

465 for (auto &Pair : EscapedLocals)

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

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

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

470 }

471

472

475 Ptr->eraseFromParent();

476

477

478

479 if (PostAllocaInsertPt) {

480 llvm::Instruction *PostPtr = PostAllocaInsertPt;

481 PostAllocaInsertPt = nullptr;

482 PostPtr->eraseFromParent();

483 }

484

485

486

487 if (IndirectBranch) {

488 llvm::PHINode *PN = castllvm::PHINode(IndirectBranch->getAddress());

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

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

491 PN->eraseFromParent();

492 }

493 }

494

496 EmitIfUsed(*this, TerminateLandingPad);

499

500 for (const auto &FuncletAndParent : TerminateFunclets)

501 EmitIfUsed(*this, FuncletAndParent.second);

502

504 EmitDeclMetadata();

505

506 for (const auto &R : DeferredReplacements) {

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

508 Old->replaceAllUsesWith(R.second);

509 castllvm::Instruction(Old)->eraseFromParent();

510 }

511 }

512 DeferredReplacements.clear();

513

514

515

516

517

518

519

521 llvm::DominatorTree DT(*CurFn);

522 llvm::PromoteMemToReg(

525 }

526

527

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

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

530 LargestVectorWidth =

531 std::max((uint64_t)LargestVectorWidth,

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

533

534

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

536 LargestVectorWidth =

537 std::max((uint64_t)LargestVectorWidth,

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

539

542

543

544

545

546

547

548

549

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

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

552 llvm::utostr(LargestVectorWidth));

553

554

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

557 if (VScaleRange) {

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

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

560 }

561

562

564 Builder.ClearInsertionPoint();

566 }

568 auto *RetAlloca =

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

571 RetAlloca->eraseFromParent();

573 }

574 }

575}

576

577

578

583 return false;

585 return false;

586 return true;

587}

588

591 return false;

593}

594

595

596

599}

600

601

602

608}

609

615}

616

617llvm::ConstantInt *

619

620

623 std::string Mangled;

624 llvm::raw_string_ostream Out(Mangled);

626 return llvm::ConstantInt::get(

628}

629

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

631 llvm::Function *Fn) {

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

633 return;

634

636

638

641 getContext().getTargetInfo().getTriple().isSPIRV())))

642 return;

643

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

645 QualType HintQTy = A->getTypeHint();

647 bool IsSignedInteger =

650 llvm::Metadata *AttrMDArgs[] = {

651 llvm::ConstantAsMetadata::get(llvm::UndefValue::get(

653 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(

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

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

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

657 }

658

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

660 llvm::Metadata *AttrMDArgs[] = {

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

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

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

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

665 }

666

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

668 llvm::Metadata *AttrMDArgs[] = {

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

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

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

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

673 }

674

675 if (const OpenCLIntelReqdSubGroupSizeAttr *A =

676 FD->getAttr()) {

677 llvm::Metadata *AttrMDArgs[] = {

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

679 Fn->setMetadata("intel_reqd_sub_group_size",

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

681 }

682}

683

684

686 const Stmt *Body = nullptr;

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

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

690 Body = OMD->getBody();

691

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

693 auto LastStmt = CS->body_rbegin();

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

695 return isa(*LastStmt);

696 }

697 return false;

698}

699

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

702 Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");

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

704 }

705}

706

707

708bool CodeGenFunction::requiresReturnValueCheck() const {

709 return requiresReturnValueNullabilityCheck() ||

712}

713

715 auto *MD = dyn_cast_or_null(D);

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

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

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

719 return false;

720

721 if (MD->parameters()[0]->getType().getCanonicalType() != Ctx.getSizeType())

722 return false;

723

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

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

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

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

728 return false;

729 }

730

731 return true;

732}

733

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

737}

738

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

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

744 });

745}

746

747

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

752 return nullptr;

754}

755

757 llvm::Function *Fn,

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

764

766

767 DidCallStackSave = false;

769 const FunctionDecl *FD = dyn_cast_or_null(D);

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

777

778

779

780 do {

781#define SANITIZER(NAME, ID) \

782 if (SanOpts.empty()) \

783 break; \

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

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

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

787

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

789#undef SANITIZER

790 } while (false);

791

792 if (D) {

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

795 bool NoSanitizeCoverage = false;

796

798 no_sanitize_mask |= Attr->getMask();

799

800 if (Attr->hasCoverage())

801 NoSanitizeCoverage = true;

802 }

803

804

806 if (no_sanitize_mask & SanitizerKind::Address)

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

808 if (no_sanitize_mask & SanitizerKind::KernelAddress)

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

810 if (no_sanitize_mask & SanitizerKind::HWAddress)

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

812 if (no_sanitize_mask & SanitizerKind::KernelHWAddress)

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

814

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

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

817

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

820

821

823 if (no_sanitize_mask & SanitizerKind::Thread)

824 Fn->addFnAttr("no_sanitize_thread");

825 }

826 }

827

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

830 } else {

831

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

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

835 SanitizerKind::KernelHWAddress))

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

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

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

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

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

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

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

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

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

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

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

847 }

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

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

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

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

852

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

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

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

860 }

861

862

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

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

865

866

867

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

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

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

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

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

875 }

876 }

877 }

878

879

880

881

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

885 }

886

887

888

889

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

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

894

895

898 Fn->addFnAttr("ptrauth-returns");

900 Fn->addFnAttr("ptrauth-calls");

902 Fn->addFnAttr("ptrauth-auth-traps");

904 Fn->addFnAttr("ptrauth-indirect-gotos");

906 Fn->addFnAttr("aarch64-jump-table-hardening");

907

908

909 bool AlwaysXRayAttr = false;

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

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

917 AlwaysXRayAttr = true;

918 }

919 if (XRayAttr->neverXRayInstrument())

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

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

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

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

925 }

926 } else {

928 Fn->addFnAttr(

929 "xray-instruction-threshold",

931 }

932

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

936

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

940

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

944

946 if (FuncGroups > 1) {

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

949 auto Group = crc32(FuncName) % FuncGroups;

951 !AlwaysXRayAttr)

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

953 }

954 }

955

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

960 break;

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

963 break;

965 break;

966 }

967 }

968

969 unsigned Count, Offset;

970 if (const auto *Attr =

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

972 Count = Attr->getCount();

973 Offset = Attr->getOffset();

974 } else {

977 }

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

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

980 if (Offset)

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

982 }

983

984

985

986

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

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

990 llvm::Triple::CODE16)

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

992

993

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

996

997

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

1000

1001

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

1004

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

1007

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

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

1010

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

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

1013

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

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

1016

1017 if (D) {

1018

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

1020 switch (A->getThunkType()) {

1021 case FunctionReturnThunksAttr::Kind::Keep:

1022 break;

1023 case FunctionReturnThunksAttr::Kind::Extern:

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

1025 break;

1026 }

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

1029 }

1030

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

1036

1037 EmitKernelMetadata(FD, Fn);

1038 }

1039

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

1041 Fn->setMetadata("clspv_libclc_builtin",

1043 }

1044

1045

1046

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

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

1050 llvm::MDBuilder MDB(Ctx);

1051 Fn->setMetadata(

1052 llvm::LLVMContext::MD_func_sanitize,

1053 MDB.createRTTIPointerPrologue(

1055 }

1056 }

1057

1058

1059

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

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

1066 RetValNullabilityPrecondition =

1068 }

1069 }

1070

1071

1072

1073

1074

1075

1076

1077

1078

1079

1080

1081

1082

1083

1084

1085 if (FD &&

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

1090

1092 llvm::fp::ExceptionBehavior FPExceptionBehavior =

1094 Builder.setDefaultConstrainedRounding(RM);

1095 Builder.setDefaultConstrainedExcept(FPExceptionBehavior);

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

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

1099 Builder.setIsFPConstrained(true);

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

1101 }

1102

1103

1104

1107 Fn->addFnAttr("stackrealign");

1108

1109

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

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

1112

1114

1115

1116

1117

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

1120

1122

1123 Builder.SetInsertPoint(EntryBB);

1124

1125

1126

1127 if (requiresReturnValueCheck()) {

1130 ReturnLocation);

1131 }

1132

1133

1135

1136

1137

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

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

1141 }

1142

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

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

1148 "__cyg_profile_func_enter");

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

1151 "__cyg_profile_func_enter_bare");

1152 }

1153

1154

1155

1156

1157

1159

1160

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

1164 else {

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

1167 }

1171 << "-mnop-mcount" << "-mfentry";

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

1173 }

1174

1178 << "-mrecord-mcount" << "-mfentry";

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

1180 }

1181 }

1182 }

1183

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

1186 llvm::Triple::systemz)

1188 << "-mpacked-stack";

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

1190 }

1191

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

1196

1198

1200

1201

1203 ++NumReturnExprs;

1205

1206

1207 auto AI = CurFn->arg_begin();

1209 ++AI;

1218 }

1221

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

1224 --EI;

1227 llvm::Type *Ty =

1228 castllvm::GetElementPtrInst(Addr)->getResultElementType();

1233 } else {

1235

1236

1237

1238

1243 }

1244

1246

1248

1249

1252

1254

1255 if (FD->hasAttr()) {

1257 }

1259 }

1260

1262

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

1265 bool IsInLambda =

1269 if (IsInLambda) {

1270

1274

1275

1276

1277

1278

1279

1282

1283

1284 CXXThisValue = ThisFieldLValue.getPointer(*this);

1285 } else {

1286

1287

1288 CXXThisValue =

1290 }

1291 }

1293 if (FD->hasCapturedVLAType()) {

1296 auto VAT = FD->getCapturedVLAType();

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

1298 }

1299 }

1301

1302

1303

1304 CXXThisValue = CXXABIThisValue;

1305 }

1306

1307

1308 if (CXXABIThisValue) {

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

1312

1313

1314

1315

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

1318

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

1322 }

1323 }

1324

1325

1326

1327

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

1329 for (const VarDecl *VD : Args) {

1330

1331

1332

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

1335 Ty = PVD->getOriginalType();

1336 else

1337 Ty = VD->getType();

1338

1341 }

1342 }

1343

1345 DI->EmitLocation(Builder, StartLoc);

1346

1347

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

1350 LargestVectorWidth = VecWidth->getVectorWidth();

1351

1354}

1355

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

1361 else

1363}

1364

1365

1366

1367

1368

1370 const Stmt *S) {

1371 llvm::BasicBlock *SkipCountBB = nullptr;

1372

1373

1376

1377

1378

1381 }

1386 if (SkipCountBB)

1388}

1389

1390

1391

1392

1394

1395

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

1397

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

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

1400 if (I.mayThrow())

1401 return;

1402

1403 F->setDoesNotThrow();

1404}

1405

1410

1411 const CXXMethodDecl *MD = dyn_cast(FD);

1418 }

1419

1420

1421

1422

1423 bool PassedParams = true;

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

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

1426 PassedParams =

1428

1429 if (PassedParams) {

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

1431 Args.push_back(Param);

1432 if (!Param->hasAttr())

1433 continue;

1434

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

1438 SizeArguments[Param] = Implicit;

1440 }

1441 }

1442

1443 if (MD && (isa(MD) || isa(MD)))

1445

1446 return ResTy;

1447}

1448

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

1454

1457

1459

1461

1462

1463

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

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

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

1467 if (!Clone) {

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

1469 llvm::GlobalValue::InternalLinkage,

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

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

1472 }

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

1474 Fn = Clone;

1475 } else {

1476

1477

1478

1479

1480

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

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

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

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

1487 Clone->replaceAllUsesWith(Fn);

1488 Clone->eraseFromParent();

1489 }

1490 break;

1491 }

1492 }

1493 }

1494

1495

1496 if (FD->hasAttr()) {

1497

1498

1499 Fn->setSubprogram(nullptr);

1500

1501 DebugInfo = nullptr;

1502 }

1503

1504

1505

1509 else

1511 CurEHLocation = BodyRange.getEnd();

1512

1513

1514

1515

1516

1517

1519

1520

1521

1523 if (SpecDecl->hasBody(SpecDecl))

1524 Loc = SpecDecl->getLocation();

1525

1527

1528 if (Body) {

1529

1530 if (isa(Body))

1531 ShouldEmitLifetimeMarkers = true;

1532

1533

1534

1535 if (ShouldEmitLifetimeMarkers)

1537 }

1538

1539

1541

1542

1543 if (Body && isa_and_nonnull(Body))

1545

1546

1547

1548

1549

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

1552

1553

1555 if (isa(FD))

1557 else if (isa(FD))

1561 FD->hasAttr())

1563 else if (isa(FD) &&

1564 cast(FD)->isLambdaStaticInvoker()) {

1565

1566

1568 } else if (isa(FD) &&

1571 cast(FD)->getParent()->getLambdaStaticInvoker() &&

1572 hasInAllocaArg(cast(FD))) {

1573

1574

1575

1576

1577

1579 } else if (FD->isDefaulted() && isa(FD) &&

1580 (cast(FD)->isCopyAssignmentOperator() ||

1581 cast(FD)->isMoveAssignmentOperator())) {

1582

1583

1585 } else if (Body) {

1587 } else

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

1589

1590

1591

1592

1593

1594

1595

1598 bool ShouldEmitUnreachable =

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

1602 SanitizerScope SanScope(this);

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

1604 EmitCheck(std::make_pair(IsFalse, SanitizerKind::SO_Return),

1605 SanitizerHandler::MissingReturn,

1607 } else if (ShouldEmitUnreachable) {

1610 }

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

1612 Builder.CreateUnreachable();

1613 Builder.ClearInsertionPoint();

1614 }

1615 }

1616

1617

1619

1621

1622

1623

1624 if (CurFn->doesNotThrow())

1626}

1627

1628

1629

1630

1632

1633 if (!S) return false;

1634

1635

1636

1637

1638

1639

1640 if (isa(S))

1641 return true;

1642

1643

1644

1645 if (isa(S) && !IgnoreCaseStmts)

1646 return true;

1647

1648

1649 if (isa(S))

1650 IgnoreCaseStmts = true;

1651

1652

1653 for (const Stmt *SubStmt : S->children())

1655 return true;

1656

1657 return false;

1658}

1659

1660

1661

1662

1664

1665 if (!S) return false;

1666

1667

1668

1669 if (isa(S) || isa(S) || isa(S) ||

1670 isa(S))

1671 return false;

1672

1673 if (isa(S))

1674 return true;

1675

1676

1677 for (const Stmt *SubStmt : S->children())

1679 return true;

1680

1681 return false;

1682}

1683

1685 if (!S) return false;

1686

1687

1688

1689

1690

1691 if (isa(S) || isa(S) || isa(S) ||

1692 isa(S) || isa(S) || isa(S) ||

1693 isa(S) || isa(S) ||

1694 isa(S) || isa(S))

1695 return false;

1696

1697 if (isa(S))

1698 return true;

1699

1700 for (const Stmt *SubStmt : S->children())

1702 return true;

1703

1704 return false;

1705}

1706

1707

1708

1709

1711 bool &ResultBool,

1712 bool AllowLabels) {

1713

1714

1715

1718 return false;

1719

1720 llvm::APSInt ResultInt;

1722 return false;

1723

1724 ResultBool = ResultInt.getBoolValue();

1725 return true;

1726}

1727

1728

1729

1730

1732 llvm::APSInt &ResultInt,

1733 bool AllowLabels) {

1734

1735

1738 return false;

1739

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

1742 return false;

1743

1745 ResultInt = Int;

1746 return true;

1747}

1748

1749

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

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

1753 break;

1754 C = Op->getSubExpr();

1755 }

1756 return C->IgnoreParens();

1757}

1758

1759

1760

1764}

1765

1766

1767

1768

1769

1772 llvm::BasicBlock *FalseBlock, uint64_t TrueCount ,

1774

1778

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

1780

1781 llvm::BasicBlock *ThenBlock = nullptr;

1782 llvm::BasicBlock *ElseBlock = nullptr;

1783 llvm::BasicBlock *NextBlock = nullptr;

1784

1785

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

1787

1788

1789

1790

1791

1792

1793

1794

1795

1796

1797

1798

1799

1800 if (LOp == BO_LAnd) {

1801 ThenBlock = CounterIncrBlock;

1802 ElseBlock = FalseBlock;

1803 NextBlock = TrueBlock;

1804 }

1805

1806

1807

1808

1809

1810

1811

1812

1813

1814

1815

1816

1817

1818 else if (LOp == BO_LOr) {

1819 ThenBlock = TrueBlock;

1820 ElseBlock = CounterIncrBlock;

1821 NextBlock = FalseBlock;

1822 } else {

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

1824 }

1825

1826

1828

1829

1831

1832

1834

1835

1837}

1838

1839

1840

1841

1842

1843

1844

1845

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

1850

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

1852

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

1855

1856

1857

1858 bool ConstantBool = false;

1860 ConstantBool) {

1861

1864 FalseBlock, TrueCount, LH);

1866 return;

1867 }

1868

1869

1870

1872 ConstantBool) {

1873

1875 FalseBlock, TrueCount, LH, CondBOp);

1877 return;

1878 }

1879

1880

1881

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

1883

1884

1886

1887 ConditionalEvaluation eval(*this);

1888 {

1890

1891

1892

1896 }

1897

1900

1901

1902 eval.begin(*this);

1904 FalseBlock, TrueCount, LH);

1905 eval.end(*this);

1907 return;

1908 }

1909

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

1912

1913

1914

1915 bool ConstantBool = false;

1917 !ConstantBool) {

1918

1921 FalseBlock, TrueCount, LH);

1923 return;

1924 }

1925

1926

1927

1929 !ConstantBool) {

1930

1932 FalseBlock, TrueCount, LH, CondBOp);

1934 return;

1935 }

1936

1937

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

1939

1940

1941

1944 uint64_t RHSCount = TrueCount - LHSCount;

1945

1946 ConditionalEvaluation eval(*this);

1947 {

1948

1949

1950

1955 }

1956

1959

1960

1961 eval.begin(*this);

1963 RHSCount, LH);

1964

1965 eval.end(*this);

1967 return;

1968 }

1969 }

1970

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

1972

1973

1974

1975

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

1980

1982

1984

1986 FalseCount, LH);

1987 }

1988 }

1989

1990 if (const ConditionalOperator *CondOp = dyn_cast(Cond)) {

1991

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

1994

1995

1996

1997 ConditionalEvaluation cond(*this);

2000

2001

2002

2003

2004

2005

2006 uint64_t LHSScaledTrueCount = 0;

2007 if (TrueCount) {

2008 double LHSRatio =

2010 LHSScaledTrueCount = TrueCount * LHSRatio;

2011 }

2012

2013 cond.begin(*this);

2016 {

2019 LHSScaledTrueCount, LH, CondOp);

2020 }

2021 cond.end(*this);

2022

2023 cond.begin(*this);

2026 TrueCount - LHSScaledTrueCount, LH, CondOp);

2027 cond.end(*this);

2028

2029 return;

2030 }

2031

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

2033

2034

2035

2036

2037

2039 return;

2040 }

2041

2042

2043 llvm::Value *CondV;

2044 {

2047 }

2048

2049

2050

2052 const Expr *MCDCBaseExpr = Cond;

2053

2054

2055

2056

2057

2058 if (ConditionalOp)

2059 MCDCBaseExpr = ConditionalOp;

2060

2062 }

2063

2064 llvm::MDNode *Weights = nullptr;

2065 llvm::MDNode *Unpredictable = nullptr;

2066

2067

2068

2069

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

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

2075 Unpredictable = MDHelper.createUnpredictable();

2076 }

2077 }

2078

2079

2080

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

2082 if (CondV != NewCondV)

2083 CondV = NewCondV;

2084 else {

2085

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

2088 }

2089

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

2091 Weights, Unpredictable);

2093 case HLSLControlFlowHintAttr::Microsoft_branch:

2094 case HLSLControlFlowHintAttr::Microsoft_flatten: {

2096

2097 llvm::ConstantInt *BranchHintConstant =

2099 HLSLControlFlowHintAttr::Spelling::Microsoft_branch

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

2102

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

2105 MDHelper.createConstant(BranchHintConstant)});

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

2108 break;

2109 }

2110

2111 case HLSLControlFlowHintAttr::SpellingNotCalculated:

2112 break;

2113 }

2114}

2115

2116

2117

2120}

2121

2122

2123

2124

2125

2126

2127

2128

2131 llvm::Value *sizeInChars) {

2133

2135 llvm::Value *baseSizeInChars

2137

2141 sizeInChars, "vla.end");

2142

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

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

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

2146

2147

2148

2150

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

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

2153

2156

2157

2159 false);

2160

2161

2162 llvm::Value *next =

2164

2165

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

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

2168 cur->addIncoming(next, loopBB);

2169

2171}

2172

2173void

2175

2178 if (cast(RT->getDecl())->isEmpty())

2179 return;

2180 }

2181 }

2182

2185

2186

2188

2189 llvm::Value *SizeVal;

2191

2192

2193 if (size.isZero()) {

2194

2196 dyn_cast_or_null(

2199 SizeVal = VlaSize.NumElts;

2201 if (!eltSize.isOne())

2203 vla = vlaType;

2204 } else {

2205 return;

2206 }

2207 } else {

2209 vla = nullptr;

2210 }

2211

2212

2213

2214

2215

2217

2219

2221

2222 llvm::GlobalVariable *NullVariable =

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

2224 true,

2225 llvm::GlobalVariable::PrivateLinkage,

2226 NullConstant, Twine());

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

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

2230

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

2232

2233

2235 return;

2236 }

2237

2238

2239

2240

2242}

2243

2245

2246 if (!IndirectBranch)

2248

2250

2251

2252 IndirectBranch->addDestination(BB);

2253 return llvm::BlockAddress::get(CurFn, BB);

2254}

2255

2257

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

2259

2261

2262

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

2264 "indirect.goto.dest");

2265

2266

2267 IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);

2268 return IndirectBranch->getParent();

2269}

2270

2271

2272

2277

2278

2279

2280 llvm::Value *numVLAElements = nullptr;

2281 if (isa(arrayType)) {

2283

2284

2285

2286 do {

2289

2290

2292 baseType = elementType;

2293 return numVLAElements;

2294 }

2295 } while (isa(arrayType));

2296

2297

2298

2299 }

2300

2301

2302

2303

2305

2306

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

2308 gepIndices.push_back(zero);

2309

2312

2313 llvm::ArrayType *llvmArrayType =

2315 while (llvmArrayType) {

2316 assert(isa(arrayType));

2317 assert(cast(arrayType)->getZExtSize() ==

2318 llvmArrayType->getNumElements());

2319

2320 gepIndices.push_back(zero);

2321 countFromCLAs *= llvmArrayType->getNumElements();

2322 eltType = arrayType->getElementType();

2323

2324 llvmArrayType =

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

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

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

2329 }

2330

2332

2333

2334

2336 countFromCLAs *= cast(arrayType)->getZExtSize();

2337 eltType = arrayType->getElementType();

2339 }

2340

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

2343 } else {

2344

2347 gepIndices, "array.begin"),

2349 }

2350

2351 baseType = eltType;

2352

2353 llvm::Value *numElements

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

2355

2356

2357 if (numVLAElements)

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

2359

2360 return numElements;

2361}

2362

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

2367}

2368

2369CodeGenFunction::VlaSizePair

2371

2372 llvm::Value *numElements = nullptr;

2373

2375 do {

2376 elementType = type->getElementType();

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

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

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

2380

2381 if (!numElements) {

2382 numElements = vlaSize;

2383 } else {

2384

2385

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

2387 }

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

2389

2390 return { numElements, elementType };

2391}

2392

2393CodeGenFunction::VlaSizePair

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

2398}

2399

2400CodeGenFunction::VlaSizePair

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

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

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

2406}

2407

2409 assert(type->isVariablyModifiedType() &&

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

2411

2413

2414

2415

2416 do {

2417 assert(type->isVariablyModifiedType());

2418

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

2421

2422#define TYPE(Class, Base)

2423#define ABSTRACT_TYPE(Class, Base)

2424#define NON_CANONICAL_TYPE(Class, Base)

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

2426#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)

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

2428 llvm_unreachable("unexpected dependent type!");

2429

2430

2431 case Type::Builtin:

2432 case Type::Complex:

2433 case Type::Vector:

2434 case Type::ExtVector:

2435 case Type::ConstantMatrix:

2436 case Type::Record:

2437 case Type::Enum:

2438 case Type::Using:

2439 case Type::TemplateSpecialization:

2440 case Type::ObjCTypeParam:

2441 case Type::ObjCObject:

2442 case Type::ObjCInterface:

2443 case Type::ObjCObjectPointer:

2444 case Type::BitInt:

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

2446

2447 case Type::Elaborated:

2448 type = cast(ty)->getNamedType();

2449 break;

2450

2451 case Type::Adjusted:

2452 type = cast(ty)->getAdjustedType();

2453 break;

2454

2455 case Type::Decayed:

2456 type = cast(ty)->getPointeeType();

2457 break;

2458

2459 case Type::Pointer:

2460 type = cast(ty)->getPointeeType();

2461 break;

2462

2463 case Type::BlockPointer:

2464 type = cast(ty)->getPointeeType();

2465 break;

2466

2467 case Type::LValueReference:

2468 case Type::RValueReference:

2469 type = cast(ty)->getPointeeType();

2470 break;

2471

2472 case Type::MemberPointer:

2473 type = cast(ty)->getPointeeType();

2474 break;

2475

2476 case Type::ArrayParameter:

2477 case Type::ConstantArray:

2478 case Type::IncompleteArray:

2479

2480 type = cast(ty)->getElementType();

2481 break;

2482

2483 case Type::VariableArray: {

2484

2486

2487

2488

2490

2491

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

2493 if (!entry) {

2495

2496

2497

2498

2499

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

2501 SanitizerScope SanScope(this);

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

2504 llvm::Value *CheckCondition =

2506 ? Builder.CreateICmpSGT(size, Zero)

2507 : Builder.CreateICmpUGT(size, Zero);

2508 llvm::Constant *StaticArgs[] = {

2512 std::make_pair(CheckCondition, SanitizerKind::SO_VLABound),

2513 SanitizerHandler::VLABoundNotPositive, StaticArgs, size);

2514 }

2515

2516

2517

2518

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

2520 }

2521 }

2523 break;

2524 }

2525

2526 case Type::FunctionProto:

2527 case Type::FunctionNoProto:

2528 type = cast(ty)->getReturnType();

2529 break;

2530

2531 case Type::Paren:

2532 case Type::TypeOf:

2533 case Type::UnaryTransform:

2534 case Type::Attributed:

2535 case Type::BTFTagAttributed:

2536 case Type::HLSLAttributedResource:

2537 case Type::SubstTemplateTypeParm:

2538 case Type::MacroQualified:

2539 case Type::CountAttributed:

2540

2542 break;

2543

2544 case Type::Typedef:

2545 case Type::Decltype:

2546 case Type::Auto:

2547 case Type::DeducedTemplateSpecialization:

2548 case Type::PackIndexing:

2549

2550 return;

2551

2552 case Type::TypeOfExpr:

2553

2554 EmitIgnoredExpr(cast(ty)->getUnderlyingExpr());

2555 return;

2556

2557 case Type::Atomic:

2558 type = cast(ty)->getValueType();

2559 break;

2560

2561 case Type::Pipe:

2562 type = cast(ty)->getElementType();

2563 break;

2564 }

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

2566}

2567

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

2572}

2573

2576}

2577

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

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

2584}

2585

2586CodeGenFunction::PeepholeProtection

2588

2589

2590

2591

2592 if (!rvalue.isScalar()) return PeepholeProtection();

2594 if (!isallvm::ZExtInst(value)) return PeepholeProtection();

2595

2596

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

2599 Builder.GetInsertBlock());

2600

2601 PeepholeProtection protection;

2602 protection.Inst = inst;

2603 return protection;

2604}

2605

2607 if (!protection.Inst) return;

2608

2609

2610 protection.Inst->eraseFromParent();

2611}

2612

2616 llvm::Value *Alignment,

2617 llvm::Value *OffsetValue) {

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

2619 Alignment =

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

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

2622 OffsetValue =

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

2624 llvm::Value *TheCheck = nullptr;

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

2626 llvm::Value *PtrIntValue =

2628

2629 if (OffsetValue) {

2630 bool IsOffsetZero = false;

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

2632 IsOffsetZero = CI->isZero();

2633

2634 if (!IsOffsetZero)

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

2636 }

2637

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

2639 llvm::Value *Mask =

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

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

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

2643 }

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

2646

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

2648 return;

2650 OffsetValue, TheCheck, Assumption);

2651}

2652

2656 llvm::Value *Alignment,

2657 llvm::Value *OffsetValue) {

2660

2662 OffsetValue);

2663}

2664

2666 llvm::Value *AnnotatedVal,

2667 StringRef AnnotationStr,

2669 const AnnotateAttr *Attr) {

2671 AnnotatedVal,

2675 };

2678 return Builder.CreateCall(AnnotationFn, Args);

2679}

2680

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

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

2687}

2688

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

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

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

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

2696 llvm::PointerType *IntrinTy =

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

2700

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

2702

2703

2704

2705 if (VTy != IntrinTy)

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

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

2709 }

2710

2712}

2713

2715

2717 : CGF(CGF) {

2720}

2721

2723 CGF->IsSanitizerScope = false;

2724}

2725

2727 const llvm::Twine &Name,

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

2731 I->setNoSanitizeMetadata();

2732}

2733

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

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

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

2738 if (CGF)

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

2740}

2741

2742

2743

2746

2747

2749 unsigned BuiltinID = TargetDecl->getBuiltinID();

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

2751 BuiltinID == X86::BI__builtin_ia32_cmpss ||

2752 BuiltinID == X86::BI__builtin_ia32_cmppd ||

2753 BuiltinID == X86::BI__builtin_ia32_cmpsd) {

2755 llvm::StringMap TargetFetureMap;

2757 llvm::APSInt Result =

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

2762 }

2763 }

2765}

2766

2767

2768

2771

2772 if (!TargetDecl)

2773 return;

2774

2775

2776

2778 if (!FD)

2779 return;

2780

2781

2782

2783

2784 unsigned BuiltinID = TargetDecl->getBuiltinID();

2785 std::string MissingFeature;

2786 llvm::StringMap CallerFeatureMap;

2788

2789

2790

2791

2793 if (BuiltinID) {

2796 FeatureList, CallerFeatureMap) && !IsHipStdPar) {

2799 << FeatureList;

2800 }

2802 TargetDecl->hasAttr()) {

2803

2804

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

2808

2810 llvm::StringMap CalleeFeatureMap;

2812

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

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

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

2816 }

2817

2818 for (const auto &F : CalleeFeatureMap) {

2819

2820 if (F.getValue())

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

2822 }

2823 if (!llvm::all_of(ReqFeatures, [&](StringRef Feature) {

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

2825 MissingFeature = Feature.str();

2826 return false;

2827 }

2828 return true;

2829 }) && !IsHipStdPar)

2833 llvm::StringMap CalleeFeatureMap;

2835

2836 for (const auto &F : CalleeFeatureMap) {

2837 if (F.getValue() && (!CallerFeatureMap.lookup(F.getKey()) ||

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

2839 !IsHipStdPar)

2842 }

2843 }

2844}

2845

2848 return;

2849

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

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

2853}

2854

2858 Callee.getAbstractInfo().getCalleeFunctionProtoType();

2859 if (FP)

2861}

2862

2863llvm::Value *

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

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

2866}

2867

2868llvm::Value *

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

2870 llvm::Value *Condition = nullptr;

2871

2872 if (RO.Architecture) {

2873 StringRef Arch = *RO.Architecture;

2874

2875

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

2877 Condition = EmitX86CpuSupports({Arch});

2878 else

2880 }

2881

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

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

2886 }

2888}

2889

2891 llvm::Function *Resolver,

2893 llvm::Function *FuncToReturn,

2894 bool SupportsIFunc) {

2895 if (SupportsIFunc) {

2896 Builder.CreateRet(FuncToReturn);

2897 return;

2898 }

2899

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

2902

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

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

2905

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

2907 Builder.CreateRetVoid();

2908 else

2910}

2911

2914

2915 llvm::Triple::ArchType ArchType =

2917

2918 switch (ArchType) {

2919 case llvm::Triple::x86:

2920 case llvm::Triple::x86_64:

2922 return;

2923 case llvm::Triple::aarch64:

2925 return;

2926 case llvm::Triple::riscv32:

2927 case llvm::Triple::riscv64:

2929 return;

2930

2931 default:

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

2933 }

2934}

2935

2938

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

2940 llvm::Triple::OSType::Linux) {

2942 return;

2943 }

2944

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

2946 Builder.SetInsertPoint(CurBlock);

2948

2950 bool HasDefault = false;

2951 unsigned DefaultIndex = 0;

2952

2953

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

2955

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

2957 HasDefault = true;

2958 DefaultIndex = Index;

2959 continue;

2960 }

2961

2962 Builder.SetInsertPoint(CurBlock);

2963

2964

2965

2966

2967

2968

2969

2970

2971

2972

2973

2974

2975

2976

2977

2978

2979

2980

2981

2982

2983

2984

2987

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

2989 std::vectorstd::string FeatStr =

2991

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

2993

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

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

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

2997 }

2998

2999 if (TargetAttrFeats.empty())

3000 continue;

3001

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

3003 CurrTargetAttrFeats.push_back(Feat);

3004

3005 Builder.SetInsertPoint(CurBlock);

3007

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

3009 CGBuilderTy RetBuilder(*this, RetBlock);

3011 Options[Index].Function, SupportsIFunc);

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

3013

3014 Builder.SetInsertPoint(CurBlock);

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

3016

3017 CurBlock = ElseBlock;

3018 }

3019

3020

3021 if (HasDefault) {

3022 Builder.SetInsertPoint(CurBlock);

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

3025 return;

3026 }

3027

3028

3029 Builder.SetInsertPoint(CurBlock);

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

3031 TrapCall->setDoesNotReturn();

3032 TrapCall->setDoesNotThrow();

3033 Builder.CreateUnreachable();

3034 Builder.ClearInsertionPoint();

3035}

3036

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

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

3042 assert(SupportsIFunc &&

3043 "Multiversion resolver requires target IFUNC support");

3044 bool AArch64CpuInitialized = false;

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

3046

3047 for (const FMVResolverOption &RO : Options) {

3048 Builder.SetInsertPoint(CurBlock);

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

3050

3051

3054 SupportsIFunc);

3055 return;

3056 }

3057

3058 if (!AArch64CpuInitialized) {

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

3060 EmitAArch64CpuInit();

3061 AArch64CpuInitialized = true;

3062 Builder.SetInsertPoint(CurBlock);

3063 }

3064

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

3066 CGBuilderTy RetBuilder(*this, RetBlock);

3068 SupportsIFunc);

3071 }

3072

3073

3074 Builder.SetInsertPoint(CurBlock);

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

3076 TrapCall->setDoesNotReturn();

3077 TrapCall->setDoesNotThrow();

3078 Builder.CreateUnreachable();

3079 Builder.ClearInsertionPoint();

3080}

3081

3084

3086

3087

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

3089 Builder.SetInsertPoint(CurBlock);

3090 EmitX86CpuInit();

3091

3092 for (const FMVResolverOption &RO : Options) {

3093 Builder.SetInsertPoint(CurBlock);

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

3095

3096

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

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

3101 SupportsIFunc);

3102 return;

3103 }

3104

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

3106 CGBuilderTy RetBuilder(*this, RetBlock);

3108 SupportsIFunc);

3111 }

3112

3113

3114 Builder.SetInsertPoint(CurBlock);

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

3116 TrapCall->setDoesNotReturn();

3117 TrapCall->setDoesNotThrow();

3118 Builder.CreateUnreachable();

3119 Builder.ClearInsertionPoint();

3120}

3121

3122

3123

3124

3125

3126

3127

3130 SourceLocation SecondaryLoc, llvm::Value *Alignment,

3131 llvm::Value *OffsetValue, llvm::Value *TheCheck,

3132 llvm::Instruction *Assumption) {

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

3134 castllvm::CallInst(Assumption)->getCalledOperand() ==

3135 llvm::Intrinsic::getOrInsertDeclaration(

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

3137 llvm::Intrinsic::assume) &&

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

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

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

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

3142

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

3144 return;

3145

3146

3147

3149 return;

3150

3151

3152

3153 Assumption->removeFromParent();

3154

3155 {

3156 SanitizerScope SanScope(this);

3157

3158 if (!OffsetValue)

3159 OffsetValue = Builder.getInt1(false);

3160

3167 EmitCheck({std::make_pair(TheCheck, SanitizerKind::SO_Alignment)},

3168 SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);

3169 }

3170

3171

3172

3173 Builder.Insert(Assumption);

3174

3175}

3176

3179 return DI->SourceLocToDebugLoc(Location);

3180

3181 return llvm::DebugLoc();

3182}

3183

3184llvm::Value *

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

3187 switch (LH) {

3189 return Cond;

3192

3193

3195 return Cond;

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

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

3198 llvm::Function *FnExpect =

3200 llvm::Value *ExpectedValueOfCond =

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

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

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

3204 }

3205 llvm_unreachable("Unknown Likelihood");

3206}

3207

3209 unsigned NumElementsDst,

3210 const llvm::Twine &Name) {

3211 auto *SrcTy = castllvm::FixedVectorType(SrcVec->getType());

3212 unsigned NumElementsSrc = SrcTy->getNumElements();

3213 if (NumElementsSrc == NumElementsDst)

3214 return SrcVec;

3215

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

3217 for (unsigned MaskIdx = 0;

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

3219 ShuffleMask[MaskIdx] = MaskIdx;

3220

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

3222}

3223

3227 if (!PointerAuth.isSigned())

3228 return;

3229

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

3231

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

3233 if (!Discriminator)

3235

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

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

3238}

3239

3243 unsigned IntrinsicID) {

3244 if (!PointerAuth)

3246

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

3248

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

3250 if (!Discriminator) {

3252 }

3253

3254

3255 auto OrigType = Pointer->getType();

3257

3258

3261

3262

3265}

3266

3267llvm::Value *

3273 llvm::Intrinsic::ptrauth_sign);

3274}

3275

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

3280

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

3282

3283 auto OrigType = Pointer->getType();

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

3287}

3288

3289llvm::Value *

3294 }

3297 }

3298

3300 llvm::Intrinsic::ptrauth_auth);

3301}

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)

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

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

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

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

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

static void TryMarkNoThrow(llvm::Function *F)

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

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

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

static bool endsWithReturn(const Decl *F)

Determine whether the function F ends with a return stmt.

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

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

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

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

llvm::MachO::Target Target

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

ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const

Parses the target attributes passed in, and returns only the ones that are valid feature names.

Builtin::Context & BuiltinInfo

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

CanQualType getSizeType() const

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

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.

const VariableArrayType * getAsVariableArrayType(QualType T) const

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)

const char * getRequiredFeatures(unsigned ID) const

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.

Represents a C++ struct/union/class.

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

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

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

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

std::string SampleProfileFile

Name of the profile file to use with -fprofile-sample-use.

bool hasProfileClangInstr() const

Check if Clang profile instrumenation is on.

XRayInstrSet XRayInstrumentationBundle

Set of XRay instrumentation kinds to emit.

bool hasSanitizeCoverage() const

PointerAuthOptions PointerAuth

Configuration for pointer-signing.

bool hasReducedDebugInfo() const

Check if type and variable info should be emitted.

bool hasSanitizeBinaryMetadata() const

unsigned getInAllocaFieldIndex() const

bool getIndirectByVal() const

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

bool isSRetAfterThis() const

CharUnits getIndirectAlign() const

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 debug location to the specified location or preferred location of ...

static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)

Apply TemporaryLocation if it is valid.

This is an IRBuilder insertion helper that forwards to CodeGenFunction::InsertHelper,...

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

This forwards to CodeGenFunction::InsertHelper.

llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)

llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)

Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")

llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)

llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")

llvm::ConstantInt * getSize(CharUnits N)

Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")

virtual void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args)=0

Emits a kernel launch stub.

Implements C++ ABI-specific code generation functions.

virtual bool hasMostDerivedReturn(GlobalDecl GD) const

virtual bool HasThisReturn(GlobalDecl GD) const

Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...

virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0

Emit the ABI-specific prolog for the function.

@ RAA_DirectInMemory

Pass it on the stack using its defined layout.

void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params)

Build a parameter variable suitable for 'this'.

virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0

Insert any ABI-specific implicit parameters into the parameter list for a function.

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

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

MangleContext & getMangleContext()

Gets the mangle context.

All available information about a concrete callee.

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.

ABIArgInfo & getReturnInfo()

bool isReturnsRetained() const

In ARC, whether this function retains its return value.

CanQualType getReturnType() const

bool isDelegateCall() const

unsigned getMaxVectorWidth() const

Return the maximum vector width in the arguments.

llvm::StructType * getArgStruct() const

Get the struct type used to represent all the arguments in memory.

void setHLSLFunctionAttributes(const FunctionDecl *FD, llvm::Function *Fn)

void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn)

virtual void functionFinished(CodeGenFunction &CGF)

Cleans up references to the objects in finished function.

llvm::OpenMPIRBuilder & getOMPBuilder()

virtual void emitFunctionProlog(CodeGenFunction &CGF, const Decl *D)

Emits OpenMP-specific function prolog.

llvm::Value * getDiscriminator() const

virtual ~CGCapturedStmtInfo()

CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures)

SanitizerScope(CodeGenFunction *CGF)

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

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

void EmitDestructorBody(FunctionArgList &Args)

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

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

void EmitNullInitialization(Address DestPtr, QualType Ty)

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

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

GlobalDecl CurGD

CurGD - The GlobalDecl for the current function being compiled.

static TypeEvaluationKind getEvaluationKind(QualType T)

getEvaluationKind - Return the TypeEvaluationKind of QualType T.

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

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

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

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

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

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

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

void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)

SanitizerSet SanOpts

Sanitizers enabled for this function.

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

void unprotectFromPeepholes(PeepholeProtection protection)

void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD)

bool ShouldInstrumentFunction()

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

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

static bool hasScalarEvaluationKind(QualType T)

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

FieldDecl * LambdaThisCaptureField

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

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

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

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

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

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

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

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

VlaSizePair getVLASize(const VariableArrayType *vla)

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

void EmitEndEHSpec(const Decl *D)

EmitEndEHSpec - Emit the end of the exception spec.

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

bool CurFuncIsThunk

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

SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack

Stack to track the controlled convergence tokens.

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

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

llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack

void EmitVariablyModifiedType(QualType Ty)

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

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

createBasicBlock - Create an LLVM basic block.

const LangOptions & getLangOpts() const

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

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

llvm::Constant * EmitCheckTypeDescriptor(QualType T)

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

llvm::BasicBlock * EHResumeBlock

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

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

EmitBlock - Emit the given block.

static bool isInstrumentedCondition(const Expr *C)

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

void EmitFunctionBody(const Stmt *Body)

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

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.

RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)

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

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

void setCurrentProfileCount(uint64_t Count)

Set the profiler's current count.

void EmitIgnoredExpr(const Expr *E)

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

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.

llvm::Type * ConvertTypeForMem(QualType T)

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

bool AlwaysEmitXRayCustomEvents() const

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

JumpDest ReturnBlock

ReturnBlock - Unified return block.

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

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

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

static const Expr * stripCond(const Expr *C)

Ignore parentheses and logical-NOT to track conditions consistently.

PeepholeProtection protectFromPeepholes(RValue rvalue)

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

const TargetInfo & getTarget() const

llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)

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

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.

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 EmitX86MultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)

llvm::Value * EmitRISCVCpuInit()

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

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

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

bool ShouldSkipSanitizerInstrumentation()

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

uint64_t getCurrentProfileCount()

Get the profiler's current count.

SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack

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

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.

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)

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

void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn)

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

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

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

CGDebugInfo * getDebugInfo()

Address EmitVAListRef(const Expr *E)

void EmitBranch(llvm::BasicBlock *Block)

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

void maybeCreateMCDCCondBitmap()

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

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

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

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

bool ShouldXRayInstrumentFunction() const

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

void EmitStartEHSpec(const Decl *D)

EmitStartEHSpec - Emit the start of the exception spec.

llvm::Value * EmitCheckValue(llvm::Value *V)

Convert a value into a format suitable for passing to a runtime sanitizer handler.

VlaSizePair getVLAElements1D(const VariableArrayType *vla)

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

bool AlwaysEmitXRayTypedEvents() const

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

void EmitConstructorBody(FunctionArgList &Args)

void SetFastMathFlags(FPOptions FPFeatures)

Set the codegen fast-math flags.

ASTContext & getContext() const

const Decl * CurFuncDecl

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

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

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

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

void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD)

llvm::SmallVector< char, 256 > LifetimeExtendedCleanupStack

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

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

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

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

Address ReturnValuePointer

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

llvm::ConstantInt * getUBSanFunctionTypeHash(QualType T) const

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

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

EmitStmt - Emit the code for the statement.

JumpDest getJumpDestForLabel(const LabelDecl *S)

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

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="")

llvm::Type * ConvertType(QualType T)

CodeGenTypes & getTypes() const

bool IsSanitizerScope

True if CodeGen currently emits code implementing sanitizer checks.

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.

QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)

RawAddress NormalCleanupDest

i32s containing the indexes of the cleanup destinations.

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

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

Address EmitMSVAListRef(const Expr *E)

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

VarBypassDetector Bypasses

EHScopeStack::stable_iterator PrologueCleanupDepth

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

static bool mightAddDeclToScope(const Stmt *S)

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

uint64_t getProfileCount(const Stmt *S)

Get the profiler's count for the given statement.

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

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

void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)

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

const CGFunctionInfo * CurFnInfo

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

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

CGBuilder insert helper.

Address EmitFieldAnnotations(const FieldDecl *D, Address V)

Emit field annotations for the given field & value.

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

void EnsureInsertPoint()

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

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

llvm::LLVMContext & getLLVMContext()

bool SawAsmBlock

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

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

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

bool checkIfFunctionMustProgress()

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

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

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

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

Emit an annotation call (intrinsic).

llvm::BasicBlock * GetIndirectGotoBlock()

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

llvm::DebugLoc EmitReturnBlock()

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

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

LValue EmitLValueForLambdaField(const FieldDecl *Field)

static bool containsBreak(const Stmt *S)

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

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

CGHLSLRuntime & getHLSLRuntime()

Return a reference to the configured HLSL runtime.

llvm::Constant * EmitAnnotationArgs(const AnnotateAttr *Attr)

Emit additional args of the annotation.

llvm::Module & getModule() const

DiagnosticsEngine & getDiags() const

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

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

const LangOptions & getLangOpts() const

CGCUDARuntime & getCUDARuntime()

Return a reference to the configured CUDA runtime.

llvm::Constant * EmitAnnotationLineNo(SourceLocation L)

Emit the annotation line number.

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

CodeGenTypes & getTypes()

const llvm::DataLayout & getDataLayout() const

bool shouldEmitConvergenceTokens() const

CGCXXABI & getCXXABI() const

CGOpenMPRuntime & getOpenMPRuntime()

Return a reference to the configured OpenMP runtime.

bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, StringRef Category=StringRef()) const

Imbue XRay attributes to a function, applying the always/never attribute lists in the process.

ProfileList::ExclusionType isFunctionBlockedFromProfileInstr(llvm::Function *Fn, SourceLocation Loc) const

ASTContext & getContext() const

llvm::SanitizerStatReport & getSanStats()

llvm::Constant * EmitAnnotationString(StringRef Str)

Emit an annotation string.

const TargetCodeGenInfo & getTargetCodeGenInfo()

const CodeGenOptions & getCodeGenOpts() const

llvm::LLVMContext & getLLVMContext()

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::Constant * EmitNullConstant(QualType T)

Return the result of value-initializing the given type, i.e.

llvm::ConstantInt * CreateKCFITypeId(QualType T)

Generate a KCFI type identifier for T.

bool MayDropFunctionReturn(const ASTContext &Context, QualType ReturnType) const

Whether this function's return type has no side effects, and thus may be trivially discarded if it is...

llvm::Constant * EmitAnnotationUnit(SourceLocation Loc)

Emit the annotation's translation unit.

llvm::ConstantInt * getSize(CharUnits numChars)

Emit the given number of characters as a value of type size_t.

void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)

Assign counters to regions and configure them for PGO of a given function.

void verifyCounterMap() const

void markStmtMaybeUsed(const Stmt *S)

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

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

Given that T is a scalar type, return the IR type that should be used for load and store operations.

llvm::Type * ConvertTypeForMem(QualType T)

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

bool isZeroInitializable(QualType T)

IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...

stable_iterator stable_begin() const

Create a stable reference to the top of the EH stack.

bool containsOnlyLifetimeMarkers(stable_iterator Old) const

bool empty() const

Determines whether the exception-scopes stack is empty.

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

void InsertHelper(llvm::Instruction *I) const

Function called by the CodeGenFunction when an instruction is created.

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.

llvm::Value * getPointer() const

virtual void checkFunctionABI(CodeGenModule &CGM, const FunctionDecl *Decl) const

Any further codegen related checks that need to be done on a function signature in a target specific ...

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

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

void Init(const Stmt *Body)

Clear the object and pre-process for the given statement, usually function body statement.

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

ConditionalOperator - The ?: ternary operator.

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

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

bool isIgnored(unsigned DiagID, SourceLocation Loc) const

Determine whether the diagnostic is known to be ignored.

This represents one expression.

bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const

EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...

FPOptions getFPFeaturesInEffect(const LangOptions &LO) const

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

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

Expr * IgnoreImpCasts() LLVM_READONLY

Skip past any implicit casts which might surround this expression until reaching a fixed point.

SourceLocation getExprLoc() const LLVM_READONLY

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

std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const

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

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.

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

GlobalDecl - represents a global declaration.

CXXCtorType getCtorType() 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

virtual void mangleCanonicalTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0

Generates a unique string for an externally visible type for use with TBAA or type uniquing.

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

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

decl_type * getPreviousDecl()

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

Encodes a location in the source.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

Stmt - This represents one statement.

StmtClass getStmtClass() const

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

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.

SourceLocation getBeginLoc() const LLVM_READONLY

bool isMicrosoft() const

Is this ABI an MSVC-compatible ABI?

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

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

virtual std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts) const

Returns target-specific min and max values VScale_Range.

The base class of the type hierarchy.

CXXRecordDecl * getAsCXXRecordDecl() const

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

bool isSignedIntegerType() const

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

bool isPointerType() const

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 isRecordType() const

bool isObjCRetainableType() const

std::optional< NullabilityKind > getNullability() const

Determine the nullability of the given type.

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.

TypeEvaluationKind

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

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

Matches all kinds of arrays.

bool Zero(InterpState &S, CodePtr OpPC)

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

@ NonNull

Values of this type can never be null.

bool isLambdaCallOperator(const CXXMethodDecl *MD)

@ Result

The result type of a method or function.

const FunctionProtoType * T

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

@ 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

llvm::BasicBlock * getBlock() const

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

llvm::PointerType * ConstGlobalsPtrTy

void* in the address space for constant globals

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

bool ReturnAddresses

Should return addresses be authenticated?

bool AArch64JumpTableHardening

Use hardened lowering for jump-table dispatch?

PointerAuthSchema FunctionPointers

The ABI for C function pointers.

bool AuthTraps

Do authentication failures cause a trap?

bool IndirectGotos

Do indirect goto label addresses need to be authenticated?

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.

SanitizerMask Mask

Bitmask of enabled sanitizers.

bool hasOneOf(SanitizerMask K) const

Check if one or more sanitizers are enabled.

bool has(XRayInstrMask K) const