Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ include/llvm-c/Core.h @@ -248,6 +248,11 @@ } LLVMCallConv; typedef enum { +#define HANDLE_VALUE(Name) LLVM##Name##ValueKind, +#include "llvm/IR/Value.def" +} LLVMValueKind; + +typedef enum { LLVMIntEQ = 32, /**< equal */ LLVMIntNE, /**< not equal */ LLVMIntUGT, /**< unsigned greater than */ @@ -1171,6 +1176,13 @@ LLVMTypeRef LLVMTypeOf(LLVMValueRef Val); /** + * Obtain the enumerated type of a Value instance. + * + * @see llvm::Value::getValueID() + */ +LLVMValueKind LLVMGetValueKind(LLVMValueRef Val); + +/** * Obtain the string name of a value. * * @see llvm::Value::getName() Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -539,6 +539,17 @@ return wrap(unwrap(Val)->getType()); } +LLVMValueKind LLVMGetValueKind(LLVMValueRef Val) { + switch(unwrap(Val)->getValueID()) { +#define HANDLE_VALUE(Name) \ + case Value::Name##Val: \ + return LLVM##Name##ValueKind; +#include "llvm/IR/Value.def" + default: + return LLVMInstructionValueKind; + } +} + const char *LLVMGetValueName(LLVMValueRef Val) { return unwrap(Val)->getName().data(); } Index: tools/llvm-c-test/echo.cpp =================================================================== --- tools/llvm-c-test/echo.cpp +++ tools/llvm-c-test/echo.cpp @@ -222,6 +222,8 @@ // Try function if (LLVMIsAFunction(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMFunctionValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); LLVMValueRef Dst = LLVMGetNamedFunction(M, Name); if (Dst) return Dst; @@ -230,6 +232,8 @@ // Try global variable if (LLVMIsAGlobalVariable(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMGlobalVariableValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name); if (Dst) return Dst; @@ -241,16 +245,24 @@ } // Try integer literal - if (LLVMIsAConstantInt(Cst)) + if (LLVMIsAConstantInt(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMConstantIntValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); return LLVMConstInt(TypeCloner(M).Clone(Cst), LLVMConstIntGetZExtValue(Cst), false); + } // Try zeroinitializer - if (LLVMIsAConstantAggregateZero(Cst)) + if (LLVMIsAConstantAggregateZero(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMConstantAggregateZeroValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); return LLVMConstNull(TypeCloner(M).Clone(Cst)); + } // Try constant array if (LLVMIsAConstantArray(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMConstantArrayValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); unsigned EltCount = LLVMGetArrayLength(Ty); SmallVector Elts; @@ -261,6 +273,8 @@ // Try contant data array if (LLVMIsAConstantDataArray(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMConstantDataArrayValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); unsigned EltCount = LLVMGetArrayLength(Ty); SmallVector Elts; @@ -271,6 +285,8 @@ // Try constant struct if (LLVMIsAConstantStruct(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMConstantStructValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); unsigned EltCount = LLVMCountStructElementTypes(Ty); SmallVector Elts; @@ -283,18 +299,20 @@ } // Try undef - if (LLVMIsUndef(Cst)) + if (LLVMIsUndef(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMUndefValueValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); return LLVMGetUndef(TypeCloner(M).Clone(Cst)); + } // Try float literal - if (LLVMIsAConstantFP(Cst)) + if (LLVMIsAConstantFP(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMConstantFPValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); report_fatal_error("ConstantFP is not supported"); + } - // This kind of constant is not supported - if (!LLVMIsAConstantExpr(Cst)) - report_fatal_error("Expected a constant expression"); - - // At this point, it must be a constant expression + // At this point, we've exhausted all supported options LLVMOpcode Op = LLVMGetConstOpcode(Cst); switch(Op) { case LLVMBitCast: @@ -338,6 +356,9 @@ if (!LLVMIsAInstruction(Src)) report_fatal_error("Expected an instruction"); + if (LLVMGetValueKind(Src) != LLVMInstructionValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + auto Ctx = LLVMGetModuleContext(M); auto Builder = LLVMCreateBuilderInContext(Ctx); auto BB = DeclareBB(LLVMGetInstructionParent(Src)); @@ -352,6 +373,9 @@ if (!LLVMIsAInstruction(Src)) report_fatal_error("Expected an instruction"); + if (LLVMGetValueKind(Src) != LLVMInstructionValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + // Check if this is something we already computed. { auto i = VMap.find(Src);