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);
428 static inline std::optional<llvm::SMTExprRef>
435 if (
const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
436 std::optional<llvm::SMTExprRef> LHS =
437 getSymExpr(Solver, Ctx, SIE->getLHS(), LTy, hasComparison);
440 llvm::APSInt NewRInt;
441 std::tie(NewRInt, RTy) =
fixAPSInt(Ctx, SIE->getRHS());
442 llvm::SMTExprRef RHS =
443 Solver->mkBitvector(NewRInt, NewRInt.getBitWidth());
444 return getBinExpr(Solver, Ctx, LHS.value(), LTy, Op, RHS, RTy, RetTy);
447 if (
const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
448 llvm::APSInt NewLInt;
449 std::tie(NewLInt, LTy) =
fixAPSInt(Ctx, ISE->getLHS());
450 llvm::SMTExprRef LHS =
451 Solver->mkBitvector(NewLInt, NewLInt.getBitWidth());
452 std::optional<llvm::SMTExprRef> RHS =
453 getSymExpr(Solver, Ctx, ISE->getRHS(), RTy, hasComparison);
456 return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS.value(), RTy, RetTy);
459 if (
const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
460 std::optional<llvm::SMTExprRef> LHS =
461 getSymExpr(Solver, Ctx, SSM->getLHS(), LTy, hasComparison);
462 std::optional<llvm::SMTExprRef> RHS =
463 getSymExpr(Solver, Ctx, SSM->getRHS(), RTy, hasComparison);
466 return getBinExpr(Solver, Ctx, LHS.value(), LTy, Op, RHS.value(), RTy,
470 assert(
false &&
"Unsupported BinarySymExpr type!");
476 static inline std::optional<llvm::SMTExprRef>
478 QualType &RetTy,
bool *hasComparison) {
479 if (
const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
485 if (
const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
489 std::optional<llvm::SMTExprRef> Exp =
490 getSymExpr(Solver, Ctx, SC->getOperand(), FromTy, hasComparison);
497 *hasComparison =
false;
498 return getCastExpr(Solver, Ctx, Exp.value(), FromTy, RetTy);
501 if (
const UnarySymExpr *USE = dyn_cast<UnarySymExpr>(Sym)) {
505 std::optional<llvm::SMTExprRef> OperandExp =
506 getSymExpr(Solver, Ctx, USE->getOperand(), OperandTy, hasComparison);
513 if (OperandTy == Ctx.
BoolTy && OperandTy != RetTy &&
517 *hasComparison =
false;
519 OperandExp =
fromCast(Solver, OperandExp.value(), RetTy,
524 llvm::SMTExprRef UnaryExp =
526 ?
fromFloatUnOp(Solver, USE->getOpcode(), OperandExp.value())
527 :
fromUnOp(Solver, USE->getOpcode(), OperandExp.value());
535 *hasComparison =
false;
536 return getCastExpr(Solver, Ctx, UnaryExp, OperandTy, RetTy);
541 if (
const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
542 std::optional<llvm::SMTExprRef> Exp =
549 assert(
false &&
"Unsupported SymbolRef type!");
557 static inline std::optional<llvm::SMTExprRef>
559 QualType &RetTy,
bool *hasComparison =
nullptr) {
561 *hasComparison =
false;
564 return getSymExpr(Solver, Ctx, Sym, RetTy, hasComparison);
568 static inline llvm::SMTExprRef
getZeroExpr(llvm::SMTSolverRef &Solver,
570 const llvm::SMTExprRef &Exp,
576 Solver->mkFloat(
Zero));
585 return Assumption ?
fromUnOp(Solver, UO_LNot, Exp) : Exp;
587 return fromBinOp(Solver, Exp, Assumption ? BO_EQ : BO_NE,
588 Solver->mkBitvector(llvm::APSInt(
"0"),
593 llvm_unreachable(
"Unsupported type for zero value!");
598 static inline std::optional<llvm::SMTExprRef>
600 const llvm::APSInt &From,
const llvm::APSInt &To,
bool InRange) {
603 llvm::APSInt NewFromInt;
604 std::tie(NewFromInt, FromTy) =
fixAPSInt(Ctx, From);
605 llvm::SMTExprRef FromExp =
606 Solver->mkBitvector(NewFromInt, NewFromInt.getBitWidth());
610 std::optional<llvm::SMTExprRef> Exp =
getExpr(Solver, Ctx, Sym, SymTy);
616 return getBinExpr(Solver, Ctx, Exp.value(), SymTy,
617 InRange ? BO_EQ : BO_NE, FromExp, FromTy,
622 llvm::APSInt NewToInt;
623 std::tie(NewToInt, ToTy) =
fixAPSInt(Ctx, To);
624 llvm::SMTExprRef ToExp =
625 Solver->mkBitvector(NewToInt, NewToInt.getBitWidth());
626 assert(FromTy == ToTy &&
"Range values have different types!");
630 std::optional<llvm::SMTExprRef> LHS =
631 getBinExpr(Solver, Ctx, Exp.value(), SymTy, InRange ? BO_GE : BO_LT,
632 FromExp, FromTy, UnusedRetTy);
633 std::optional<llvm::SMTExprRef> RHS =
getBinExpr(
634 Solver, Ctx, Exp.value(), SymTy, InRange ? BO_LE : BO_GT, ToExp, ToTy,
638 return fromBinOp(Solver, LHS.value(), InRange ? BO_LAnd : BO_LOr,
645 const llvm::APSInt &Int) {
646 return Ctx.
getBitIntType(Int.isUnsigned(), Int.getBitWidth());
650 static inline std::pair<llvm::APSInt, QualType>
660 llvm::SMTExprRef &RHS,
QualType <y,
662 assert(!LTy.
isNull() && !RTy.
isNull() &&
"Input type is null!");
669 Solver, Ctx, LHS, LTy, RHS, RTy);
675 Solver, Ctx, LHS, LTy, RHS, RTy);
695 LHS =
fromCast(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
698 RHS =
fromCast(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
709 "Pointer types have different bitwidths!");
733 template <
typename T,
T (*doCast)(llvm::SMTSolverRef &Solver,
const T &,
741 assert(!LTy.
isNull() && !RTy.
isNull() &&
"Input type is null!");
747 LHS = (*doCast)(Solver, LHS, NewTy, NewBitWidth, LTy, LBitWidth);
749 LBitWidth = NewBitWidth;
754 RHS = (*doCast)(Solver, RHS, NewTy, NewBitWidth, RTy, RBitWidth);
756 RBitWidth = NewBitWidth;
768 if (isLSignedTy == isRSignedTy) {
771 RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
774 LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
777 }
else if (order != (isLSignedTy ? 1 : -1)) {
781 RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
784 LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
787 }
else if (LBitWidth != RBitWidth) {
792 RHS = (doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
795 LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
805 RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
807 LHS = (doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
815 template <
typename T,
T (*doCast)(llvm::SMTSolverRef &Solver,
const T &,
825 LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
827 LBitWidth = RBitWidth;
830 RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
832 RBitWidth = LBitWidth;
843 RHS = (*doCast)(Solver, RHS, LTy, LBitWidth, RTy, RBitWidth);
845 }
else if (order == 0) {
846 LHS = (*doCast)(Solver, LHS, RTy, RBitWidth, LTy, LBitWidth);
849 llvm_unreachable(
"Unsupported floating-point type cast!");
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,...
Top level wrappers for InstallAPI frontend operations.
const FunctionProtoType * T