1 /**
2 Copyright: Copyright (c) 2020, Joakim Brännström. All rights reserved.
3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 */
6 module clang.Eval;
7 
8 import clang.c.Index;
9 
10 import clang.Cursor;
11 import clang.Util;
12 
13 /** The Eval class represent an evaluation of a statement. It may or may not
14  * succeed.
15  */
16 @safe struct Eval {
17     private alias CType = CXEvalResult;
18 
19     CType cx;
20     alias cx this;
21 
22     /** Trusted: on the assumption that dispose as implemented by the LLVM
23      * community is good _enough_. Any bugs should by now have been found.
24      */
25     void dispose() @trusted {
26         clang_EvalResult_dispose(cx);
27     }
28 
29     bool isValid() @safe pure nothrow const @nogc {
30         return cx !is CType.init;
31     }
32 
33     CXEvalResultKind kind() const @trusted {
34         return clang_EvalResult_getKind(cast(void*) cx);
35     }
36 
37     /** Returns the evaluation result as integer if the
38      * kind is Int.
39      */
40     int asInt() const @trusted
41     in(kind == CXEvalResultKind.int_, "must be CXEvalResultKind.int_") {
42         return clang_EvalResult_getAsInt(cast(void*) cx);
43     }
44 
45     /** Returns: the evaluation result as a long long integer if the kind is
46      * Int.
47      *
48      * This prevents overflows that may happen if the result is returned
49      * with clang_EvalResult_getAsInt.
50      */
51     long asLong() const @trusted
52     in(kind == CXEvalResultKind.int_, "must be CXEvalResultKind.int_") {
53         return clang_EvalResult_getAsLongLong(cast(void*) cx);
54     }
55 
56     /** Returns: the evaluation result as an unsigned integer if the kind is
57      * Int and clang_EvalResult_isUnsignedInt is non-zero.
58      */
59     ulong asUnsigned() const @trusted
60     in(kind == CXEvalResultKind.int_, "must be CXEvalResultKind.int_") {
61         return clang_EvalResult_getAsUnsigned(cast(void*) cx);
62     }
63 
64     /// Returns: the evaluation result as double if the kind is double.
65     double asDouble() const @trusted
66     in(kind == CXEvalResultKind.float_, "must be CXEvalResultKind.float_") {
67         return clang_EvalResult_getAsDouble(cast(void*) cx);
68     }
69 
70     /** Returns: the evaluation result as a constant string if the kind is
71      * other than Int or float.
72      *
73      * User must not free this pointer, instead call clang_EvalResult_dispose
74      * on the CXEvalResult returned by clang_Cursor_Evaluate.
75      */
76     string asStr() const @trusted
77     in(kind != CXEvalResultKind.int_ && kind != CXEvalResultKind.float_,
78             "must NOT be CXEvalResultKind.int_ or float_") {
79         import std.conv : to;
80 
81         auto cstr = clang_EvalResult_getAsStr(cast(void*) cx);
82         auto str = to!string(cstr).idup;
83         return str;
84     }
85 
86     /** Returns: true if the evaluation result resulted in an unsigned integer.
87      */
88     bool isUnsignedInt() const @trusted
89     in(kind == CXEvalResultKind.int_, "must be CXEvalResultKind.int_") {
90         return clang_EvalResult_isUnsignedInt(cast(void*) cx) != 0;
91     }
92 }