Index: llvm/include/llvm-c/Core.h =================================================================== --- llvm/include/llvm-c/Core.h +++ llvm/include/llvm-c/Core.h @@ -548,6 +548,20 @@ */ void LLVMContextSetDiscardValueNames(LLVMContextRef C, LLVMBool Discard); +/** + * Retrieve whether the given context supports typed pointers. + * + * @see LLVMContext::supportsTypedPointers() + */ +LLVMBool LLVMContextSupportsTypedPointers(LLVMContextRef C); + +/** + * 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 +1456,13 @@ */ LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace); +/** + * 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. * Index: llvm/lib/IR/Core.cpp =================================================================== --- llvm/lib/IR/Core.cpp +++ llvm/lib/IR/Core.cpp @@ -115,6 +115,14 @@ unwrap(C)->setDiscardValueNames(Discard); } +LLVMBool LLVMContextSupportsTypedPointers(LLVMContextRef C) { + return unwrap(C)->supportsTypedPointers(); +} + +void LLVMContextSetOpaquePointers(LLVMContextRef C, LLVMBool OpaquePointers) { + unwrap(C)->setOpaquePointers(OpaquePointers); +} + void LLVMContextDispose(LLVMContextRef C) { delete unwrap(C); } @@ -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))); } Index: llvm/test/Bindings/llvm-c/echo.ll =================================================================== --- llvm/test/Bindings/llvm-c/echo.ll +++ 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 } Index: llvm/tools/llvm-c-test/echo.cpp =================================================================== --- llvm/tools/llvm-c-test/echo.cpp +++ llvm/tools/llvm-c-test/echo.cpp @@ -138,10 +138,11 @@ LLVMGetArrayLength(Src) ); case LLVMPointerTypeKind: - return LLVMPointerType( - Clone(LLVMGetElementType(Src)), - LLVMGetPointerAddressSpace(Src) - ); + if (LLVMContextSupportsTypedPointers(Ctx)) + return LLVMPointerType(Clone(LLVMGetElementType(Src)), + LLVMGetPointerAddressSpace(Src)); + else + return LLVMPointerTypeInContext(Ctx, LLVMGetPointerAddressSpace(Src)); case LLVMVectorTypeKind: return LLVMVectorType( Clone(LLVMGetElementType(Src)), @@ -997,7 +998,10 @@ const char *Name = LLVMGetValueName2(Cur, &NameLen); if (LLVMGetNamedGlobal(M, Name)) report_fatal_error("GlobalVariable already cloned"); - LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name); + if (LLVMContextSupportsTypedPointers(Ctx)) + LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name); + else + LLVMAddGlobal(M, TypeCloner(M).Clone(LLVMGlobalGetValueType(Cur)), Name); Next = LLVMGetNextGlobal(Cur); if (Next == nullptr) { @@ -1029,7 +1033,12 @@ 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; + if (LLVMContextSupportsTypedPointers(Ctx)) + Ty = LLVMGetElementType(TypeCloner(M).Clone(Cur)); + else + Ty = TypeCloner(M).Clone(LLVMGlobalGetValueType(Cur)); + auto F = LLVMAddFunction(M, Name, Ty); // Copy attributes @@ -1390,7 +1399,7 @@ } } -int llvm_echo(void) { +static int do_llvm_echo(bool opaque_pointers) { LLVMEnablePrettyStackTrace(); LLVMModuleRef Src = llvm_load_module(false, true); @@ -1399,6 +1408,8 @@ size_t ModuleIdentLen; const char *ModuleName = LLVMGetModuleIdentifier(Src, &ModuleIdentLen); LLVMContextRef Ctx = LLVMContextCreate(); + if (opaque_pointers) + LLVMContextSetOpaquePointers(Ctx, true); LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleName, Ctx); LLVMSetSourceFileName(M, SourceFileName, SourceFileLen); @@ -1425,3 +1436,7 @@ return 0; } + +int llvm_echo(void) { return do_llvm_echo(false); } + +int llvm_echo_opaque_pointers(void) { return do_llvm_echo(true); } Index: llvm/tools/llvm-c-test/llvm-c-test.h =================================================================== --- llvm/tools/llvm-c-test/llvm-c-test.h +++ llvm/tools/llvm-c-test/llvm-c-test.h @@ -51,6 +51,7 @@ // echo.c int llvm_echo(void); +int llvm_echo_opaque_pointers(void); // diagnostic.c int llvm_test_diagnostic_handler(void); Index: llvm/tools/llvm-c-test/main.c =================================================================== --- llvm/tools/llvm-c-test/main.c +++ 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"); @@ -94,6 +97,8 @@ return llvm_test_callsite_attributes(); } else if (argc == 2 && !strcmp(argv[1], "--echo")) { return llvm_echo(); + } else if (argc == 2 && !strcmp(argv[1], "--echo-opaque-pointers")) { + return llvm_echo_opaque_pointers(); } else if (argc == 2 && !strcmp(argv[1], "--test-diagnostic-handler")) { return llvm_test_diagnostic_handler(); } else if (argc == 2 && !strcmp(argv[1], "--test-dibuilder")) {