llvm/clang/lib/CodeGen/CGStmt.cpp

//===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===//
//
// 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 contains code to emit Stmt nodes as LLVM code.
//
//===----------------------------------------------------------------------===//

#include "CGDebugInfo.h"
#include "CGOpenMPRuntime.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "TargetInfo.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Assumptions.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/Support/SaveAndRestore.h"
#include <optional>

usingnamespaceclang;
usingnamespaceCodeGen;

//===----------------------------------------------------------------------===//
//                              Statement Emission
//===----------------------------------------------------------------------===//

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

void CodeGenFunction::EmitStopPoint(const Stmt *S) {}

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

bool CodeGenFunction::EmitSimpleStmt(const Stmt *S,
                                     ArrayRef<const Attr *> Attrs) {}

/// EmitCompoundStmt - Emit a compound statement {..} node.  If GetLast is true,
/// this captures the expression result of the last sub-statement and returns it
/// (for use by the statement expression extension).
Address CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
                                          AggValueSlot AggSlot) {}

Address
CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S,
                                              bool GetLast,
                                              AggValueSlot AggSlot) {}

void CodeGenFunction::SimplifyForwardingBlocks(llvm::BasicBlock *BB) {}

void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) {}

void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) {}

void CodeGenFunction::EmitBlockAfterUses(llvm::BasicBlock *block) {}

CodeGenFunction::JumpDest
CodeGenFunction::getJumpDestForLabel(const LabelDecl *D) {}

void CodeGenFunction::EmitLabel(const LabelDecl *D) {}

/// Change the cleanup scope of the labels in this lexical scope to
/// match the scope of the enclosing context.
void CodeGenFunction::LexicalScope::rescopeLabels() {}


void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {}

void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) {}

void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {}


void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {}

void CodeGenFunction::EmitIfStmt(const IfStmt &S) {}

bool CodeGenFunction::checkIfLoopMustProgress(const Expr *ControllingExpression,
                                              bool HasEmptyBody) {}

// [C++26][stmt.iter.general] (DR)
// A trivially empty iteration statement is an iteration statement matching one
// of the following forms:
//  - while ( expression ) ;
//  - while ( expression ) { }
//  - do ; while ( expression ) ;
//  - do { } while ( expression ) ;
//  - for ( init-statement expression(opt); ) ;
//  - for ( init-statement expression(opt); ) { }
template <typename LoopStmt> static bool hasEmptyLoopBody(const LoopStmt &S) {}

void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
                                    ArrayRef<const Attr *> WhileAttrs) {}

void CodeGenFunction::EmitDoStmt(const DoStmt &S,
                                 ArrayRef<const Attr *> DoAttrs) {}

void CodeGenFunction::EmitForStmt(const ForStmt &S,
                                  ArrayRef<const Attr *> ForAttrs) {}

void
CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
                                     ArrayRef<const Attr *> ForAttrs) {}

void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {}

namespace {
// RAII struct used to save and restore a return statment's result expression.
struct SaveRetExprRAII {};
} // namespace

/// Determine if the given call uses the swiftasync calling convention.
static bool isSwiftAsyncCallee(const CallExpr *CE) {}

/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
/// if the function returns void, or may be missing one if the function returns
/// non-void.  Fun stuff :).
void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {}

void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) {}

void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) {}

void CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) {}

/// EmitCaseStmtRange - If case statement range is not too big then
/// add multiple cases to switch instruction, one for each value within
/// the range. If range is too big then emit "if" condition check.
void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S,
                                        ArrayRef<const Attr *> Attrs) {}

void CodeGenFunction::EmitCaseStmt(const CaseStmt &S,
                                   ArrayRef<const Attr *> Attrs) {}

void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S,
                                      ArrayRef<const Attr *> Attrs) {}

/// CollectStatementsForCase - Given the body of a 'switch' statement and a
/// constant value that is being switched on, see if we can dead code eliminate
/// the body of the switch to a simple series of statements to emit.  Basically,
/// on a switch (5) we want to find these statements:
///    case 5:
///      printf(...);    <--
///      ++i;            <--
///      break;
///
/// and add them to the ResultStmts vector.  If it is unsafe to do this
/// transformation (for example, one of the elided statements contains a label
/// that might be jumped to), return CSFC_Failure.  If we handled it and 'S'
/// should include statements after it (e.g. the printf() line is a substmt of
/// the case) then return CSFC_FallThrough.  If we handled it and found a break
/// statement, then return CSFC_Success.
///
/// If Case is non-null, then we are looking for the specified case, checking
/// that nothing we jump over contains labels.  If Case is null, then we found
/// the case and are looking for the break.
///
/// If the recursive walk actually finds our Case, then we set FoundCase to
/// true.
///
enum CSFC_Result {};
static CSFC_Result CollectStatementsForCase(const Stmt *S,
                                            const SwitchCase *Case,
                                            bool &FoundCase,
                              SmallVectorImpl<const Stmt*> &ResultStmts) {}

/// FindCaseStatementsForValue - Find the case statement being jumped to and
/// then invoke CollectStatementsForCase to find the list of statements to emit
/// for a switch on constant.  See the comment above CollectStatementsForCase
/// for more details.
static bool FindCaseStatementsForValue(const SwitchStmt &S,
                                       const llvm::APSInt &ConstantCondValue,
                                SmallVectorImpl<const Stmt*> &ResultStmts,
                                       ASTContext &C,
                                       const SwitchCase *&ResultCase) {}

static std::optional<SmallVector<uint64_t, 16>>
getLikelihoodWeights(ArrayRef<Stmt::Likelihood> Likelihoods) {}

void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {}

static std::string
SimplifyConstraint(const char *Constraint, const TargetInfo &Target,
                 SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=nullptr) {}

/// AddVariableConstraints - Look at AsmExpr and if it is a variable declared
/// as using a particular register add that as a constraint that will be used
/// in this asm stmt.
static std::string
AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr,
                       const TargetInfo &Target, CodeGenModule &CGM,
                       const AsmStmt &Stmt, const bool EarlyClobber,
                       std::string *GCCReg = nullptr) {}

std::pair<llvm::Value*, llvm::Type *> CodeGenFunction::EmitAsmInputLValue(
    const TargetInfo::ConstraintInfo &Info, LValue InputValue,
    QualType InputType, std::string &ConstraintStr, SourceLocation Loc) {}

std::pair<llvm::Value *, llvm::Type *>
CodeGenFunction::EmitAsmInput(const TargetInfo::ConstraintInfo &Info,
                              const Expr *InputExpr,
                              std::string &ConstraintStr) {}

/// getAsmSrcLocInfo - Return the !srcloc metadata node to attach to an inline
/// asm call instruction.  The !srcloc MDNode contains a list of constant
/// integers which are the source locations of the start of each line in the
/// asm.
static llvm::MDNode *getAsmSrcLocInfo(const StringLiteral *Str,
                                      CodeGenFunction &CGF) {}

static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect,
                              bool HasUnwindClobber, bool ReadOnly,
                              bool ReadNone, bool NoMerge, bool NoConvergent,
                              const AsmStmt &S,
                              const std::vector<llvm::Type *> &ResultRegTypes,
                              const std::vector<llvm::Type *> &ArgElemTypes,
                              CodeGenFunction &CGF,
                              std::vector<llvm::Value *> &RegResults) {}

static void
EmitAsmStores(CodeGenFunction &CGF, const AsmStmt &S,
              const llvm::ArrayRef<llvm::Value *> RegResults,
              const llvm::ArrayRef<llvm::Type *> ResultRegTypes,
              const llvm::ArrayRef<llvm::Type *> ResultTruncRegTypes,
              const llvm::ArrayRef<LValue> ResultRegDests,
              const llvm::ArrayRef<QualType> ResultRegQualTys,
              const llvm::BitVector &ResultTypeRequiresCast,
              const llvm::BitVector &ResultRegIsFlagReg) {}

static void EmitHipStdParUnsupportedAsm(CodeGenFunction *CGF,
                                        const AsmStmt &S) {}

void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {}

LValue CodeGenFunction::InitCapturedStruct(const CapturedStmt &S) {}

/// Generate an outlined function for the body of a CapturedStmt, store any
/// captured variables into the captured struct, and call the outlined function.
llvm::Function *
CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) {}

Address CodeGenFunction::GenerateCapturedStmtArgument(const CapturedStmt &S) {}

/// Creates the outlined function for a CapturedStmt.
llvm::Function *
CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) {}

namespace {
// Returns the first convergence entry/loop/anchor instruction found in |BB|.
// std::nullptr otherwise.
llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) {}

} // namespace

llvm::CallBase *
CodeGenFunction::addConvergenceControlToken(llvm::CallBase *Input,
                                            llvm::Value *ParentToken) {}

llvm::IntrinsicInst *
CodeGenFunction::emitConvergenceLoopToken(llvm::BasicBlock *BB,
                                          llvm::Value *ParentToken) {}

llvm::IntrinsicInst *
CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) {}