39 SVal LeftV = State->getSVal(LHS, SF);
40 SVal RightV = State->getSVal(RHS, SF);
44 if (Op == BO_Assign) {
53 evalStore(Tmp2, B, LHS, N, State->BindExpr(B, SF, ExprVal), LeftV,
70 ConjureIfNeeded(RightV, LeftV, RHS->
getType());
71 ConjureIfNeeded(LeftV, RightV, LHS->
getType());
78 State = createTemporaryRegionIfNeeded(State, SF, LHS);
84 State = State->BindExpr(B, SF,
Result);
91 Tmp2.
insert(Engine.makePostStmtNode(B, State, N));
99 llvm_unreachable(
"Invalid opcode for compound assignment.");
100 case BO_MulAssign: Op = BO_Mul;
break;
101 case BO_DivAssign: Op = BO_Div;
break;
102 case BO_RemAssign: Op = BO_Rem;
break;
103 case BO_AddAssign: Op = BO_Add;
break;
104 case BO_SubAssign: Op = BO_Sub;
break;
105 case BO_ShlAssign: Op = BO_Shl;
break;
106 case BO_ShrAssign: Op = BO_Shr;
break;
107 case BO_AndAssign: Op = BO_And;
break;
108 case BO_XorAssign: Op = BO_Xor;
break;
109 case BO_OrAssign: Op = BO_Or;
break;
115 evalLoad(Tmp, B, LHS, N, State, LeftV);
118 State = N->getState();
119 SVal V = State->getSVal(LHS, SF);
129 V = svalBuilder.evalCast(
V, CLHSTy, LTy);
141 StoredInLeftV = svalBuilder.conjureSymbolVal(
145 Result = svalBuilder.evalCast(StoredInLeftV, CTy, LTy);
149 StoredInLeftV = svalBuilder.evalCast(
Result, LTy, CTy);
155 State = State->BindExpr(B, SF, LeftV);
157 State = State->BindExpr(B, SF,
Result);
159 evalStore(Tmp2, B, LHS, N, State, LeftV, StoredInLeftV);
182 dyn_cast_or_null<BlockDataRegion>(
V.getAsRegion())) {
184 auto ReferencedVars = BDR->referenced_vars();
187 for (
auto Var : ReferencedVars) {
188 const VarRegion *capturedR = Var.getCapturedRegion();
197 const Expr *copyExpr =
nullptr;
199 assert(CI->getVariable() == capturedR->
getDecl());
200 copyExpr = CI->getCopyExpr();
204 if (capturedR != originalR) {
208 originalV = State->getSVal(copyExpr, SF);
231 if (T->isLValueReferenceType()) {
234 }
else if (T->isRValueReferenceType()) {
239 SVal OrigV = state->getSVal(Ex, SF);
240 SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
241 SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
243 if (CastE->
getCastKind() == CK_BooleanToSignedIntegral &&
V.isValid())
244 V = svalBuilder.evalMinus(
V.castAs<
NonLoc>());
246 state = state->BindExpr(CastE, SF,
V);
265 evalLoad(Dst, CastE, CastE, Node, State, State->getSVal(Ex, SF));
269 if (CastE->
getCastKind() == CK_LValueToRValueBitCast) {
277 evalLocation(DstEvalLoc, CastE, Ex, Node, State, State->getSVal(Ex, SF),
292 if (
const MemRegion *MR = State->getSVal(Ex, SF).getAsRegion()) {
293 SVal OrigV = State->getSVal(MR);
294 CastedV = svalBuilder.evalCast(svalBuilder.simplifySVal(State, OrigV),
297 State = State->BindExpr(CastE, SF, CastedV);
307 if (
const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
308 T = ExCast->getTypeAsWritten();
316 case CK_LValueToRValue:
317 case CK_LValueToRValueBitCast:
318 llvm_unreachable(
"LValueToRValue casts handled earlier.");
323 case CK_ARCProduceObject:
324 case CK_ARCConsumeObject:
325 case CK_ARCReclaimReturnedObject:
326 case CK_ARCExtendBlockObject:
327 case CK_CopyAndAutoreleaseBlockObject:
331 case CK_AtomicToNonAtomic:
332 case CK_NonAtomicToAtomic:
335 case CK_ConstructorConversion:
336 case CK_UserDefinedConversion:
337 case CK_FunctionToPointerDecay:
338 case CK_BuiltinFnToFnPtr:
339 case CK_HLSLArrayRValue: {
343 SVal V = state->getSVal(Ex, SF);
344 state = state->BindExpr(CastE, SF,
V);
348 case CK_MemberPointerToBoolean:
349 case CK_PointerToBoolean: {
350 SVal V = state->getSVal(Ex, SF);
353 V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
354 if (
V.isUndef() || PTMSV) {
355 state = state->BindExpr(CastE, SF,
V);
364 case CK_ArrayToPointerDecay:
366 case CK_AddressSpaceConversion:
367 case CK_BooleanToSignedIntegral:
368 case CK_IntegralToPointer:
369 case CK_PointerToIntegral: {
370 SVal V = state->getSVal(Ex, SF);
372 state = state->BindExpr(CastE, SF,
UnknownVal());
380 case CK_IntegralToBoolean:
381 case CK_IntegralToFloating:
382 case CK_FloatingToIntegral:
383 case CK_FloatingToBoolean:
384 case CK_FloatingCast:
385 case CK_FloatingRealToComplex:
386 case CK_FloatingComplexToReal:
387 case CK_FloatingComplexToBoolean:
388 case CK_FloatingComplexCast:
389 case CK_FloatingComplexToIntegralComplex:
390 case CK_IntegralRealToComplex:
391 case CK_IntegralComplexToReal:
392 case CK_IntegralComplexToBoolean:
393 case CK_IntegralComplexCast:
394 case CK_IntegralComplexToFloatingComplex:
395 case CK_CPointerToObjCPointerCast:
396 case CK_BlockPointerToObjCPointerCast:
397 case CK_AnyPointerToBlockPointerCast:
398 case CK_ObjCObjectLValueCast:
399 case CK_ZeroToOCLOpaqueType:
400 case CK_IntToOCLSampler:
401 case CK_LValueBitCast:
402 case CK_FloatingToFixedPoint:
403 case CK_FixedPointToFloating:
404 case CK_FixedPointCast:
405 case CK_FixedPointToBoolean:
406 case CK_FixedPointToIntegral:
407 case CK_IntegralToFixedPoint: {
411 case CK_IntegralCast: {
413 SVal V = state->getSVal(Ex, SF);
414 if (AMgr.options.ShouldSupportSymbolicIntegerCasts)
415 V = svalBuilder.evalCast(
V, T, ExTy);
417 V = svalBuilder.evalIntegralCast(state,
V, T, ExTy);
418 state = state->BindExpr(CastE, SF,
V);
422 case CK_DerivedToBase:
423 case CK_UncheckedDerivedToBase: {
425 SVal val = state->getSVal(Ex, SF);
427 state = state->BindExpr(CastE, SF, val);
433 SVal val = state->getSVal(Ex, SF);
444 if (std::optional<SVal>
V =
445 StateMgr.getStoreManager().evalBaseToDerived(val, T)) {
451 if (T->isReferenceType()) {
458 state = state->BindExpr(CastE, SF,
459 svalBuilder.makeNullWithType(resultType));
467 state = state->BindExpr(CastE, SF, NewSym);
470 state = state->BindExpr(CastE, SF, val);
475 case CK_BaseToDerived: {
476 SVal val = state->getSVal(Ex, SF);
488 val = svalBuilder.conjureSymbolVal(
492 state = state->BindExpr(CastE, SF, val);
496 case CK_NullToPointer: {
497 SVal V = svalBuilder.makeNullWithType(CastE->
getType());
498 state = state->BindExpr(CastE, SF,
V);
502 case CK_NullToMemberPointer: {
503 SVal V = svalBuilder.getMemberPointer(
nullptr);
504 state = state->BindExpr(CastE, SF,
V);
508 case CK_DerivedToBaseMemberPointer:
509 case CK_BaseToDerivedMemberPointer:
510 case CK_ReinterpretMemberPointer: {
511 SVal V = state->getSVal(Ex, SF);
514 svalBuilder.makePointerToMember(
getBasicVals().accumCXXBase(
516 state = state->BindExpr(CastE, SF, CastedPTMSV);
527 case CK_HLSLElementwiseCast:
528 case CK_HLSLAggregateSplatCast:
529 case CK_HLSLMatrixTruncation:
530 case CK_HLSLVectorTruncation: {
534 SVal result = svalBuilder.conjureSymbolVal(
537 state = state->BindExpr(CastE, SF, result);
554 SVal V = State->getSVal(
CL->getInitializer(), SF);
560 Loc CLLoc = State->getLValue(
CL, SF);
561 State = State->bindLoc(CLLoc,
V, SF);
598 NodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
610 SVal InitVal = state->getSVal(InitEx, SF);
614 state = finishObjectConstruction(state, DS, SF);
623 if (InitEx->isGLValue()) {
627 InitVal = svalBuilder.conjureSymbolVal(
635 evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, SF), InitVal,
true);
709 if (
const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
711 assert(Term->isLogicalOp());
715 X = svalBuilder.makeIntVal(constant, B->
getType());
721 assert(!SrcBlock->
empty());
734 svalBuilder.evalCast(RHSVal, B->
getType(), RHS->getType()),
756 auto Edge = N->getLocationAs<
BlockEdge>();
757 if (!Edge.has_value()) {
765 SrcBlock = Edge->getSrc();
766 SrcState = N->getState();
770 assert(SrcBlock &&
"missing function entry");
774 bool hasValue =
false;
777 for (
CFGElement CE : llvm::reverse(*SrcBlock)) {
778 if (std::optional<CFGStmt> CS = CE.getAs<
CFGStmt>()) {
785 L = OpaqueEx->getSourceExpr();
789 if (ValEx == L->
IgnoreParens() || ValEx == R->IgnoreParens()) {
791 V = SrcState->getSVal(ValEx, SF);
811 APSInt IV =
Result.Val.getInt();
815 SVal X = svalBuilder.makeIntVal(IV);
832 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
837 if (Ex->
getKind() == UETT_SizeOf || Ex->
getKind() == UETT_DataSizeOf ||
838 Ex->
getKind() == UETT_CountOf) {
839 if (!T->isIncompleteType() && !T->isConstantSizeType()) {
840 assert(T->isVariableArrayType() &&
"Unknown non-constant-sized type.");
857 state = state->BindExpr(
858 Ex, N->getStackFrame(),
875 const Expr *Ex =
U->getSubExpr()->IgnoreParens();
878 Bldr.
generateNode(
U, N, state->BindExpr(
U, SF, state->getSVal(Ex, SF)));
888 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
891 switch (
U->getOpcode()) {
900 const Expr *Ex =
U->getSubExpr()->IgnoreParens();
909 assert (
U->getType() == Ex->
getType());
912 Bldr.
generateNode(
U, N, state->BindExpr(
U, SF, state->getSVal(Ex, SF)));
917 const Expr *Ex =
U->getSubExpr()->IgnoreParens();
933 const Expr *Ex =
U->getSubExpr()->IgnoreParens();
934 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
950 assert(!
U->isGLValue());
961 assert (!
U->isGLValue());
962 const Expr *Ex =
U->getSubExpr()->IgnoreParens();
967 SVal V = state->getSVal(Ex, SF);
969 if (
V.isUnknownOrUndef()) {
974 switch (
U->getOpcode()) {
976 llvm_unreachable(
"Invalid Opcode.");
979 state = state->BindExpr(
980 U, SF, svalBuilder.evalComplement(
V.castAs<
NonLoc>()));
985 state->BindExpr(
U, SF, svalBuilder.evalMinus(
V.castAs<
NonLoc>()));
993 if (std::optional<Loc> LV =
V.getAs<
Loc>()) {
994 Loc X = svalBuilder.makeNullWithType(Ex->
getType());
1004 state = state->BindExpr(
U, SF,
Result);
1020 assert (
U->isIncrementDecrementOp());
1021 const Expr *Ex =
U->getSubExpr()->IgnoreParens();
1025 SVal loc = state->getSVal(Ex, SF);
1034 state = N->getState();
1035 assert(SF == N->getStackFrame());
1036 SVal V2_untested = state->getSVal(Ex, SF);
1040 state = state->BindExpr(
U, SF, V2_untested);
1061 if (
U->getType()->isAnyPointerType())
1062 RHS = svalBuilder.makeArrayIndex(1);
1063 else if (
U->getType()->isIntegralOrEnumerationType())
1064 RHS = svalBuilder.makeIntVal(1,
U->getType());
1072 if (
U->getType()->isBooleanType() &&
U->isIncrementOp())
1073 Result = svalBuilder.makeTruthVal(
true,
U->getType());
1089 svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(
U->getType()));
1091 if (!state->assume(Constraint,
true)) {
1094 Constraint = svalBuilder.evalEQ(state, SymVal,
1095 svalBuilder.makeZeroVal(
U->getType()));
1097 state = state->assume(Constraint,
false);
1106 state = state->BindExpr(
U, SF,
loc);
1108 state = state->BindExpr(
U, SF,
U->isPostfix() ? V2 :
Result);
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isAdditiveOp(Opcode Opc)
static bool isAssignmentOp(Opcode Opc)
static bool isCompoundAssignmentOp(Opcode Opc)
BinaryOperatorKind Opcode
Represents a block literal declaration, which is like an unnamed FunctionDecl.
capture_const_iterator capture_begin() const
capture_const_iterator capture_end() const
const CFGBlock * getSrc() const
const CFGBlock * getDst() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
const BlockDecl * getBlockDecl() const
This class is used for builtin types like 'int'.
Represents a single basic block in a source-level CFG.
reverse_iterator rbegin()
CFGTerminator getTerminator() const
succ_iterator succ_begin()
unsigned succ_size() const
Represents a top-level expression in a basic block.
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
const Stmt * getStmt() const
Represents CFGBlock terminator statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CompoundLiteralExpr - [C99 6.5.2.5].
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
decl_iterator decl_begin()
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Represents a point after we ran remove dead bindings BEFORE processing the given statement.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type.
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
A (possibly-)qualified type.
It represents a stack frame of the call stack.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isRValueReferenceType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isLValueReferenceType() const
bool isAnyComplexType() const
bool isVectorType() const
bool isFloatingType() const
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
const Expr * getInit() const
BlockDataRegion - A region that represents a block instance.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
void insert(ExplodedNode *N)
ImplTy::iterator iterator
const ProgramStateRef & getState() const
pred_iterator pred_begin()
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
unsigned pred_size() const
const StackFrame * getStackFrame() const
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
BasicValueFactory & getBasicVals()
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, SVal LHS, SVal RHS, QualType T)
void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryOperator - Transfer function logic for unary operators.
void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitDeclStmt - Transfer function logic for DeclStmts.
ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex, const StackFrame *SF, QualType T, QualType ExTy, const CastExpr *CastE, NodeBuilder &Bldr, ExplodedNode *Pred)
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBlockExpr - Transfer function logic for BlockExprs.
void VisitIncrementDecrementOperator(const UnaryOperator *U, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Handle ++ and – (both pre- and post-increment).
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
StoreManager & getStoreManager()
ConstCFGElementRef getCFGElementRef() const
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef< SVal > Vs, PointerEscapeKind K, const CallEvent *Call=nullptr) const
A simple wrapper when you only need to notify checkers of pointer-escape of some values.
CheckerManager & getCheckerManager() const
static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const StackFrame *SF)
By looking at a certain item that may be potentially part of an object's ConstructionContext,...
unsigned getNumVisitedCurrent() const
void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitOffsetOfExpr - Transfer function for offsetof.
void evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx, const Expr *BoundExpr, ExplodedNode *Pred, ProgramStateRef St, SVal location, const ProgramPointTag *tag=nullptr, QualType LoadTy=QualType())
Simulate a read of the result of Ex.
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
void handleUOExtension(ExplodedNode *N, const UnaryOperator *U, NodeBuilder &Bldr)
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, const ProgramPointTag *tag=nullptr)
evalStore - Handle the semantics of a store via an assignment.
static bool isLocType(QualType T)
MemRegion - The root abstract class for all memory regions.
This is the simplest builder which generates nodes in the ExplodedGraph.
void takeNodes(const ExplodedNodeSet &S)
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
Generates a node in the ExplodedGraph.
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
void addNodes(const ExplodedNodeSet &S)
const ExplodedNodeSet & getResults() const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
bool isZeroConstant() const
bool isUnknownOrUndef() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
std::optional< SVal > evalBaseToDerived(SVal Base, QualType DerivedPtrType)
Attempts to do a down cast.
TypedValueRegion - An abstract class representing regions having a typed value.
const VarDecl * getDecl() const override=0
Value representing integer constant.
Value representing pointer-to-member.
@ PSK_EscapeOther
The reason for pointer escape is unknown.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)
@ Other
Other implicit parameter.
EvalResult is a struct with detailed info about an evaluated expression.