13#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONV_H
14#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONV_H
19#include "llvm/Support/SMTAPI.h"
40 static inline llvm::SMTSortRef
mkSort(llvm::SMTSolverRef &Solver,
41 const QualType &Ty,
unsigned BitWidth) {
43 return Solver->getBoolSort();
46 return Solver->getFloatSort(BitWidth);
48 return Solver->getBitvectorSort(BitWidth);
52 static inline llvm::SMTExprRef
fromUnOp(llvm::SMTSolverRef &Solver,
54 const llvm::SMTExprRef &Exp) {
57 return Solver->mkBVNeg(Exp);
60 return Solver->mkBVNot(Exp);
63 return Solver->mkNot(Exp);
67 llvm_unreachable(
"Unimplemented opcode");
71 static inline llvm::SMTExprRef
fromFloatUnOp(llvm::SMTSolverRef &Solver,
73 const llvm::SMTExprRef &Exp) {
76 return Solver->mkFPNeg(Exp);
83 llvm_unreachable(
"Unimplemented opcode");
87 static inline llvm::SMTExprRef
89 const std::vector<llvm::SMTExprRef> &ASTs) {
90 assert(!ASTs.empty());
92 if (Op != BO_LAnd && Op != BO_LOr)
93 llvm_unreachable(
"Unimplemented opcode");
95 llvm::SMTExprRef res = ASTs.front();
96 for (std::size_t i = 1; i < ASTs.size(); ++i)
97 res = (Op == BO_LAnd) ? Solver->mkAnd(res, ASTs[i])
98 : Solver->mkOr(res, ASTs[i]);
103 static inline llvm::SMTExprRef
fromBinOp(llvm::SMTSolverRef &Solver,
104 const llvm::SMTExprRef &LHS,
106 const llvm::SMTExprRef &RHS,
108 assert(*Solver->getSort(LHS) == *Solver->getSort(RHS) &&
109 "AST's must have the same sort!");
114 return Solver->mkBVMul(LHS, RHS);
117 return isSigned ? Solver->mkBVSDiv(LHS, RHS) : Solver->mkBVUDiv(LHS, RHS);
120 return isSigned ? Solver->mkBVSRem(LHS, RHS) : Solver->mkBVURem(LHS, RHS);
124 return Solver->mkBVAdd(LHS, RHS);
127 return Solver->mkBVSub(LHS, RHS);
131 return Solver->mkBVShl(LHS, RHS);
134 return isSigned ? Solver->mkBVAshr(LHS, RHS) : Solver->mkBVLshr(LHS, RHS);
138 return isSigned ? Solver->mkBVSlt(LHS, RHS) : Solver->mkBVUlt(LHS, RHS);
141 return isSigned ? Solver->mkBVSgt(LHS, RHS) : Solver->mkBVUgt(LHS, RHS);
144 return isSigned ? Solver->mkBVSle(LHS, RHS) : Solver->mkBVUle(LHS, RHS);
147 return isSigned ? Solver->mkBVSge(LHS, RHS) : Solver->mkBVUge(LHS, RHS);
151 return Solver->mkEqual(LHS, RHS);
155 fromBinOp(Solver, LHS, BO_EQ, RHS, isSigned));
159 return Solver->mkBVAnd(LHS, RHS);
162 return Solver->mkBVXor(LHS, RHS);
165 return Solver->mkBVOr(LHS, RHS);
169 return Solver->mkAnd(LHS, RHS);
172 return Solver->mkOr(LHS, RHS);
176 llvm_unreachable(
"Unimplemented opcode");
181 static inline llvm::SMTExprRef
184 const llvm::APFloat::fltCategory &RHS) {
189 case llvm::APFloat::fcInfinity:
190 return Solver->mkFPIsInfinite(LHS);
192 case llvm::APFloat::fcNaN:
193 return Solver->mkFPIsNaN(LHS);
195 case llvm::APFloat::fcNormal:
196 return Solver->mkFPIsNormal(LHS);
198 case llvm::APFloat::fcZero:
199 return Solver->mkFPIsZero(LHS);
210 llvm_unreachable(
"Unimplemented opcode");
215 const llvm::SMTExprRef &LHS,
217 const llvm::SMTExprRef &RHS) {
218 assert(*Solver->getSort(LHS) == *Solver->getSort(RHS) &&
219 "AST's must have the same sort!");
224 return Solver->mkFPMul(LHS, RHS);
227 return Solver->mkFPDiv(LHS, RHS);
230 return Solver->mkFPRem(LHS, RHS);
234 return Solver->mkFPAdd(LHS, RHS);
237 return Solver->mkFPSub(LHS, RHS);
241 return Solver->mkFPLt(LHS, RHS);
244 return Solver->mkFPGt(LHS, RHS);
247 return Solver->mkFPLe(LHS, RHS);
250 return Solver->mkFPGe(LHS, RHS);
254 return Solver->mkFPEqual(LHS, RHS);
263 return fromBinOp(Solver, LHS, Op, RHS,
false);
268 llvm_unreachable(
"Unimplemented opcode");
273 static inline llvm::SMTExprRef
fromCast(llvm::SMTSolverRef &Solver,
274 const llvm::SMTExprRef &Exp,
277 uint64_t FromBitWidth) {
281 if (FromTy == ToTy && FromBitWidth == ToBitWidth)
291 assert(ToBitWidth > 0 &&
"BitWidth must be positive!");
292 return Solver->mkIte(
293 Exp, Solver->mkBitvector(llvm::APSInt(
"1"), ToBitWidth),
294 Solver->mkBitvector(llvm::APSInt(
"0"), ToBitWidth));
297 if (ToBitWidth > FromBitWidth)
299 ? Solver->mkBVSignExt(ToBitWidth - FromBitWidth, Exp)
300 : Solver->mkBVZeroExt(ToBitWidth - FromBitWidth, Exp);
302 if (ToBitWidth < FromBitWidth)
303 return Solver->mkBVExtract(ToBitWidth - 1, 0, Exp);
310 if (ToBitWidth != FromBitWidth)
311 return Solver->mkFPtoFP(Exp, Solver->getFloatSort(ToBitWidth));
317 llvm::SMTSortRef Sort = Solver->getFloatSort(ToBitWidth);
319 ? Solver->mkSBVtoFP(Exp, Sort)
320 : Solver->mkUBVtoFP(Exp, Sort);
325 ? Solver->mkFPtoSBV(Exp, ToBitWidth)
326 : Solver->mkFPtoUBV(Exp, ToBitWidth);
328 llvm_unreachable(
"Unsupported explicit type cast!");
332 static inline llvm::APSInt
castAPSInt(llvm::SMTSolverRef &Solver,
335 uint64_t FromWidth) {
341 static inline llvm::SMTExprRef
348 llvm::raw_svector_ostream
OS(Str);
350 return Solver->mkSymbol(Str.c_str(),
mkSort(Solver, Ty, BitWidth));
354 static inline llvm::SMTExprRef
getCastExpr(llvm::SMTSolverRef &Solver,
356 const llvm::SMTExprRef &Exp,
362 static inline std::optional<llvm::SMTExprRef>
364 const llvm::SMTExprRef &Exp,
QualType Ty) {
377 Solver->mkBitvector(llvm::APSInt::getUnsigned(0),
380 assert(
false &&
"Unsupported type for boolean conversion!");
386 static inline std::optional<llvm::SMTExprRef>
388 const llvm::SMTExprRef &LHS,
QualType LTy,
391 llvm::SMTExprRef NewLHS = LHS;
392 llvm::SMTExprRef NewRHS = RHS;
405 if (!LHSOpt || !RHSOpt)
407 NewLHS = LHSOpt.value();
408 NewRHS = RHSOpt.value();
409 return fromBinOp(Solver, NewLHS, Op, NewRHS,
false);
429 static inline std::optional<llvm::SMTExprRef>
436 if (
const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
437 std::optional<llvm::SMTExprRef> LHS =
438 getSymExpr(Solver, Ctx, SIE->getLHS(), LTy, hasComparison);
441 llvm::APSInt NewRInt;
442 std::tie(NewRInt, RTy) =
fixAPSInt(Ctx, SIE->getRHS());
443 llvm::SMTExprRef RHS =
444 Solver->mkBitvector(NewRInt, NewRInt.getBitWidth());
445 return getBinExpr(Solver, Ctx, LHS.value(), LTy, Op, RHS, RTy, RetTy);
448 if (
const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
449 llvm::APSInt NewLInt;
450 std::tie(NewLInt, LTy) =
fixAPSInt(Ctx, ISE->getLHS());
451 llvm::SMTExprRef LHS =
452 Solver->mkBitvector(NewLInt, NewLInt.getBitWidth());
453 std::optional<llvm::SMTExprRef> RHS =
454 getSymExpr(Solver, Ctx, ISE->getRHS(), RTy, hasComparison);
457 return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS.value(), RTy, RetTy);
460 if (
const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
461 std::optional<llvm::SMTExprRef> LHS =
462 getSymExpr(Solver, Ctx, SSM->getLHS(), LTy, hasComparison);
463 std::optional<llvm::SMTExprRef> RHS =
464 getSymExpr(Solver, Ctx, SSM->getRHS(), RTy, hasComparison);
467 return getBinExpr(Solver, Ctx, LHS.value(), LTy, Op, RHS.value(), RTy,
471 assert(
false &&
"Unsupported BinarySymExpr type!");
477 static inline std::optional<llvm::SMTExprRef>
479 QualType &RetTy,
bool *hasComparison) {
480 if (
const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
486 if (
const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
490 std::optional<llvm::SMTExprRef> Exp =
491 getSymExpr(Solver, Ctx, SC->getOperand(), FromTy, hasComparison);
498 *hasComparison =
false;
499 return getCastExpr(Solver, Ctx, Exp.value(), FromTy, RetTy);
502 if (
const UnarySymExpr *USE = dyn_cast<UnarySymExpr>(Sym)) {
506 std::optional<llvm::SMTExprRef> OperandExp =
507 getSymExpr(Solver, Ctx, USE->getOperand(), OperandTy, hasComparison);
514 if (OperandTy == Ctx.
BoolTy && OperandTy != RetTy &&
518 *hasComparison =
false;
520 OperandExp =
fromCast(Solver, OperandExp.value(), RetTy,
525 llvm::SMTExprRef UnaryExp =
527 ?
fromFloatUnOp(Solver, USE->getOpcode(), OperandExp.value())
528 :
fromUnOp(Solver, USE->getOpcode(), OperandExp.value());
536 *hasComparison =
false;
537 return getCastExpr(Solver, Ctx, UnaryExp, OperandTy, RetTy);
542 if (
const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
543 std::optional<llvm::SMTExprRef> Exp =
550 assert(
false &&
"Unsupported SymbolRef type!");
558 static inline std::optional<llvm::SMTExprRef>
560 QualType &RetTy,
bool *hasComparison =
nullptr) {
562 *hasComparison =
false;
565 return getSymExpr(Solver, Ctx, Sym, RetTy, hasComparison);
569 static inline llvm::SMTExprRef
getZeroExpr(llvm::SMTSolverRef &Solver,
571 const llvm::SMTExprRef &Exp,
577 Solver->mkFloat(
Zero));
586 return Assumption ?
fromUnOp(Solver, UO_LNot, Exp) : Exp;
588 return fromBinOp(Solver, Exp, Assumption ? BO_EQ : BO_NE,
589 Solver->mkBitvector(llvm::APSInt(
"0"),
594 llvm_unreachable(
"Unsupported type for zero value!");
599 static inline std::optional<llvm::SMTExprRef>
601 const llvm::APSInt &From,
const llvm::APSInt &To,
bool InRange) {
604 llvm::APSInt NewFromInt;
605 std::tie(NewFromInt, FromTy) =
fixAPSInt(Ctx, From);
606 llvm::SMTExprRef FromExp =
607 Solver->mkBitvector(NewFromInt, NewFromInt.getBitWidth());
611 std::optional<llvm::SMTExprRef> Exp =
getExpr(Solver, Ctx, Sym, SymTy);
617 return getBinExpr(Solver, Ctx, Exp.value(), SymTy,
618 InRange ? BO_EQ : BO_NE, FromExp, FromTy,
623 llvm::APSInt NewToInt;
624 std::tie(NewToInt, ToTy) =
fixAPSInt(Ctx, To);
625 llvm::SMTExprRef ToExp =
626 Solver->mkBitvector(NewToInt, NewToInt.getBitWidth());
627 assert(FromTy == ToTy &&
"Range values have different types!");
631 std::optional<llvm::SMTExprRef> LHS =
632 getBinExpr(Solver, Ctx, Exp.value(), SymTy, InRange ? BO_GE : BO_LT,
633 FromExp, FromTy, UnusedRetTy);
634 std::optional<llvm::SMTExprRef> RHS =
getBinExpr(
635 Solver, Ctx, Exp.value(), SymTy, InRange ? BO_LE : BO_GT, ToExp, ToTy,
639 return fromBinOp(Solver, LHS.value(), InRange ? BO_LAnd : BO_LOr,
646 const llvm::APSInt &Int) {
647 return Ctx.
getBitIntType(Int.isUnsigned(), Int.getBitWidth());
651 static inline std::pair<llvm::APSInt, QualType>
661 llvm::SMTExprRef &RHS,
QualType <y,
663 assert(!LTy.
isNull() && !RTy.
isNull() &&
"Input type is null!");
670 Solver, Ctx, LHS, LTy, RHS, RTy);
676 Solver, Ctx, LHS, LTy, RHS, RTy);
696 LHS =
fromCast(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
699 RHS =
fromCast(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
710 "Pointer types have different bitwidths!");
734 template <
typename T,
T (*doCast)(llvm::SMTSolverRef &Solver,
const T &,
742 assert(!LTy.
isNull() && !RTy.
isNull() &&
"Input type is null!");
748 LHS = (*doCast)(Solver, LHS, NewTy, NewBitWidth, LTy, LBitWidth);
750 LBitWidth = NewBitWidth;
755 RHS = (*doCast)(Solver, RHS, NewTy, NewBitWidth, RTy, RBitWidth);
757 RBitWidth = NewBitWidth;
769 if (isLSignedTy == isRSignedTy) {
772 RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
775 LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
778 }
else if (order != (isLSignedTy ? 1 : -1)) {
782 RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
785 LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
788 }
else if (LBitWidth != RBitWidth) {
793 RHS = (doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
796 LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
806 RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
808 LHS = (doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
816 template <
typename T,
T (*doCast)(llvm::SMTSolverRef &Solver,
const T &,
826 LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
828 LBitWidth = RBitWidth;
831 RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
833 RBitWidth = LBitWidth;
844 RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
846 }
else if (order == 0) {
847 LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
850 llvm_unreachable(
"Unsupported floating-point type cast!");
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
int getIntegerTypeOrder(QualType LHS, QualType RHS) const
Return the highest ranked integer type, see C99 6.3.1.8p1.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
QualType getCorrespondingUnsignedType(QualType T) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
QualType getBitIntType(bool Unsigned, unsigned NumBits) const
Return a bit-precise integer type with the specified signedness and bit count.
static bool isLogicalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
bool isComparisonOp() const
BinaryOperatorKind Opcode
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isVoidPointerType() const
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isReferenceType() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isObjCObjectPointerType() const
bool isRealFloatingType() const
Floating point categories.
bool isAnyPointerType() const
bool isNullPtrType() const
A record of the "type" of an APSInt, used for conversions.
llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY
Convert and return a new APSInt with the given value, but this type's bit width and signedness.
Represents a symbolic expression involving a binary operator.
BinaryOperator::Opcode getOpcode() const
static llvm::SMTSortRef mkSort(llvm::SMTSolverRef &Solver, const QualType &Ty, unsigned BitWidth)
static std::optional< llvm::SMTExprRef > getRangeExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym, const llvm::APSInt &From, const llvm::APSInt &To, bool InRange)
static llvm::SMTExprRef fromFloatBinOp(llvm::SMTSolverRef &Solver, const llvm::SMTExprRef &LHS, const BinaryOperator::Opcode Op, const llvm::SMTExprRef &RHS)
Construct an SMTSolverRef from a floating-point binary operator.
static std::optional< llvm::SMTExprRef > getBinExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const llvm::SMTExprRef &LHS, QualType LTy, BinaryOperator::Opcode Op, const llvm::SMTExprRef &RHS, QualType RTy, QualType &RetTy)
static QualType getAPSIntType(ASTContext &Ctx, const llvm::APSInt &Int)
static llvm::SMTExprRef getZeroExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const llvm::SMTExprRef &Exp, QualType Ty, bool Assumption)
static void doIntTypeConversion(llvm::SMTSolverRef &Solver, ASTContext &Ctx, T &LHS, QualType <y, T &RHS, QualType &RTy)
static std::optional< llvm::SMTExprRef > convertToBoolExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const llvm::SMTExprRef &Exp, QualType Ty)
static llvm::SMTExprRef fromNBinOp(llvm::SMTSolverRef &Solver, const BinaryOperator::Opcode Op, const std::vector< llvm::SMTExprRef > &ASTs)
Construct an SMTSolverRef from a n-ary binary operator.
static std::optional< llvm::SMTExprRef > getSymExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym, QualType &RetTy, bool *hasComparison)
static void doTypeConversion(llvm::SMTSolverRef &Solver, ASTContext &Ctx, llvm::SMTExprRef &LHS, llvm::SMTExprRef &RHS, QualType <y, QualType &RTy)
static std::optional< llvm::SMTExprRef > getSymBinExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const BinarySymExpr *BSE, bool *hasComparison, QualType &RetTy)
static std::optional< llvm::SMTExprRef > getExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym, QualType &RetTy, bool *hasComparison=nullptr)
static llvm::SMTExprRef fromFloatSpecialBinOp(llvm::SMTSolverRef &Solver, const llvm::SMTExprRef &LHS, const BinaryOperator::Opcode Op, const llvm::APFloat::fltCategory &RHS)
Construct an SMTSolverRef from a special floating-point binary operator.
static QualType getSymbolicValueType(QualType Ty)
static llvm::SMTExprRef fromData(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const SymbolData *Sym)
Construct an SMTSolverRef from a SymbolData.
static void doFloatTypeConversion(llvm::SMTSolverRef &Solver, ASTContext &Ctx, T &LHS, QualType <y, T &RHS, QualType &RTy)
static llvm::SMTExprRef fromBinOp(llvm::SMTSolverRef &Solver, const llvm::SMTExprRef &LHS, const BinaryOperator::Opcode Op, const llvm::SMTExprRef &RHS, bool isSigned)
Construct an SMTSolverRef from a binary operator.
static llvm::SMTExprRef getCastExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, const llvm::SMTExprRef &Exp, QualType FromTy, QualType ToTy)
static std::pair< llvm::APSInt, QualType > fixAPSInt(ASTContext &Ctx, const llvm::APSInt &Int)
static llvm::SMTExprRef fromCast(llvm::SMTSolverRef &Solver, const llvm::SMTExprRef &Exp, QualType ToTy, uint64_t ToBitWidth, QualType FromTy, uint64_t FromBitWidth)
Construct an SMTSolverRef from a QualType FromTy to a QualType ToTy, and their bit widths.
static uint64_t getSMTBitWidth(ASTContext &Ctx, QualType Ty)
static llvm::APSInt castAPSInt(llvm::SMTSolverRef &Solver, const llvm::APSInt &V, QualType ToTy, uint64_t ToWidth, QualType FromTy, uint64_t FromWidth)
static llvm::SMTExprRef fromFloatUnOp(llvm::SMTSolverRef &Solver, const UnaryOperator::Opcode Op, const llvm::SMTExprRef &Exp)
Constructs an SMTSolverRef from a floating-point unary operator.
static llvm::SMTExprRef fromUnOp(llvm::SMTSolverRef &Solver, const UnaryOperator::Opcode Op, const llvm::SMTExprRef &Exp)
Constructs an SMTSolverRef from an unary operator.
virtual QualType getType() const =0
SymbolID getSymbolID() const
Get a unique identifier for this symbol.
Represents a cast expression.
A symbol representing data which can be stored in a memory location (region).
virtual StringRef getKindStr() const =0
Get a string representation of the kind of the region.
Represents a symbolic expression involving a unary operator.
BinarySymExprImpl< APSIntPtr, const SymExpr *, SymExpr::Kind::IntSymExprKind > IntSymExpr
Represents a symbolic expression like 3 - 'x'.
const SymExpr * SymbolRef
BinarySymExprImpl< const SymExpr *, const SymExpr *, SymExpr::Kind::SymSymExprKind > SymSymExpr
Represents a symbolic expression like 'x' + 'y'.
BinarySymExprImpl< const SymExpr *, APSIntPtr, SymExpr::Kind::SymIntExprKind > SymIntExpr
Represents a symbolic expression like 'x' + 3.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T