Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ include/llvm-c/Core.h @@ -248,6 +248,37 @@ } LLVMCallConv; typedef enum { + LLVMArgumentValueKind, + LLVMBasicBlockValueKind, + LLVMMemoryUseValueKind, + LLVMMemoryDefValueKind, + LLVMMemoryPhiValueKind, + + LLVMFunctionValueKind, + LLVMGlobalAliasValueKind, + LLVMGlobalVariableValueKind, + LLVMBlockAddressValueKind, + LLVMConstantExprValueKind, + LLVMConstantArrayValueKind, + LLVMConstantStructValueKind, + LLVMConstantVectorValueKind, + + LLVMUndefValueValueKind, + LLVMConstantAggregateZeroValueKind, + LLVMConstantDataArrayValueKind, + LLVMConstantDataVectorValueKind, + LLVMConstantIntValueKind, + LLVMConstantFPValueKind, + LLVMConstantPointerNullValueKind, + LLVMConstantTokenNoneValueKind, + + LLVMMetadataAsValueValueKind, + LLVMInlineAsmValueKind, + + LLVMInstructionValueKind, +} LLVMValueKind; + +typedef enum { LLVMIntEQ = 32, /**< equal */ LLVMIntNE, /**< not equal */ LLVMIntUGT, /**< unsigned greater than */ @@ -1171,6 +1202,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,18 +222,26 @@ // Try function if (LLVMIsAFunction(Cst)) { - LLVMValueRef Dst = LLVMGetNamedFunction(M, Name); - if (Dst) - return Dst; - report_fatal_error("Could not find function"); + if (LLVMGetValueKind(Cst) != LLVMFunctionValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + auto Ret = LLVMGetNamedFunction(M, Name); + if (!Ret) + report_fatal_error("Could not find function"); + if (LLVMGetValueKind(Ret) != LLVMFunctionValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + return Ret; } // Try global variable if (LLVMIsAGlobalVariable(Cst)) { - LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name); - if (Dst) - return Dst; - report_fatal_error("Could not find function"); + if (LLVMGetValueKind(Cst) != LLVMGlobalVariableValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + auto Ret = LLVMGetNamedGlobal(M, Name); + if (!Ret) + report_fatal_error("Could not find function"); + if (LLVMGetValueKind(Ret) != LLVMGlobalVariableValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + return Ret; } fprintf(stderr, "Could not find @%s\n", Name); @@ -241,60 +249,95 @@ } // Try integer literal - if (LLVMIsAConstantInt(Cst)) - return LLVMConstInt(TypeCloner(M).Clone(Cst), - LLVMConstIntGetZExtValue(Cst), false); + if (LLVMIsAConstantInt(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMConstantIntValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + auto Ret = LLVMConstInt(TypeCloner(M).Clone(Cst), + LLVMConstIntGetZExtValue(Cst), false); + if (LLVMGetValueKind(Ret) != LLVMConstantIntValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + } // Try zeroinitializer - if (LLVMIsAConstantAggregateZero(Cst)) - return LLVMConstNull(TypeCloner(M).Clone(Cst)); + if (LLVMIsAConstantAggregateZero(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMConstantAggregateZeroValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + auto Ret = LLVMConstNull(TypeCloner(M).Clone(Cst)); + if (LLVMGetValueKind(Ret) != LLVMConstantAggregateZeroValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + return Ret; + } // 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; for (unsigned i = 0; i < EltCount; i++) Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M)); - return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount); + auto Ret = LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount); + if (LLVMGetValueKind(Ret) != LLVMConstantArrayValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); } // 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; for (unsigned i = 0; i < EltCount; i++) Elts.push_back(clone_constant(LLVMGetElementAsConstant(Cst, i), M)); - return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount); + auto Ret = LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount); + if (LLVMGetValueKind(Ret) != LLVMConstantDataArrayValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + return Ret; } // 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; for (unsigned i = 0; i < EltCount; i++) Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M)); + LLVMValueRef Ret; if (LLVMGetStructName(Ty)) - return LLVMConstNamedStruct(Ty, Elts.data(), EltCount); - return LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(), - EltCount, LLVMIsPackedStruct(Ty)); + Ret = LLVMConstNamedStruct(Ty, Elts.data(), EltCount); + else + Ret = LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(), + EltCount, LLVMIsPackedStruct(Ty)); + if (LLVMGetValueKind(Ret) != LLVMConstantStructValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + return Ret; } // Try undef - if (LLVMIsUndef(Cst)) - return LLVMGetUndef(TypeCloner(M).Clone(Cst)); + if (LLVMIsUndef(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMUndefValueValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + auto Dst = LLVMGetUndef(TypeCloner(M).Clone(Cst)); + if (LLVMGetValueKind(Dst) != LLVMUndefValueValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + return Dst; + } // 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 LLVMOpcode Op = LLVMGetConstOpcode(Cst); switch(Op) { case LLVMBitCast: @@ -338,6 +381,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 +398,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);