Skip to content

Commit bec0222

Browse files
authored
Merge pull request rust-lang#247 from wasmerio/add-metadata-support
Add metadata support
2 parents 2d715ed + daf6ce2 commit bec0222

20 files changed

+413
-167
lines changed

.travis.yml

+11-11
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ matrix:
4242
packages:
4343
- *BASE_PACKAGES
4444
- llvm-3.6-dev
45-
rust: 1.45.2
45+
rust: 1.52
4646
dist: trusty
4747
- env:
4848
- LLVM_VERSION="3.7"
@@ -55,7 +55,7 @@ matrix:
5555
packages:
5656
- *BASE_PACKAGES
5757
- llvm-3.7-dev
58-
rust: 1.45.2
58+
rust: 1.52
5959
dist: trusty
6060
- env:
6161
- LLVM_VERSION="3.8"
@@ -68,7 +68,7 @@ matrix:
6868
packages:
6969
- *BASE_PACKAGES
7070
- llvm-3.8-dev
71-
rust: 1.45.2
71+
rust: 1.52
7272
dist: trusty
7373
# 3.9 seems to have a linking issue :/
7474
# - env:
@@ -96,7 +96,7 @@ matrix:
9696
packages:
9797
- *BASE_PACKAGES
9898
- llvm-4.0-dev
99-
rust: 1.45.2
99+
rust: 1.52
100100
dist: trusty
101101
- env:
102102
- LLVM_VERSION="5.0"
@@ -109,7 +109,7 @@ matrix:
109109
packages:
110110
- *BASE_PACKAGES
111111
- llvm-5.0-dev
112-
rust: 1.45.2
112+
rust: 1.52
113113
dist: trusty
114114
- env:
115115
- LLVM_VERSION="6.0"
@@ -122,7 +122,7 @@ matrix:
122122
packages:
123123
- *BASE_PACKAGES
124124
- llvm-6.0-dev
125-
rust: 1.45.2
125+
rust: 1.52
126126
dist: trusty
127127
- env:
128128
- LLVM_VERSION="7.0"
@@ -135,7 +135,7 @@ matrix:
135135
packages:
136136
- *BASE_PACKAGES
137137
- llvm-7-dev
138-
rust: 1.45.2
138+
rust: 1.52
139139
dist: trusty
140140
- env:
141141
- LLVM_VERSION="8.0"
@@ -163,7 +163,7 @@ matrix:
163163
packages:
164164
- *BASE_PACKAGES
165165
- llvm-9-dev
166-
rust: 1.45.2
166+
rust: 1.52
167167
dist: bionic
168168
- env:
169169
- LLVM_VERSION="10.0"
@@ -179,7 +179,7 @@ matrix:
179179
- *BASE_PACKAGES
180180
- llvm-10-dev
181181
- libclang-common-10-dev
182-
rust: 1.45.2
182+
rust: 1.52
183183
dist: bionic
184184
- env:
185185
- LLVM_VERSION="11.0"
@@ -195,7 +195,7 @@ matrix:
195195
- *BASE_PACKAGES
196196
- llvm-11-dev
197197
- libclang-common-11-dev
198-
rust: 1.45.2
198+
rust: 1.52
199199
dist: bionic
200200
- env:
201201
- LLVM_VERSION="12.0"
@@ -211,7 +211,7 @@ matrix:
211211
- *BASE_PACKAGES
212212
- llvm-12-dev
213213
- libclang-common-12-dev
214-
rust: 1.45.2
214+
rust: 1.52
215215
dist: bionic
216216
- deploy: # Documentation build; Only latest supported LLVM version for now
217217
provider: pages

examples/kaleidoscope/main.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ use self::inkwell::builder::Builder;
2525
use self::inkwell::context::Context;
2626
use self::inkwell::module::Module;
2727
use self::inkwell::passes::PassManager;
28-
use self::inkwell::types::BasicTypeEnum;
29-
use self::inkwell::values::{BasicValue, BasicValueEnum, FloatValue, FunctionValue, PointerValue};
28+
use self::inkwell::types::BasicMetadataTypeEnum;
29+
use self::inkwell::values::{BasicValue, BasicMetadataValueEnum, FloatValue, FunctionValue, PointerValue};
3030
use self::inkwell::{OptimizationLevel, FloatPredicate};
3131

3232
use crate::Token::*;
@@ -982,7 +982,7 @@ impl<'a, 'ctx> Compiler<'a, 'ctx> {
982982
compiled_args.push(self.compile_expr(arg)?);
983983
}
984984

985-
let argsv: Vec<BasicValueEnum> = compiled_args.iter().by_ref().map(|&val| val.into()).collect();
985+
let argsv: Vec<BasicMetadataValueEnum> = compiled_args.iter().by_ref().map(|&val| val.into()).collect();
986986

987987
match self.builder.build_call(fun, argsv.as_slice(), "tmp").try_as_basic_value().left() {
988988
Some(value) => Ok(value.into_float_value()),
@@ -1093,7 +1093,7 @@ impl<'a, 'ctx> Compiler<'a, 'ctx> {
10931093
let args_types = std::iter::repeat(ret_type)
10941094
.take(proto.args.len())
10951095
.map(|f| f.into())
1096-
.collect::<Vec<BasicTypeEnum>>();
1096+
.collect::<Vec<BasicMetadataTypeEnum>>();
10971097
let args_types = args_types.as_slice();
10981098

10991099
let fn_type = self.context.f64_type().fn_type(args_types, false);

src/builder.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use llvm_sys::prelude::{LLVMBuilderRef, LLVMValueRef};
1010
use crate::{AtomicOrdering, AtomicRMWBinOp, IntPredicate, FloatPredicate};
1111
use crate::basic_block::BasicBlock;
1212
use crate::support::to_c_str;
13-
use crate::values::{AggregateValue, AggregateValueEnum, AsValueRef, FunctionValue, BasicValue, BasicValueEnum, PhiValue, IntValue, PointerValue, VectorValue, InstructionValue, GlobalValue, IntMathValue, FloatMathValue, PointerMathValue, InstructionOpcode, CallSiteValue};
13+
use crate::values::{AggregateValue, AggregateValueEnum, AsValueRef, FunctionValue, BasicValue, BasicValueEnum, PhiValue, IntValue, PointerValue, VectorValue, InstructionValue, GlobalValue, IntMathValue, FloatMathValue, PointerMathValue, InstructionOpcode, CallSiteValue, BasicMetadataValueEnum};
1414
#[llvm_versions(7.0..=latest)]
1515
use crate::debug_info::DILocation;
1616
#[llvm_versions(3.9..=latest)]
@@ -126,17 +126,18 @@ impl<'ctx> Builder<'ctx> {
126126
/// let fn_value = module.add_function("ret", fn_type, None);
127127
/// let entry = context.append_basic_block(fn_value, "entry");
128128
/// let i32_arg = fn_value.get_first_param().unwrap();
129+
/// let md_string = context.metadata_string("a metadata");
129130
///
130131
/// builder.position_at_end(entry);
131132
///
132-
/// let ret_val = builder.build_call(fn_value, &[i32_arg], "call")
133+
/// let ret_val = builder.build_call(fn_value, &[i32_arg.into(), md_string.into()], "call")
133134
/// .try_as_basic_value()
134135
/// .left()
135136
/// .unwrap();
136137
///
137138
/// builder.build_return(Some(&ret_val));
138139
/// ```
139-
pub fn build_call<F>(&self, function: F, args: &[BasicValueEnum<'ctx>], name: &str) -> CallSiteValue<'ctx>
140+
pub fn build_call<F>(&self, function: F, args: &[BasicMetadataValueEnum<'ctx>], name: &str) -> CallSiteValue<'ctx>
140141
where
141142
F: Into<CallableValue<'ctx>>,
142143
{

src/context.rs

+24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! A `Context` is an opaque owner and manager of core global data.
22
33
use llvm_sys::core::{LLVMAppendBasicBlockInContext, LLVMContextCreate, LLVMContextDispose, LLVMCreateBuilderInContext, LLVMDoubleTypeInContext, LLVMFloatTypeInContext, LLVMFP128TypeInContext, LLVMInsertBasicBlockInContext, LLVMInt16TypeInContext, LLVMInt1TypeInContext, LLVMInt32TypeInContext, LLVMInt64TypeInContext, LLVMInt8TypeInContext, LLVMIntTypeInContext, LLVMModuleCreateWithNameInContext, LLVMStructCreateNamed, LLVMStructTypeInContext, LLVMVoidTypeInContext, LLVMHalfTypeInContext, LLVMGetGlobalContext, LLVMPPCFP128TypeInContext, LLVMConstStructInContext, LLVMMDNodeInContext, LLVMMDStringInContext, LLVMGetMDKindIDInContext, LLVMX86FP80TypeInContext, LLVMConstStringInContext, LLVMContextSetDiagnosticHandler};
4+
#[llvm_versions(6.0..=latest)]
5+
use llvm_sys::core::LLVMMetadataTypeInContext;
46
#[llvm_versions(3.9..=latest)]
57
use llvm_sys::core::{LLVMCreateEnumAttribute, LLVMCreateStringAttribute};
68
#[llvm_versions(3.6..7.0)]
@@ -28,6 +30,8 @@ use crate::module::Module;
2830
use crate::support::{to_c_str, LLVMString};
2931
use crate::targets::TargetData;
3032
use crate::types::{AnyTypeEnum, BasicTypeEnum, FloatType, IntType, StructType, VoidType, AsTypeRef, FunctionType};
33+
#[llvm_versions(6.0..=latest)]
34+
use crate::types::MetadataType;
3135
use crate::values::{AsValueRef, BasicMetadataValueEnum, BasicValueEnum, FunctionValue, StructValue, MetadataValue, VectorValue, PointerValue};
3236

3337
use std::marker::PhantomData;
@@ -427,6 +431,26 @@ impl Context {
427431
}
428432
}
429433

434+
/// Gets the `MetadataType` representing 128 bit width. It will be assigned the current context.
435+
///
436+
/// # Example
437+
///
438+
/// ```
439+
/// use inkwell::context::Context;
440+
/// use inkwell::values::IntValue;
441+
///
442+
/// let context = Context::create();
443+
/// let md_type = context.metadata_type();
444+
///
445+
/// assert_eq!(*md_type.get_context(), context);
446+
/// ```
447+
#[llvm_versions(6.0..=latest)]
448+
pub fn metadata_type(&self) -> MetadataType {
449+
unsafe {
450+
MetadataType::new(LLVMMetadataTypeInContext(self.context))
451+
}
452+
}
453+
430454
/// Gets the `IntType` representing a bit width of a pointer. It will be assigned the referenced context.
431455
///
432456
/// # Example

src/module.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -818,8 +818,8 @@ impl<'ctx> Module<'ctx> {
818818
/// let md_string = context.metadata_string("lots of metadata here");
819819
/// let md_node = context.metadata_node(&[bool_val.into(), f32_val.into()]);
820820
///
821-
/// module.add_global_metadata("my_md", &md_string);
822-
/// module.add_global_metadata("my_md", &md_node);
821+
/// module.add_global_metadata("my_md", &md_string).unwrap();
822+
/// module.add_global_metadata("my_md", &md_node).unwrap();
823823
///
824824
/// assert_eq!(module.get_global_metadata_size("my_md"), 2);
825825
///
@@ -835,12 +835,17 @@ impl<'ctx> Module<'ctx> {
835835
/// assert_eq!(md_1[0].into_int_value(), bool_val);
836836
/// assert_eq!(md_1[1].into_float_value(), f32_val);
837837
/// ```
838-
pub fn add_global_metadata(&self, key: &str, metadata: &MetadataValue<'ctx>) {
839-
let c_string = to_c_str(key);
838+
pub fn add_global_metadata(&self, key: &str, metadata: &MetadataValue<'ctx>) -> Result<(), &'static str> {
839+
if !metadata.is_node() {
840+
return Err("metadata is expected to be a node.")
841+
}
840842

843+
let c_string = to_c_str(key);
841844
unsafe {
842-
LLVMAddNamedMetadataOperand(self.module.get(), c_string.as_ptr(), metadata.as_value_ref())
845+
LLVMAddNamedMetadataOperand(self.module.get(), c_string.as_ptr(), metadata.as_value_ref());
843846
}
847+
848+
Ok(())
844849
}
845850

846851
// REVIEW: Better name? get_global_metadata_len or _count?
@@ -863,8 +868,8 @@ impl<'ctx> Module<'ctx> {
863868
/// let md_string = context.metadata_string("lots of metadata here");
864869
/// let md_node = context.metadata_node(&[bool_val.into(), f32_val.into()]);
865870
///
866-
/// module.add_global_metadata("my_md", &md_string);
867-
/// module.add_global_metadata("my_md", &md_node);
871+
/// module.add_global_metadata("my_md", &md_string).unwrap();
872+
/// module.add_global_metadata("my_md", &md_node).unwrap();
868873
///
869874
/// assert_eq!(module.get_global_metadata_size("my_md"), 2);
870875
///
@@ -908,8 +913,8 @@ impl<'ctx> Module<'ctx> {
908913
/// let md_string = context.metadata_string("lots of metadata here");
909914
/// let md_node = context.metadata_node(&[bool_val.into(), f32_val.into()]);
910915
///
911-
/// module.add_global_metadata("my_md", &md_string);
912-
/// module.add_global_metadata("my_md", &md_node);
916+
/// module.add_global_metadata("my_md", &md_string).unwrap();
917+
/// module.add_global_metadata("my_md", &md_node).unwrap();
913918
///
914919
/// assert_eq!(module.get_global_metadata_size("my_md"), 2);
915920
///

src/types/array_type.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::context::ContextRef;
66
use crate::types::traits::AsTypeRef;
77
use crate::types::{Type, BasicTypeEnum, PointerType, FunctionType};
88
use crate::values::{AsValueRef, ArrayValue, IntValue};
9+
use crate::types::enums::BasicMetadataTypeEnum;
910

1011
/// An `ArrayType` is the type of contiguous constants or variables.
1112
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -103,7 +104,7 @@ impl<'ctx> ArrayType<'ctx> {
103104
/// let i8_array_type = i8_type.array_type(3);
104105
/// let fn_type = i8_array_type.fn_type(&[], false);
105106
/// ```
106-
pub fn fn_type(self, param_types: &[BasicTypeEnum<'ctx>], is_var_args: bool) -> FunctionType<'ctx> {
107+
pub fn fn_type(self, param_types: &[BasicMetadataTypeEnum<'ctx>], is_var_args: bool) -> FunctionType<'ctx> {
107108
self.array_type.fn_type(param_types, is_var_args)
108109
}
109110

0 commit comments

Comments
 (0)