Merge pull request #1115 from dave-bartolomeo/dave/Lambdas

C++: IR construction for lambda expressions
This commit is contained in:
Robert Marsh
2019-03-26 15:08:34 -07:00
committed by GitHub
10 changed files with 1446 additions and 84 deletions

View File

@@ -57,6 +57,14 @@ class LambdaExpression extends Expr, @lambdaexpr {
Operator getLambdaFunction() {
result = getType().(Closure).getLambdaFunction()
}
/**
* Gets the initializer that initializes the captured variables in the closure, if any.
* A lambda that does not capture any variables will not have an initializer.
*/
Expr getInitializer() {
result = getChild(0)
}
}
/**

View File

@@ -3,6 +3,6 @@ private import semmle.code.cpp.ir.internal.TempVariableTag
class TempVariableTag extends TTempVariableTag {
string toString() {
result = "Tag"
result = getTempVariableTagId(this)
}
}

View File

@@ -99,6 +99,7 @@ class InstructionTag extends TInstructionTag {
string getInstructionTagId(TInstructionTag tag) {
tag = OnlyInstructionTag() and result = "Only" or // Single instruction (not including implicit Load)
tag = InitializerVariableAddressTag() and result = "InitVarAddr" or
tag = InitializerLoadStringTag() and result = "InitLoadStr" or
tag = InitializerStoreTag() and result = "InitStore" or
tag = InitializerUninitializedTag() and result = "InitUninit" or
tag = ZeroPadStringConstantTag() and result = "ZeroPadConst" or

View File

@@ -268,6 +268,9 @@ newtype TTranslatedElement =
) or
exists(ThrowExpr throw |
throw.getExpr().getFullyConverted() = expr
) or
exists(LambdaExpression lambda |
lambda.getInitializer().getFullyConverted() = expr
)
)
} or

View File

@@ -2608,3 +2608,122 @@ class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr {
result = getTranslatedExpr(expr.getVariableAccess().getFullyConverted())
}
}
/**
* The IR translation of a lambda expression. This initializes a temporary variable whose type is that of the lambda,
* using the initializer list that represents the captures of the lambda.
*/
class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationContext {
override LambdaExpression expr;
override final Instruction getFirstInstruction() {
result = getInstruction(InitializerVariableAddressTag())
}
override final TranslatedElement getChild(int id) {
id = 0 and result = getInitialization()
}
override Instruction getResult() {
result = getInstruction(LoadTag())
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
(
tag = InitializerVariableAddressTag() and
kind instanceof GotoEdge and
result = getInstruction(InitializerStoreTag())
) or
(
tag = InitializerStoreTag() and
kind instanceof GotoEdge and
(
result = getInitialization().getFirstInstruction() or
not hasInitializer() and result = getInstruction(LoadTag())
)
) or
(
tag = LoadTag() and
kind instanceof GotoEdge and
result = getParent().getChildSuccessor(this)
)
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitialization() and
result = getInstruction(LoadTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType,
boolean isGLValue) {
(
tag = InitializerVariableAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getResultType() and
isGLValue = true
) or
(
tag = InitializerStoreTag() and
opcode instanceof Opcode::Uninitialized and
resultType = getResultType() and
isGLValue = false
) or
(
tag = LoadTag() and
opcode instanceof Opcode::Load and
resultType = getResultType() and
isGLValue = false
)
}
override Instruction getInstructionOperand(InstructionTag tag,
OperandTag operandTag) {
(
tag = InitializerStoreTag() and
operandTag instanceof AddressOperandTag and
result = getInstruction(InitializerVariableAddressTag())
) or
(
tag = LoadTag() and
(
(
operandTag instanceof AddressOperandTag and
result = getInstruction(InitializerVariableAddressTag())
) or
(
operandTag instanceof LoadOperandTag and
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
)
)
)
}
override IRVariable getInstructionVariable(InstructionTag tag) {
(
tag = InitializerVariableAddressTag() or
tag = InitializerStoreTag()
) and
result = getTempVariable(LambdaTempVar())
}
override predicate hasTempVariable(TempVariableTag tag, Type type) {
tag = LambdaTempVar() and
type = getResultType()
}
override final Instruction getTargetAddress() {
result = getInstruction(InitializerVariableAddressTag())
}
override final Type getTargetType() {
result = getResultType()
}
private predicate hasInitializer() {
exists(getInitialization())
}
private TranslatedInitialization getInitialization() {
result = getTranslatedInitialization(expr.getChild(0).getFullyConverted())
}
}

View File

@@ -35,8 +35,7 @@ abstract class InitializationContext extends TranslatedElement {
* Represents the IR translation of any initialization, whether from an
* initializer list or from a direct initializer.
*/
abstract class TranslatedInitialization extends TranslatedElement,
TTranslatedInitialization {
abstract class TranslatedInitialization extends TranslatedElement, TTranslatedInitialization {
Expr expr;
TranslatedInitialization() {
@@ -78,10 +77,10 @@ abstract class TranslatedInitialization extends TranslatedElement,
/**
* Represents the IR translation of an initialization from an initializer list.
*/
abstract class TranslatedListInitialization extends TranslatedInitialization,
InitializationContext {
abstract class TranslatedListInitialization extends TranslatedInitialization, InitializationContext {
override Instruction getFirstInstruction() {
result = getChild(0).getFirstInstruction()
result = getChild(0).getFirstInstruction() or
not exists(getChild(0)) and result = getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
@@ -117,8 +116,7 @@ abstract class TranslatedListInitialization extends TranslatedInitialization,
* Represents the IR translation of an initialization of a class object from an
* initializer list.
*/
class TranslatedClassListInitialization extends
TranslatedListInitialization
class TranslatedClassListInitialization extends TranslatedListInitialization
{
override ClassAggregateLiteral expr;
@@ -135,8 +133,7 @@ class TranslatedClassListInitialization extends
* Represents the IR translation of an initialization of an array from an
* initializer list.
*/
class TranslatedArrayListInitialization extends
TranslatedListInitialization {
class TranslatedArrayListInitialization extends TranslatedListInitialization {
override ArrayAggregateLiteral expr;
override TranslatedElement getChild(int id) {
@@ -175,23 +172,20 @@ abstract class TranslatedDirectInitialization extends TranslatedInitialization {
* expression, where the initialization is performed via bitwise copy (as
* opposed to a constructor).
*/
class TranslatedSimpleDirectInitialization extends
TranslatedDirectInitialization {
class TranslatedSimpleDirectInitialization extends TranslatedDirectInitialization {
TranslatedSimpleDirectInitialization() {
not expr instanceof ConstructorCall and
not expr instanceof StringLiteral
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
Type resultType, boolean isGLValue) {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType, boolean isGLValue) {
tag = InitializerStoreTag() and
opcode instanceof Opcode::Store and
resultType = getContext().getTargetType() and
isGLValue = false
}
override Instruction getInstructionSuccessor(InstructionTag tag,
EdgeKind kind) {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = InitializerStoreTag() and
result = getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
@@ -201,8 +195,7 @@ class TranslatedSimpleDirectInitialization extends
child = getInitializer() and result = getInstruction(InitializerStoreTag())
}
override Instruction getInstructionOperand(InstructionTag tag,
OperandTag operandTag) {
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
tag = InitializerStoreTag() and
(
(
@@ -221,12 +214,10 @@ class TranslatedSimpleDirectInitialization extends
* Represents the IR translation of an initialization of an array from a string
* literal.
*/
class TranslatedStringLiteralInitialization extends
TranslatedDirectInitialization {
class TranslatedStringLiteralInitialization extends TranslatedDirectInitialization {
override StringLiteral expr;
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
Type resultType, boolean isGLValue) {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType, boolean isGLValue) {
(
// Load the string literal to make it a prvalue of type `char[len]`
tag = InitializerLoadStringTag() and
@@ -280,8 +271,7 @@ class TranslatedStringLiteralInitialization extends
)
}
override Instruction getInstructionSuccessor(InstructionTag tag,
EdgeKind kind) {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
(
@@ -321,8 +311,7 @@ class TranslatedStringLiteralInitialization extends
child = getInitializer() and result = getInstruction(InitializerLoadStringTag())
}
override Instruction getInstructionOperand(InstructionTag tag,
OperandTag operandTag) {
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
(
tag = InitializerLoadStringTag() and
(
@@ -422,17 +411,14 @@ class TranslatedStringLiteralInitialization extends
}
}
class TranslatedConstructorInitialization extends
TranslatedDirectInitialization, StructorCallContext {
class TranslatedConstructorInitialization extends TranslatedDirectInitialization, StructorCallContext {
override ConstructorCall expr;
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
Type resultType, boolean isGLValue) {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType, boolean isGLValue) {
none()
}
override Instruction getInstructionSuccessor(InstructionTag tag,
EdgeKind kind) {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
none()
}
@@ -440,8 +426,7 @@ class TranslatedConstructorInitialization extends
child = getInitializer() and result = getParent().getChildSuccessor(this)
}
override Instruction getInstructionOperand(InstructionTag tag,
OperandTag operandTag) {
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
none()
}
@@ -454,13 +439,11 @@ class TranslatedConstructorInitialization extends
* Gets the `TranslatedFieldInitialization` for field `field` within initializer
* list `initList`.
*/
TranslatedFieldInitialization getTranslatedFieldInitialization(
ClassAggregateLiteral initList, Field field) {
TranslatedFieldInitialization getTranslatedFieldInitialization(ClassAggregateLiteral initList, Field field) {
result.getAST() = initList and result.getField() = field
}
TranslatedFieldInitialization getTranslatedConstructorFieldInitialization(
ConstructorFieldInit init) {
TranslatedFieldInitialization getTranslatedConstructorFieldInitialization(ConstructorFieldInit init) {
result.getAST() = init
}
@@ -496,16 +479,14 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
result = field.getInitializationOrder()
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
Type resultType, boolean isGLValue) {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType, boolean isGLValue) {
tag = getFieldAddressTag() and
opcode instanceof Opcode::FieldAddress and
resultType = field.getType().getUnspecifiedType() and
isGLValue = true
}
override Instruction getInstructionOperand(InstructionTag tag,
OperandTag operandTag) {
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
tag = getFieldAddressTag() and
operandTag instanceof UnaryOperandTag and
result = getParent().(InitializationContext).getTargetAddress()
@@ -528,9 +509,8 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
* Represents the IR translation of the initialization of a field from an
* explicit element in an initializer list.
*/
class TranslatedExplicitFieldInitialization extends
TranslatedFieldInitialization, InitializationContext,
TTranslatedExplicitFieldInitialization {
class TranslatedExplicitFieldInitialization extends TranslatedFieldInitialization, InitializationContext,
TTranslatedExplicitFieldInitialization {
Expr expr;
TranslatedExplicitFieldInitialization() {
@@ -545,8 +525,7 @@ class TranslatedExplicitFieldInitialization extends
result = field.getType().getUnspecifiedType()
}
override Instruction getInstructionSuccessor(InstructionTag tag,
EdgeKind kind) {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = getFieldAddressTag() and
result = getInitialization().getFirstInstruction() and
kind instanceof GotoEdge
@@ -576,14 +555,12 @@ private string getZeroValue(Type type) {
* Represents the IR translation of the initialization of a field without a
* corresponding element in the initializer list.
*/
class TranslatedFieldValueInitialization extends
TranslatedFieldInitialization, TTranslatedFieldValueInitialization {
class TranslatedFieldValueInitialization extends TranslatedFieldInitialization, TTranslatedFieldValueInitialization {
TranslatedFieldValueInitialization() {
this = TTranslatedFieldValueInitialization(ast, field)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
Type resultType, boolean isGLValue) {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType, boolean isGLValue) {
TranslatedFieldInitialization.super.hasInstruction(opcode, tag, resultType, isGLValue) or
(
tag = getFieldDefaultValueTag() and
@@ -599,8 +576,7 @@ class TranslatedFieldValueInitialization extends
)
}
override Instruction getInstructionSuccessor(InstructionTag tag,
EdgeKind kind) {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
(
@@ -623,8 +599,7 @@ class TranslatedFieldValueInitialization extends
result = getZeroValue(field.getType().getUnspecifiedType())
}
override Instruction getInstructionOperand(InstructionTag tag,
OperandTag operandTag) {
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
result = TranslatedFieldInitialization.super.getInstructionOperand(tag, operandTag) or
(
tag = getFieldDefaultValueStoreTag() and
@@ -681,8 +656,7 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
result = getInstruction(getElementIndexTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
Type resultType, boolean isGLValue) {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType, boolean isGLValue) {
(
tag = getElementIndexTag() and
opcode instanceof Opcode::Constant and
@@ -697,15 +671,13 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
)
}
override Instruction getInstructionSuccessor(InstructionTag tag,
EdgeKind kind) {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = getElementIndexTag() and
result = getInstruction(getElementAddressTag()) and
kind instanceof GotoEdge
}
override Instruction getInstructionOperand(InstructionTag tag,
OperandTag operandTag) {
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
tag = getElementAddressTag() and
(
(
@@ -764,8 +736,7 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
result = getElementType()
}
override Instruction getInstructionSuccessor(InstructionTag tag,
EdgeKind kind) {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind) or
(
tag = getElementAddressTag() and
@@ -806,8 +777,7 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
elementCount)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
Type resultType, boolean isGLValue) {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType, boolean isGLValue) {
TranslatedElementInitialization.super.hasInstruction(opcode, tag, resultType, isGLValue) or
(
tag = getElementDefaultValueTag() and
@@ -823,8 +793,7 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
)
}
override Instruction getInstructionSuccessor(InstructionTag tag,
EdgeKind kind) {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind) or
(
kind instanceof GotoEdge and
@@ -862,8 +831,7 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
result = elementCount * getElementType().getSize()
}
override Instruction getInstructionOperand(InstructionTag tag,
OperandTag operandTag) {
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
result = TranslatedElementInitialization.super.getInstructionOperand(tag, operandTag) or
(
tag = getElementDefaultValueStoreTag() and
@@ -943,8 +911,7 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
result = getInstruction(OnlyInstructionTag())
}
override final predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType,
boolean isGLValue) {
override final predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType, boolean isGLValue) {
tag = OnlyInstructionTag() and
opcode instanceof Opcode::ConvertToBase and
resultType = call.getTarget().getDeclaringType().getUnspecifiedType() and
@@ -961,15 +928,13 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
result = getInstruction(OnlyInstructionTag())
}
override final Instruction getInstructionOperand(InstructionTag tag,
OperandTag operandTag) {
override final Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
result = getTranslatedFunction(getFunction()).getInitializeThisInstruction()
}
override final predicate getInstructionInheritance(InstructionTag tag,
Class baseClass, Class derivedClass) {
override final predicate getInstructionInheritance(InstructionTag tag, Class baseClass, Class derivedClass) {
tag = OnlyInstructionTag() and
baseClass = call.getTarget().getDeclaringType().getUnspecifiedType() and
derivedClass = getFunction().getDeclaringType().getUnspecifiedType()
@@ -980,7 +945,7 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
* Represents a call to a delegating or base class constructor from within a constructor.
*/
abstract class TranslatedConstructorCallFromConstructor extends TranslatedStructorCallFromStructor,
TTranslatedConstructorBaseInit {
TTranslatedConstructorBaseInit {
TranslatedConstructorCallFromConstructor() {
this = TTranslatedConstructorBaseInit(call)
}
@@ -1004,8 +969,7 @@ class TranslatedConstructorDelegationInit extends TranslatedConstructorCallFromC
result = getStructorCall().getFirstInstruction()
}
override final predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType,
boolean isGLValue) {
override final predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType, boolean isGLValue) {
none()
}
@@ -1022,8 +986,7 @@ class TranslatedConstructorDelegationInit extends TranslatedConstructorCallFromC
* Represents the IR translation of a call to a base class constructor from within a
* derived class constructor
*/
class TranslatedConstructorBaseInit extends TranslatedConstructorCallFromConstructor,
TranslatedBaseStructorCall {
class TranslatedConstructorBaseInit extends TranslatedConstructorCallFromConstructor, TranslatedBaseStructorCall {
TranslatedConstructorBaseInit() {
not call instanceof ConstructorDelegationInit
}
@@ -1041,8 +1004,7 @@ TranslatedDestructorBaseDestruction getTranslatedDestructorBaseDestruction(Destr
* Represents the IR translation of a call to a base class destructor from within a
* derived class destructor.
*/
class TranslatedDestructorBaseDestruction extends TranslatedBaseStructorCall,
TTranslatedDestructorBaseDestruction {
class TranslatedDestructorBaseDestruction extends TranslatedBaseStructorCall, TTranslatedDestructorBaseDestruction {
TranslatedDestructorBaseDestruction() {
this = TTranslatedDestructorBaseDestruction(call)
}

View File

@@ -3,10 +3,12 @@ import cpp
newtype TTempVariableTag =
ConditionValueTempVar() or
ReturnValueTempVar() or
ThrowTempVar()
ThrowTempVar() or
LambdaTempVar()
string getTempVariableTagId(TTempVariableTag tag) {
tag = ConditionValueTempVar() and result = "CondVal" or
tag = ReturnValueTempVar() and result = "Ret" or
tag = ThrowTempVar() and result = "Throw"
tag = ThrowTempVar() and result = "Throw" or
tag = LambdaTempVar() and result = "Lambda"
}

View File

@@ -6627,3 +6627,783 @@ ir.cpp:
# 988| Type = double
# 988| Value = 1.0
# 988| ValueCategory = prvalue
# 1009| EmptyStruct& EmptyStruct::operator=(EmptyStruct const&)
# 1009| params:
#-----| 0: p#0
#-----| Type = const EmptyStruct &
# 1009| EmptyStruct& EmptyStruct::operator=(EmptyStruct&&)
# 1009| params:
#-----| 0: p#0
#-----| Type = EmptyStruct &&
# 1011| void EmptyStructInit()
# 1011| params:
# 1011| body: { ... }
# 1012| 0: declaration
# 1012| 0: definition of s
# 1012| Type = EmptyStruct
# 1012| init: initializer for s
# 1012| expr: {...}
# 1012| Type = EmptyStruct
# 1012| ValueCategory = prvalue
# 1013| 1: return ...
# 1015| (lambda [] type at line 1015, col. 12)& (lambda [] type at line 1015, col. 12)::operator=((lambda [] type at line 1015, col. 12) const&)
# 1015| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1015, col. 12 &
# 1015| void (lambda [] type at line 1015, col. 12)::(constructor)((lambda [] type at line 1015, col. 12) const&)
# 1015| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1015, col. 12 &
# 1015| void (lambda [] type at line 1015, col. 12)::(constructor)((lambda [] type at line 1015, col. 12)&&)
# 1015| params:
#-----| 0: p#0
#-----| Type = lambda [] type at line 1015, col. 12 &&
# 1015| initializations:
# 1015| body: { ... }
# 1015| 0: return ...
# 1015| void (lambda [] type at line 1015, col. 12)::(constructor)()
# 1015| params:
# 1015| void (lambda [] type at line 1015, col. 12)::_FUN()
# 1015| params:
# 1015| void (lambda [] type at line 1015, col. 12)::operator()() const
# 1015| params:
# 1015| body: { ... }
# 1015| 0: return ...
# 1015| void(* (lambda [] type at line 1015, col. 12)::operator void (*)()() const)()
# 1015| params:
#-----| body: { ... }
# 1015| 0: return ...
# 1015| 0: _FUN
# 1015| Type = ..(*)(..)
# 1015| ValueCategory = prvalue(load)
# 1017| void Lambda(int, String const&)
# 1017| params:
# 1017| 0: x
# 1017| Type = int
# 1017| 1: s
# 1017| Type = const String &
# 1017| body: { ... }
# 1018| 0: declaration
# 1018| 0: definition of lambda_empty
# 1018| Type = decltype([...](...){...})
# 1018| init: initializer for lambda_empty
# 1018| expr: [...](...){...}
# 1018| Type = decltype([...](...){...})
# 1018| ValueCategory = prvalue
# 1019| 1: ExprStmt
# 1019| 0: call to operator()
# 1019| Type = char
# 1019| Value = 65
# 1019| ValueCategory = prvalue
# 1019| -1: (const lambda [] type at line 1018, col. 23)...
# 1019| Conversion = glvalue conversion
# 1019| Type = const lambda [] type at line 1018, col. 23
# 1019| ValueCategory = lvalue
# 1019| expr: lambda_empty
# 1019| Type = decltype([...](...){...})
# 1019| ValueCategory = lvalue
# 1019| 0: (float)...
# 1019| Conversion = integral to floating point conversion
# 1019| Type = float
# 1019| Value = 0.0
# 1019| ValueCategory = prvalue
# 1019| expr: 0
# 1019| Type = int
# 1019| Value = 0
# 1019| ValueCategory = prvalue
# 1020| 2: declaration
# 1020| 0: definition of lambda_ref
# 1020| Type = decltype([...](...){...})
# 1020| init: initializer for lambda_ref
# 1020| expr: [...](...){...}
# 1020| Type = decltype([...](...){...})
# 1020| ValueCategory = prvalue
# 1020| 0: {...}
# 1020| Type = decltype([...](...){...})
# 1020| ValueCategory = prvalue
# 1020| .s: (reference to)
# 1020| Type = const String &
# 1020| ValueCategory = prvalue
# 1020| expr: (reference dereference)
# 1020| Type = const String
# 1020| ValueCategory = lvalue
#-----| expr: s
#-----| Type = const String &
#-----| ValueCategory = prvalue(load)
#-----| .x: (reference to)
#-----| Type = int &
#-----| ValueCategory = prvalue
#-----| expr: x
#-----| Type = int
#-----| ValueCategory = lvalue
# 1021| 3: ExprStmt
# 1021| 0: call to operator()
# 1021| Type = char
# 1021| ValueCategory = prvalue
# 1021| -1: (const lambda [] type at line 1020, col. 21)...
# 1021| Conversion = glvalue conversion
# 1021| Type = const lambda [] type at line 1020, col. 21
# 1021| ValueCategory = lvalue
# 1021| expr: lambda_ref
# 1021| Type = decltype([...](...){...})
# 1021| ValueCategory = lvalue
# 1021| 0: (float)...
# 1021| Conversion = integral to floating point conversion
# 1021| Type = float
# 1021| Value = 1.0
# 1021| ValueCategory = prvalue
# 1021| expr: 1
# 1021| Type = int
# 1021| Value = 1
# 1021| ValueCategory = prvalue
# 1022| 4: declaration
# 1022| 0: definition of lambda_val
# 1022| Type = decltype([...](...){...})
# 1022| init: initializer for lambda_val
# 1022| expr: call to (constructor)
# 1022| Type = void
# 1022| ValueCategory = prvalue
# 1022| 0: (reference to)
# 1022| Type = lambda [] type at line 1022, col. 21 &
# 1022| ValueCategory = prvalue
# 1022| expr: [...](...){...}
# 1022| Type = decltype([...](...){...})
# 1022| ValueCategory = prvalue
# 1022| 0: {...}
# 1022| Type = decltype([...](...){...})
# 1022| ValueCategory = prvalue
#-----| .s: call to String
#-----| Type = void
#-----| ValueCategory = prvalue
#-----| .x: x
#-----| Type = int
#-----| ValueCategory = prvalue(load)
# 1023| 5: ExprStmt
# 1023| 0: call to operator()
# 1023| Type = char
# 1023| ValueCategory = prvalue
# 1023| -1: (const lambda [] type at line 1022, col. 21)...
# 1023| Conversion = glvalue conversion
# 1023| Type = const lambda [] type at line 1022, col. 21
# 1023| ValueCategory = lvalue
# 1023| expr: lambda_val
# 1023| Type = decltype([...](...){...})
# 1023| ValueCategory = lvalue
# 1023| 0: (float)...
# 1023| Conversion = integral to floating point conversion
# 1023| Type = float
# 1023| Value = 2.0
# 1023| ValueCategory = prvalue
# 1023| expr: 2
# 1023| Type = int
# 1023| Value = 2
# 1023| ValueCategory = prvalue
# 1024| 6: declaration
# 1024| 0: definition of lambda_ref_explicit
# 1024| Type = decltype([...](...){...})
# 1024| init: initializer for lambda_ref_explicit
# 1024| expr: [...](...){...}
# 1024| Type = decltype([...](...){...})
# 1024| ValueCategory = prvalue
# 1024| 0: {...}
# 1024| Type = decltype([...](...){...})
# 1024| ValueCategory = prvalue
# 1024| .s: (reference to)
# 1024| Type = const String &
# 1024| ValueCategory = prvalue
# 1024| expr: (reference dereference)
# 1024| Type = const String
# 1024| ValueCategory = lvalue
# 1024| expr: s
# 1024| Type = const String &
# 1024| ValueCategory = prvalue(load)
# 1025| 7: ExprStmt
# 1025| 0: call to operator()
# 1025| Type = char
# 1025| ValueCategory = prvalue
# 1025| -1: (const lambda [] type at line 1024, col. 30)...
# 1025| Conversion = glvalue conversion
# 1025| Type = const lambda [] type at line 1024, col. 30
# 1025| ValueCategory = lvalue
# 1025| expr: lambda_ref_explicit
# 1025| Type = decltype([...](...){...})
# 1025| ValueCategory = lvalue
# 1025| 0: (float)...
# 1025| Conversion = integral to floating point conversion
# 1025| Type = float
# 1025| Value = 3.0
# 1025| ValueCategory = prvalue
# 1025| expr: 3
# 1025| Type = int
# 1025| Value = 3
# 1025| ValueCategory = prvalue
# 1026| 8: declaration
# 1026| 0: definition of lambda_val_explicit
# 1026| Type = decltype([...](...){...})
# 1026| init: initializer for lambda_val_explicit
# 1026| expr: call to (constructor)
# 1026| Type = void
# 1026| ValueCategory = prvalue
# 1026| 0: (reference to)
# 1026| Type = lambda [] type at line 1026, col. 30 &
# 1026| ValueCategory = prvalue
# 1026| expr: [...](...){...}
# 1026| Type = decltype([...](...){...})
# 1026| ValueCategory = prvalue
# 1026| 0: {...}
# 1026| Type = decltype([...](...){...})
# 1026| ValueCategory = prvalue
#-----| .s: call to String
#-----| Type = void
#-----| ValueCategory = prvalue
# 1027| 9: ExprStmt
# 1027| 0: call to operator()
# 1027| Type = char
# 1027| ValueCategory = prvalue
# 1027| -1: (const lambda [] type at line 1026, col. 30)...
# 1027| Conversion = glvalue conversion
# 1027| Type = const lambda [] type at line 1026, col. 30
# 1027| ValueCategory = lvalue
# 1027| expr: lambda_val_explicit
# 1027| Type = decltype([...](...){...})
# 1027| ValueCategory = lvalue
# 1027| 0: (float)...
# 1027| Conversion = integral to floating point conversion
# 1027| Type = float
# 1027| Value = 4.0
# 1027| ValueCategory = prvalue
# 1027| expr: 4
# 1027| Type = int
# 1027| Value = 4
# 1027| ValueCategory = prvalue
# 1028| 10: declaration
# 1028| 0: definition of lambda_mixed_explicit
# 1028| Type = decltype([...](...){...})
# 1028| init: initializer for lambda_mixed_explicit
# 1028| expr: [...](...){...}
# 1028| Type = decltype([...](...){...})
# 1028| ValueCategory = prvalue
# 1028| 0: {...}
# 1028| Type = decltype([...](...){...})
# 1028| ValueCategory = prvalue
# 1028| .s: (reference to)
# 1028| Type = const String &
# 1028| ValueCategory = prvalue
# 1028| expr: (reference dereference)
# 1028| Type = const String
# 1028| ValueCategory = lvalue
# 1028| expr: s
# 1028| Type = const String &
# 1028| ValueCategory = prvalue(load)
# 1028| .x: x
# 1028| Type = int
# 1028| ValueCategory = prvalue(load)
# 1029| 11: ExprStmt
# 1029| 0: call to operator()
# 1029| Type = char
# 1029| ValueCategory = prvalue
# 1029| -1: (const lambda [] type at line 1028, col. 32)...
# 1029| Conversion = glvalue conversion
# 1029| Type = const lambda [] type at line 1028, col. 32
# 1029| ValueCategory = lvalue
# 1029| expr: lambda_mixed_explicit
# 1029| Type = decltype([...](...){...})
# 1029| ValueCategory = lvalue
# 1029| 0: (float)...
# 1029| Conversion = integral to floating point conversion
# 1029| Type = float
# 1029| Value = 5.0
# 1029| ValueCategory = prvalue
# 1029| expr: 5
# 1029| Type = int
# 1029| Value = 5
# 1029| ValueCategory = prvalue
# 1030| 12: declaration
# 1030| 0: definition of r
# 1030| Type = int
# 1030| init: initializer for r
# 1030| expr: ... - ...
# 1030| Type = int
# 1030| ValueCategory = prvalue
# 1030| 0: x
# 1030| Type = int
# 1030| ValueCategory = prvalue(load)
# 1030| 1: 1
# 1030| Type = int
# 1030| Value = 1
# 1030| ValueCategory = prvalue
# 1031| 13: declaration
# 1031| 0: definition of lambda_inits
# 1031| Type = decltype([...](...){...})
# 1031| init: initializer for lambda_inits
# 1031| expr: [...](...){...}
# 1031| Type = decltype([...](...){...})
# 1031| ValueCategory = prvalue
# 1031| 0: {...}
# 1031| Type = decltype([...](...){...})
# 1031| ValueCategory = prvalue
# 1031| .s: (reference to)
# 1031| Type = const String &
# 1031| ValueCategory = prvalue
# 1031| expr: (reference dereference)
# 1031| Type = const String
# 1031| ValueCategory = lvalue
# 1031| expr: s
# 1031| Type = const String &
# 1031| ValueCategory = prvalue(load)
# 1031| .x: x
# 1031| Type = int
# 1031| ValueCategory = prvalue(load)
# 1031| .i: ... + ...
# 1031| Type = int
# 1031| ValueCategory = prvalue
# 1031| 0: x
# 1031| Type = int
# 1031| ValueCategory = prvalue(load)
# 1031| 1: 1
# 1031| Type = int
# 1031| Value = 1
# 1031| ValueCategory = prvalue
# 1031| .j: (reference to)
# 1031| Type = int &
# 1031| ValueCategory = prvalue
# 1031| expr: r
# 1031| Type = int
# 1031| ValueCategory = lvalue
# 1032| 14: ExprStmt
# 1032| 0: call to operator()
# 1032| Type = char
# 1032| ValueCategory = prvalue
# 1032| -1: (const lambda [] type at line 1031, col. 23)...
# 1032| Conversion = glvalue conversion
# 1032| Type = const lambda [] type at line 1031, col. 23
# 1032| ValueCategory = lvalue
# 1032| expr: lambda_inits
# 1032| Type = decltype([...](...){...})
# 1032| ValueCategory = lvalue
# 1032| 0: (float)...
# 1032| Conversion = integral to floating point conversion
# 1032| Type = float
# 1032| Value = 6.0
# 1032| ValueCategory = prvalue
# 1032| expr: 6
# 1032| Type = int
# 1032| Value = 6
# 1032| ValueCategory = prvalue
# 1033| 15: return ...
# 1018| (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)& (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)::operator=((void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23) const&)
# 1018| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1018, col. 23 &
# 1018| void (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23) const&)
# 1018| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1018, col. 23 &
# 1018| void (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)&&)
# 1018| params:
#-----| 0: p#0
#-----| Type = lambda [] type at line 1018, col. 23 &&
# 1018| initializations:
# 1018| body: { ... }
# 1018| 0: return ...
# 1018| void (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)::(constructor)()
# 1018| params:
# 1018| char (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)::_FUN(float)
# 1018| params:
# 1018| 0: f
# 1018| Type = float
# 1018| char (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)::operator()(float) const
# 1018| params:
# 1018| 0: f
# 1018| Type = float
# 1018| body: { ... }
# 1018| 0: return ...
# 1018| 0: 65
# 1018| Type = char
# 1018| Value = 65
# 1018| ValueCategory = prvalue
# 1018| char(* (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)::operator char (*)(float)() const)(float)
# 1018| params:
#-----| body: { ... }
# 1018| 0: return ...
# 1018| 0: _FUN
# 1018| Type = ..(*)(..)
# 1018| ValueCategory = prvalue(load)
# 1020| (void Lambda(int, String const&))::(lambda [] type at line 1020, col. 21)& (void Lambda(int, String const&))::(lambda [] type at line 1020, col. 21)::operator=((void Lambda(int, String const&))::(lambda [] type at line 1020, col. 21) const&)
# 1020| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1020, col. 21 &
# 1020| void (void Lambda(int, String const&))::(lambda [] type at line 1020, col. 21)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1020, col. 21) const&)
# 1020| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1020, col. 21 &
# 1020| void (void Lambda(int, String const&))::(lambda [] type at line 1020, col. 21)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1020, col. 21)&&)
# 1020| params:
#-----| 0: p#0
#-----| Type = lambda [] type at line 1020, col. 21 &&
# 1020| initializations:
# 1020| 0: constructor init of field s
# 1020| Type = const String &
# 1020| ValueCategory = prvalue
# 1020| 0: Unknown literal
# 1020| Type = const String &
# 1020| ValueCategory = prvalue
# 1020| 1: constructor init of field x
# 1020| Type = int &
# 1020| ValueCategory = prvalue
# 1020| 0: Unknown literal
# 1020| Type = int &
# 1020| ValueCategory = prvalue
# 1020| body: { ... }
# 1020| 0: return ...
# 1020| void (void Lambda(int, String const&))::(lambda [] type at line 1020, col. 21)::(constructor)()
# 1020| params:
# 1020| char (void Lambda(int, String const&))::(lambda [] type at line 1020, col. 21)::operator()(float) const
# 1020| params:
# 1020| 0: f
# 1020| Type = float
# 1020| body: { ... }
# 1020| 0: return ...
# 1020| 0: access to array
# 1020| Type = char
# 1020| ValueCategory = prvalue(load)
# 1020| 0: call to c_str
# 1020| Type = const char *
# 1020| ValueCategory = prvalue
# 1020| -1: (reference dereference)
# 1020| Type = const String
# 1020| ValueCategory = lvalue
#-----| expr: s
#-----| Type = const String &
#-----| ValueCategory = prvalue(load)
#-----| -1: this
#-----| Type = const lambda [] type at line 1020, col. 21 *
#-----| ValueCategory = prvalue(load)
# 1020| 1: (reference dereference)
# 1020| Type = int
# 1020| ValueCategory = prvalue(load)
#-----| expr: x
#-----| Type = int &
#-----| ValueCategory = prvalue(load)
#-----| -1: this
#-----| Type = const lambda [] type at line 1020, col. 21 *
#-----| ValueCategory = prvalue(load)
# 1022| (void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21)& (void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21)::operator=((void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21) const&)
# 1022| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1022, col. 21 &
# 1022| void (void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21) const&)
# 1022| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1022, col. 21 &
# 1022| void (void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21)&&)
# 1022| params:
#-----| 0: p#0
#-----| Type = lambda [] type at line 1022, col. 21 &&
# 1022| initializations:
# 1022| 0: constructor init of field s
# 1022| Type = const String
# 1022| ValueCategory = prvalue
# 1022| 0: call to String
# 1022| Type = void
# 1022| ValueCategory = prvalue
# 1022| 1: constructor init of field x
# 1022| Type = int
# 1022| ValueCategory = prvalue
# 1022| 0: Unknown literal
# 1022| Type = int
# 1022| ValueCategory = prvalue
# 1022| body: { ... }
# 1022| 0: return ...
# 1022| void (void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21)::(constructor)()
# 1022| params:
# 1022| void (void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21)::~<unnamed>()
# 1022| params:
#-----| body: { ... }
#-----| 0: return ...
# 1022| destructions:
# 1022| 0: destructor field destruction of s
# 1022| Type = const String
# 1022| ValueCategory = prvalue
# 1022| 0: call to ~String
# 1022| Type = void
# 1022| ValueCategory = prvalue
# 1022| -1: s
# 1022| Type = const String
# 1022| ValueCategory = lvalue
# 1022| char (void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21)::operator()(float) const
# 1022| params:
# 1022| 0: f
# 1022| Type = float
# 1022| body: { ... }
# 1022| 0: return ...
# 1022| 0: access to array
# 1022| Type = char
# 1022| ValueCategory = prvalue(load)
# 1022| 0: call to c_str
# 1022| Type = const char *
# 1022| ValueCategory = prvalue
#-----| -1: s
#-----| Type = const String
#-----| ValueCategory = lvalue
#-----| -1: this
#-----| Type = const lambda [] type at line 1022, col. 21 *
#-----| ValueCategory = prvalue(load)
#-----| 1: x
#-----| Type = int
#-----| ValueCategory = prvalue(load)
#-----| -1: this
#-----| Type = const lambda [] type at line 1022, col. 21 *
#-----| ValueCategory = prvalue(load)
# 1024| (void Lambda(int, String const&))::(lambda [] type at line 1024, col. 30)& (void Lambda(int, String const&))::(lambda [] type at line 1024, col. 30)::operator=((void Lambda(int, String const&))::(lambda [] type at line 1024, col. 30) const&)
# 1024| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1024, col. 30 &
# 1024| void (void Lambda(int, String const&))::(lambda [] type at line 1024, col. 30)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1024, col. 30) const&)
# 1024| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1024, col. 30 &
# 1024| void (void Lambda(int, String const&))::(lambda [] type at line 1024, col. 30)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1024, col. 30)&&)
# 1024| params:
#-----| 0: p#0
#-----| Type = lambda [] type at line 1024, col. 30 &&
# 1024| initializations:
# 1024| 0: constructor init of field s
# 1024| Type = const String &
# 1024| ValueCategory = prvalue
# 1024| 0: Unknown literal
# 1024| Type = const String &
# 1024| ValueCategory = prvalue
# 1024| body: { ... }
# 1024| 0: return ...
# 1024| void (void Lambda(int, String const&))::(lambda [] type at line 1024, col. 30)::(constructor)()
# 1024| params:
# 1024| char (void Lambda(int, String const&))::(lambda [] type at line 1024, col. 30)::operator()(float) const
# 1024| params:
# 1024| 0: f
# 1024| Type = float
# 1024| body: { ... }
# 1024| 0: return ...
# 1024| 0: access to array
# 1024| Type = char
# 1024| ValueCategory = prvalue(load)
# 1024| 0: call to c_str
# 1024| Type = const char *
# 1024| ValueCategory = prvalue
# 1024| -1: (reference dereference)
# 1024| Type = const String
# 1024| ValueCategory = lvalue
#-----| expr: s
#-----| Type = const String &
#-----| ValueCategory = prvalue(load)
#-----| -1: this
#-----| Type = const lambda [] type at line 1024, col. 30 *
#-----| ValueCategory = prvalue(load)
# 1024| 1: 0
# 1024| Type = int
# 1024| Value = 0
# 1024| ValueCategory = prvalue
# 1026| (void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)& (void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)::operator=((void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30) const&)
# 1026| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1026, col. 30 &
# 1026| void (void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30) const&)
# 1026| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1026, col. 30 &
# 1026| void (void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)&&)
# 1026| params:
#-----| 0: p#0
#-----| Type = lambda [] type at line 1026, col. 30 &&
# 1026| initializations:
# 1026| 0: constructor init of field s
# 1026| Type = const String
# 1026| ValueCategory = prvalue
# 1026| 0: call to String
# 1026| Type = void
# 1026| ValueCategory = prvalue
# 1026| body: { ... }
# 1026| 0: return ...
# 1026| void (void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)::(constructor)()
# 1026| params:
# 1026| void (void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)::~<unnamed>()
# 1026| params:
#-----| body: { ... }
#-----| 0: return ...
# 1026| destructions:
# 1026| 0: destructor field destruction of s
# 1026| Type = const String
# 1026| ValueCategory = prvalue
# 1026| 0: call to ~String
# 1026| Type = void
# 1026| ValueCategory = prvalue
# 1026| -1: s
# 1026| Type = const String
# 1026| ValueCategory = lvalue
# 1026| char (void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)::operator()(float) const
# 1026| params:
# 1026| 0: f
# 1026| Type = float
# 1026| body: { ... }
# 1026| 0: return ...
# 1026| 0: access to array
# 1026| Type = char
# 1026| ValueCategory = prvalue(load)
# 1026| 0: call to c_str
# 1026| Type = const char *
# 1026| ValueCategory = prvalue
#-----| -1: s
#-----| Type = const String
#-----| ValueCategory = lvalue
#-----| -1: this
#-----| Type = const lambda [] type at line 1026, col. 30 *
#-----| ValueCategory = prvalue(load)
# 1026| 1: 0
# 1026| Type = int
# 1026| Value = 0
# 1026| ValueCategory = prvalue
# 1028| (void Lambda(int, String const&))::(lambda [] type at line 1028, col. 32)& (void Lambda(int, String const&))::(lambda [] type at line 1028, col. 32)::operator=((void Lambda(int, String const&))::(lambda [] type at line 1028, col. 32) const&)
# 1028| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1028, col. 32 &
# 1028| void (void Lambda(int, String const&))::(lambda [] type at line 1028, col. 32)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1028, col. 32) const&)
# 1028| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1028, col. 32 &
# 1028| void (void Lambda(int, String const&))::(lambda [] type at line 1028, col. 32)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1028, col. 32)&&)
# 1028| params:
#-----| 0: p#0
#-----| Type = lambda [] type at line 1028, col. 32 &&
# 1028| initializations:
# 1028| 0: constructor init of field s
# 1028| Type = const String &
# 1028| ValueCategory = prvalue
# 1028| 0: Unknown literal
# 1028| Type = const String &
# 1028| ValueCategory = prvalue
# 1028| 1: constructor init of field x
# 1028| Type = int
# 1028| ValueCategory = prvalue
# 1028| 0: Unknown literal
# 1028| Type = int
# 1028| ValueCategory = prvalue
# 1028| body: { ... }
# 1028| 0: return ...
# 1028| void (void Lambda(int, String const&))::(lambda [] type at line 1028, col. 32)::(constructor)()
# 1028| params:
# 1028| char (void Lambda(int, String const&))::(lambda [] type at line 1028, col. 32)::operator()(float) const
# 1028| params:
# 1028| 0: f
# 1028| Type = float
# 1028| body: { ... }
# 1028| 0: return ...
# 1028| 0: access to array
# 1028| Type = char
# 1028| ValueCategory = prvalue(load)
# 1028| 0: call to c_str
# 1028| Type = const char *
# 1028| ValueCategory = prvalue
# 1028| -1: (reference dereference)
# 1028| Type = const String
# 1028| ValueCategory = lvalue
#-----| expr: s
#-----| Type = const String &
#-----| ValueCategory = prvalue(load)
#-----| -1: this
#-----| Type = const lambda [] type at line 1028, col. 32 *
#-----| ValueCategory = prvalue(load)
#-----| 1: x
#-----| Type = int
#-----| ValueCategory = prvalue(load)
#-----| -1: this
#-----| Type = const lambda [] type at line 1028, col. 32 *
#-----| ValueCategory = prvalue(load)
# 1031| (void Lambda(int, String const&))::(lambda [] type at line 1031, col. 23)& (void Lambda(int, String const&))::(lambda [] type at line 1031, col. 23)::operator=((void Lambda(int, String const&))::(lambda [] type at line 1031, col. 23) const&)
# 1031| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1031, col. 23 &
# 1031| void (void Lambda(int, String const&))::(lambda [] type at line 1031, col. 23)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1031, col. 23) const&)
# 1031| params:
#-----| 0: p#0
#-----| Type = const lambda [] type at line 1031, col. 23 &
# 1031| void (void Lambda(int, String const&))::(lambda [] type at line 1031, col. 23)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1031, col. 23)&&)
# 1031| params:
#-----| 0: p#0
#-----| Type = lambda [] type at line 1031, col. 23 &&
# 1031| initializations:
# 1031| 0: constructor init of field s
# 1031| Type = const String &
# 1031| ValueCategory = prvalue
# 1031| 0: Unknown literal
# 1031| Type = const String &
# 1031| ValueCategory = prvalue
# 1031| 1: constructor init of field x
# 1031| Type = int
# 1031| ValueCategory = prvalue
# 1031| 0: Unknown literal
# 1031| Type = int
# 1031| ValueCategory = prvalue
# 1031| 2: constructor init of field i
# 1031| Type = int
# 1031| ValueCategory = prvalue
# 1031| 0: Unknown literal
# 1031| Type = int
# 1031| ValueCategory = prvalue
# 1031| 3: constructor init of field j
# 1031| Type = int &
# 1031| ValueCategory = prvalue
# 1031| 0: Unknown literal
# 1031| Type = int &
# 1031| ValueCategory = prvalue
# 1031| body: { ... }
# 1031| 0: return ...
# 1031| void (void Lambda(int, String const&))::(lambda [] type at line 1031, col. 23)::(constructor)()
# 1031| params:
# 1031| char (void Lambda(int, String const&))::(lambda [] type at line 1031, col. 23)::operator()(float) const
# 1031| params:
# 1031| 0: f
# 1031| Type = float
# 1031| body: { ... }
# 1031| 0: return ...
# 1031| 0: access to array
# 1031| Type = char
# 1031| ValueCategory = prvalue(load)
# 1031| 0: call to c_str
# 1031| Type = const char *
# 1031| ValueCategory = prvalue
# 1031| -1: (reference dereference)
# 1031| Type = const String
# 1031| ValueCategory = lvalue
#-----| expr: s
#-----| Type = const String &
#-----| ValueCategory = prvalue(load)
#-----| -1: this
#-----| Type = const lambda [] type at line 1031, col. 23 *
#-----| ValueCategory = prvalue(load)
# 1031| 1: ... - ...
# 1031| Type = int
# 1031| ValueCategory = prvalue
# 1031| 0: ... + ...
# 1031| Type = int
# 1031| ValueCategory = prvalue
#-----| 0: x
#-----| Type = int
#-----| ValueCategory = prvalue(load)
#-----| -1: this
#-----| Type = const lambda [] type at line 1031, col. 23 *
#-----| ValueCategory = prvalue(load)
# 1031| 1: i
# 1031| Type = int
# 1031| ValueCategory = prvalue(load)
#-----| -1: this
#-----| Type = const lambda [] type at line 1031, col. 23 *
#-----| ValueCategory = prvalue(load)
# 1031| 1: (reference dereference)
# 1031| Type = int
# 1031| ValueCategory = prvalue(load)
# 1031| expr: j
# 1031| Type = int &
# 1031| ValueCategory = prvalue(load)
#-----| -1: this
#-----| Type = const lambda [] type at line 1031, col. 23 *
#-----| ValueCategory = prvalue(load)

View File

@@ -1006,4 +1006,47 @@ void OperatorDeleteArray() {
}
#endif
struct EmptyStruct {};
void EmptyStructInit() {
EmptyStruct s = {};
}
auto lam = []() {};
void Lambda(int x, const String& s) {
auto lambda_empty = [](float f) { return 'A'; };
lambda_empty(0);
auto lambda_ref = [&](float f) { return s.c_str()[x]; };
lambda_ref(1);
auto lambda_val = [=](float f) { return s.c_str()[x]; };
lambda_val(2);
auto lambda_ref_explicit = [&s](float f) { return s.c_str()[0]; };
lambda_ref_explicit(3);
auto lambda_val_explicit = [s](float f) { return s.c_str()[0]; };
lambda_val_explicit(4);
auto lambda_mixed_explicit = [&s, x](float f) { return s.c_str()[x]; };
lambda_mixed_explicit(5);
int r = x - 1;
auto lambda_inits = [&s, x, i = x + 1, &j = r](float f) { return s.c_str()[x + i - j]; };
lambda_inits(6);
}
#if 0 // Explicit capture of `this` requires possible extractor fixes.
struct LambdaContainer {
int x;
void LambdaMember(const String& s) {
auto lambda_implicit_this = [=](float f) { return s.c_str()[x]; };
lambda_implicit_this(1);
auto lambda_explicit_this_byref = [this, &s](float f) { return s.c_str()[x]; };
lambda_explicit_this_byref(2);
auto lambda_explicit_this_bycopy = [*this, &s](float f) { return s.c_str()[x]; };
lambda_explicit_this_bycopy(3);
}
};
#endif
// semmle-extractor-options: -std=c++17

View File

@@ -4366,3 +4366,447 @@ ir.cpp:
# 987| v0_21(void) = ReturnValue : r0_20, mu0_2
# 987| v0_22(void) = UnmodeledUse : mu*
# 987| v0_23(void) = ExitFunction :
# 1011| void EmptyStructInit()
# 1011| Block 0
# 1011| v0_0(void) = EnterFunction :
# 1011| mu0_1(unknown) = AliasedDefinition :
# 1011| mu0_2(unknown) = UnmodeledDefinition :
# 1012| r0_3(glval<EmptyStruct>) = VariableAddress[s] :
# 1012| mu0_4(EmptyStruct) = Uninitialized[s] : r0_3
# 1013| v0_5(void) = NoOp :
# 1011| v0_6(void) = ReturnVoid :
# 1011| v0_7(void) = UnmodeledUse : mu*
# 1011| v0_8(void) = ExitFunction :
# 1015| void (lambda [] type at line 1015, col. 12)::(constructor)((lambda [] type at line 1015, col. 12)&&)
# 1015| Block 0
# 1015| v0_0(void) = EnterFunction :
# 1015| mu0_1(unknown) = AliasedDefinition :
# 1015| mu0_2(unknown) = UnmodeledDefinition :
# 1015| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
#-----| r0_4(glval<lambda [] type at line 1015, col. 12 &&>) = VariableAddress[p#0] :
#-----| mu0_5(lambda [] type at line 1015, col. 12 &&) = InitializeParameter[p#0] : r0_4
# 1015| v0_6(void) = NoOp :
# 1015| v0_7(void) = ReturnVoid :
# 1015| v0_8(void) = UnmodeledUse : mu*
# 1015| v0_9(void) = ExitFunction :
# 1015| void (lambda [] type at line 1015, col. 12)::operator()() const
# 1015| Block 0
# 1015| v0_0(void) = EnterFunction :
# 1015| mu0_1(unknown) = AliasedDefinition :
# 1015| mu0_2(unknown) = UnmodeledDefinition :
# 1015| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
# 1015| v0_4(void) = NoOp :
# 1015| v0_5(void) = ReturnVoid :
# 1015| v0_6(void) = UnmodeledUse : mu*
# 1015| v0_7(void) = ExitFunction :
# 1015| void(* (lambda [] type at line 1015, col. 12)::operator void (*)()() const)()
# 1015| Block 0
# 1015| v0_0(void) = EnterFunction :
# 1015| mu0_1(unknown) = AliasedDefinition :
# 1015| mu0_2(unknown) = UnmodeledDefinition :
# 1015| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
# 1015| r0_4(glval<..(*)(..)>) = VariableAddress[#return] :
# 1015| r0_5(glval<..(*)(..)>) = FunctionAddress[_FUN] :
# 1015| mu0_6(..(*)(..)) = Store : r0_4, r0_5
# 1015| r0_7(glval<..(*)(..)>) = VariableAddress[#return] :
# 1015| v0_8(void) = ReturnValue : r0_7, mu0_2
# 1015| v0_9(void) = UnmodeledUse : mu*
# 1015| v0_10(void) = ExitFunction :
# 1017| void Lambda(int, String const&)
# 1017| Block 0
# 1017| v0_0(void) = EnterFunction :
# 1017| mu0_1(unknown) = AliasedDefinition :
# 1017| mu0_2(unknown) = UnmodeledDefinition :
# 1017| r0_3(glval<int>) = VariableAddress[x] :
# 1017| mu0_4(int) = InitializeParameter[x] : r0_3
# 1017| r0_5(glval<String &>) = VariableAddress[s] :
# 1017| mu0_6(String &) = InitializeParameter[s] : r0_5
# 1018| r0_7(glval<decltype([...](...){...})>) = VariableAddress[lambda_empty] :
# 1018| r0_8(glval<decltype([...](...){...})>) = VariableAddress[#temp1018:23] :
# 1018| mu0_9(decltype([...](...){...})) = Uninitialized[#temp1018:23] : r0_8
# 1018| r0_10(decltype([...](...){...})) = Load : r0_8, mu0_2
# 1018| mu0_11(decltype([...](...){...})) = Store : r0_7, r0_10
# 1019| r0_12(char) = Constant[65] :
# 1020| r0_13(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref] :
# 1020| r0_14(glval<decltype([...](...){...})>) = VariableAddress[#temp1020:21] :
# 1020| mu0_15(decltype([...](...){...})) = Uninitialized[#temp1020:21] : r0_14
# 1020| r0_16(glval<String &>) = FieldAddress[s] : r0_14
#-----| r0_17(glval<String &>) = VariableAddress[s] :
#-----| r0_18(String &) = Load : r0_17, mu0_2
# 1020| mu0_19(String &) = Store : r0_16, r0_18
# 1020| r0_20(glval<int &>) = FieldAddress[x] : r0_14
#-----| r0_21(glval<int>) = VariableAddress[x] :
#-----| mu0_22(int &) = Store : r0_20, r0_21
# 1020| r0_23(decltype([...](...){...})) = Load : r0_14, mu0_2
# 1020| mu0_24(decltype([...](...){...})) = Store : r0_13, r0_23
# 1021| r0_25(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref] :
# 1021| r0_26(glval<decltype([...](...){...})>) = Convert : r0_25
# 1021| r0_27(glval<unknown>) = FunctionAddress[operator()] :
# 1021| r0_28(float) = Constant[1.0] :
# 1021| r0_29(char) = Call : r0_27, this:r0_26, r0_28
# 1021| mu0_30(unknown) = ^CallSideEffect : mu0_2
# 1022| r0_31(glval<decltype([...](...){...})>) = VariableAddress[lambda_val] :
# 1022| r0_32(glval<unknown>) = FunctionAddress[(constructor)] :
# 1022| r0_33(glval<decltype([...](...){...})>) = VariableAddress[#temp1022:21] :
# 1022| mu0_34(decltype([...](...){...})) = Uninitialized[#temp1022:21] : r0_33
# 1022| r0_35(glval<String>) = FieldAddress[s] : r0_33
#-----| r0_36(glval<unknown>) = FunctionAddress[String] :
#-----| v0_37(void) = Call : r0_36, this:r0_35
#-----| mu0_38(unknown) = ^CallSideEffect : mu0_2
# 1022| r0_39(glval<int>) = FieldAddress[x] : r0_33
#-----| r0_40(glval<int>) = VariableAddress[x] :
#-----| r0_41(int) = Load : r0_40, mu0_2
#-----| mu0_42(int) = Store : r0_39, r0_41
# 1022| r0_43(decltype([...](...){...})) = Load : r0_33, mu0_2
# 1022| v0_44(void) = Call : r0_32, this:r0_31, r0_43
# 1022| mu0_45(unknown) = ^CallSideEffect : mu0_2
# 1023| r0_46(glval<decltype([...](...){...})>) = VariableAddress[lambda_val] :
# 1023| r0_47(glval<decltype([...](...){...})>) = Convert : r0_46
# 1023| r0_48(glval<unknown>) = FunctionAddress[operator()] :
# 1023| r0_49(float) = Constant[2.0] :
# 1023| r0_50(char) = Call : r0_48, this:r0_47, r0_49
# 1023| mu0_51(unknown) = ^CallSideEffect : mu0_2
# 1024| r0_52(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref_explicit] :
# 1024| r0_53(glval<decltype([...](...){...})>) = VariableAddress[#temp1024:30] :
# 1024| mu0_54(decltype([...](...){...})) = Uninitialized[#temp1024:30] : r0_53
# 1024| r0_55(glval<String &>) = FieldAddress[s] : r0_53
# 1024| r0_56(glval<String &>) = VariableAddress[s] :
# 1024| r0_57(String &) = Load : r0_56, mu0_2
# 1024| mu0_58(String &) = Store : r0_55, r0_57
# 1024| r0_59(decltype([...](...){...})) = Load : r0_53, mu0_2
# 1024| mu0_60(decltype([...](...){...})) = Store : r0_52, r0_59
# 1025| r0_61(glval<decltype([...](...){...})>) = VariableAddress[lambda_ref_explicit] :
# 1025| r0_62(glval<decltype([...](...){...})>) = Convert : r0_61
# 1025| r0_63(glval<unknown>) = FunctionAddress[operator()] :
# 1025| r0_64(float) = Constant[3.0] :
# 1025| r0_65(char) = Call : r0_63, this:r0_62, r0_64
# 1025| mu0_66(unknown) = ^CallSideEffect : mu0_2
# 1026| r0_67(glval<decltype([...](...){...})>) = VariableAddress[lambda_val_explicit] :
# 1026| r0_68(glval<unknown>) = FunctionAddress[(constructor)] :
# 1026| r0_69(glval<decltype([...](...){...})>) = VariableAddress[#temp1026:30] :
# 1026| mu0_70(decltype([...](...){...})) = Uninitialized[#temp1026:30] : r0_69
# 1026| r0_71(glval<String>) = FieldAddress[s] : r0_69
#-----| r0_72(glval<unknown>) = FunctionAddress[String] :
#-----| v0_73(void) = Call : r0_72, this:r0_71
#-----| mu0_74(unknown) = ^CallSideEffect : mu0_2
# 1026| r0_75(decltype([...](...){...})) = Load : r0_69, mu0_2
# 1026| v0_76(void) = Call : r0_68, this:r0_67, r0_75
# 1026| mu0_77(unknown) = ^CallSideEffect : mu0_2
# 1027| r0_78(glval<decltype([...](...){...})>) = VariableAddress[lambda_val_explicit] :
# 1027| r0_79(glval<decltype([...](...){...})>) = Convert : r0_78
# 1027| r0_80(glval<unknown>) = FunctionAddress[operator()] :
# 1027| r0_81(float) = Constant[4.0] :
# 1027| r0_82(char) = Call : r0_80, this:r0_79, r0_81
# 1027| mu0_83(unknown) = ^CallSideEffect : mu0_2
# 1028| r0_84(glval<decltype([...](...){...})>) = VariableAddress[lambda_mixed_explicit] :
# 1028| r0_85(glval<decltype([...](...){...})>) = VariableAddress[#temp1028:32] :
# 1028| mu0_86(decltype([...](...){...})) = Uninitialized[#temp1028:32] : r0_85
# 1028| r0_87(glval<String &>) = FieldAddress[s] : r0_85
# 1028| r0_88(glval<String &>) = VariableAddress[s] :
# 1028| r0_89(String &) = Load : r0_88, mu0_2
# 1028| mu0_90(String &) = Store : r0_87, r0_89
# 1028| r0_91(glval<int>) = FieldAddress[x] : r0_85
# 1028| r0_92(glval<int>) = VariableAddress[x] :
# 1028| r0_93(int) = Load : r0_92, mu0_2
# 1028| mu0_94(int) = Store : r0_91, r0_93
# 1028| r0_95(decltype([...](...){...})) = Load : r0_85, mu0_2
# 1028| mu0_96(decltype([...](...){...})) = Store : r0_84, r0_95
# 1029| r0_97(glval<decltype([...](...){...})>) = VariableAddress[lambda_mixed_explicit] :
# 1029| r0_98(glval<decltype([...](...){...})>) = Convert : r0_97
# 1029| r0_99(glval<unknown>) = FunctionAddress[operator()] :
# 1029| r0_100(float) = Constant[5.0] :
# 1029| r0_101(char) = Call : r0_99, this:r0_98, r0_100
# 1029| mu0_102(unknown) = ^CallSideEffect : mu0_2
# 1030| r0_103(glval<int>) = VariableAddress[r] :
# 1030| r0_104(glval<int>) = VariableAddress[x] :
# 1030| r0_105(int) = Load : r0_104, mu0_2
# 1030| r0_106(int) = Constant[1] :
# 1030| r0_107(int) = Sub : r0_105, r0_106
# 1030| mu0_108(int) = Store : r0_103, r0_107
# 1031| r0_109(glval<decltype([...](...){...})>) = VariableAddress[lambda_inits] :
# 1031| r0_110(glval<decltype([...](...){...})>) = VariableAddress[#temp1031:23] :
# 1031| mu0_111(decltype([...](...){...})) = Uninitialized[#temp1031:23] : r0_110
# 1031| r0_112(glval<String &>) = FieldAddress[s] : r0_110
# 1031| r0_113(glval<String &>) = VariableAddress[s] :
# 1031| r0_114(String &) = Load : r0_113, mu0_2
# 1031| mu0_115(String &) = Store : r0_112, r0_114
# 1031| r0_116(glval<int>) = FieldAddress[x] : r0_110
# 1031| r0_117(glval<int>) = VariableAddress[x] :
# 1031| r0_118(int) = Load : r0_117, mu0_2
# 1031| mu0_119(int) = Store : r0_116, r0_118
# 1031| r0_120(glval<int>) = FieldAddress[i] : r0_110
# 1031| r0_121(glval<int>) = VariableAddress[x] :
# 1031| r0_122(int) = Load : r0_121, mu0_2
# 1031| r0_123(int) = Constant[1] :
# 1031| r0_124(int) = Add : r0_122, r0_123
# 1031| mu0_125(int) = Store : r0_120, r0_124
# 1031| r0_126(glval<int &>) = FieldAddress[j] : r0_110
# 1031| r0_127(glval<int>) = VariableAddress[r] :
# 1031| mu0_128(int &) = Store : r0_126, r0_127
# 1031| r0_129(decltype([...](...){...})) = Load : r0_110, mu0_2
# 1031| mu0_130(decltype([...](...){...})) = Store : r0_109, r0_129
# 1032| r0_131(glval<decltype([...](...){...})>) = VariableAddress[lambda_inits] :
# 1032| r0_132(glval<decltype([...](...){...})>) = Convert : r0_131
# 1032| r0_133(glval<unknown>) = FunctionAddress[operator()] :
# 1032| r0_134(float) = Constant[6.0] :
# 1032| r0_135(char) = Call : r0_133, this:r0_132, r0_134
# 1032| mu0_136(unknown) = ^CallSideEffect : mu0_2
# 1033| v0_137(void) = NoOp :
# 1017| v0_138(void) = ReturnVoid :
# 1017| v0_139(void) = UnmodeledUse : mu*
# 1017| v0_140(void) = ExitFunction :
# 1018| void (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)&&)
# 1018| Block 0
# 1018| v0_0(void) = EnterFunction :
# 1018| mu0_1(unknown) = AliasedDefinition :
# 1018| mu0_2(unknown) = UnmodeledDefinition :
# 1018| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
#-----| r0_4(glval<lambda [] type at line 1018, col. 23 &&>) = VariableAddress[p#0] :
#-----| mu0_5(lambda [] type at line 1018, col. 23 &&) = InitializeParameter[p#0] : r0_4
# 1018| v0_6(void) = NoOp :
# 1018| v0_7(void) = ReturnVoid :
# 1018| v0_8(void) = UnmodeledUse : mu*
# 1018| v0_9(void) = ExitFunction :
# 1018| char (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)::operator()(float) const
# 1018| Block 0
# 1018| v0_0(void) = EnterFunction :
# 1018| mu0_1(unknown) = AliasedDefinition :
# 1018| mu0_2(unknown) = UnmodeledDefinition :
# 1018| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
# 1018| r0_4(glval<float>) = VariableAddress[f] :
# 1018| mu0_5(float) = InitializeParameter[f] : r0_4
# 1018| r0_6(glval<char>) = VariableAddress[#return] :
# 1018| r0_7(char) = Constant[65] :
# 1018| mu0_8(char) = Store : r0_6, r0_7
# 1018| r0_9(glval<char>) = VariableAddress[#return] :
# 1018| v0_10(void) = ReturnValue : r0_9, mu0_2
# 1018| v0_11(void) = UnmodeledUse : mu*
# 1018| v0_12(void) = ExitFunction :
# 1018| char(* (void Lambda(int, String const&))::(lambda [] type at line 1018, col. 23)::operator char (*)(float)() const)(float)
# 1018| Block 0
# 1018| v0_0(void) = EnterFunction :
# 1018| mu0_1(unknown) = AliasedDefinition :
# 1018| mu0_2(unknown) = UnmodeledDefinition :
# 1018| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
# 1018| r0_4(glval<..(*)(..)>) = VariableAddress[#return] :
# 1018| r0_5(glval<..(*)(..)>) = FunctionAddress[_FUN] :
# 1018| mu0_6(..(*)(..)) = Store : r0_4, r0_5
# 1018| r0_7(glval<..(*)(..)>) = VariableAddress[#return] :
# 1018| v0_8(void) = ReturnValue : r0_7, mu0_2
# 1018| v0_9(void) = UnmodeledUse : mu*
# 1018| v0_10(void) = ExitFunction :
# 1020| char (void Lambda(int, String const&))::(lambda [] type at line 1020, col. 21)::operator()(float) const
# 1020| Block 0
# 1020| v0_0(void) = EnterFunction :
# 1020| mu0_1(unknown) = AliasedDefinition :
# 1020| mu0_2(unknown) = UnmodeledDefinition :
# 1020| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
# 1020| r0_4(glval<float>) = VariableAddress[f] :
# 1020| mu0_5(float) = InitializeParameter[f] : r0_4
# 1020| r0_6(glval<char>) = VariableAddress[#return] :
#-----| r0_7(lambda [] type at line 1020, col. 21 *) = CopyValue : r0_3
#-----| r0_8(glval<String &>) = FieldAddress[s] : r0_7
#-----| r0_9(String &) = Load : r0_8, mu0_2
# 1020| r0_10(glval<unknown>) = FunctionAddress[c_str] :
# 1020| r0_11(char *) = Call : r0_10, this:r0_9
# 1020| mu0_12(unknown) = ^CallSideEffect : mu0_2
#-----| r0_13(lambda [] type at line 1020, col. 21 *) = CopyValue : r0_3
#-----| r0_14(glval<int &>) = FieldAddress[x] : r0_13
#-----| r0_15(int &) = Load : r0_14, mu0_2
# 1020| r0_16(int) = Load : r0_15, mu0_2
# 1020| r0_17(char *) = PointerAdd[1] : r0_11, r0_16
# 1020| r0_18(char) = Load : r0_17, mu0_2
# 1020| mu0_19(char) = Store : r0_6, r0_18
# 1020| r0_20(glval<char>) = VariableAddress[#return] :
# 1020| v0_21(void) = ReturnValue : r0_20, mu0_2
# 1020| v0_22(void) = UnmodeledUse : mu*
# 1020| v0_23(void) = ExitFunction :
# 1022| void (void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21)::~<unnamed>()
# 1022| Block 0
# 1022| v0_0(void) = EnterFunction :
# 1022| mu0_1(unknown) = AliasedDefinition :
# 1022| mu0_2(unknown) = UnmodeledDefinition :
# 1022| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
#-----| v0_4(void) = NoOp :
# 1022| r0_5(glval<String>) = FieldAddress[s] : r0_3
# 1022| r0_6(glval<unknown>) = FunctionAddress[~String] :
# 1022| v0_7(void) = Call : r0_6, this:r0_5
# 1022| mu0_8(unknown) = ^CallSideEffect : mu0_2
# 1022| v0_9(void) = ReturnVoid :
# 1022| v0_10(void) = UnmodeledUse : mu*
# 1022| v0_11(void) = ExitFunction :
# 1022| char (void Lambda(int, String const&))::(lambda [] type at line 1022, col. 21)::operator()(float) const
# 1022| Block 0
# 1022| v0_0(void) = EnterFunction :
# 1022| mu0_1(unknown) = AliasedDefinition :
# 1022| mu0_2(unknown) = UnmodeledDefinition :
# 1022| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
# 1022| r0_4(glval<float>) = VariableAddress[f] :
# 1022| mu0_5(float) = InitializeParameter[f] : r0_4
# 1022| r0_6(glval<char>) = VariableAddress[#return] :
#-----| r0_7(lambda [] type at line 1022, col. 21 *) = CopyValue : r0_3
#-----| r0_8(glval<String>) = FieldAddress[s] : r0_7
# 1022| r0_9(glval<unknown>) = FunctionAddress[c_str] :
# 1022| r0_10(char *) = Call : r0_9, this:r0_8
# 1022| mu0_11(unknown) = ^CallSideEffect : mu0_2
#-----| r0_12(lambda [] type at line 1022, col. 21 *) = CopyValue : r0_3
#-----| r0_13(glval<int>) = FieldAddress[x] : r0_12
#-----| r0_14(int) = Load : r0_13, mu0_2
# 1022| r0_15(char *) = PointerAdd[1] : r0_10, r0_14
# 1022| r0_16(char) = Load : r0_15, mu0_2
# 1022| mu0_17(char) = Store : r0_6, r0_16
# 1022| r0_18(glval<char>) = VariableAddress[#return] :
# 1022| v0_19(void) = ReturnValue : r0_18, mu0_2
# 1022| v0_20(void) = UnmodeledUse : mu*
# 1022| v0_21(void) = ExitFunction :
# 1024| char (void Lambda(int, String const&))::(lambda [] type at line 1024, col. 30)::operator()(float) const
# 1024| Block 0
# 1024| v0_0(void) = EnterFunction :
# 1024| mu0_1(unknown) = AliasedDefinition :
# 1024| mu0_2(unknown) = UnmodeledDefinition :
# 1024| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
# 1024| r0_4(glval<float>) = VariableAddress[f] :
# 1024| mu0_5(float) = InitializeParameter[f] : r0_4
# 1024| r0_6(glval<char>) = VariableAddress[#return] :
#-----| r0_7(lambda [] type at line 1024, col. 30 *) = CopyValue : r0_3
#-----| r0_8(glval<String &>) = FieldAddress[s] : r0_7
#-----| r0_9(String &) = Load : r0_8, mu0_2
# 1024| r0_10(glval<unknown>) = FunctionAddress[c_str] :
# 1024| r0_11(char *) = Call : r0_10, this:r0_9
# 1024| mu0_12(unknown) = ^CallSideEffect : mu0_2
# 1024| r0_13(int) = Constant[0] :
# 1024| r0_14(char *) = PointerAdd[1] : r0_11, r0_13
# 1024| r0_15(char) = Load : r0_14, mu0_2
# 1024| mu0_16(char) = Store : r0_6, r0_15
# 1024| r0_17(glval<char>) = VariableAddress[#return] :
# 1024| v0_18(void) = ReturnValue : r0_17, mu0_2
# 1024| v0_19(void) = UnmodeledUse : mu*
# 1024| v0_20(void) = ExitFunction :
# 1026| void (void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)&&)
# 1026| Block 0
# 1026| v0_0(void) = EnterFunction :
# 1026| mu0_1(unknown) = AliasedDefinition :
# 1026| mu0_2(unknown) = UnmodeledDefinition :
# 1026| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
#-----| r0_4(glval<lambda [] type at line 1026, col. 30 &&>) = VariableAddress[p#0] :
#-----| mu0_5(lambda [] type at line 1026, col. 30 &&) = InitializeParameter[p#0] : r0_4
# 1026| r0_6(glval<String>) = FieldAddress[s] : r0_3
# 1026| r0_7(glval<unknown>) = FunctionAddress[String] :
# 1026| v0_8(void) = Call : r0_7, this:r0_6
# 1026| mu0_9(unknown) = ^CallSideEffect : mu0_2
# 1026| v0_10(void) = NoOp :
# 1026| v0_11(void) = ReturnVoid :
# 1026| v0_12(void) = UnmodeledUse : mu*
# 1026| v0_13(void) = ExitFunction :
# 1026| void (void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)::~<unnamed>()
# 1026| Block 0
# 1026| v0_0(void) = EnterFunction :
# 1026| mu0_1(unknown) = AliasedDefinition :
# 1026| mu0_2(unknown) = UnmodeledDefinition :
# 1026| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
#-----| v0_4(void) = NoOp :
# 1026| r0_5(glval<String>) = FieldAddress[s] : r0_3
# 1026| r0_6(glval<unknown>) = FunctionAddress[~String] :
# 1026| v0_7(void) = Call : r0_6, this:r0_5
# 1026| mu0_8(unknown) = ^CallSideEffect : mu0_2
# 1026| v0_9(void) = ReturnVoid :
# 1026| v0_10(void) = UnmodeledUse : mu*
# 1026| v0_11(void) = ExitFunction :
# 1026| char (void Lambda(int, String const&))::(lambda [] type at line 1026, col. 30)::operator()(float) const
# 1026| Block 0
# 1026| v0_0(void) = EnterFunction :
# 1026| mu0_1(unknown) = AliasedDefinition :
# 1026| mu0_2(unknown) = UnmodeledDefinition :
# 1026| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
# 1026| r0_4(glval<float>) = VariableAddress[f] :
# 1026| mu0_5(float) = InitializeParameter[f] : r0_4
# 1026| r0_6(glval<char>) = VariableAddress[#return] :
#-----| r0_7(lambda [] type at line 1026, col. 30 *) = CopyValue : r0_3
#-----| r0_8(glval<String>) = FieldAddress[s] : r0_7
# 1026| r0_9(glval<unknown>) = FunctionAddress[c_str] :
# 1026| r0_10(char *) = Call : r0_9, this:r0_8
# 1026| mu0_11(unknown) = ^CallSideEffect : mu0_2
# 1026| r0_12(int) = Constant[0] :
# 1026| r0_13(char *) = PointerAdd[1] : r0_10, r0_12
# 1026| r0_14(char) = Load : r0_13, mu0_2
# 1026| mu0_15(char) = Store : r0_6, r0_14
# 1026| r0_16(glval<char>) = VariableAddress[#return] :
# 1026| v0_17(void) = ReturnValue : r0_16, mu0_2
# 1026| v0_18(void) = UnmodeledUse : mu*
# 1026| v0_19(void) = ExitFunction :
# 1028| char (void Lambda(int, String const&))::(lambda [] type at line 1028, col. 32)::operator()(float) const
# 1028| Block 0
# 1028| v0_0(void) = EnterFunction :
# 1028| mu0_1(unknown) = AliasedDefinition :
# 1028| mu0_2(unknown) = UnmodeledDefinition :
# 1028| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
# 1028| r0_4(glval<float>) = VariableAddress[f] :
# 1028| mu0_5(float) = InitializeParameter[f] : r0_4
# 1028| r0_6(glval<char>) = VariableAddress[#return] :
#-----| r0_7(lambda [] type at line 1028, col. 32 *) = CopyValue : r0_3
#-----| r0_8(glval<String &>) = FieldAddress[s] : r0_7
#-----| r0_9(String &) = Load : r0_8, mu0_2
# 1028| r0_10(glval<unknown>) = FunctionAddress[c_str] :
# 1028| r0_11(char *) = Call : r0_10, this:r0_9
# 1028| mu0_12(unknown) = ^CallSideEffect : mu0_2
#-----| r0_13(lambda [] type at line 1028, col. 32 *) = CopyValue : r0_3
#-----| r0_14(glval<int>) = FieldAddress[x] : r0_13
#-----| r0_15(int) = Load : r0_14, mu0_2
# 1028| r0_16(char *) = PointerAdd[1] : r0_11, r0_15
# 1028| r0_17(char) = Load : r0_16, mu0_2
# 1028| mu0_18(char) = Store : r0_6, r0_17
# 1028| r0_19(glval<char>) = VariableAddress[#return] :
# 1028| v0_20(void) = ReturnValue : r0_19, mu0_2
# 1028| v0_21(void) = UnmodeledUse : mu*
# 1028| v0_22(void) = ExitFunction :
# 1031| char (void Lambda(int, String const&))::(lambda [] type at line 1031, col. 23)::operator()(float) const
# 1031| Block 0
# 1031| v0_0(void) = EnterFunction :
# 1031| mu0_1(unknown) = AliasedDefinition :
# 1031| mu0_2(unknown) = UnmodeledDefinition :
# 1031| r0_3(glval<decltype([...](...){...})>) = InitializeThis :
# 1031| r0_4(glval<float>) = VariableAddress[f] :
# 1031| mu0_5(float) = InitializeParameter[f] : r0_4
# 1031| r0_6(glval<char>) = VariableAddress[#return] :
#-----| r0_7(lambda [] type at line 1031, col. 23 *) = CopyValue : r0_3
#-----| r0_8(glval<String &>) = FieldAddress[s] : r0_7
#-----| r0_9(String &) = Load : r0_8, mu0_2
# 1031| r0_10(glval<unknown>) = FunctionAddress[c_str] :
# 1031| r0_11(char *) = Call : r0_10, this:r0_9
# 1031| mu0_12(unknown) = ^CallSideEffect : mu0_2
#-----| r0_13(lambda [] type at line 1031, col. 23 *) = CopyValue : r0_3
#-----| r0_14(glval<int>) = FieldAddress[x] : r0_13
#-----| r0_15(int) = Load : r0_14, mu0_2
#-----| r0_16(lambda [] type at line 1031, col. 23 *) = CopyValue : r0_3
# 1031| r0_17(glval<int>) = FieldAddress[i] : r0_16
# 1031| r0_18(int) = Load : r0_17, mu0_2
# 1031| r0_19(int) = Add : r0_15, r0_18
#-----| r0_20(lambda [] type at line 1031, col. 23 *) = CopyValue : r0_3
# 1031| r0_21(glval<int &>) = FieldAddress[j] : r0_20
# 1031| r0_22(int &) = Load : r0_21, mu0_2
# 1031| r0_23(int) = Load : r0_22, mu0_2
# 1031| r0_24(int) = Sub : r0_19, r0_23
# 1031| r0_25(char *) = PointerAdd[1] : r0_11, r0_24
# 1031| r0_26(char) = Load : r0_25, mu0_2
# 1031| mu0_27(char) = Store : r0_6, r0_26
# 1031| r0_28(glval<char>) = VariableAddress[#return] :
# 1031| v0_29(void) = ReturnValue : r0_28, mu0_2
# 1031| v0_30(void) = UnmodeledUse : mu*
# 1031| v0_31(void) = ExitFunction :