16 #include "clang/Config/config.h" 18 using namespace clang;
21 #if CLANG_ANALYZER_WITH_Z3 29 friend class Z3Context;
34 Z3Config() : Config(Z3_mk_config()) {
36 Z3_set_param_value(Config,
"model",
"true");
38 Z3_set_param_value(Config,
"proof",
"false");
40 Z3_set_param_value(Config,
"timeout",
"15000");
43 ~Z3Config() { Z3_del_config(Config); }
47 void Z3ErrorHandler(Z3_context Context, Z3_error_code
Error) {
48 llvm::report_fatal_error(
"Z3 error: " +
49 llvm::Twine(Z3_get_error_msg(Context, Error)));
58 Context = Z3_mk_context_rc(Z3Config().Config);
61 Z3_set_error_handler(Context, Z3ErrorHandler);
64 virtual ~Z3Context() {
65 Z3_del_context(Context);
71 class Z3Sort :
public SMTSort {
72 friend class Z3Solver;
80 Z3Sort(Z3Context &
C, Z3_sort ZS) : Context(C), Sort(ZS) {
81 Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
85 Z3Sort(
const Z3Sort &Other) : Context(Other.Context), Sort(Other.Sort) {
86 Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
91 Z3Sort &operator=(
const Z3Sort &Other) {
92 Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Other.Sort));
93 Z3_dec_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
98 Z3Sort(Z3Sort &&Other) =
delete;
99 Z3Sort &operator=(Z3Sort &&Other) =
delete;
103 Z3_dec_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
106 bool isBitvectorSortImpl()
const override {
107 return (Z3_get_sort_kind(Context.Context, Sort) == Z3_BV_SORT);
110 bool isFloatSortImpl()
const override {
111 return (Z3_get_sort_kind(Context.Context, Sort) == Z3_FLOATING_POINT_SORT);
114 bool isBooleanSortImpl()
const override {
115 return (Z3_get_sort_kind(Context.Context, Sort) == Z3_BOOL_SORT);
118 unsigned getBitvectorSortSizeImpl()
const override {
119 return Z3_get_bv_sort_size(Context.Context, Sort);
122 unsigned getFloatSortSizeImpl()
const override {
123 return Z3_fpa_get_ebits(Context.Context, Sort) +
124 Z3_fpa_get_sbits(Context.Context, Sort);
127 bool equal_to(SMTSort
const &Other)
const override {
128 return Z3_is_eq_sort(Context.Context, Sort,
129 static_cast<const Z3Sort &>(Other).Sort);
132 void print(raw_ostream &
OS)
const override {
133 OS << Z3_sort_to_string(Context.Context, Sort);
137 static const Z3Sort &toZ3Sort(
const SMTSort &S) {
138 return static_cast<const Z3Sort &
>(S);
141 class Z3Expr :
public SMTExpr {
142 friend class Z3Solver;
149 Z3Expr(Z3Context &
C, Z3_ast ZA) : SMTExpr(), Context(C), AST(ZA) {
150 Z3_inc_ref(Context.Context, AST);
154 Z3Expr(
const Z3Expr &Copy) : SMTExpr(), Context(Copy.Context), AST(Copy.AST) {
155 Z3_inc_ref(Context.Context, AST);
160 Z3Expr &operator=(
const Z3Expr &Other) {
161 Z3_inc_ref(Context.Context, Other.AST);
162 Z3_dec_ref(Context.Context, AST);
167 Z3Expr(Z3Expr &&Other) =
delete;
168 Z3Expr &operator=(Z3Expr &&Other) =
delete;
172 Z3_dec_ref(Context.Context, AST);
175 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
176 ID.AddInteger(Z3_get_ast_hash(Context.Context, AST));
180 bool equal_to(SMTExpr
const &Other)
const override {
181 assert(Z3_is_eq_sort(Context.Context, Z3_get_sort(Context.Context, AST),
182 Z3_get_sort(Context.Context,
183 static_cast<const Z3Expr &>(Other).AST)) &&
184 "AST's must have the same sort");
185 return Z3_is_eq_ast(Context.Context, AST,
186 static_cast<const Z3Expr &>(Other).AST);
189 void print(raw_ostream &
OS)
const override {
190 OS << Z3_ast_to_string(Context.Context, AST);
194 static const Z3Expr &toZ3Expr(
const SMTExpr &E) {
195 return static_cast<const Z3Expr &
>(E);
199 friend class Z3Solver;
206 Z3Model(Z3Context &
C, Z3_model ZM) : Context(C), Model(ZM) {
207 Z3_model_inc_ref(Context.Context, Model);
210 Z3Model(
const Z3Model &Other) =
delete;
211 Z3Model(Z3Model &&Other) =
delete;
212 Z3Model &operator=(Z3Model &Other) =
delete;
213 Z3Model &operator=(Z3Model &&Other) =
delete;
217 Z3_model_dec_ref(Context.Context, Model);
220 void print(raw_ostream &
OS)
const {
221 OS << Z3_model_to_string(Context.Context, Model);
224 LLVM_DUMP_METHOD
void dump()
const { print(llvm::errs()); }
228 static const llvm::fltSemantics &getFloatSemantics(
unsigned BitWidth) {
231 llvm_unreachable(
"Unsupported floating-point semantics!");
234 return llvm::APFloat::IEEEhalf();
236 return llvm::APFloat::IEEEsingle();
238 return llvm::APFloat::IEEEdouble();
240 return llvm::APFloat::IEEEquad();
245 static bool areEquivalent(
const llvm::fltSemantics &LHS,
246 const llvm::fltSemantics &RHS) {
247 return (llvm::APFloat::semanticsPrecision(LHS) ==
248 llvm::APFloat::semanticsPrecision(RHS)) &&
249 (llvm::APFloat::semanticsMinExponent(LHS) ==
250 llvm::APFloat::semanticsMinExponent(RHS)) &&
251 (llvm::APFloat::semanticsMaxExponent(LHS) ==
252 llvm::APFloat::semanticsMaxExponent(RHS)) &&
253 (llvm::APFloat::semanticsSizeInBits(LHS) ==
254 llvm::APFloat::semanticsSizeInBits(RHS));
259 typedef llvm::ImmutableSet<std::pair<SymbolRef, Z3Expr>> ConstraintZ3Ty;
264 class Z3Solver :
public SMTSolver {
265 friend class Z3ConstraintManager;
272 Z3Solver() : Solver(Z3_mk_simple_solver(Context.Context)) {
273 Z3_solver_inc_ref(Context.Context, Solver);
276 Z3Solver(
const Z3Solver &Other) =
delete;
277 Z3Solver(Z3Solver &&Other) =
delete;
278 Z3Solver &operator=(Z3Solver &Other) =
delete;
279 Z3Solver &operator=(Z3Solver &&Other) =
delete;
283 Z3_solver_dec_ref(Context.Context, Solver);
286 void addConstraint(
const SMTExprRef &Exp)
const override {
287 Z3_solver_assert(Context.Context, Solver, toZ3Expr(*Exp).AST);
291 return std::make_shared<Z3Sort>(Context, Z3_mk_bool_sort(Context.Context));
294 SMTSortRef getBitvectorSort(
unsigned BitWidth)
override {
295 return std::make_shared<Z3Sort>(Context,
296 Z3_mk_bv_sort(Context.Context, BitWidth));
300 return std::make_shared<Z3Sort>(
301 Context, Z3_get_sort(Context.Context, toZ3Expr(*Exp).AST));
305 return std::make_shared<Z3Sort>(Context,
306 Z3_mk_fpa_sort_16(Context.Context));
310 return std::make_shared<Z3Sort>(Context,
311 Z3_mk_fpa_sort_32(Context.Context));
315 return std::make_shared<Z3Sort>(Context,
316 Z3_mk_fpa_sort_64(Context.Context));
320 return std::make_shared<Z3Sort>(Context,
321 Z3_mk_fpa_sort_128(Context.Context));
324 SMTExprRef newExprRef(
const SMTExpr &E)
const override {
325 return std::make_shared<Z3Expr>(toZ3Expr(E));
330 Z3Expr(Context, Z3_mk_bvneg(Context.Context, toZ3Expr(*Exp).AST)));
335 Z3Expr(Context, Z3_mk_bvnot(Context.Context, toZ3Expr(*Exp).AST)));
340 Z3Expr(Context, Z3_mk_not(Context.Context, toZ3Expr(*Exp).AST)));
345 Z3Expr(Context, Z3_mk_bvadd(Context.Context, toZ3Expr(*LHS).AST,
346 toZ3Expr(*RHS).AST)));
351 Z3Expr(Context, Z3_mk_bvsub(Context.Context, toZ3Expr(*LHS).AST,
352 toZ3Expr(*RHS).AST)));
357 Z3Expr(Context, Z3_mk_bvmul(Context.Context, toZ3Expr(*LHS).AST,
358 toZ3Expr(*RHS).AST)));
363 Z3Expr(Context, Z3_mk_bvsrem(Context.Context, toZ3Expr(*LHS).AST,
364 toZ3Expr(*RHS).AST)));
369 Z3Expr(Context, Z3_mk_bvurem(Context.Context, toZ3Expr(*LHS).AST,
370 toZ3Expr(*RHS).AST)));
375 Z3Expr(Context, Z3_mk_bvsdiv(Context.Context, toZ3Expr(*LHS).AST,
376 toZ3Expr(*RHS).AST)));
381 Z3Expr(Context, Z3_mk_bvudiv(Context.Context, toZ3Expr(*LHS).AST,
382 toZ3Expr(*RHS).AST)));
387 Z3Expr(Context, Z3_mk_bvshl(Context.Context, toZ3Expr(*LHS).AST,
388 toZ3Expr(*RHS).AST)));
393 Z3Expr(Context, Z3_mk_bvashr(Context.Context, toZ3Expr(*LHS).AST,
394 toZ3Expr(*RHS).AST)));
399 Z3Expr(Context, Z3_mk_bvlshr(Context.Context, toZ3Expr(*LHS).AST,
400 toZ3Expr(*RHS).AST)));
405 Z3Expr(Context, Z3_mk_bvxor(Context.Context, toZ3Expr(*LHS).AST,
406 toZ3Expr(*RHS).AST)));
411 Z3Expr(Context, Z3_mk_bvor(Context.Context, toZ3Expr(*LHS).AST,
412 toZ3Expr(*RHS).AST)));
417 Z3Expr(Context, Z3_mk_bvand(Context.Context, toZ3Expr(*LHS).AST,
418 toZ3Expr(*RHS).AST)));
423 Z3Expr(Context, Z3_mk_bvult(Context.Context, toZ3Expr(*LHS).AST,
424 toZ3Expr(*RHS).AST)));
429 Z3Expr(Context, Z3_mk_bvslt(Context.Context, toZ3Expr(*LHS).AST,
430 toZ3Expr(*RHS).AST)));
435 Z3Expr(Context, Z3_mk_bvugt(Context.Context, toZ3Expr(*LHS).AST,
436 toZ3Expr(*RHS).AST)));
441 Z3Expr(Context, Z3_mk_bvsgt(Context.Context, toZ3Expr(*LHS).AST,
442 toZ3Expr(*RHS).AST)));
447 Z3Expr(Context, Z3_mk_bvule(Context.Context, toZ3Expr(*LHS).AST,
448 toZ3Expr(*RHS).AST)));
453 Z3Expr(Context, Z3_mk_bvsle(Context.Context, toZ3Expr(*LHS).AST,
454 toZ3Expr(*RHS).AST)));
459 Z3Expr(Context, Z3_mk_bvuge(Context.Context, toZ3Expr(*LHS).AST,
460 toZ3Expr(*RHS).AST)));
465 Z3Expr(Context, Z3_mk_bvsge(Context.Context, toZ3Expr(*LHS).AST,
466 toZ3Expr(*RHS).AST)));
470 Z3_ast Args[2] = {toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST};
471 return newExprRef(Z3Expr(Context, Z3_mk_and(Context.Context, 2, Args)));
475 Z3_ast Args[2] = {toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST};
476 return newExprRef(Z3Expr(Context, Z3_mk_or(Context.Context, 2, Args)));
481 Z3Expr(Context, Z3_mk_eq(Context.Context, toZ3Expr(*LHS).AST,
482 toZ3Expr(*RHS).AST)));
487 Z3Expr(Context, Z3_mk_fpa_neg(Context.Context, toZ3Expr(*Exp).AST)));
491 return newExprRef(Z3Expr(
492 Context, Z3_mk_fpa_is_infinite(Context.Context, toZ3Expr(*Exp).AST)));
497 Z3Expr(Context, Z3_mk_fpa_is_nan(Context.Context, toZ3Expr(*Exp).AST)));
501 return newExprRef(Z3Expr(
502 Context, Z3_mk_fpa_is_normal(Context.Context, toZ3Expr(*Exp).AST)));
506 return newExprRef(Z3Expr(
507 Context, Z3_mk_fpa_is_zero(Context.Context, toZ3Expr(*Exp).AST)));
511 SMTExprRef RoundingMode = getFloatRoundingMode();
514 Z3_mk_fpa_mul(Context.Context, toZ3Expr(*LHS).AST,
515 toZ3Expr(*RHS).AST, toZ3Expr(*RoundingMode).AST)));
519 SMTExprRef RoundingMode = getFloatRoundingMode();
522 Z3_mk_fpa_div(Context.Context, toZ3Expr(*LHS).AST,
523 toZ3Expr(*RHS).AST, toZ3Expr(*RoundingMode).AST)));
528 Z3Expr(Context, Z3_mk_fpa_rem(Context.Context, toZ3Expr(*LHS).AST,
529 toZ3Expr(*RHS).AST)));
533 SMTExprRef RoundingMode = getFloatRoundingMode();
536 Z3_mk_fpa_add(Context.Context, toZ3Expr(*LHS).AST,
537 toZ3Expr(*RHS).AST, toZ3Expr(*RoundingMode).AST)));
541 SMTExprRef RoundingMode = getFloatRoundingMode();
544 Z3_mk_fpa_sub(Context.Context, toZ3Expr(*LHS).AST,
545 toZ3Expr(*RHS).AST, toZ3Expr(*RoundingMode).AST)));
550 Z3Expr(Context, Z3_mk_fpa_lt(Context.Context, toZ3Expr(*LHS).AST,
551 toZ3Expr(*RHS).AST)));
556 Z3Expr(Context, Z3_mk_fpa_gt(Context.Context, toZ3Expr(*LHS).AST,
557 toZ3Expr(*RHS).AST)));
562 Z3Expr(Context, Z3_mk_fpa_leq(Context.Context, toZ3Expr(*LHS).AST,
563 toZ3Expr(*RHS).AST)));
568 Z3Expr(Context, Z3_mk_fpa_geq(Context.Context, toZ3Expr(*LHS).AST,
569 toZ3Expr(*RHS).AST)));
574 Z3Expr(Context, Z3_mk_fpa_eq(Context.Context, toZ3Expr(*LHS).AST,
575 toZ3Expr(*RHS).AST)));
581 Z3Expr(Context, Z3_mk_ite(Context.Context, toZ3Expr(*Cond).AST,
582 toZ3Expr(*T).AST, toZ3Expr(*F).AST)));
586 return newExprRef(Z3Expr(
587 Context, Z3_mk_sign_ext(Context.Context, i, toZ3Expr(*Exp).AST)));
591 return newExprRef(Z3Expr(
592 Context, Z3_mk_zero_ext(Context.Context, i, toZ3Expr(*Exp).AST)));
595 SMTExprRef mkBVExtract(
unsigned High,
unsigned Low,
597 return newExprRef(Z3Expr(Context, Z3_mk_extract(Context.Context, High, Low,
598 toZ3Expr(*Exp).AST)));
603 Z3Expr(Context, Z3_mk_concat(Context.Context, toZ3Expr(*LHS).AST,
604 toZ3Expr(*RHS).AST)));
608 SMTExprRef RoundingMode = getFloatRoundingMode();
609 return newExprRef(Z3Expr(
611 Z3_mk_fpa_to_fp_float(Context.Context, toZ3Expr(*RoundingMode).AST,
612 toZ3Expr(*From).AST, toZ3Sort(*To).Sort)));
616 SMTExprRef RoundingMode = getFloatRoundingMode();
617 return newExprRef(Z3Expr(
619 Z3_mk_fpa_to_fp_signed(Context.Context, toZ3Expr(*RoundingMode).AST,
620 toZ3Expr(*From).AST, toZ3Sort(*To).Sort)));
624 SMTExprRef RoundingMode = getFloatRoundingMode();
625 return newExprRef(Z3Expr(
627 Z3_mk_fpa_to_fp_unsigned(Context.Context, toZ3Expr(*RoundingMode).AST,
628 toZ3Expr(*From).AST, toZ3Sort(*To).Sort)));
632 SMTExprRef RoundingMode = getFloatRoundingMode();
633 return newExprRef(Z3Expr(
634 Context, Z3_mk_fpa_to_sbv(Context.Context, toZ3Expr(*RoundingMode).AST,
635 toZ3Expr(*From).AST, ToWidth)));
639 SMTExprRef RoundingMode = getFloatRoundingMode();
640 return newExprRef(Z3Expr(
641 Context, Z3_mk_fpa_to_ubv(Context.Context, toZ3Expr(*RoundingMode).AST,
642 toZ3Expr(*From).AST, ToWidth)));
646 return newExprRef(Z3Expr(Context, b ? Z3_mk_true(Context.Context)
647 : Z3_mk_false(Context.Context)));
650 SMTExprRef mkBitvector(
const llvm::APSInt Int,
unsigned BitWidth)
override {
651 const SMTSortRef Sort = getBitvectorSort(BitWidth);
653 Z3Expr(Context, Z3_mk_numeral(Context.Context, Int.toString(10).c_str(),
654 toZ3Sort(*Sort).Sort)));
657 SMTExprRef mkFloat(
const llvm::APFloat Float)
override {
659 getFloatSort(llvm::APFloat::semanticsSizeInBits(Float.getSemantics()));
661 llvm::APSInt Int = llvm::APSInt(Float.bitcastToAPInt(),
false);
662 SMTExprRef Z3Int = mkBitvector(Int, Int.getBitWidth());
663 return newExprRef(Z3Expr(
664 Context, Z3_mk_fpa_to_fp_bv(Context.Context, toZ3Expr(*Z3Int).AST,
665 toZ3Sort(*Sort).Sort)));
670 Z3Expr(Context, Z3_mk_const(Context.Context,
671 Z3_mk_string_symbol(Context.Context, Name),
672 toZ3Sort(*Sort).Sort)));
675 llvm::APSInt getBitvector(
const SMTExprRef &Exp,
unsigned BitWidth,
676 bool isUnsigned)
override {
678 llvm::APInt(BitWidth,
679 Z3_get_numeral_string(Context.Context, toZ3Expr(*Exp).AST),
684 bool getBoolean(
const SMTExprRef &Exp)
override {
685 return Z3_get_bool_value(Context.Context, toZ3Expr(*Exp).AST) == Z3_L_TRUE;
690 return newExprRef(Z3Expr(Context, Z3_mk_fpa_rne(Context.Context)));
694 llvm::APFloat &Float,
bool useSemantics) {
695 assert(Sort->isFloatSort() &&
"Unsupported sort to floating-point!");
697 llvm::APSInt Int(Sort->getFloatSortSize(),
true);
698 const llvm::fltSemantics &Semantics =
699 getFloatSemantics(Sort->getFloatSortSize());
700 SMTSortRef BVSort = getBitvectorSort(Sort->getFloatSortSize());
701 if (!toAPSInt(BVSort, AST, Int,
true)) {
705 if (useSemantics && !areEquivalent(Float.getSemantics(), Semantics)) {
706 assert(
false &&
"Floating-point types don't match!");
710 Float = llvm::APFloat(Semantics, Int);
715 llvm::APSInt &Int,
bool useSemantics) {
716 if (Sort->isBitvectorSort()) {
717 if (useSemantics && Int.getBitWidth() != Sort->getBitvectorSortSize()) {
718 assert(
false &&
"Bitvector types don't match!");
728 if (Sort->getBitvectorSortSize() <= 64 ||
729 Sort->getBitvectorSortSize() == 128) {
730 Int = getBitvector(AST, Int.getBitWidth(), Int.isUnsigned());
734 assert(
false &&
"Bitwidth not supported!");
738 if (Sort->isBooleanSort()) {
739 if (useSemantics && Int.getBitWidth() < 1) {
740 assert(
false &&
"Boolean type doesn't match!");
744 Int = llvm::APSInt(llvm::APInt(Int.getBitWidth(), getBoolean(AST)),
749 llvm_unreachable(
"Unsupported sort to integer!");
752 bool getInterpretation(
const SMTExprRef &Exp, llvm::APSInt &Int)
override {
753 Z3Model Model(Context, Z3_solver_get_model(Context.Context, Solver));
754 Z3_func_decl Func = Z3_get_app_decl(
755 Context.Context, Z3_to_app(Context.Context, toZ3Expr(*Exp).AST));
756 if (Z3_model_has_interp(Context.Context, Model.Model, Func) != Z3_L_TRUE)
761 Z3_model_get_const_interp(Context.Context, Model.Model, Func)));
763 return toAPSInt(Sort, Assign, Int,
true);
766 bool getInterpretation(
const SMTExprRef &Exp, llvm::APFloat &Float)
override {
767 Z3Model Model(Context, Z3_solver_get_model(Context.Context, Solver));
768 Z3_func_decl Func = Z3_get_app_decl(
769 Context.Context, Z3_to_app(Context.Context, toZ3Expr(*Exp).AST));
770 if (Z3_model_has_interp(Context.Context, Model.Model, Func) != Z3_L_TRUE)
775 Z3_model_get_const_interp(Context.Context, Model.Model, Func)));
777 return toAPFloat(Sort, Assign, Float,
true);
781 Z3_lbool res = Z3_solver_check(Context.Context, Solver);
782 if (res == Z3_L_TRUE)
785 if (res == Z3_L_FALSE)
791 void push()
override {
return Z3_solver_push(Context.Context, Solver); }
793 void pop(
unsigned NumStates = 1)
override {
794 assert(Z3_solver_get_num_scopes(Context.Context, Solver) >= NumStates);
795 return Z3_solver_pop(Context.Context, Solver, NumStates);
798 bool isFPSupported()
override {
return true; }
801 void reset()
override { Z3_solver_reset(Context.Context, Solver); }
803 void print(raw_ostream &
OS)
const override {
804 OS << Z3_solver_to_string(Context.Context, Solver);
808 class Z3ConstraintManager :
public SMTConstraintManager<ConstraintZ3, Z3Expr> {
812 Z3ConstraintManager(SubEngine *SE, SValBuilder &SB)
813 : SMTConstraintManager(SE, SB, Solver) {}
821 #if CLANG_ANALYZER_WITH_Z3 822 return llvm::make_unique<Z3Solver>();
824 llvm::report_fatal_error(
"Clang was not compiled with Z3 support, rebuild " 825 "with -DCLANG_ANALYZER_ENABLE_Z3_SOLVER=ON",
831 std::unique_ptr<ConstraintManager>
833 #if CLANG_ANALYZER_WITH_Z3 834 return llvm::make_unique<Z3ConstraintManager>(Eng, StMgr.
getSValBuilder());
836 llvm::report_fatal_error(
"Clang was not compiled with Z3 support, rebuild " 837 "with -DCLANG_ANALYZER_ENABLE_Z3_SOLVER=ON",
std::shared_ptr< SMTSort > SMTSortRef
Shared pointer for SMTSorts, used by SMTSolver API.
SValBuilder & getSValBuilder()
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
std::unique_ptr< ConstraintManager > CreateZ3ConstraintManager(ProgramStateManager &statemgr, SubEngine *subengine)
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type)
Declares a program state trait for type Type called Name, and introduce a type named NameTy...
SMTSolverRef CreateZ3Solver()
Convenience method to create and Z3Solver object.
Dataflow Directional Tag Classes.
std::shared_ptr< SMTSolver > SMTSolverRef
Shared pointer for SMTSolvers.
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
Defines the clang::TargetInfo interface.
std::shared_ptr< SMTExpr > SMTExprRef
Shared pointer for SMTExprs, used by SMTSolver API.