llvm/clang/lib/AST/Stmt.cpp

//===- Stmt.cpp - Statement AST Node Implementation -----------------------===//
//
// 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 file implements the Stmt class and statement subclasses.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/Stmt.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtOpenACC.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstring>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>

usingnamespaceclang;

static struct StmtClassNameTable {} StmtClassInfo[Stmt::lastStmtConstant+1];

static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {}

void *Stmt::operator new(size_t bytes, const ASTContext& C,
                         unsigned alignment) {}

const char *Stmt::getStmtClassName() const {}

// Check that no statement / expression class is polymorphic. LLVM style RTTI
// should be used instead. If absolutely needed an exception can still be added
// here by defining the appropriate macro (but please don't do this).
#define STMT
#include "clang/AST/StmtNodes.inc"

// Check that no statement / expression class has a non-trival destructor.
// Statements and expressions are allocated with the BumpPtrAllocator from
// ASTContext and therefore their destructor is not executed.
#define STMT
// FIXME: InitListExpr is not trivially destructible due to its ASTVector.
#define INITLISTEXPR
#include "clang/AST/StmtNodes.inc"

void Stmt::PrintStats() {}

void Stmt::addStmtClass(StmtClass s) {}

bool Stmt::StatisticsEnabled =;
void Stmt::EnableStatistics() {}

static std::pair<Stmt::Likelihood, const Attr *>
getLikelihood(ArrayRef<const Attr *> Attrs) {}

static std::pair<Stmt::Likelihood, const Attr *> getLikelihood(const Stmt *S) {}

Stmt::Likelihood Stmt::getLikelihood(ArrayRef<const Attr *> Attrs) {}

Stmt::Likelihood Stmt::getLikelihood(const Stmt *S) {}

const Attr *Stmt::getLikelihoodAttr(const Stmt *S) {}

Stmt::Likelihood Stmt::getLikelihood(const Stmt *Then, const Stmt *Else) {}

std::tuple<bool, const Attr *, const Attr *>
Stmt::determineLikelihoodConflict(const Stmt *Then, const Stmt *Else) {}

/// Skip no-op (attributed, compound) container stmts and skip captured
/// stmt at the top, if \a IgnoreCaptured is true.
Stmt *Stmt::IgnoreContainers(bool IgnoreCaptured) {}

/// Strip off all label-like statements.
///
/// This will strip off label statements, case statements, attributed
/// statements and default statements recursively.
const Stmt *Stmt::stripLabelLikeStatements() const {}

namespace {

  struct good {};
  struct bad {};

  // These silly little functions have to be static inline to suppress
  // unused warnings, and they have to be defined to suppress other
  // warnings.
  static good is_good(good) {}

  children_t;
  template <class T> good implements_children(children_t T::*) {}
  LLVM_ATTRIBUTE_UNUSED
  static bad implements_children(children_t Stmt::*) {}

  getBeginLoc_t;
  template <class T> good implements_getBeginLoc(getBeginLoc_t T::*) {}
  LLVM_ATTRIBUTE_UNUSED
  static bad implements_getBeginLoc(getBeginLoc_t Stmt::*) {}

  getLocEnd_t;
  template <class T> good implements_getEndLoc(getLocEnd_t T::*) {}
  LLVM_ATTRIBUTE_UNUSED
  static bad implements_getEndLoc(getLocEnd_t Stmt::*) {}

#define ASSERT_IMPLEMENTS_children(type)
#define ASSERT_IMPLEMENTS_getBeginLoc(type)
#define ASSERT_IMPLEMENTS_getEndLoc(type)

} // namespace

/// Check whether the various Stmt classes implement their member
/// functions.
LLVM_ATTRIBUTE_UNUSED
static inline void check_implementations() {}

Stmt::child_range Stmt::children() {}

// Amusing macro metaprogramming hack: check whether a class provides
// a more specific implementation of getSourceRange.
//
// See also Expr.cpp:getExprLoc().
namespace {

  /// This implementation is used when a class provides a custom
  /// implementation of getSourceRange.
  template <class S, class T>
  SourceRange getSourceRangeImpl(const Stmt *stmt,
                                 SourceRange (T::*v)() const) {}

  /// This implementation is used when a class doesn't provide a custom
  /// implementation of getSourceRange.  Overload resolution should pick it over
  /// the implementation above because it's more specialized according to
  /// function template partial ordering.
  template <class S>
  SourceRange getSourceRangeImpl(const Stmt *stmt,
                                 SourceRange (Stmt::*v)() const) {}

} // namespace

SourceRange Stmt::getSourceRange() const {}

SourceLocation Stmt::getBeginLoc() const {}

SourceLocation Stmt::getEndLoc() const {}

int64_t Stmt::getID(const ASTContext &Context) const {}

CompoundStmt::CompoundStmt(ArrayRef<Stmt *> Stmts, FPOptionsOverride FPFeatures,
                           SourceLocation LB, SourceLocation RB)
    :{}

void CompoundStmt::setStmts(ArrayRef<Stmt *> Stmts) {}

CompoundStmt *CompoundStmt::Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
                                   FPOptionsOverride FPFeatures,
                                   SourceLocation LB, SourceLocation RB) {}

CompoundStmt *CompoundStmt::CreateEmpty(const ASTContext &C, unsigned NumStmts,
                                        bool HasFPFeatures) {}

const Expr *ValueStmt::getExprStmt() const {}

const char *LabelStmt::getName() const {}

AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc,
                                       ArrayRef<const Attr*> Attrs,
                                       Stmt *SubStmt) {}

AttributedStmt *AttributedStmt::CreateEmpty(const ASTContext &C,
                                            unsigned NumAttrs) {}

std::string AsmStmt::generateAsmString(const ASTContext &C) const {}

StringRef AsmStmt::getOutputConstraint(unsigned i) const {}

const Expr *AsmStmt::getOutputExpr(unsigned i) const {}

StringRef AsmStmt::getInputConstraint(unsigned i) const {}

const Expr *AsmStmt::getInputExpr(unsigned i) const {}

StringRef AsmStmt::getClobber(unsigned i) const {}

/// getNumPlusOperands - Return the number of output operands that have a "+"
/// constraint.
unsigned AsmStmt::getNumPlusOperands() const {}

char GCCAsmStmt::AsmStringPiece::getModifier() const {}

StringRef GCCAsmStmt::getClobber(unsigned i) const {}

Expr *GCCAsmStmt::getOutputExpr(unsigned i) {}

/// getOutputConstraint - Return the constraint string for the specified
/// output operand.  All output constraints are known to be non-empty (either
/// '=' or '+').
StringRef GCCAsmStmt::getOutputConstraint(unsigned i) const {}

Expr *GCCAsmStmt::getInputExpr(unsigned i) {}

void GCCAsmStmt::setInputExpr(unsigned i, Expr *E) {}

AddrLabelExpr *GCCAsmStmt::getLabelExpr(unsigned i) const {}

StringRef GCCAsmStmt::getLabelName(unsigned i) const {}

/// getInputConstraint - Return the specified input constraint.  Unlike output
/// constraints, these can be empty.
StringRef GCCAsmStmt::getInputConstraint(unsigned i) const {}

void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C,
                                                IdentifierInfo **Names,
                                                StringLiteral **Constraints,
                                                Stmt **Exprs,
                                                unsigned NumOutputs,
                                                unsigned NumInputs,
                                                unsigned NumLabels,
                                                StringLiteral **Clobbers,
                                                unsigned NumClobbers) {}

/// getNamedOperand - Given a symbolic operand reference like %[foo],
/// translate this into a numeric value needed to reference the same operand.
/// This returns -1 if the operand name is invalid.
int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const {}

/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
/// it into pieces.  If the asm string is erroneous, emit errors and return
/// true, otherwise return false.
unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
                                const ASTContext &C, unsigned &DiagOffs) const {}

/// Assemble final IR asm string (GCC-style).
std::string GCCAsmStmt::generateAsmString(const ASTContext &C) const {}

/// Assemble final IR asm string (MS-style).
std::string MSAsmStmt::generateAsmString(const ASTContext &C) const {}

Expr *MSAsmStmt::getOutputExpr(unsigned i) {}

Expr *MSAsmStmt::getInputExpr(unsigned i) {}

void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {}

//===----------------------------------------------------------------------===//
// Constructors
//===----------------------------------------------------------------------===//

GCCAsmStmt::GCCAsmStmt(const ASTContext &C, SourceLocation asmloc,
                       bool issimple, bool isvolatile, unsigned numoutputs,
                       unsigned numinputs, IdentifierInfo **names,
                       StringLiteral **constraints, Expr **exprs,
                       StringLiteral *asmstr, unsigned numclobbers,
                       StringLiteral **clobbers, unsigned numlabels,
                       SourceLocation rparenloc)
    :{}

MSAsmStmt::MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
                     SourceLocation lbraceloc, bool issimple, bool isvolatile,
                     ArrayRef<Token> asmtoks, unsigned numoutputs,
                     unsigned numinputs,
                     ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs,
                     StringRef asmstr, ArrayRef<StringRef> clobbers,
                     SourceLocation endloc)
    :{}

static StringRef copyIntoContext(const ASTContext &C, StringRef str) {}

void MSAsmStmt::initialize(const ASTContext &C, StringRef asmstr,
                           ArrayRef<Token> asmtoks,
                           ArrayRef<StringRef> constraints,
                           ArrayRef<Expr*> exprs,
                           ArrayRef<StringRef> clobbers) {}

IfStmt::IfStmt(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind,
               Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LPL,
               SourceLocation RPL, Stmt *Then, SourceLocation EL, Stmt *Else)
    :{}

IfStmt::IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit)
    :{}

IfStmt *IfStmt::Create(const ASTContext &Ctx, SourceLocation IL,
                       IfStatementKind Kind, Stmt *Init, VarDecl *Var,
                       Expr *Cond, SourceLocation LPL, SourceLocation RPL,
                       Stmt *Then, SourceLocation EL, Stmt *Else) {}

IfStmt *IfStmt::CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar,
                            bool HasInit) {}

VarDecl *IfStmt::getConditionVariable() {}

void IfStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) {}

bool IfStmt::isObjCAvailabilityCheck() const {}

std::optional<Stmt *> IfStmt::getNondiscardedCase(const ASTContext &Ctx) {}

std::optional<const Stmt *>
IfStmt::getNondiscardedCase(const ASTContext &Ctx) const {}

ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
                 Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
                 SourceLocation RP)
  :{}

VarDecl *ForStmt::getConditionVariable() const {}

void ForStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {}

SwitchStmt::SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
                       Expr *Cond, SourceLocation LParenLoc,
                       SourceLocation RParenLoc)
    :{}

SwitchStmt::SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar)
    :{}

SwitchStmt *SwitchStmt::Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
                               Expr *Cond, SourceLocation LParenLoc,
                               SourceLocation RParenLoc) {}

SwitchStmt *SwitchStmt::CreateEmpty(const ASTContext &Ctx, bool HasInit,
                                    bool HasVar) {}

VarDecl *SwitchStmt::getConditionVariable() {}

void SwitchStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) {}

WhileStmt::WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
                     Stmt *Body, SourceLocation WL, SourceLocation LParenLoc,
                     SourceLocation RParenLoc)
    :{}

WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar)
    :{}

WhileStmt *WhileStmt::Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
                             Stmt *Body, SourceLocation WL,
                             SourceLocation LParenLoc,
                             SourceLocation RParenLoc) {}

WhileStmt *WhileStmt::CreateEmpty(const ASTContext &Ctx, bool HasVar) {}

VarDecl *WhileStmt::getConditionVariable() {}

void WhileStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) {}

// IndirectGotoStmt
LabelDecl *IndirectGotoStmt::getConstantTarget() {}

// ReturnStmt
ReturnStmt::ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
    :{}

ReturnStmt::ReturnStmt(EmptyShell Empty, bool HasNRVOCandidate)
    :{}

ReturnStmt *ReturnStmt::Create(const ASTContext &Ctx, SourceLocation RL,
                               Expr *E, const VarDecl *NRVOCandidate) {}

ReturnStmt *ReturnStmt::CreateEmpty(const ASTContext &Ctx,
                                    bool HasNRVOCandidate) {}

// CaseStmt
CaseStmt *CaseStmt::Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
                           SourceLocation caseLoc, SourceLocation ellipsisLoc,
                           SourceLocation colonLoc) {}

CaseStmt *CaseStmt::CreateEmpty(const ASTContext &Ctx,
                                bool CaseStmtIsGNURange) {}

SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
                       Stmt *Handler)
    :{}

SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
                               SourceLocation TryLoc, Stmt *TryBlock,
                               Stmt *Handler) {}

SEHExceptStmt* SEHTryStmt::getExceptHandler() const {}

SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {}

SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
    :{}

SEHExceptStmt* SEHExceptStmt::Create(const ASTContext &C, SourceLocation Loc,
                                     Expr *FilterExpr, Stmt *Block) {}

SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, Stmt *Block)
    :{}

SEHFinallyStmt* SEHFinallyStmt::Create(const ASTContext &C, SourceLocation Loc,
                                       Stmt *Block) {}

CapturedStmt::Capture::Capture(SourceLocation Loc, VariableCaptureKind Kind,
                               VarDecl *Var)
    :{}

CapturedStmt::VariableCaptureKind
CapturedStmt::Capture::getCaptureKind() const {}

VarDecl *CapturedStmt::Capture::getCapturedVar() const {}

CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const {}

CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
                           ArrayRef<Capture> Captures,
                           ArrayRef<Expr *> CaptureInits,
                           CapturedDecl *CD,
                           RecordDecl *RD)
  :{}

CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
  :{}

CapturedStmt *CapturedStmt::Create(const ASTContext &Context, Stmt *S,
                                   CapturedRegionKind Kind,
                                   ArrayRef<Capture> Captures,
                                   ArrayRef<Expr *> CaptureInits,
                                   CapturedDecl *CD,
                                   RecordDecl *RD) {}

CapturedStmt *CapturedStmt::CreateDeserialized(const ASTContext &Context,
                                               unsigned NumCaptures) {}

Stmt::child_range CapturedStmt::children() {}

Stmt::const_child_range CapturedStmt::children() const {}

CapturedDecl *CapturedStmt::getCapturedDecl() {}

const CapturedDecl *CapturedStmt::getCapturedDecl() const {}

/// Set the outlined function declaration.
void CapturedStmt::setCapturedDecl(CapturedDecl *D) {}

/// Retrieve the captured region kind.
CapturedRegionKind CapturedStmt::getCapturedRegionKind() const {}

/// Set the captured region kind.
void CapturedStmt::setCapturedRegionKind(CapturedRegionKind Kind) {}

bool CapturedStmt::capturesVariable(const VarDecl *Var) const {}