Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -32,7 +32,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 36 +#define CINDEX_VERSION_MINOR 37 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -5262,6 +5262,25 @@ CINDEX_LINKAGE int clang_EvalResult_getAsInt(CXEvalResult E); /** + * \brief Returns the evaluation result as a long long integer if the + * kind is Int. This prevents overflows that may happen if the result is + * returned with clang_EvalResult_getAsInt. + */ +CINDEX_LINKAGE long long clang_EvalResult_getAsLongLong(CXEvalResult E); + +/** + * \brief Returns a non-zero value if the kind is Int and the evaluation + * result resulted in an unsigned integer. + */ +CINDEX_LINKAGE unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E); + +/** + * \brief Returns the evaluation result as an unsigned integer if + * the kind is Int and clang_EvalResult_isUnsignedInt is non-zero. + */ +CINDEX_LINKAGE unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E); + +/** * \brief Returns the evaluation result as double if the * kind is double. */ Index: test/Index/evaluate-cursor.cpp =================================================================== --- test/Index/evaluate-cursor.cpp +++ test/Index/evaluate-cursor.cpp @@ -15,6 +15,12 @@ int a = __LINE__; } +unsigned long long foo_int = 1ull << 60; + +unsigned long long HUGE = 1ull << 63; + +long long HUGE_NEG = -(1ll << 35); + // RUN: c-index-test -evaluate-cursor-at=%s:4:7 \ // RUN: -evaluate-cursor-at=%s:8:7 \ // RUN: -evaluate-cursor-at=%s:8:11 -std=c++11 %s | FileCheck %s @@ -28,3 +34,11 @@ // CHECK-MACRO: [function macro] // CHECK-MACRO: [function macro] // CHECK-MACRO: [builtin macro] + +// RUN: c-index-test -evaluate-cursor-at=%s:18:20 \ +// RUN: -evaluate-cursor-at=%s:20:20 \ +// RUN: -evaluate-cursor-at=%s:22:11 \ +// RUN: -std=c++11 %s | FileCheck -check-prefix=CHECK-LONG %s +// CHECK-LONG: unsigned, Value: 1152921504606846976 +// CHECK-LONG: unsigned, Value: 9223372036854775808 +// CHECK-LONG: Value: -34359738368 Index: tools/c-index-test/c-index-test.c =================================================================== --- tools/c-index-test/c-index-test.c +++ tools/c-index-test/c-index-test.c @@ -2462,8 +2462,14 @@ switch (clang_EvalResult_getKind(result)) { case CXEval_Int: { - int val = clang_EvalResult_getAsInt(result); - printf("Kind: Int , Value: %d", val); + printf("Kind: Int, "); + if (clang_EvalResult_isUnsignedInt(result)) { + unsigned long long val = clang_EvalResult_getAsUnsigned(result); + printf("unsigned, Value: %llu", val); + } else { + long long val = clang_EvalResult_getAsLongLong(result); + printf("Value: %lld", val); + } break; } case CXEval_Float: Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -3511,10 +3511,12 @@ struct ExprEvalResult { CXEvalResultKind EvalType; union { - int intVal; + unsigned long long unsignedVal; + long long intVal; double floatVal; char *stringVal; } EvalData; + bool IsUnsignedInt; ~ExprEvalResult() { if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float && EvalType != CXEval_Int) { @@ -3535,10 +3537,32 @@ } int clang_EvalResult_getAsInt(CXEvalResult E) { + return clang_EvalResult_getAsLongLong(E); +} + +long long clang_EvalResult_getAsLongLong(CXEvalResult E) { + if (!E) { + return 0; + } + ExprEvalResult *Result = (ExprEvalResult*)E; + if (Result->IsUnsignedInt) + return Result->EvalData.unsignedVal; + return Result->EvalData.intVal; +} + +unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) { + return ((ExprEvalResult *)E)->IsUnsignedInt; +} + +unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) { if (!E) { return 0; } - return ((ExprEvalResult *)E)->EvalData.intVal; + + ExprEvalResult *Result = (ExprEvalResult*)E; + if (Result->IsUnsignedInt) + return Result->EvalData.unsignedVal; + return Result->EvalData.intVal; } double clang_EvalResult_getAsDouble(CXEvalResult E) { @@ -3569,10 +3593,19 @@ CallExpr *callExpr; auto result = llvm::make_unique(); result->EvalType = CXEval_UnExposed; + result->IsUnsignedInt = false; if (ER.Val.isInt()) { result->EvalType = CXEval_Int; - result->EvalData.intVal = ER.Val.getInt().getExtValue(); + + auto& val = ER.Val.getInt(); + if (val.isUnsigned()) { + result->IsUnsignedInt = true; + result->EvalData.unsignedVal = val.getZExtValue(); + } else { + result->EvalData.intVal = val.getExtValue(); + } + return result.release(); } Index: tools/libclang/libclang.exports =================================================================== --- tools/libclang/libclang.exports +++ tools/libclang/libclang.exports @@ -335,6 +335,9 @@ clang_Cursor_Evaluate clang_EvalResult_getKind clang_EvalResult_getAsInt +clang_EvalResult_getAsLongLong +clang_EvalResult_getAsUnsigned +clang_EvalResult_isUnsignedInt clang_EvalResult_getAsDouble clang_EvalResult_getAsStr clang_EvalResult_dispose