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 @@ -548,6 +548,13 @@ */ void LLVMContextSetDiscardValueNames(LLVMContextRef C, LLVMBool Discard); +/** + * Set whether the given context is in opaque pointer mode. + * + * @see LLVMContext::setOpaquePointers() + */ +void LLVMContextSetOpaquePointers(LLVMContextRef C, LLVMBool OpaquePointers); + /** * Destroy a context instance. * @@ -1442,6 +1449,22 @@ */ LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace); +/** + * Determine whether a pointer is opaque. + * + * True if this is an instance of an opaque PointerType. + * + * @see llvm::Type::isOpaquePointerTy() + */ +LLVMBool LLVMPointerTypeIsOpaque(LLVMTypeRef Ty); + +/** + * Create an opaque pointer type in a context. + * + * @see llvm::PointerType::get() + */ +LLVMTypeRef LLVMPointerTypeInContext(LLVMContextRef C, unsigned AddressSpace); + /** * Obtain the address space of a pointer type. * 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 @@ -115,6 +115,10 @@ unwrap(C)->setDiscardValueNames(Discard); } +void LLVMContextSetOpaquePointers(LLVMContextRef C, LLVMBool OpaquePointers) { + unwrap(C)->setOpaquePointers(OpaquePointers); +} + void LLVMContextDispose(LLVMContextRef C) { delete unwrap(C); } @@ -788,6 +792,10 @@ return wrap(PointerType::get(unwrap(ElementType), AddressSpace)); } +LLVMBool LLVMPointerTypeIsOpaque(LLVMTypeRef Ty) { + return unwrap(Ty)->isOpaquePointerTy(); +} + LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount) { return wrap(FixedVectorType::get(unwrap(ElementType), ElementCount)); } @@ -824,6 +832,10 @@ /*--.. Operations on other types ...........................................--*/ +LLVMTypeRef LLVMPointerTypeInContext(LLVMContextRef C, unsigned AddressSpace) { + return wrap(PointerType::get(*unwrap(C), AddressSpace)); +} + LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C) { return wrap(Type::getVoidTy(*unwrap(C))); } diff --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll --- a/llvm/test/Bindings/llvm-c/echo.ll +++ b/llvm/test/Bindings/llvm-c/echo.ll @@ -1,6 +1,10 @@ ; RUN: llvm-as < %s | llvm-dis > %t.orig ; RUN: llvm-as < %s | llvm-c-test --echo > %t.echo ; RUN: diff -w %t.orig %t.echo +; +; RUN: llvm-as -opaque-pointers < %s | llvm-dis -opaque-pointers > %t.orig_opaque +; RUN: llvm-as -opaque-pointers < %s | llvm-c-test --echo --opaque-pointers > %t.echo_opaque +; RUN: diff -w %t.orig_opaque %t.echo_opaque source_filename = "/test/Bindings/echo.ll" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" @@ -237,10 +241,9 @@ define void @test_intrinsics() { entry: %sp = call i8* @llvm.stacksave() - %x = alloca i32, align 4 - %0 = bitcast i32* %x to i8* - call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) - call void @llvm.lifetime.end.p0i8(i64 4, i8* %0) + %0 = alloca i8, align 1 + call void @llvm.lifetime.start.p0i8(i64 1, i8* %0) + call void @llvm.lifetime.end.p0i8(i64 1, i8* %0) call void @llvm.stackrestore(i8* %sp) ret void } 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 @@ -138,10 +138,11 @@ LLVMGetArrayLength(Src) ); case LLVMPointerTypeKind: - return LLVMPointerType( - Clone(LLVMGetElementType(Src)), - LLVMGetPointerAddressSpace(Src) - ); + if (LLVMPointerTypeIsOpaque(Src)) + return LLVMPointerTypeInContext(Ctx, LLVMGetPointerAddressSpace(Src)); + else + return LLVMPointerType(Clone(LLVMGetElementType(Src)), + LLVMGetPointerAddressSpace(Src)); case LLVMVectorTypeKind: return LLVMVectorType( Clone(LLVMGetElementType(Src)), @@ -997,7 +998,7 @@ const char *Name = LLVMGetValueName2(Cur, &NameLen); if (LLVMGetNamedGlobal(M, Name)) report_fatal_error("GlobalVariable already cloned"); - LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name); + LLVMAddGlobal(M, TypeCloner(M).Clone(LLVMGlobalGetValueType(Cur)), Name); Next = LLVMGetNextGlobal(Cur); if (Next == nullptr) { @@ -1029,7 +1030,8 @@ const char *Name = LLVMGetValueName2(Cur, &NameLen); if (LLVMGetNamedFunction(M, Name)) report_fatal_error("Function already cloned"); - auto Ty = LLVMGetElementType(TypeCloner(M).Clone(Cur)); + LLVMTypeRef Ty = TypeCloner(M).Clone(LLVMGlobalGetValueType(Cur)); + auto F = LLVMAddFunction(M, Name, Ty); // Copy attributes @@ -1390,7 +1392,7 @@ } } -int llvm_echo(void) { +int llvm_echo(bool OpaquePointers) { LLVMEnablePrettyStackTrace(); LLVMModuleRef Src = llvm_load_module(false, true); @@ -1399,6 +1401,8 @@ size_t ModuleIdentLen; const char *ModuleName = LLVMGetModuleIdentifier(Src, &ModuleIdentLen); LLVMContextRef Ctx = LLVMContextCreate(); + if (OpaquePointers) + LLVMContextSetOpaquePointers(Ctx, true); LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleName, Ctx); LLVMSetSourceFileName(M, SourceFileName, SourceFileLen); diff --git a/llvm/tools/llvm-c-test/llvm-c-test.h b/llvm/tools/llvm-c-test/llvm-c-test.h --- a/llvm/tools/llvm-c-test/llvm-c-test.h +++ b/llvm/tools/llvm-c-test/llvm-c-test.h @@ -50,7 +50,7 @@ int llvm_targets_list(void); // echo.c -int llvm_echo(void); +int llvm_echo(bool OpaquePointers); // diagnostic.c int llvm_test_diagnostic_handler(void); diff --git a/llvm/tools/llvm-c-test/main.c b/llvm/tools/llvm-c-test/main.c --- a/llvm/tools/llvm-c-test/main.c +++ b/llvm/tools/llvm-c-test/main.c @@ -49,6 +49,9 @@ " Read lines of name, rpn from stdin - print generated module\n\n"); fprintf(stderr, " * --echo\n"); fprintf(stderr, " Read bitcode file from stdin - print it back out\n\n"); + fprintf(stderr, " * --echo --opaque-pointers\n"); + fprintf(stderr, " Read bitcode file from stdin - print it back out in " + "opaque pointer mode\n\n"); fprintf(stderr, " * --test-diagnostic-handler\n"); fprintf(stderr, " Read bitcode file from stdin with a diagnostic handler set\n\n"); @@ -92,8 +95,8 @@ return llvm_test_function_attributes(); } else if (argc == 2 && !strcmp(argv[1], "--test-callsite-attributes")) { return llvm_test_callsite_attributes(); - } else if (argc == 2 && !strcmp(argv[1], "--echo")) { - return llvm_echo(); + } else if ((argc == 2 || argc == 3) && !strcmp(argv[1], "--echo")) { + return llvm_echo(argc == 3 ? !strcmp(argv[2], "--opaque-pointers") : 0); } else if (argc == 2 && !strcmp(argv[1], "--test-diagnostic-handler")) { return llvm_test_diagnostic_handler(); } else if (argc == 2 && !strcmp(argv[1], "--test-dibuilder")) {