llvm/clang/lib/CodeGen/CodeGenFunction.cpp

//===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This coordinates the per-function state used while generating code.
//
//===----------------------------------------------------------------------===//

#include "CodeGenFunction.h"
#include "CGBlocks.h"
#include "CGCUDARuntime.h"
#include "CGCXXABI.h"
#include "CGCleanup.h"
#include "CGDebugInfo.h"
#include "CGHLSLRuntime.h"
#include "CGOpenMPRuntime.h"
#include "CodeGenModule.h"
#include "CodeGenPGO.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/FPEnv.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Operator.h"
#include "llvm/Support/CRC.h"
#include "llvm/Support/xxhash.h"
#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include <optional>

usingnamespaceclang;
usingnamespaceCodeGen;

namespace llvm {
extern cl::opt<bool> EnableSingleByteCoverage;
} // namespace llvm

/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
/// markers.
static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts,
                                      const LangOptions &LangOpts) {}

CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
    :{}

CodeGenFunction::~CodeGenFunction() {}

// Map the LangOption for exception behavior into
// the corresponding enum in the IR.
llvm::fp::ExceptionBehavior
clang::ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind) {}

void CodeGenFunction::SetFastMathFlags(FPOptions FPFeatures) {}

CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF,
                                                  const Expr *E)
    :{}

CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF,
                                                  FPOptions FPFeatures)
    :{}

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

CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() {}

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

LValue
CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
                                            KnownNonNull_t IsKnownNonNull) {}

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

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

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

llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {}

llvm::Type *CodeGenFunction::ConvertType(QualType T) {}

llvm::Type *CodeGenFunction::convertTypeForLoadStore(QualType ASTTy,
                                                     llvm::Type *LLVMTy) {}

TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {}

llvm::DebugLoc CodeGenFunction::EmitReturnBlock() {}

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

void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {}

/// ShouldInstrumentFunction - Return true if the current function should be
/// instrumented with __cyg_profile_func_* calls
bool CodeGenFunction::ShouldInstrumentFunction() {}

bool CodeGenFunction::ShouldSkipSanitizerInstrumentation() {}

/// ShouldXRayInstrument - Return true if the current function should be
/// instrumented with XRay nop sleds.
bool CodeGenFunction::ShouldXRayInstrumentFunction() const {}

/// AlwaysEmitXRayCustomEvents - Return true if we should emit IR for calls to
/// the __xray_customevent(...) builtin calls, when doing XRay instrumentation.
bool CodeGenFunction::AlwaysEmitXRayCustomEvents() const {}

bool CodeGenFunction::AlwaysEmitXRayTypedEvents() const {}

llvm::ConstantInt *
CodeGenFunction::getUBSanFunctionTypeHash(QualType Ty) const {}

void CodeGenFunction::EmitKernelMetadata(const FunctionDecl *FD,
                                         llvm::Function *Fn) {}

/// Determine whether the function F ends with a return stmt.
static bool endsWithReturn(const Decl* F) {}

void CodeGenFunction::markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) {}

/// Check if the return value of this function requires sanitization.
bool CodeGenFunction::requiresReturnValueCheck() const {}

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

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

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

/// Return the UBSan prologue signature for \p FD if one is available.
static llvm::Constant *getPrologueSignature(CodeGenModule &CGM,
                                            const FunctionDecl *FD) {}

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

void CodeGenFunction::EmitFunctionBody(const Stmt *Body) {}

/// When instrumenting to collect profile data, the counts for some blocks
/// such as switch cases need to not include the fall-through counts, so
/// emit a branch around the instrumentation code. When not instrumenting,
/// this just calls EmitBlock().
void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
                                               const Stmt *S) {}

/// Tries to mark the given function nounwind based on the
/// non-existence of any throwing calls within it.  We believe this is
/// lightweight enough to do at -O0.
static void TryMarkNoThrow(llvm::Function *F) {}

QualType CodeGenFunction::BuildFunctionArgList(GlobalDecl GD,
                                               FunctionArgList &Args) {}

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

/// ContainsLabel - Return true if the statement contains a label in it.  If
/// this statement is not executed normally, it not containing a label means
/// that we can just remove the code.
bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) {}

/// containsBreak - Return true if the statement contains a break out of it.
/// If the statement (recursively) contains a switch or loop with a break
/// inside of it, this is fine.
bool CodeGenFunction::containsBreak(const Stmt *S) {}

bool CodeGenFunction::mightAddDeclToScope(const Stmt *S) {}

/// ConstantFoldsToSimpleInteger - If the specified expression does not fold
/// to a constant, or if it does but contains a label, return false.  If it
/// constant folds return true and set the boolean result in Result.
bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
                                                   bool &ResultBool,
                                                   bool AllowLabels) {}

/// ConstantFoldsToSimpleInteger - If the specified expression does not fold
/// to a constant, or if it does but contains a label, return false.  If it
/// constant folds return true and set the folded value.
bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
                                                   llvm::APSInt &ResultInt,
                                                   bool AllowLabels) {}

/// Strip parentheses and simplistic logical-NOT operators.
const Expr *CodeGenFunction::stripCond(const Expr *C) {}

/// Determine whether the given condition is an instrumentable condition
/// (i.e. no "&&" or "||").
bool CodeGenFunction::isInstrumentedCondition(const Expr *C) {}

/// EmitBranchToCounterBlock - Emit a conditional branch to a new block that
/// increments a profile counter based on the semantics of the given logical
/// operator opcode.  This is used to instrument branch condition coverage for
/// logical operators.
void CodeGenFunction::EmitBranchToCounterBlock(
    const Expr *Cond, BinaryOperator::Opcode LOp, llvm::BasicBlock *TrueBlock,
    llvm::BasicBlock *FalseBlock, uint64_t TrueCount /* = 0 */,
    Stmt::Likelihood LH /* =None */, const Expr *CntrIdx /* = nullptr */) {}

/// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if
/// statement) to the specified blocks.  Based on the condition, this might try
/// to simplify the codegen of the conditional based on the branch.
/// \param LH The value of the likelihood attribute on the True branch.
/// \param ConditionalOp Used by MC/DC code coverage to track the result of the
/// ConditionalOperator (ternary) through a recursive call for the operator's
/// LHS and RHS nodes.
void CodeGenFunction::EmitBranchOnBoolExpr(
    const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock,
    uint64_t TrueCount, Stmt::Likelihood LH, const Expr *ConditionalOp) {}

/// ErrorUnsupported - Print out an error that codegen doesn't support the
/// specified stmt yet.
void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type) {}

/// emitNonZeroVLAInit - Emit the "zero" initialization of a
/// variable-length array whose elements have a non-zero bit-pattern.
///
/// \param baseType the inner-most element type of the array
/// \param src - a char* pointing to the bit-pattern for a single
/// base element of the array
/// \param sizeInChars - the total size of the VLA, in chars
static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType,
                               Address dest, Address src,
                               llvm::Value *sizeInChars) {}

void
CodeGenFunction::EmitNullInitialization(Address DestPtr, QualType Ty) {}

llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelDecl *L) {}

llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() {}

/// Computes the length of an array in elements, as well as the base
/// element type and a properly-typed first element pointer.
llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,
                                              QualType &baseType,
                                              Address &addr) {}

CodeGenFunction::VlaSizePair CodeGenFunction::getVLASize(QualType type) {}

CodeGenFunction::VlaSizePair
CodeGenFunction::getVLASize(const VariableArrayType *type) {}

CodeGenFunction::VlaSizePair
CodeGenFunction::getVLAElements1D(QualType type) {}

CodeGenFunction::VlaSizePair
CodeGenFunction::getVLAElements1D(const VariableArrayType *Vla) {}

void CodeGenFunction::EmitVariablyModifiedType(QualType type) {}

Address CodeGenFunction::EmitVAListRef(const Expr* E) {}

Address CodeGenFunction::EmitMSVAListRef(const Expr *E) {}

void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E,
                                              const APValue &Init) {}

CodeGenFunction::PeepholeProtection
CodeGenFunction::protectFromPeepholes(RValue rvalue) {}

void CodeGenFunction::unprotectFromPeepholes(PeepholeProtection protection) {}

void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
                                              QualType Ty, SourceLocation Loc,
                                              SourceLocation AssumptionLoc,
                                              llvm::Value *Alignment,
                                              llvm::Value *OffsetValue) {}

void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
                                              const Expr *E,
                                              SourceLocation AssumptionLoc,
                                              llvm::Value *Alignment,
                                              llvm::Value *OffsetValue) {}

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

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

Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
                                              Address Addr) {}

CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() {}

CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF)
    :{}

CodeGenFunction::SanitizerScope::~SanitizerScope() {}

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

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

// Emits an error if we don't have a valid set of target features for the
// called function.
void CodeGenFunction::checkTargetFeatures(const CallExpr *E,
                                          const FunctionDecl *TargetDecl) {}

// Emits an error if we don't have a valid set of target features for the
// called function.
void CodeGenFunction::checkTargetFeatures(SourceLocation Loc,
                                          const FunctionDecl *TargetDecl) {}

void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) {}

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

llvm::Value *CodeGenFunction::FormAArch64ResolverCondition(
    const MultiVersionResolverOption &RO) {}

llvm::Value *CodeGenFunction::FormX86ResolverCondition(
    const MultiVersionResolverOption &RO) {}

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

void CodeGenFunction::EmitMultiVersionResolver(
    llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {}

static int getPriorityFromAttrString(StringRef AttrStr) {}

void CodeGenFunction::EmitRISCVMultiVersionResolver(
    llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {}

void CodeGenFunction::EmitAArch64MultiVersionResolver(
    llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {}

void CodeGenFunction::EmitX86MultiVersionResolver(
    llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {}

// Loc - where the diagnostic will point, where in the source code this
//  alignment has failed.
// SecondaryLoc - if present (will be present if sufficiently different from
//  Loc), the diagnostic will additionally point a "Note:" to this location.
//  It should be the location where the __attribute__((assume_aligned))
//  was written e.g.
void CodeGenFunction::emitAlignmentAssumptionCheck(
    llvm::Value *Ptr, QualType Ty, SourceLocation Loc,
    SourceLocation SecondaryLoc, llvm::Value *Alignment,
    llvm::Value *OffsetValue, llvm::Value *TheCheck,
    llvm::Instruction *Assumption) {}

llvm::DebugLoc CodeGenFunction::SourceLocToDebugLoc(SourceLocation Location) {}

llvm::Value *
CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
                                                      Stmt::Likelihood LH) {}

llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec,
                                                    unsigned NumElementsDst,
                                                    const llvm::Twine &Name) {}

void CodeGenFunction::EmitPointerAuthOperandBundle(
    const CGPointerAuthInfo &PointerAuth,
    SmallVectorImpl<llvm::OperandBundleDef> &Bundles) {}

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

llvm::Value *
CodeGenFunction::EmitPointerAuthSign(const CGPointerAuthInfo &PointerAuth,
                                     llvm::Value *Pointer) {}

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

llvm::Value *
CodeGenFunction::EmitPointerAuthAuth(const CGPointerAuthInfo &PointerAuth,
                                     llvm::Value *Pointer) {}