diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -151,6 +151,13 @@ resolving the best cast operation given a source value and destination type. This function is a direct wrapper of ``CastInst::getCastOpcode``. +* Add ``LLVMGetAggregateElement`` function as a wrapper for + ``Constant::getAggregateElement``, which can be used to fetch an element of a + constant struct, array or vector, independently of the underlying + representation. The ``LLVMGetElementAsConstant`` function is deprecated in + favor of the new function, which works on all constant aggregates, rather than + only instances of ``ConstantDataSequential``. + Changes to the Go bindings -------------------------- diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -2111,12 +2111,24 @@ LLVMValueRef *ConstantVals, unsigned Count); +/** + * Get element of a constant aggregate (struct, array or vector) at the + * specified index. Returns null if the index is out of range, or it's not + * possible to determine the element (e.g., because the constant is a + * constant expression.) + * + * @see llvm::Constant::getAggregateElement() + */ +LLVMValueRef LLVMGetAggregateElement(LLVMValueRef C, unsigned Idx); + /** * Get an element at specified index as a constant. * * @see ConstantDataSequential::getElementAsConstant() */ -LLVMValueRef LLVMGetElementAsConstant(LLVMValueRef C, unsigned idx); +LLVM_ATTRIBUTE_C_DEPRECATED( + LLVMValueRef LLVMGetElementAsConstant(LLVMValueRef C, unsigned idx), + "Use LLVMGetAggregateElement instead"); /** * Create a ConstantVector from values. diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -1445,6 +1445,10 @@ DontNullTerminate); } +LLVMValueRef LLVMGetAggregateElement(LLVMValueRef C, unsigned Idx) { + return wrap(unwrap(C)->getAggregateElement(Idx)); +} + LLVMValueRef LLVMGetElementAsConstant(LLVMValueRef C, unsigned idx) { return wrap(unwrap(C)->getElementAsConstant(idx)); } diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp --- a/llvm/tools/llvm-c-test/echo.cpp +++ b/llvm/tools/llvm-c-test/echo.cpp @@ -301,25 +301,16 @@ return LLVMConstNull(TypeCloner(M).Clone(Cst)); } - // Try constant array - if (LLVMIsAConstantArray(Cst)) { - check_value_kind(Cst, LLVMConstantArrayValueKind); + // Try constant array or constant data array + if (LLVMIsAConstantArray(Cst) || LLVMIsAConstantDataArray(Cst)) { + check_value_kind(Cst, LLVMIsAConstantArray(Cst) + ? LLVMConstantArrayValueKind + : LLVMConstantDataArrayValueKind); 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); - } - - // Try constant data array - if (LLVMIsAConstantDataArray(Cst)) { - check_value_kind(Cst, LLVMConstantDataArrayValueKind); - 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)); + Elts.push_back(clone_constant(LLVMGetAggregateElement(Cst, i), M)); return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount); } @@ -369,25 +360,16 @@ report_fatal_error("ConstantFP is not supported"); } - // Try ConstantVector - if (LLVMIsAConstantVector(Cst)) { - check_value_kind(Cst, LLVMConstantVectorValueKind); - LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); - unsigned EltCount = LLVMGetVectorSize(Ty); - SmallVector Elts; - for (unsigned i = 0; i < EltCount; i++) - Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M)); - return LLVMConstVector(Elts.data(), EltCount); - } - - // Try ConstantDataVector - if (LLVMIsAConstantDataVector(Cst)) { - check_value_kind(Cst, LLVMConstantDataVectorValueKind); + // Try ConstantVector or ConstantDataVector + if (LLVMIsAConstantVector(Cst) || LLVMIsAConstantDataVector(Cst)) { + check_value_kind(Cst, LLVMIsAConstantVector(Cst) + ? LLVMConstantVectorValueKind + : LLVMConstantDataVectorValueKind); LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); unsigned EltCount = LLVMGetVectorSize(Ty); SmallVector Elts; for (unsigned i = 0; i < EltCount; i++) - Elts.push_back(clone_constant(LLVMGetElementAsConstant(Cst, i), M)); + Elts.push_back(clone_constant(LLVMGetAggregateElement(Cst, i), M)); return LLVMConstVector(Elts.data(), EltCount); }