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 @@ -213,6 +213,7 @@ } LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) { + LLVMValueRef Ret; if (!LLVMIsAConstant(Cst)) report_fatal_error("Expected a constant"); @@ -222,88 +223,97 @@ // 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"); + Ret = LLVMGetNamedFunction(M, Name); + if (!Ret) + report_fatal_error("Could not find function"); // Try global variable - if (LLVMIsAGlobalVariable(Cst)) { - LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name); - if (Dst) - return Dst; - report_fatal_error("Could not find function"); + } else if (LLVMIsAGlobalVariable(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMGlobalVariableValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + Ret = LLVMGetNamedGlobal(M, Name); + if (!Ret) + report_fatal_error("Could not find function"); + } else { + fprintf(stderr, "Could not find @%s\n", Name); + exit(-1); } - - fprintf(stderr, "Could not find @%s\n", Name); - exit(-1); - } - // Try integer literal - if (LLVMIsAConstantInt(Cst)) - return LLVMConstInt(TypeCloner(M).Clone(Cst), - LLVMConstIntGetZExtValue(Cst), false); - + } else if (LLVMIsAConstantInt(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMConstantIntValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + Ret = LLVMConstInt(TypeCloner(M).Clone(Cst), LLVMConstIntGetZExtValue(Cst), + false); // Try zeroinitializer - if (LLVMIsAConstantAggregateZero(Cst)) - return LLVMConstNull(TypeCloner(M).Clone(Cst)); - + } else if (LLVMIsAConstantAggregateZero(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMConstantAggregateZeroValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + Ret = LLVMConstNull(TypeCloner(M).Clone(Cst)); // Try constant array - if (LLVMIsAConstantArray(Cst)) { + } else 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); - } - + Ret = LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount); // Try contant data array - if (LLVMIsAConstantDataArray(Cst)) { + } else 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); - } - + Ret = LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount); // Try constant struct - if (LLVMIsAConstantStruct(Cst)) { + } else 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)); 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)); // Try undef - if (LLVMIsUndef(Cst)) - return LLVMGetUndef(TypeCloner(M).Clone(Cst)); - + } else if (LLVMIsUndef(Cst)) { + if (LLVMGetValueKind(Cst) != LLVMUndefValueValueKind) + report_fatal_error("LLVMGetValueKind returned incorrect type"); + Ret = LLVMGetUndef(TypeCloner(M).Clone(Cst)); // Try float literal - if (LLVMIsAConstantFP(Cst)) + } else 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)) + } else 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: - return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M), - TypeCloner(M).Clone(Cst)); - default: - fprintf(stderr, "%d is not a supported opcode\n", Op); - exit(-1); + // At this point, it must be a constant expression, and thus, an opcode + } else { + LLVMOpcode Op = LLVMGetConstOpcode(Cst); + switch(Op) { + case LLVMBitCast: + return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M), + TypeCloner(M).Clone(Cst)); + default: + fprintf(stderr, "%d is not a supported opcode\n", Op); + exit(-1); + } } + if (LLVMGetValueKind(Ret) != LLVMGetValueKind(Cst)) { + report_fatal_error( + "The ValueKind of Ret is not equal to the ValueKind of Cst"); + } + return Ret; } struct FunCloner { @@ -338,6 +348,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 +365,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);