llvm/clang/lib/Sema/SemaStmt.cpp

//===--- SemaStmt.cpp - Semantic Analysis for 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 file implements semantic analysis for statements.
//
//===----------------------------------------------------------------------===//

#include "CheckExprLifetime.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/EvaluatedExprVisitor.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/IgnoreExpr.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaObjC.h"
#include "clang/Sema/SemaOpenMP.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"

usingnamespaceclang;
usingnamespacesema;

StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) {}


StmtResult Sema::ActOnExprStmtError() {}

StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc,
                               bool HasLeadingEmptyMacro) {}

StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,
                               SourceLocation EndLoc) {}

void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {}

/// Diagnose unused comparisons, both builtin and overloaded operators.
/// For '==' and '!=', suggest fixits for '=' or '|='.
///
/// Adding a cast to void (or other expression wrappers) will prevent the
/// warning from firing.
static bool DiagnoseUnusedComparison(Sema &S, const Expr *E) {}

static bool DiagnoseNoDiscard(Sema &S, const WarnUnusedResultAttr *A,
                              SourceLocation Loc, SourceRange R1,
                              SourceRange R2, bool IsCtor) {}

void Sema::DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID) {}

void Sema::ActOnStartOfCompoundStmt(bool IsStmtExpr) {}

void Sema::ActOnAfterCompoundStatementLeadingPragmas() {}

void Sema::ActOnFinishOfCompoundStmt() {}

sema::CompoundScopeInfo &Sema::getCurCompoundScope() const {}

StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
                                   ArrayRef<Stmt *> Elts, bool isStmtExpr) {}

ExprResult
Sema::ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val) {}

StmtResult
Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal,
                    SourceLocation DotDotDotLoc, ExprResult RHSVal,
                    SourceLocation ColonLoc) {}

void Sema::ActOnCaseStmtBody(Stmt *S, Stmt *SubStmt) {}

StmtResult
Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
                       Stmt *SubStmt, Scope *CurScope) {}

StmtResult
Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
                     SourceLocation ColonLoc, Stmt *SubStmt) {}

StmtResult Sema::BuildAttributedStmt(SourceLocation AttrsLoc,
                                     ArrayRef<const Attr *> Attrs,
                                     Stmt *SubStmt) {}

StmtResult Sema::ActOnAttributedStmt(const ParsedAttributes &Attrs,
                                     Stmt *SubStmt) {}

bool Sema::checkAndRewriteMustTailAttr(Stmt *St, const Attr &MTA) {}

bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) {}

namespace {
class CommaVisitor : public EvaluatedExprVisitor<CommaVisitor> {};
}

StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc,
                             IfStatementKind StatementKind,
                             SourceLocation LParenLoc, Stmt *InitStmt,
                             ConditionResult Cond, SourceLocation RParenLoc,
                             Stmt *thenStmt, SourceLocation ElseLoc,
                             Stmt *elseStmt) {}

StmtResult Sema::BuildIfStmt(SourceLocation IfLoc,
                             IfStatementKind StatementKind,
                             SourceLocation LParenLoc, Stmt *InitStmt,
                             ConditionResult Cond, SourceLocation RParenLoc,
                             Stmt *thenStmt, SourceLocation ElseLoc,
                             Stmt *elseStmt) {}

namespace {
  struct CaseCompareFunctor {};
}

/// CmpCaseVals - Comparison predicate for sorting case values.
///
static bool CmpCaseVals(const std::pair<llvm::APSInt, CaseStmt*>& lhs,
                        const std::pair<llvm::APSInt, CaseStmt*>& rhs) {}

/// CmpEnumVals - Comparison predicate for sorting enumeration values.
///
static bool CmpEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
                        const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
{}

/// EqEnumVals - Comparison preficate for uniqing enumeration values.
///
static bool EqEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
                       const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
{}

/// GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of
/// potentially integral-promoted expression @p expr.
static QualType GetTypeBeforeIntegralPromotion(const Expr *&E) {}

ExprResult Sema::CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond) {}

StmtResult Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
                                        SourceLocation LParenLoc,
                                        Stmt *InitStmt, ConditionResult Cond,
                                        SourceLocation RParenLoc) {}

static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {}

/// Check the specified case value is in range for the given unpromoted switch
/// type.
static void checkCaseValue(Sema &S, SourceLocation Loc, const llvm::APSInt &Val,
                           unsigned UnpromotedWidth, bool UnpromotedSign) {}

EnumValsTy;

/// Returns true if we should emit a diagnostic about this case expression not
/// being a part of the enum used in the switch controlling expression.
static bool ShouldDiagnoseSwitchCaseNotInEnum(const Sema &S,
                                              const EnumDecl *ED,
                                              const Expr *CaseExpr,
                                              EnumValsTy::iterator &EI,
                                              EnumValsTy::iterator &EIEnd,
                                              const llvm::APSInt &Val) {}

static void checkEnumTypesInSwitchStmt(Sema &S, const Expr *Cond,
                                       const Expr *Case) {}

StmtResult
Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
                            Stmt *BodyStmt) {}

void
Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
                             Expr *SrcExpr) {}

StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc,
                                SourceLocation LParenLoc, ConditionResult Cond,
                                SourceLocation RParenLoc, Stmt *Body) {}

StmtResult
Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
                  SourceLocation WhileLoc, SourceLocation CondLParen,
                  Expr *Cond, SourceLocation CondRParen) {}

namespace {
  // Use SetVector since the diagnostic cares about the ordering of the Decl's.
  DeclSetVector;

  // This visitor will traverse a conditional statement and store all
  // the evaluated decls into a vector.  Simple is set to true if none
  // of the excluded constructs are used.
  class DeclExtractor : public EvaluatedExprVisitor<DeclExtractor> {}; // end class DeclExtractor

  // DeclMatcher checks to see if the decls are used in a non-evaluated
  // context.
  class DeclMatcher : public EvaluatedExprVisitor<DeclMatcher> {};  // end class DeclMatcher

  void CheckForLoopConditionalStatement(Sema &S, Expr *Second,
                                        Expr *Third, Stmt *Body) {}

  // If Statement is an incemement or decrement, return true and sets the
  // variables Increment and DRE.
  bool ProcessIterationStmt(Sema &S, Stmt* Statement, bool &Increment,
                            DeclRefExpr *&DRE) {}

  // A visitor to determine if a continue or break statement is a
  // subexpression.
  class BreakContinueFinder : public ConstEvaluatedExprVisitor<BreakContinueFinder> {};  // end class BreakContinueFinder

  // Emit a warning when a loop increment/decrement appears twice per loop
  // iteration.  The conditions which trigger this warning are:
  // 1) The last statement in the loop body and the third expression in the
  //    for loop are both increment or both decrement of the same variable
  // 2) No continue statements in the loop body.
  void CheckForRedundantIteration(Sema &S, Expr *Third, Stmt *Body) {}

} // end namespace


void Sema::CheckBreakContinueBinding(Expr *E) {}

StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
                              Stmt *First, ConditionResult Second,
                              FullExprArg third, SourceLocation RParenLoc,
                              Stmt *Body) {}

StmtResult Sema::ActOnForEachLValueExpr(Expr *E) {}

/// Finish building a variable declaration for a for-range statement.
/// \return true if an error occurs.
static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init,
                                  SourceLocation Loc, int DiagID) {}

namespace {
// An enum to represent whether something is dealing with a call to begin()
// or a call to end() in a range-based for loop.
enum BeginEndFunction {};

/// Produce a note indicating which begin/end function was implicitly called
/// by a C++11 for-range statement. This is often not obvious from the code,
/// nor from the diagnostics produced when analysing the implicit expressions
/// required in a for-range statement.
void NoteForRangeBeginEndFunction(Sema &SemaRef, Expr *E,
                                  BeginEndFunction BEF) {}

/// Build a variable declaration for a for-range statement.
VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc,
                              QualType Type, StringRef Name) {}

}

static bool ObjCEnumerationCollection(Expr *Collection) {}

StmtResult Sema::ActOnCXXForRangeStmt(
    Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt,
    Stmt *First, SourceLocation ColonLoc, Expr *Range, SourceLocation RParenLoc,
    BuildForRangeKind Kind,
    ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {}

/// Create the initialization, compare, and increment steps for
/// the range-based for loop expression.
/// This function does not handle array-based for loops,
/// which are created in Sema::BuildCXXForRangeStmt.
///
/// \returns a ForRangeStatus indicating success or what kind of error occurred.
/// BeginExpr and EndExpr are set and FRS_Success is returned on success;
/// CandidateSet and BEF are set and some non-success value is returned on
/// failure.
static Sema::ForRangeStatus
BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange,
                      QualType RangeType, VarDecl *BeginVar, VarDecl *EndVar,
                      SourceLocation ColonLoc, SourceLocation CoawaitLoc,
                      OverloadCandidateSet *CandidateSet, ExprResult *BeginExpr,
                      ExprResult *EndExpr, BeginEndFunction *BEF) {}

/// Speculatively attempt to dereference an invalid range expression.
/// If the attempt fails, this function will return a valid, null StmtResult
/// and emit no diagnostics.
static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S,
                                                 SourceLocation ForLoc,
                                                 SourceLocation CoawaitLoc,
                                                 Stmt *InitStmt,
                                                 Stmt *LoopVarDecl,
                                                 SourceLocation ColonLoc,
                                                 Expr *Range,
                                                 SourceLocation RangeLoc,
                                                 SourceLocation RParenLoc) {}

StmtResult Sema::BuildCXXForRangeStmt(
    SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt,
    SourceLocation ColonLoc, Stmt *RangeDecl, Stmt *Begin, Stmt *End,
    Expr *Cond, Expr *Inc, Stmt *LoopVarDecl, SourceLocation RParenLoc,
    BuildForRangeKind Kind,
    ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {}

// Warn when the loop variable is a const reference that creates a copy.
// Suggest using the non-reference type for copies.  If a copy can be prevented
// suggest the const reference type that would do so.
// For instance, given "for (const &Foo : Range)", suggest
// "for (const Foo : Range)" to denote a copy is made for the loop.  If
// possible, also suggest "for (const &Bar : Range)" if this type prevents
// the copy altogether.
static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef,
                                                    const VarDecl *VD,
                                                    QualType RangeInitType) {}

/// Determines whether the @p VariableType's declaration is a record with the
/// clang::trivial_abi attribute.
static bool hasTrivialABIAttr(QualType VariableType) {}

// Warns when the loop variable can be changed to a reference type to
// prevent a copy.  For instance, if given "for (const Foo x : Range)" suggest
// "for (const Foo &x : Range)" if this form does not make a copy.
static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef,
                                                const VarDecl *VD) {}

/// DiagnoseForRangeVariableCopies - Diagnose three cases and fixes for them.
/// 1) for (const foo &x : foos) where foos only returns a copy.  Suggest
///    using "const foo x" to show that a copy is made
/// 2) for (const bar &x : foos) where bar is a temporary initialized by bar.
///    Suggest either "const bar x" to keep the copying or "const foo& x" to
///    prevent the copy.
/// 3) for (const foo x : foos) where x is constructed from a reference foo.
///    Suggest "const foo &x" to prevent the copy.
static void DiagnoseForRangeVariableCopies(Sema &SemaRef,
                                           const CXXForRangeStmt *ForStmt) {}

StmtResult Sema::FinishCXXForRangeStmt(Stmt *S, Stmt *B) {}

StmtResult Sema::ActOnGotoStmt(SourceLocation GotoLoc,
                               SourceLocation LabelLoc,
                               LabelDecl *TheDecl) {}

StmtResult
Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
                            Expr *E) {}

static void CheckJumpOutOfSEHFinally(Sema &S, SourceLocation Loc,
                                     const Scope &DestScope) {}

StmtResult
Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {}

StmtResult
Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {}

Sema::NamedReturnInfo Sema::getNamedReturnInfo(Expr *&E,
                                               SimplerImplicitMoveMode Mode) {}

Sema::NamedReturnInfo Sema::getNamedReturnInfo(const VarDecl *VD) {}

const VarDecl *Sema::getCopyElisionCandidate(NamedReturnInfo &Info,
                                             QualType ReturnType) {}

/// Verify that the initialization sequence that was picked for the
/// first overload resolution is permissible under C++98.
///
/// Reject (possibly converting) constructors not taking an rvalue reference,
/// or user conversion operators which are not ref-qualified.
static bool
VerifyInitializationSequenceCXX98(const Sema &S,
                                  const InitializationSequence &Seq) {}

ExprResult Sema::PerformMoveOrCopyInitialization(
    const InitializedEntity &Entity, const NamedReturnInfo &NRInfo, Expr *Value,
    bool SupressSimplerImplicitMoves) {}

/// Determine whether the declared return type of the specified function
/// contains 'auto'.
static bool hasDeducedReturnType(FunctionDecl *FD) {}

StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
                                         Expr *RetValExp,
                                         NamedReturnInfo &NRInfo,
                                         bool SupressSimplerImplicitMoves) {}

namespace {
/// Marks all typedefs in all local classes in a type referenced.
///
/// In a function like
/// auto f() {
///   struct S { typedef int a; };
///   return S();
/// }
///
/// the local type escapes and could be referenced in some TUs but not in
/// others. Pretend that all local typedefs are always referenced, to not warn
/// on this. This isn't necessary if f has internal linkage, or the typedef
/// is private.
class LocalTypedefNameReferencer
    : public RecursiveASTVisitor<LocalTypedefNameReferencer> {};
bool LocalTypedefNameReferencer::VisitRecordType(const RecordType *RT) {}
}

TypeLoc Sema::getReturnTypeLoc(FunctionDecl *FD) const {}

bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
                                            SourceLocation ReturnLoc,
                                            Expr *RetExpr, const AutoType *AT) {}

StmtResult
Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
                      Scope *CurScope) {}

static bool CheckSimplerImplicitMovesMSVCWorkaround(const Sema &S,
                                                    const Expr *E) {}

StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
                                 bool AllowRecovery) {}

StmtResult
Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl,
                         Stmt *HandlerBlock) {}

namespace {
class CatchHandlerType {};
} // namespace

namespace llvm {
template <> struct DenseMapInfo<CatchHandlerType> {};
}

namespace {
class CatchTypePublicBases {};
}

StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
                                  ArrayRef<Stmt *> Handlers) {}

StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc,
                                  Stmt *TryBlock, Stmt *Handler) {}

StmtResult Sema::ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr,
                                     Stmt *Block) {}

void Sema::ActOnStartSEHFinallyBlock() {}

void Sema::ActOnAbortSEHFinallyBlock() {}

StmtResult Sema::ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block) {}

StmtResult
Sema::ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope) {}

StmtResult Sema::BuildMSDependentExistsStmt(SourceLocation KeywordLoc,
                                            bool IsIfExists,
                                            NestedNameSpecifierLoc QualifierLoc,
                                            DeclarationNameInfo NameInfo,
                                            Stmt *Nested)
{}


StmtResult Sema::ActOnMSDependentExistsStmt(SourceLocation KeywordLoc,
                                            bool IsIfExists,
                                            CXXScopeSpec &SS,
                                            UnqualifiedId &Name,
                                            Stmt *Nested) {}

RecordDecl*
Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc,
                                   unsigned NumParams) {}

static bool
buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI,
                             SmallVectorImpl<CapturedStmt::Capture> &Captures,
                             SmallVectorImpl<Expr *> &CaptureInits) {}

void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
                                    CapturedRegionKind Kind,
                                    unsigned NumParams) {}

void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
                                    CapturedRegionKind Kind,
                                    ArrayRef<CapturedParamNameType> Params,
                                    unsigned OpenMPCaptureLevel) {}

void Sema::ActOnCapturedRegionError() {}

StmtResult Sema::ActOnCapturedRegionEnd(Stmt *S) {}