clang 19.0.0git
Functions
SemaLambda.cpp File Reference
#include "clang/Sema/SemaLambda.h"
#include "TypeLocBuilder.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/Template.h"
#include "llvm/ADT/STLExtras.h"
#include <optional>

Go to the source code of this file.

Functions

static std::optional< unsignedgetStackIndexOfNearestEnclosingCaptureReadyLambda (ArrayRef< const clang::sema::FunctionScopeInfo * > FunctionScopes, ValueDecl *VarToCapture)
 Examines the FunctionScopeInfo stack to determine the nearest enclosing lambda (to the current lambda) that is 'capture-ready' for the variable referenced in the current lambda (i.e.
 
static TemplateParameterListgetGenericLambdaTemplateParameterList (LambdaScopeInfo *LSI, Sema &SemaRef)
 
static bool isInInlineFunction (const DeclContext *DC)
 Determine whether the given context is or is enclosed in an inline function.
 
static QualType buildTypeForLambdaCallOperator (Sema &S, clang::CXXRecordDecl *Class, TemplateParameterList *TemplateParams, TypeSourceInfo *MethodTypeInfo)
 
static void buildLambdaScopeReturnType (Sema &S, LambdaScopeInfo *LSI, CXXMethodDecl *CallOperator, bool ExplicitResultType)
 
static EnumDeclfindEnumForBlockReturn (Expr *E)
 If this expression is an enumerator-like expression of some type T, return the type T; otherwise, return null.
 
static EnumDeclfindEnumForBlockReturn (ReturnStmt *ret)
 Attempt to find a type T for which the returned expression of the given statement is an enumerator-like expression of that type.
 
static EnumDeclfindCommonEnumForBlockReturns (ArrayRef< ReturnStmt * > returns)
 Attempt to find a common type T for which all of the returned expressions in a block are enumerator-like expressions of that type.
 
static void adjustBlockReturnsToEnum (Sema &S, ArrayRef< ReturnStmt * > returns, QualType returnType)
 Adjust the given return statements so that they formally return the given type.
 
static LambdaScopeInfogetCurrentLambdaScopeUnsafe (Sema &S)
 
static TypeSourceInfogetDummyLambdaType (Sema &S, SourceLocation Loc=SourceLocation())
 
static TypeSourceInfogetLambdaType (Sema &S, LambdaIntroducer &Intro, Declarator &ParamInfo, Scope *CurScope, SourceLocation Loc, bool &ExplicitResultType)
 
template<typename Func >
static void repeatForLambdaConversionFunctionCallingConvs (Sema &S, const FunctionProtoType &CallOpProto, Func F)
 
static CallingConv getLambdaConversionFunctionCallConv (Sema &S, const FunctionProtoType *CallOpProto)
 
static void addFunctionPointerConversion (Sema &S, SourceRange IntroducerRange, CXXRecordDecl *Class, CXXMethodDecl *CallOperator, QualType InvokerFunctionTy)
 Add a lambda's conversion to function pointer, as described in C++11 [expr.prim.lambda]p6.
 
static void addFunctionPointerConversions (Sema &S, SourceRange IntroducerRange, CXXRecordDecl *Class, CXXMethodDecl *CallOperator)
 Add a lambda's conversion to function pointers, as described in C++11 [expr.prim.lambda]p6.
 
static void addBlockPointerConversion (Sema &S, SourceRange IntroducerRange, CXXRecordDecl *Class, CXXMethodDecl *CallOperator)
 Add a lambda's conversion to block pointer.
 
static LambdaCaptureDefault mapImplicitCaptureStyle (CapturingScopeInfo::ImplicitCaptureStyle ICS)
 
static FunctionDeclgetPatternFunctionDecl (FunctionDecl *FD)
 

Function Documentation

◆ addBlockPointerConversion()

static void addBlockPointerConversion ( Sema S,
SourceRange  IntroducerRange,
CXXRecordDecl Class,
CXXMethodDecl CallOperator 
)
static

◆ addFunctionPointerConversion()

static void addFunctionPointerConversion ( Sema S,
SourceRange  IntroducerRange,
CXXRecordDecl Class,
CXXMethodDecl CallOperator,
QualType  InvokerFunctionTy 
)
static

Add a lambda's conversion to function pointer, as described in C++11 [expr.prim.lambda]p6.

Definition at line 1600 of file SemaLambda.cpp.

References clang::Qualifiers::addConst(), clang::AS_private, clang::AS_public, clang::Class, clang::Constexpr, clang::Sema::Context, clang::CXXConversionDecl::Create(), clang::CXXMethodDecl::Create(), clang::FunctionTemplateDecl::Create(), clang::ParmVarDecl::Create(), clang::ASTContext::DeclarationNames, clang::EST_BasicNoexcept, clang::FunctionProtoType::ExtProtoInfo::ExceptionSpec, clang::IdentifierTable::get(), clang::TypeLoc::getAs(), clang::SourceRange::getBegin(), clang::DeclaratorDecl::getBeginLoc(), clang::FunctionDecl::getBody(), clang::ASTContext::getCanonicalType(), clang::FunctionDecl::getConstexprKind(), clang::Sema::getCurFPFeatures(), clang::DeclarationNameTable::getCXXConversionFunctionName(), clang::ASTContext::getDefaultCallingConvention(), clang::FunctionDecl::getDescribedFunctionTemplate(), clang::Stmt::getEndLoc(), clang::ASTContext::getFunctionType(), clang::NamedDecl::getIdentifier(), clang::getLambdaStaticInvokerName(), clang::Sema::getLangOpts(), clang::Decl::getLocation(), clang::FunctionDecl::getNumParams(), clang::FunctionDecl::getParamDecl(), clang::ASTContext::getPointerType(), clang::FunctionTypeLoc::getReturnLoc(), clang::VarDecl::getStorageClass(), clang::TemplateDecl::getTemplateParameters(), clang::DeclaratorDecl::getTrailingRequiresClause(), clang::ASTContext::getTranslationUnitDecl(), clang::ASTContext::getTrivialTypeSourceInfo(), clang::ValueDecl::getType(), clang::TypeSourceInfo::getTypeLoc(), clang::DeclaratorDecl::getTypeSourceInfo(), clang::ASTContext::Idents, clang::FPOptions::isFPConstrained(), clang::CXXMethodDecl::isImplicitObjectMemberFunction(), clang::DeclarationNameLoc::makeNamedTypeLoc(), P, clang::FunctionDecl::parameters(), clang::SC_Static, clang::Decl::setAccess(), clang::FunctionDecl::setDescribedFunctionTemplate(), clang::Decl::setImplicit(), clang::FunctionDecl::setParams(), clang::DeclaratorDecl::setTrailingRequiresClause(), clang::FunctionProtoType::ExceptionSpecInfo::Type, clang::FunctionProtoType::ExtProtoInfo::TypeQuals, and clang::Unspecified.

Referenced by addFunctionPointerConversions().

◆ addFunctionPointerConversions()

static void addFunctionPointerConversions ( Sema S,
SourceRange  IntroducerRange,
CXXRecordDecl Class,
CXXMethodDecl CallOperator 
)
static

Add a lambda's conversion to function pointers, as described in C++11 [expr.prim.lambda]p6.

Note that in most cases, this should emit only a single pointer conversion. In the event that the default calling convention for free and member functions is different, it will emit both conventions.

Definition at line 1775 of file SemaLambda.cpp.

References addFunctionPointerConversion(), clang::Type::castAs(), clang::Class, clang::Sema::getLambdaConversionFunctionResultType(), clang::ValueDecl::getType(), and repeatForLambdaConversionFunctionCallingConvs().

Referenced by clang::Sema::BuildLambdaExpr().

◆ adjustBlockReturnsToEnum()

static void adjustBlockReturnsToEnum ( Sema S,
ArrayRef< ReturnStmt * >  returns,
QualType  returnType 
)
static

◆ buildLambdaScopeReturnType()

static void buildLambdaScopeReturnType ( Sema S,
LambdaScopeInfo LSI,
CXXMethodDecl CallOperator,
bool  ExplicitResultType 
)
static

◆ buildTypeForLambdaCallOperator()

static QualType buildTypeForLambdaCallOperator ( Sema S,
clang::CXXRecordDecl Class,
TemplateParameterList TemplateParams,
TypeSourceInfo MethodTypeInfo 
)
static

◆ findCommonEnumForBlockReturns()

static EnumDecl * findCommonEnumForBlockReturns ( ArrayRef< ReturnStmt * >  returns)
static

Attempt to find a common type T for which all of the returned expressions in a block are enumerator-like expressions of that type.

Definition at line 602 of file SemaLambda.cpp.

References findEnumForBlockReturn(), and clang::TagDecl::hasNameForLinkage().

Referenced by clang::Sema::deduceClosureReturnType().

◆ findEnumForBlockReturn() [1/2]

static EnumDecl * findEnumForBlockReturn ( Expr E)
static

If this expression is an enumerator-like expression of some type T, return the type T; otherwise, return null.

Pointer comparisons on the result here should always work because it's derived from either the parent of an EnumConstantDecl (i.e. the definition) or the declaration returned by EnumType::getDecl() (i.e. the definition).

Definition at line 530 of file SemaLambda.cpp.

References findEnumForBlockReturn(), clang::Type::getAs(), clang::Expr::getType(), and clang::Expr::IgnoreParens().

Referenced by findCommonEnumForBlockReturns(), and findEnumForBlockReturn().

◆ findEnumForBlockReturn() [2/2]

static EnumDecl * findEnumForBlockReturn ( ReturnStmt ret)
static

Attempt to find a type T for which the returned expression of the given statement is an enumerator-like expression of that type.

Definition at line 593 of file SemaLambda.cpp.

References findEnumForBlockReturn(), and clang::ReturnStmt::getRetValue().

◆ getCurrentLambdaScopeUnsafe()

static LambdaScopeInfo * getCurrentLambdaScopeUnsafe ( Sema S)
static

◆ getDummyLambdaType()

static TypeSourceInfo * getDummyLambdaType ( Sema S,
SourceLocation  Loc = SourceLocation() 
)
static

◆ getGenericLambdaTemplateParameterList()

static TemplateParameterList * getGenericLambdaTemplateParameterList ( LambdaScopeInfo LSI,
Sema SemaRef 
)
inlinestatic

◆ getLambdaConversionFunctionCallConv()

static CallingConv getLambdaConversionFunctionCallConv ( Sema S,
const FunctionProtoType CallOpProto 
)
static

◆ getLambdaType()

static TypeSourceInfo * getLambdaType ( Sema S,
LambdaIntroducer Intro,
Declarator ParamInfo,
Scope CurScope,
SourceLocation  Loc,
bool ExplicitResultType 
)
static

◆ getPatternFunctionDecl()

static FunctionDecl * getPatternFunctionDecl ( FunctionDecl FD)
static

◆ getStackIndexOfNearestEnclosingCaptureReadyLambda()

static std::optional< unsigned > getStackIndexOfNearestEnclosingCaptureReadyLambda ( ArrayRef< const clang::sema::FunctionScopeInfo * >  FunctionScopes,
ValueDecl VarToCapture 
)
inlinestatic

Examines the FunctionScopeInfo stack to determine the nearest enclosing lambda (to the current lambda) that is 'capture-ready' for the variable referenced in the current lambda (i.e.

VarToCapture). If successful, returns the index into Sema's FunctionScopeInfo stack of the capture-ready lambda's LambdaScopeInfo.

Climbs down the stack of lambdas (deepest nested lambda - i.e. current lambda - is on top) to determine the index of the nearest enclosing/outer lambda that is ready to capture the VarToCapture being referenced in the current lambda. As we climb down the stack, we want the index of the first such lambda - that is the lambda with the highest index that is 'capture-ready'.

A lambda 'L' is capture-ready for 'V' (var or this) if:

  • its enclosing context is non-dependent
  • and if the chain of lambdas between L and the lambda in which V is potentially used (i.e. the lambda at the top of the scope info stack), can all capture or have already captured V. If VarToCapture is 'null' then we are trying to capture 'this'.

Note that a lambda that is deemed 'capture-ready' still needs to be checked for whether it is 'capture-capable' (see getStackIndexOfNearestEnclosingCaptureCapableLambda), before it can truly capture.

Parameters
FunctionScopes- Sema's stack of nested FunctionScopeInfo's (which a LambdaScopeInfo inherits from). The current/deepest/innermost lambda is at the top of the stack and has the highest index.
VarToCapture- the variable to capture. If NULL, capture 'this'.
Returns
An std::optional<unsigned> Index that if evaluates to 'true' contains the index (into Sema's FunctionScopeInfo stack) of the innermost lambda which is capture-ready. If the return value evaluates to 'false' then no lambda is capture-ready for VarToCapture.

Definition at line 67 of file SemaLambda.cpp.

References clang::DeclContext::Equals(), clang::Decl::getDeclContext(), clang::getLambdaAwareParentOfDeclContext(), clang::sema::CapturingScopeInfo::ImpCaptureStyle, clang::sema::CapturingScopeInfo::isCaptured(), clang::sema::CapturingScopeInfo::isCXXThisCaptured(), clang::DeclContext::isDependentContext(), clang::isLambdaCallOperator(), and clang::DeclContext::isTranslationUnit().

Referenced by clang::getStackIndexOfNearestEnclosingCaptureCapableLambda().

◆ isInInlineFunction()

static bool isInInlineFunction ( const DeclContext DC)
static

Determine whether the given context is or is enclosed in an inline function.

Definition at line 267 of file SemaLambda.cpp.

References clang::DeclContext::getLexicalParent(), and clang::DeclContext::isFileContext().

Referenced by clang::Sema::getCurrentMangleNumberContext().

◆ mapImplicitCaptureStyle()

static LambdaCaptureDefault mapImplicitCaptureStyle ( CapturingScopeInfo::ImplicitCaptureStyle  ICS)
static

◆ repeatForLambdaConversionFunctionCallingConvs()

template<typename Func >
static void repeatForLambdaConversionFunctionCallingConvs ( Sema S,
const FunctionProtoType CallOpProto,
Func  F 
)
static

Implement emitting a version of the operator for many of the calling conventions for MSVC, as described here: https://devblogs.microsoft.com/oldnewthing/20150220-00/?p=44623. Experimentally, we determined that cdecl, stdcall, fastcall, and vectorcall are generated by MSVC when it is supported by the target. Additionally, we are ensuring that the default-free/default-member and call-operator calling convention are generated as well. NOTE: We intentionally generate a 'thiscall' on Win32 implicitly from the 'member default', despite MSVC not doing so. We do this in order to ensure that someone who intentionally places 'thiscall' on the lambda call operator will still get that overload, since we don't have the a way of detecting the attribute by the time we get here.

Definition at line 1522 of file SemaLambda.cpp.

References clang::C, clang::CC_C, clang::CC_X86FastCall, clang::CC_X86StdCall, clang::CC_X86VectorCall, clang::TargetInfo::CCCR_OK, clang::TargetInfo::checkCallingConvention(), clang::Sema::Context, clang::Sema::getASTContext(), clang::FunctionType::getCallConv(), clang::ASTContext::getDefaultCallingConvention(), clang::Sema::getLangOpts(), clang::ASTContext::getTargetInfo(), and clang::FunctionProtoType::isVariadic().

Referenced by addFunctionPointerConversions().