1use std::collections::HashMap;
6use std::fmt;
7
8use llvm_ir::{
9 ArgId, Argument, BasicBlock, BlockId, ConstId, ConstantData, Context, FastMathFlags, FloatKind,
10 FloatPredicate, Function, GlobalId, GlobalVariable, InstrKind, Instruction, IntArithFlags,
11 IntPredicate, Linkage, Module, TailCallKind, TypeData, TypeId, ValueRef,
12};
13
14use crate::lexer::{Keyword, LexError, Lexer, Token};
15
16#[derive(Clone, Debug)]
22pub struct ParseError {
23 pub line: usize,
25 pub col: usize,
27 pub message: String,
29}
30
31impl fmt::Display for ParseError {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 write!(
34 f,
35 "parse error at {}:{}: {}",
36 self.line, self.col, self.message
37 )
38 }
39}
40
41impl From<LexError> for ParseError {
42 fn from(e: LexError) -> Self {
43 ParseError {
44 line: e.line,
45 col: e.col,
46 message: e.message,
47 }
48 }
49}
50
51impl From<&LexError> for ParseError {
52 fn from(e: &LexError) -> Self {
53 ParseError {
54 line: e.line,
55 col: e.col,
56 message: e.message.clone(),
57 }
58 }
59}
60
61struct Parser<'src> {
66 lex: Lexer<'src>,
67 ctx: Context,
68 module: Module,
69 pending_blocks: HashMap<String, BlockId>,
71 current_func: Option<usize>, locals: HashMap<String, ValueRef>,
75 unnamed: HashMap<u64, ValueRef>,
77}
78
79impl<'src> Parser<'src> {
80 fn new(src: &'src str) -> Self {
81 Parser {
82 lex: Lexer::new(src),
83 ctx: Context::new(),
84 module: Module::new(""),
85 pending_blocks: HashMap::new(),
86 current_func: None,
87 locals: HashMap::new(),
88 unnamed: HashMap::new(),
89 }
90 }
91
92 fn err(&self, msg: impl Into<String>) -> ParseError {
93 ParseError {
94 line: self.lex.current_line(),
95 col: self.lex.current_col(),
96 message: msg.into(),
97 }
98 }
99
100 fn parse_module(&mut self) -> Result<(), ParseError> {
105 loop {
106 match self.lex.peek()? {
107 Token::Eof => break,
108 Token::Kw(Keyword::Source) => {
109 self.parse_source_filename()?;
110 }
111 Token::Kw(Keyword::Target) => {
112 self.parse_target()?;
113 }
114 Token::LocalIdent(_) => {
115 self.parse_named_type_def()?;
116 }
117 Token::GlobalIdent(_) => {
118 self.parse_global_or_function()?;
119 }
120 Token::Kw(Keyword::Define) => {
121 self.parse_function(false)?;
122 }
123 Token::Kw(Keyword::Declare) => {
124 self.parse_function(true)?;
125 }
126 Token::Bang => {
127 self.parse_metadata_definition_or_skip()?;
128 }
129 _ => {
130 let t = self.lex.next()?;
131 return Err(self.err(format!("unexpected top-level token {:?}", t)));
132 }
133 }
134 }
135 Ok(())
136 }
137
138 fn parse_source_filename(&mut self) -> Result<(), ParseError> {
139 self.lex.expect_kw(&Keyword::Source)?;
140 self.lex.expect(&Token::Equal)?;
141 let s = self.lex.expect_string_lit()?;
142 self.module.source_filename = Some(s);
143 Ok(())
144 }
145
146 fn parse_target(&mut self) -> Result<(), ParseError> {
147 self.lex.expect_kw(&Keyword::Target)?;
148 match self.lex.next()? {
149 Token::Kw(Keyword::Triple) => {
150 self.lex.expect(&Token::Equal)?;
151 let s = self.lex.expect_string_lit()?;
152 self.module.target_triple = Some(s);
153 }
154 Token::Kw(Keyword::Datalayout) => {
155 self.lex.expect(&Token::Equal)?;
156 let s = self.lex.expect_string_lit()?;
157 self.module.data_layout = Some(s);
158 }
159 t => return Err(self.err(format!("unexpected after 'target': {:?}", t))),
160 }
161 Ok(())
162 }
163
164 fn parse_named_type_def(&mut self) -> Result<(), ParseError> {
165 let name = self.lex.expect_local_ident()?;
167 self.lex.expect(&Token::Equal)?;
168 self.lex.expect_kw(&Keyword::Type)?;
169 let ty_id = self.ctx.mk_struct_named(name.clone());
171 match self.lex.peek()? {
173 Token::Kw(Keyword::Void) => {
174 self.lex.next()?;
176 }
177 _ => {
178 let fields = self.parse_struct_body()?;
179 self.ctx.define_struct_body(ty_id, fields.0, fields.1);
180 }
181 }
182 self.module.register_named_type(name, ty_id);
183 Ok(())
184 }
185
186 fn parse_global_or_function(&mut self) -> Result<(), ParseError> {
187 let name = self.lex.expect_global_ident()?;
189 self.lex.expect(&Token::Equal)?;
190 let linkage = self.parse_optional_linkage();
191 match self.lex.peek()? {
192 Token::Kw(Keyword::Global) | Token::Kw(Keyword::Constant) => {
193 let is_const = matches!(self.lex.peek()?, Token::Kw(Keyword::Constant));
194 self.lex.next()?;
195 let ty = self.parse_type()?;
196 let init = if !self.at_statement_end() {
197 let c = self.parse_constant(ty)?;
198 Some(c)
199 } else {
200 None
201 };
202 let gv = GlobalVariable {
203 name,
204 ty,
205 initializer: init,
206 is_constant: is_const,
207 linkage,
208 };
209 self.module.add_global(gv);
210 }
211 _ => {
212 return Err(self.err(format!("expected 'global' or 'constant' for @{}", name)));
213 }
214 }
215 Ok(())
216 }
217
218 fn at_statement_end(&mut self) -> bool {
219 matches!(
220 self.lex.peek(),
221 Ok(Token::Eof)
222 | Ok(Token::Kw(Keyword::Define))
223 | Ok(Token::Kw(Keyword::Declare))
224 | Ok(Token::GlobalIdent(_))
225 | Ok(Token::LocalIdent(_))
226 | Ok(Token::Kw(Keyword::Target))
227 | Ok(Token::Kw(Keyword::Source))
228 | Ok(Token::Bang)
229 )
230 }
231
232 fn parse_optional_linkage(&mut self) -> Linkage {
237 match self.lex.peek() {
238 Ok(Token::Kw(Keyword::Private)) => {
239 let _ = self.lex.next();
240 Linkage::Private
241 }
242 Ok(Token::Kw(Keyword::Internal)) => {
243 let _ = self.lex.next();
244 Linkage::Internal
245 }
246 Ok(Token::Kw(Keyword::External)) => {
247 let _ = self.lex.next();
248 Linkage::External
249 }
250 Ok(Token::Kw(Keyword::Weak)) => {
251 let _ = self.lex.next();
252 Linkage::Weak
253 }
254 Ok(Token::Kw(Keyword::WeakOdr)) => {
255 let _ = self.lex.next();
256 Linkage::WeakOdr
257 }
258 Ok(Token::Kw(Keyword::Linkonce)) => {
259 let _ = self.lex.next();
260 Linkage::LinkOnce
261 }
262 Ok(Token::Kw(Keyword::LinkonceOdr)) => {
263 let _ = self.lex.next();
264 Linkage::LinkOnceOdr
265 }
266 Ok(Token::Kw(Keyword::Common)) => {
267 let _ = self.lex.next();
268 Linkage::Common
269 }
270 Ok(Token::Kw(Keyword::AvailableExternally)) => {
271 let _ = self.lex.next();
272 Linkage::AvailableExternally
273 }
274 _ => Linkage::External,
275 }
276 }
277
278 fn parse_type(&mut self) -> Result<TypeId, ParseError> {
283 let base = match self.lex.peek()? {
284 Token::Kw(Keyword::Void) => {
285 self.lex.next()?;
286 self.ctx.void_ty
287 }
288 Token::Kw(Keyword::Half) => {
289 self.lex.next()?;
290 self.ctx.mk_float(FloatKind::Half)
291 }
292 Token::Kw(Keyword::Bfloat) => {
293 self.lex.next()?;
294 self.ctx.mk_float(FloatKind::BFloat)
295 }
296 Token::Kw(Keyword::Float) => {
297 self.lex.next()?;
298 self.ctx.f32_ty
299 }
300 Token::Kw(Keyword::Double) => {
301 self.lex.next()?;
302 self.ctx.f64_ty
303 }
304 Token::Kw(Keyword::Fp128) => {
305 self.lex.next()?;
306 self.ctx.mk_float(FloatKind::Fp128)
307 }
308 Token::Kw(Keyword::X86Fp80) => {
309 self.lex.next()?;
310 self.ctx.mk_float(FloatKind::X86Fp80)
311 }
312 Token::Kw(Keyword::Label) => {
313 self.lex.next()?;
314 self.ctx.label_ty
315 }
316 Token::Kw(Keyword::Ptr) => {
317 self.lex.next()?;
318 self.ctx.ptr_ty
319 }
320 Token::IntType(bits) => {
321 let b = *bits;
322 self.lex.next()?;
323 self.ctx.mk_int(b)
324 }
325 Token::LBracket => self.parse_array_type()?,
326 Token::LAngle => self.parse_vector_type()?,
327 Token::LBrace => {
328 let (fields, packed) = self.parse_struct_body()?;
329 self.ctx.mk_struct_anon(fields, packed)
330 }
331 Token::LocalIdent(_) => {
332 let name = self.lex.expect_local_ident()?;
334 self.ctx.mk_struct_named(name)
335 }
336 _ => {
337 let t = self.lex.next()?;
338 return Err(self.err(format!("expected type, got {:?}", t)));
339 }
340 };
341
342 if self.lex.eat(&Token::Star) {
344 return Ok(self.ctx.ptr_ty);
345 }
346
347 Ok(base)
348 }
349
350 fn parse_array_type(&mut self) -> Result<TypeId, ParseError> {
351 self.lex.expect(&Token::LBracket)?;
352 let len = self.lex.expect_uint_lit()?;
353 self.lex.expect_kw(&Keyword::X)?;
354 let elem = self.parse_type()?;
355 self.lex.expect(&Token::RBracket)?;
356 Ok(self.ctx.mk_array(elem, len))
357 }
358
359 fn parse_vector_type(&mut self) -> Result<TypeId, ParseError> {
360 self.lex.expect(&Token::LAngle)?;
361 let scalable = self.lex.eat_kw(Keyword::Vscale);
363 if scalable {
364 self.lex.expect_kw(&Keyword::X)?;
365 }
366 let len = self.lex.expect_uint_lit()? as u32;
367 self.lex.expect_kw(&Keyword::X)?;
368 let elem = self.parse_type()?;
369 self.lex.expect(&Token::RAngle)?;
370 Ok(self.ctx.mk_vector(elem, len, scalable))
371 }
372
373 fn parse_struct_body(&mut self) -> Result<(Vec<TypeId>, bool), ParseError> {
375 let packed = self.lex.eat(&Token::LAngle);
376 self.lex.expect(&Token::LBrace)?;
377 let mut fields = Vec::new();
378 if !matches!(self.lex.peek()?, Token::RBrace) {
379 fields.push(self.parse_type()?);
380 while self.lex.eat(&Token::Comma) {
381 fields.push(self.parse_type()?);
382 }
383 }
384 self.lex.expect(&Token::RBrace)?;
385 if packed {
386 self.lex.expect(&Token::RAngle)?;
387 }
388 Ok((fields, packed))
389 }
390
391 #[allow(dead_code)]
392 fn parse_function_type(&mut self, ret: TypeId) -> Result<TypeId, ParseError> {
393 self.lex.expect(&Token::LParen)?;
394 let mut params = Vec::new();
395 let mut variadic = false;
396 if !matches!(self.lex.peek()?, Token::RParen) {
397 if self.lex.eat(&Token::Ellipsis) {
398 variadic = true;
399 } else {
400 params.push(self.parse_type()?);
401 while self.lex.eat(&Token::Comma) {
402 if self.lex.eat(&Token::Ellipsis) {
403 variadic = true;
404 break;
405 }
406 params.push(self.parse_type()?);
407 }
408 }
409 }
410 self.lex.expect(&Token::RParen)?;
411 Ok(self.ctx.mk_fn_type(ret, params, variadic))
412 }
413
414 fn parse_function(&mut self, is_declaration: bool) -> Result<(), ParseError> {
419 if is_declaration {
420 self.lex.expect_kw(&Keyword::Declare)?;
421 } else {
422 self.lex.expect_kw(&Keyword::Define)?;
423 }
424
425 let linkage = self.parse_optional_linkage();
426
427 self.skip_fn_attrs()?;
430
431 let ret_ty = self.parse_type()?;
432 let name = self.lex.expect_global_ident()?;
433
434 self.lex.expect(&Token::LParen)?;
436 let mut params: Vec<(TypeId, String)> = Vec::new();
437 let mut variadic = false;
438 if !matches!(self.lex.peek()?, Token::RParen) {
439 if self.lex.eat(&Token::Ellipsis) {
440 variadic = true;
441 } else {
442 let (ty, pname) = self.parse_param()?;
443 params.push((ty, pname));
444 while self.lex.eat(&Token::Comma) {
445 if self.lex.eat(&Token::Ellipsis) {
446 variadic = true;
447 break;
448 }
449 let (ty, pname) = self.parse_param()?;
450 params.push((ty, pname));
451 }
452 }
453 }
454 self.lex.expect(&Token::RParen)?;
455
456 self.skip_trailing_fn_attrs()?;
458
459 let fn_ty =
460 self.ctx
461 .mk_fn_type(ret_ty, params.iter().map(|(ty, _)| *ty).collect(), variadic);
462 let args: Vec<Argument> = params
463 .into_iter()
464 .enumerate()
465 .map(|(i, (ty, nm))| Argument {
466 name: nm,
467 ty,
468 index: i as u32,
469 })
470 .collect();
471
472 self.locals.clear();
474 self.unnamed.clear();
475 self.pending_blocks.clear();
476
477 for (i, arg) in args.iter().enumerate() {
479 let vref = ValueRef::Argument(ArgId(i as u32));
480 if !arg.name.is_empty() {
481 self.locals.insert(arg.name.clone(), vref);
482 }
483 }
484
485 if is_declaration {
486 let func = Function::new_declaration(&name, fn_ty, args, linkage);
487 let idx = self.module.add_function(func);
488 self.current_func = Some(idx.0 as usize);
489 return Ok(());
490 }
491
492 let func = Function::new(&name, fn_ty, args, linkage);
494 let idx = self.module.add_function(func);
495 self.current_func = Some(idx.0 as usize);
496
497 self.lex.expect(&Token::LBrace)?;
498 loop {
499 match self.lex.peek()? {
500 Token::RBrace => {
501 self.lex.next()?;
502 break;
503 }
504 _ => {
505 self.parse_block()?;
506 }
507 }
508 }
509
510 Ok(())
511 }
512
513 fn parse_param(&mut self) -> Result<(TypeId, String), ParseError> {
514 let ty = self.parse_type()?;
515 self.skip_param_attrs()?;
517 let name = match self.lex.peek() {
519 Ok(Token::LocalIdent(_)) => self.lex.expect_local_ident()?,
520 _ => String::new(),
521 };
522 Ok((ty, name))
523 }
524
525 fn parse_block(&mut self) -> Result<(), ParseError> {
530 let bb_name = match self.lex.peek()? {
532 Token::LocalIdent(_) => {
533 let n = self.lex.expect_local_ident()?;
534 self.lex.eat(&Token::Colon);
536 n
537 }
538 Token::IntLit(n) => {
539 let n = *n as u64;
540 let s = n.to_string();
541 self.lex.next()?;
542 self.lex.eat(&Token::Colon);
543 s
544 }
545 _ => "entry".to_string(),
546 };
547
548 let fid = self
549 .current_func
550 .ok_or_else(|| self.err("block outside function"))?;
551 let func = &mut self.module.functions[fid];
552
553 let bid = if let Some(&existing) = self.pending_blocks.get(&bb_name) {
555 existing
556 } else {
557 let bb = BasicBlock::new(&bb_name);
558 let bid = func.add_block(bb);
559 self.pending_blocks.insert(bb_name.clone(), bid);
560 bid
561 };
562
563 loop {
571 match self.lex.peek()? {
572 Token::RBrace => break,
573 Token::LocalIdent(_) | Token::IntLit(_) => {
574 if self.block_is_complete(bid) {
577 break;
578 }
579 self.parse_instruction(bid)?;
580 }
581 _ => {
582 self.parse_instruction(bid)?;
583 }
584 }
585 }
586
587 Ok(())
588 }
589
590 fn block_is_complete(&self, bid: BlockId) -> bool {
591 let fid = match self.current_func {
592 Some(f) => f,
593 None => return false,
594 };
595 self.module.functions[fid].block(bid).is_complete()
596 }
597
598 fn parse_instruction(&mut self, bid: BlockId) -> Result<(), ParseError> {
603 let fid = self
604 .current_func
605 .ok_or_else(|| self.err("instruction outside function"))?;
606
607 let (result_name, result_slot) = match self.lex.peek()? {
609 Token::LocalIdent(_) => {
610 let n = self.lex.expect_local_ident()?;
613 if self.lex.eat(&Token::Equal) {
614 (Some(n), None)
616 } else {
617 return Err(self.err(format!("unexpected identifier '{}'", n)));
619 }
620 }
621 Token::IntLit(slot) => {
622 let slot = *slot as u64;
623 self.lex.next()?;
624 if self.lex.eat(&Token::Equal) {
625 (None, Some(slot))
626 } else {
627 return Err(self.err("expected '=' after slot number"));
628 }
629 }
630 _ => (None, None),
631 };
632
633 let (kind, ty) = self.parse_instr_kind()?;
634 let metadata_attachments = self.parse_optional_metadata_attachments()?;
635 let is_term = kind.is_terminator();
636
637 let instr_name = result_name.clone();
638 let instr = Instruction::new(instr_name, ty, kind);
639 let iid = self.module.functions[fid].alloc_instr(instr);
640 for (key, value) in metadata_attachments {
641 self.module.functions[fid].add_instr_metadata(iid, key.clone(), value.clone());
642 if key == "dbg" {
643 if let Some(loc_id) = Self::parse_metadata_ref_id(&value) {
644 self.module.functions[fid].set_instr_dbg_loc(iid, loc_id);
645 }
646 }
647 }
648
649 if is_term {
650 self.module.functions[fid]
651 .block_mut(bid)
652 .set_terminator(iid);
653 } else {
654 self.module.functions[fid].block_mut(bid).append_instr(iid);
655 }
656
657 let vref = ValueRef::Instruction(iid);
658 if let Some(name) = result_name {
659 self.locals.insert(name, vref);
660 } else if let Some(slot) = result_slot {
661 self.unnamed.insert(slot, vref);
662 }
663
664 Ok(())
665 }
666
667 fn parse_instr_kind(&mut self) -> Result<(InstrKind, TypeId), ParseError> {
668 match self.lex.peek()? {
669 Token::Kw(Keyword::Add) => {
671 self.lex.next()?;
672 let flags = self.parse_int_arith_flags();
673 let (lhs, ty) = self.parse_typed_value()?;
674 self.lex.expect(&Token::Comma)?;
675 let rhs = self.parse_value(ty)?;
676 Ok((InstrKind::Add { flags, lhs, rhs }, ty))
677 }
678 Token::Kw(Keyword::Sub) => {
679 self.lex.next()?;
680 let flags = self.parse_int_arith_flags();
681 let (lhs, ty) = self.parse_typed_value()?;
682 self.lex.expect(&Token::Comma)?;
683 let rhs = self.parse_value(ty)?;
684 Ok((InstrKind::Sub { flags, lhs, rhs }, ty))
685 }
686 Token::Kw(Keyword::Mul) => {
687 self.lex.next()?;
688 let flags = self.parse_int_arith_flags();
689 let (lhs, ty) = self.parse_typed_value()?;
690 self.lex.expect(&Token::Comma)?;
691 let rhs = self.parse_value(ty)?;
692 Ok((InstrKind::Mul { flags, lhs, rhs }, ty))
693 }
694 Token::Kw(Keyword::Udiv) => {
695 self.lex.next()?;
696 let exact = self.lex.eat_kw(Keyword::Exact);
697 let (lhs, ty) = self.parse_typed_value()?;
698 self.lex.expect(&Token::Comma)?;
699 let rhs = self.parse_value(ty)?;
700 Ok((InstrKind::UDiv { exact, lhs, rhs }, ty))
701 }
702 Token::Kw(Keyword::Sdiv) => {
703 self.lex.next()?;
704 let exact = self.lex.eat_kw(Keyword::Exact);
705 let (lhs, ty) = self.parse_typed_value()?;
706 self.lex.expect(&Token::Comma)?;
707 let rhs = self.parse_value(ty)?;
708 Ok((InstrKind::SDiv { exact, lhs, rhs }, ty))
709 }
710 Token::Kw(Keyword::Urem) => {
711 self.lex.next()?;
712 let (lhs, ty) = self.parse_typed_value()?;
713 self.lex.expect(&Token::Comma)?;
714 let rhs = self.parse_value(ty)?;
715 Ok((InstrKind::URem { lhs, rhs }, ty))
716 }
717 Token::Kw(Keyword::Srem) => {
718 self.lex.next()?;
719 let (lhs, ty) = self.parse_typed_value()?;
720 self.lex.expect(&Token::Comma)?;
721 let rhs = self.parse_value(ty)?;
722 Ok((InstrKind::SRem { lhs, rhs }, ty))
723 }
724 Token::Kw(Keyword::And) => {
726 self.lex.next()?;
727 let (lhs, ty) = self.parse_typed_value()?;
728 self.lex.expect(&Token::Comma)?;
729 let rhs = self.parse_value(ty)?;
730 Ok((InstrKind::And { lhs, rhs }, ty))
731 }
732 Token::Kw(Keyword::Or) => {
733 self.lex.next()?;
734 let (lhs, ty) = self.parse_typed_value()?;
735 self.lex.expect(&Token::Comma)?;
736 let rhs = self.parse_value(ty)?;
737 Ok((InstrKind::Or { lhs, rhs }, ty))
738 }
739 Token::Kw(Keyword::Xor) => {
740 self.lex.next()?;
741 let (lhs, ty) = self.parse_typed_value()?;
742 self.lex.expect(&Token::Comma)?;
743 let rhs = self.parse_value(ty)?;
744 Ok((InstrKind::Xor { lhs, rhs }, ty))
745 }
746 Token::Kw(Keyword::Shl) => {
747 self.lex.next()?;
748 let flags = self.parse_int_arith_flags();
749 let (lhs, ty) = self.parse_typed_value()?;
750 self.lex.expect(&Token::Comma)?;
751 let rhs = self.parse_value(ty)?;
752 Ok((InstrKind::Shl { flags, lhs, rhs }, ty))
753 }
754 Token::Kw(Keyword::Lshr) => {
755 self.lex.next()?;
756 let exact = self.lex.eat_kw(Keyword::Exact);
757 let (lhs, ty) = self.parse_typed_value()?;
758 self.lex.expect(&Token::Comma)?;
759 let rhs = self.parse_value(ty)?;
760 Ok((InstrKind::LShr { exact, lhs, rhs }, ty))
761 }
762 Token::Kw(Keyword::Ashr) => {
763 self.lex.next()?;
764 let exact = self.lex.eat_kw(Keyword::Exact);
765 let (lhs, ty) = self.parse_typed_value()?;
766 self.lex.expect(&Token::Comma)?;
767 let rhs = self.parse_value(ty)?;
768 Ok((InstrKind::AShr { exact, lhs, rhs }, ty))
769 }
770 Token::Kw(Keyword::Fadd) => {
772 self.lex.next()?;
773 let flags = self.parse_fast_math_flags();
774 let (lhs, ty) = self.parse_typed_value()?;
775 self.lex.expect(&Token::Comma)?;
776 let rhs = self.parse_value(ty)?;
777 Ok((InstrKind::FAdd { flags, lhs, rhs }, ty))
778 }
779 Token::Kw(Keyword::Fsub) => {
780 self.lex.next()?;
781 let flags = self.parse_fast_math_flags();
782 let (lhs, ty) = self.parse_typed_value()?;
783 self.lex.expect(&Token::Comma)?;
784 let rhs = self.parse_value(ty)?;
785 Ok((InstrKind::FSub { flags, lhs, rhs }, ty))
786 }
787 Token::Kw(Keyword::Fmul) => {
788 self.lex.next()?;
789 let flags = self.parse_fast_math_flags();
790 let (lhs, ty) = self.parse_typed_value()?;
791 self.lex.expect(&Token::Comma)?;
792 let rhs = self.parse_value(ty)?;
793 Ok((InstrKind::FMul { flags, lhs, rhs }, ty))
794 }
795 Token::Kw(Keyword::Fdiv) => {
796 self.lex.next()?;
797 let flags = self.parse_fast_math_flags();
798 let (lhs, ty) = self.parse_typed_value()?;
799 self.lex.expect(&Token::Comma)?;
800 let rhs = self.parse_value(ty)?;
801 Ok((InstrKind::FDiv { flags, lhs, rhs }, ty))
802 }
803 Token::Kw(Keyword::Frem) => {
804 self.lex.next()?;
805 let flags = self.parse_fast_math_flags();
806 let (lhs, ty) = self.parse_typed_value()?;
807 self.lex.expect(&Token::Comma)?;
808 let rhs = self.parse_value(ty)?;
809 Ok((InstrKind::FRem { flags, lhs, rhs }, ty))
810 }
811 Token::Kw(Keyword::Fneg) => {
812 self.lex.next()?;
813 let flags = self.parse_fast_math_flags();
814 let (operand, ty) = self.parse_typed_value()?;
815 Ok((InstrKind::FNeg { flags, operand }, ty))
816 }
817 Token::Kw(Keyword::Icmp) => {
819 self.lex.next()?;
820 let pred = self.parse_int_pred()?;
821 let (lhs, _ty) = self.parse_typed_value()?;
822 self.lex.expect(&Token::Comma)?;
823 let rhs = self.parse_value(_ty)?;
824 let i1 = self.ctx.i1_ty;
825 Ok((InstrKind::ICmp { pred, lhs, rhs }, i1))
826 }
827 Token::Kw(Keyword::Fcmp) => {
828 self.lex.next()?;
829 let flags = self.parse_fast_math_flags();
830 let pred = self.parse_float_pred()?;
831 let (lhs, _ty) = self.parse_typed_value()?;
832 self.lex.expect(&Token::Comma)?;
833 let rhs = self.parse_value(_ty)?;
834 let i1 = self.ctx.i1_ty;
835 Ok((
836 InstrKind::FCmp {
837 flags,
838 pred,
839 lhs,
840 rhs,
841 },
842 i1,
843 ))
844 }
845 Token::Kw(Keyword::Alloca) => {
847 self.lex.next()?;
848 let alloc_ty = self.parse_type()?;
849 let (num_elements, comma_before_align_consumed) =
855 if self.lex.eat(&Token::Comma) {
856 match self.lex.peek()? {
857 Token::Kw(Keyword::Align) => (None, true),
858 _ => {
859 let (ne, _) = self.parse_typed_value()?;
860 (Some(ne), false)
861 }
862 }
863 } else {
864 (None, false)
865 };
866 let align = if comma_before_align_consumed {
867 if self.lex.eat_kw(Keyword::Align) {
869 let a = self.lex.expect_uint_lit()? as u32;
870 Some(a)
871 } else {
872 None
873 }
874 } else {
875 self.parse_optional_align()?
876 };
877 let ptr_ty = self.ctx.ptr_ty;
878 Ok((
879 InstrKind::Alloca {
880 alloc_ty,
881 num_elements,
882 align,
883 },
884 ptr_ty,
885 ))
886 }
887 Token::Kw(Keyword::Load) => {
888 self.lex.next()?;
889 let volatile = self.lex.eat_kw(Keyword::Volatile);
890 let ty = self.parse_type()?;
891 self.lex.expect(&Token::Comma)?;
892 let (_ptr_ty, ptr) = {
893 let ptype = self.parse_type()?;
894 (ptype, self.parse_value(ptype)?)
895 };
896 let align = self.parse_optional_align()?;
897 Ok((
898 InstrKind::Load {
899 ty,
900 ptr,
901 align,
902 volatile,
903 },
904 ty,
905 ))
906 }
907 Token::Kw(Keyword::Store) => {
908 self.lex.next()?;
909 let volatile = self.lex.eat_kw(Keyword::Volatile);
910 let (val, _val_ty) = self.parse_typed_value()?;
911 self.lex.expect(&Token::Comma)?;
912 let ptr_ty2 = self.parse_type()?;
913 let ptr = self.parse_value(ptr_ty2)?;
914 let align = self.parse_optional_align()?;
915 let void_ty = self.ctx.void_ty;
916 Ok((
917 InstrKind::Store {
918 val,
919 ptr,
920 align,
921 volatile,
922 },
923 void_ty,
924 ))
925 }
926 Token::Kw(Keyword::Getelementptr) => {
927 self.lex.next()?;
928 let inbounds = self.lex.eat_kw(Keyword::Inbounds);
929 let base_ty = self.parse_type()?;
930 self.lex.expect(&Token::Comma)?;
931 let ptr_ty2 = self.parse_type()?;
932 let ptr = self.parse_value(ptr_ty2)?;
933 let mut indices = Vec::new();
934 while self.lex.eat(&Token::Comma) {
935 let (idx, _) = self.parse_typed_value()?;
936 indices.push(idx);
937 }
938 let ptr_ty = self.ctx.ptr_ty;
939 Ok((
940 InstrKind::GetElementPtr {
941 inbounds,
942 base_ty,
943 ptr,
944 indices,
945 },
946 ptr_ty,
947 ))
948 }
949 Token::Kw(Keyword::Trunc) => {
951 self.lex.next()?;
952 let (val, _) = self.parse_typed_value()?;
953 self.lex.expect_kw(&Keyword::To)?;
954 let to = self.parse_type()?;
955 Ok((InstrKind::Trunc { val, to }, to))
956 }
957 Token::Kw(Keyword::Zext) => {
958 self.lex.next()?;
959 let (val, _) = self.parse_typed_value()?;
960 self.lex.expect_kw(&Keyword::To)?;
961 let to = self.parse_type()?;
962 Ok((InstrKind::ZExt { val, to }, to))
963 }
964 Token::Kw(Keyword::Sext) => {
965 self.lex.next()?;
966 let (val, _) = self.parse_typed_value()?;
967 self.lex.expect_kw(&Keyword::To)?;
968 let to = self.parse_type()?;
969 Ok((InstrKind::SExt { val, to }, to))
970 }
971 Token::Kw(Keyword::Fptrunc) => {
972 self.lex.next()?;
973 let (val, _) = self.parse_typed_value()?;
974 self.lex.expect_kw(&Keyword::To)?;
975 let to = self.parse_type()?;
976 Ok((InstrKind::FPTrunc { val, to }, to))
977 }
978 Token::Kw(Keyword::Fpext) => {
979 self.lex.next()?;
980 let (val, _) = self.parse_typed_value()?;
981 self.lex.expect_kw(&Keyword::To)?;
982 let to = self.parse_type()?;
983 Ok((InstrKind::FPExt { val, to }, to))
984 }
985 Token::Kw(Keyword::Fptoui) => {
986 self.lex.next()?;
987 let (val, _) = self.parse_typed_value()?;
988 self.lex.expect_kw(&Keyword::To)?;
989 let to = self.parse_type()?;
990 Ok((InstrKind::FPToUI { val, to }, to))
991 }
992 Token::Kw(Keyword::Fptosi) => {
993 self.lex.next()?;
994 let (val, _) = self.parse_typed_value()?;
995 self.lex.expect_kw(&Keyword::To)?;
996 let to = self.parse_type()?;
997 Ok((InstrKind::FPToSI { val, to }, to))
998 }
999 Token::Kw(Keyword::Uitofp) => {
1000 self.lex.next()?;
1001 let (val, _) = self.parse_typed_value()?;
1002 self.lex.expect_kw(&Keyword::To)?;
1003 let to = self.parse_type()?;
1004 Ok((InstrKind::UIToFP { val, to }, to))
1005 }
1006 Token::Kw(Keyword::Sitofp) => {
1007 self.lex.next()?;
1008 let (val, _) = self.parse_typed_value()?;
1009 self.lex.expect_kw(&Keyword::To)?;
1010 let to = self.parse_type()?;
1011 Ok((InstrKind::SIToFP { val, to }, to))
1012 }
1013 Token::Kw(Keyword::Ptrtoint) => {
1014 self.lex.next()?;
1015 let (val, _) = self.parse_typed_value()?;
1016 self.lex.expect_kw(&Keyword::To)?;
1017 let to = self.parse_type()?;
1018 Ok((InstrKind::PtrToInt { val, to }, to))
1019 }
1020 Token::Kw(Keyword::Inttoptr) => {
1021 self.lex.next()?;
1022 let (val, _) = self.parse_typed_value()?;
1023 self.lex.expect_kw(&Keyword::To)?;
1024 let to = self.parse_type()?;
1025 Ok((InstrKind::IntToPtr { val, to }, to))
1026 }
1027 Token::Kw(Keyword::Bitcast) => {
1028 self.lex.next()?;
1029 let (val, _) = self.parse_typed_value()?;
1030 self.lex.expect_kw(&Keyword::To)?;
1031 let to = self.parse_type()?;
1032 Ok((InstrKind::BitCast { val, to }, to))
1033 }
1034 Token::Kw(Keyword::Addrspacecast) => {
1035 self.lex.next()?;
1036 let (val, _) = self.parse_typed_value()?;
1037 self.lex.expect_kw(&Keyword::To)?;
1038 let to = self.parse_type()?;
1039 Ok((InstrKind::AddrSpaceCast { val, to }, to))
1040 }
1041 Token::Kw(Keyword::Freeze) => {
1042 self.lex.next()?;
1043 let (val, ty) = self.parse_typed_value()?;
1044 Ok((InstrKind::Freeze { val }, ty))
1045 }
1046 Token::Kw(Keyword::Select) => {
1048 self.lex.next()?;
1049 let (cond, _) = self.parse_typed_value()?;
1050 self.lex.expect(&Token::Comma)?;
1051 let (then_val, ty) = self.parse_typed_value()?;
1052 self.lex.expect(&Token::Comma)?;
1053 let (else_val, _) = self.parse_typed_value()?;
1055 Ok((
1056 InstrKind::Select {
1057 cond,
1058 then_val,
1059 else_val,
1060 },
1061 ty,
1062 ))
1063 }
1064 Token::Kw(Keyword::Phi) => {
1065 self.lex.next()?;
1066 let ty = self.parse_type()?;
1067 let mut incoming = Vec::new();
1068 loop {
1069 self.lex.expect(&Token::LBracket)?;
1071 let val = self.parse_value(ty)?;
1072 self.lex.expect(&Token::Comma)?;
1073 let block_name = self.lex.expect_local_ident()?;
1074 let bid = self.get_or_create_block(&block_name)?;
1075 self.lex.expect(&Token::RBracket)?;
1076 incoming.push((val, bid));
1077 if !self.lex.eat(&Token::Comma) {
1078 break;
1079 }
1080 }
1081 Ok((InstrKind::Phi { ty, incoming }, ty))
1082 }
1083 Token::Kw(Keyword::Extractvalue) => {
1084 self.lex.next()?;
1085 let (aggregate, agg_ty) = self.parse_typed_value()?;
1086 let mut indices = Vec::new();
1087 while self.lex.eat(&Token::Comma) {
1088 let idx = self.lex.expect_uint_lit()? as u32;
1089 indices.push(idx);
1090 }
1091 let mut result_ty = agg_ty;
1093 for &idx in &indices {
1094 result_ty = match self.ctx.get_type(result_ty) {
1095 TypeData::Struct(s) => {
1096 s.fields.get(idx as usize).copied().unwrap_or(result_ty)
1097 }
1098 TypeData::Array { element, .. } => *element,
1099 TypeData::Vector { element, .. } => *element,
1100 _ => result_ty,
1101 };
1102 }
1103 Ok((InstrKind::ExtractValue { aggregate, indices }, result_ty))
1104 }
1105 Token::Kw(Keyword::Insertvalue) => {
1106 self.lex.next()?;
1107 let (aggregate, agg_ty) = self.parse_typed_value()?;
1108 self.lex.expect(&Token::Comma)?;
1109 let (val, _val_ty) = self.parse_typed_value()?;
1110 let mut indices = Vec::new();
1111 while self.lex.eat(&Token::Comma) {
1112 let idx = self.lex.expect_uint_lit()? as u32;
1113 indices.push(idx);
1114 }
1115 Ok((
1116 InstrKind::InsertValue {
1117 aggregate,
1118 val,
1119 indices,
1120 },
1121 agg_ty,
1122 ))
1123 }
1124 Token::Kw(Keyword::Extractelement) => {
1125 self.lex.next()?;
1126 let (vec, vec_ty) = self.parse_typed_value()?;
1127 self.lex.expect(&Token::Comma)?;
1128 let (idx, _) = self.parse_typed_value()?;
1129 let elem_ty = match self.ctx.get_type(vec_ty) {
1131 llvm_ir::types::TypeData::Vector { element, .. } => *element,
1132 _ => vec_ty,
1133 };
1134 Ok((InstrKind::ExtractElement { vec, idx }, elem_ty))
1135 }
1136 Token::Kw(Keyword::Insertelement) => {
1137 self.lex.next()?;
1138 let (vec, vec_ty) = self.parse_typed_value()?;
1139 self.lex.expect(&Token::Comma)?;
1140 let (val, _) = self.parse_typed_value()?;
1141 self.lex.expect(&Token::Comma)?;
1142 let (idx, _) = self.parse_typed_value()?;
1143 Ok((InstrKind::InsertElement { vec, val, idx }, vec_ty))
1144 }
1145 Token::Kw(Keyword::Shufflevector) => {
1146 self.lex.next()?;
1147 let (v1, vec_ty) = self.parse_typed_value()?;
1148 self.lex.expect(&Token::Comma)?;
1149 let (v2, _) = self.parse_typed_value()?;
1150 self.lex.expect(&Token::Comma)?;
1151 let mask = self.parse_shuffle_mask()?;
1153 Ok((InstrKind::ShuffleVector { v1, v2, mask }, vec_ty))
1154 }
1155 Token::Kw(Keyword::Call)
1157 | Token::Kw(Keyword::Tail)
1158 | Token::Kw(Keyword::Musttail)
1159 | Token::Kw(Keyword::Notail) => {
1160 let tail = match self.lex.peek()? {
1161 Token::Kw(Keyword::Tail) => {
1162 self.lex.next()?;
1163 TailCallKind::Tail
1164 }
1165 Token::Kw(Keyword::Musttail) => {
1166 self.lex.next()?;
1167 TailCallKind::MustTail
1168 }
1169 Token::Kw(Keyword::Notail) => {
1170 self.lex.next()?;
1171 TailCallKind::NoTail
1172 }
1173 _ => TailCallKind::None,
1174 };
1175 self.lex.expect_kw(&Keyword::Call)?;
1176 let _fmf = self.parse_fast_math_flags();
1178 let ret_ty = self.parse_type()?;
1180 let callee = match self.lex.peek()? {
1182 Token::GlobalIdent(_) => {
1183 let gname = self.lex.expect_global_ident()?;
1184 self.resolve_global_ref(&gname)?
1185 }
1186 Token::LocalIdent(_) => {
1187 let lname = self.lex.expect_local_ident()?;
1188 self.resolve_local(&lname)?
1189 }
1190 _ => return Err(self.err("expected callee name")),
1191 };
1192 self.lex.expect(&Token::LParen)?;
1194 let mut args = Vec::new();
1195 if !matches!(self.lex.peek()?, Token::RParen) {
1196 let (a, _) = self.parse_typed_value()?;
1197 args.push(a);
1198 while self.lex.eat(&Token::Comma) {
1199 if self.lex.eat(&Token::Ellipsis) {
1200 break;
1201 }
1202 let (a, _) = self.parse_typed_value()?;
1203 args.push(a);
1204 }
1205 }
1206 self.lex.expect(&Token::RParen)?;
1207 let param_tys: Vec<TypeId> = args.iter().map(|a| self.type_of_vref(*a)).collect();
1209 let callee_ty = self.ctx.mk_fn_type(ret_ty, param_tys, false);
1210 Ok((
1211 InstrKind::Call {
1212 tail,
1213 callee_ty,
1214 callee,
1215 args,
1216 },
1217 ret_ty,
1218 ))
1219 }
1220 Token::Kw(Keyword::Ret) => {
1222 self.lex.next()?;
1223 let void_ty = self.ctx.void_ty;
1224 if self.lex.eat_kw(Keyword::Void) {
1225 Ok((InstrKind::Ret { val: None }, void_ty))
1226 } else {
1227 let (val, _) = self.parse_typed_value()?;
1228 Ok((InstrKind::Ret { val: Some(val) }, void_ty))
1229 }
1230 }
1231 Token::Kw(Keyword::Br) => {
1232 self.lex.next()?;
1233 let void_ty = self.ctx.void_ty;
1234 match self.lex.peek()? {
1236 Token::Kw(Keyword::Label) => {
1237 self.lex.next()?;
1238 let dest_name = self.lex.expect_local_ident()?;
1239 let dest = self.get_or_create_block(&dest_name)?;
1240 Ok((InstrKind::Br { dest }, void_ty))
1241 }
1242 _ => {
1243 let (cond, _) = self.parse_typed_value()?;
1244 self.lex.expect(&Token::Comma)?;
1245 self.lex.expect_kw(&Keyword::Label)?;
1246 let then_name = self.lex.expect_local_ident()?;
1247 let then_dest = self.get_or_create_block(&then_name)?;
1248 self.lex.expect(&Token::Comma)?;
1249 self.lex.expect_kw(&Keyword::Label)?;
1250 let else_name = self.lex.expect_local_ident()?;
1251 let else_dest = self.get_or_create_block(&else_name)?;
1252 Ok((
1253 InstrKind::CondBr {
1254 cond,
1255 then_dest,
1256 else_dest,
1257 },
1258 void_ty,
1259 ))
1260 }
1261 }
1262 }
1263 Token::Kw(Keyword::Switch) => {
1264 self.lex.next()?;
1265 let void_ty = self.ctx.void_ty;
1266 let (val, _val_ty) = self.parse_typed_value()?;
1267 self.lex.expect(&Token::Comma)?;
1268 self.lex.expect_kw(&Keyword::Label)?;
1269 let default_name = self.lex.expect_local_ident()?;
1270 let default = self.get_or_create_block(&default_name)?;
1271 self.lex.expect(&Token::LBracket)?;
1272 let mut cases = Vec::new();
1273 while !matches!(self.lex.peek()?, Token::RBracket) {
1274 let (case_val, _) = self.parse_typed_value()?;
1276 self.lex.expect(&Token::Comma)?;
1277 self.lex.expect_kw(&Keyword::Label)?;
1278 let dest_name = self.lex.expect_local_ident()?;
1279 let dest = self.get_or_create_block(&dest_name)?;
1280 cases.push((case_val, dest));
1281 }
1282 self.lex.expect(&Token::RBracket)?;
1283 Ok((
1284 InstrKind::Switch {
1285 val,
1286 default,
1287 cases,
1288 },
1289 void_ty,
1290 ))
1291 }
1292 Token::Kw(Keyword::Unreachable) => {
1293 self.lex.next()?;
1294 let void_ty = self.ctx.void_ty;
1295 Ok((InstrKind::Unreachable, void_ty))
1296 }
1297 _ => {
1298 let t = self.lex.next()?;
1299 Err(self.err(format!("unknown instruction opcode: {:?}", t)))
1300 }
1301 }
1302 }
1303
1304 fn parse_typed_value(&mut self) -> Result<(ValueRef, TypeId), ParseError> {
1309 let ty = self.parse_type()?;
1310 let val = self.parse_value(ty)?;
1311 Ok((val, ty))
1312 }
1313
1314 fn parse_value(&mut self, ty: TypeId) -> Result<ValueRef, ParseError> {
1315 match self.lex.peek()? {
1316 Token::LocalIdent(_) => {
1317 let name = self.lex.expect_local_ident()?;
1318 self.resolve_local(&name)
1319 }
1320 Token::GlobalIdent(_) => {
1321 let name = self.lex.expect_global_ident()?;
1322 self.resolve_global_ref(&name)
1323 }
1324 Token::IntLit(_) | Token::UIntLit(_) => {
1325 let n = self.lex.expect_uint_lit()?;
1326 let c = self.ctx.const_int(ty, n);
1327 Ok(ValueRef::Constant(c))
1328 }
1329 Token::FloatLit(_) => {
1330 if let Token::FloatLit(f) = self.lex.next()? {
1331 let bits = f.to_bits();
1332 let c = self.ctx.const_float(ty, bits);
1333 Ok(ValueRef::Constant(c))
1334 } else {
1335 unreachable!()
1336 }
1337 }
1338 Token::Kw(Keyword::Undef) => {
1339 self.lex.next()?;
1340 Ok(ValueRef::Constant(self.ctx.const_undef(ty)))
1341 }
1342 Token::Kw(Keyword::Poison) => {
1343 self.lex.next()?;
1344 Ok(ValueRef::Constant(self.ctx.const_poison(ty)))
1345 }
1346 Token::Kw(Keyword::Null) => {
1347 self.lex.next()?;
1348 Ok(ValueRef::Constant(self.ctx.const_null(ty)))
1349 }
1350 Token::Kw(Keyword::Zeroinitializer) => {
1351 self.lex.next()?;
1352 Ok(ValueRef::Constant(self.ctx.const_zero(ty)))
1353 }
1354 Token::Kw(Keyword::True) => {
1355 self.lex.next()?;
1356 let i1 = self.ctx.i1_ty;
1357 Ok(ValueRef::Constant(self.ctx.const_int(i1, 1)))
1358 }
1359 Token::Kw(Keyword::False) => {
1360 self.lex.next()?;
1361 let i1 = self.ctx.i1_ty;
1362 Ok(ValueRef::Constant(self.ctx.const_int(i1, 0)))
1363 }
1364 _ => {
1365 let t = self.lex.next()?;
1366 Err(self.err(format!("expected value, got {:?}", t)))
1367 }
1368 }
1369 }
1370
1371 fn parse_constant(&mut self, ty: TypeId) -> Result<ConstId, ParseError> {
1372 let vref = self.parse_value(ty)?;
1373 match vref {
1374 ValueRef::Constant(c) => Ok(c),
1375 _ => Err(self.err("expected constant")),
1376 }
1377 }
1378
1379 fn resolve_local(&self, name: &str) -> Result<ValueRef, ParseError> {
1380 if let Some(&v) = self.locals.get(name) {
1381 return Ok(v);
1382 }
1383 if let Ok(slot) = name.parse::<u64>() {
1385 if let Some(&v) = self.unnamed.get(&slot) {
1386 return Ok(v);
1387 }
1388 }
1389 Err(ParseError {
1390 line: self.lex.current_line(),
1391 col: self.lex.current_col(),
1392 message: format!("undefined local value '%{}'", name),
1393 })
1394 }
1395
1396 fn resolve_global_ref(&mut self, name: &str) -> Result<ValueRef, ParseError> {
1397 let ptr_ty = self.ctx.ptr_ty;
1398 if let Some(gid) = self.module.get_global_id(name) {
1400 let c = self.ctx.push_const(ConstantData::GlobalRef {
1401 ty: ptr_ty,
1402 id: gid,
1403 name: name.to_string(),
1404 });
1405 return Ok(ValueRef::Constant(c));
1406 }
1407 if self.module.get_function_id(name).is_some() {
1410 let c = self.ctx.push_const(ConstantData::GlobalRef {
1411 ty: ptr_ty,
1412 id: GlobalId(u32::MAX),
1413 name: name.to_string(),
1414 });
1415 return Ok(ValueRef::Constant(c));
1416 }
1417 let c = self.ctx.push_const(ConstantData::GlobalRef {
1419 ty: ptr_ty,
1420 id: GlobalId(u32::MAX),
1421 name: name.to_string(),
1422 });
1423 Ok(ValueRef::Constant(c))
1424 }
1425
1426 fn type_of_vref(&self, vref: ValueRef) -> TypeId {
1427 if let Some(fid) = self.current_func {
1428 if fid < self.module.functions.len() {
1429 let func = &self.module.functions[fid];
1430 match vref {
1431 ValueRef::Instruction(id) if (id.0 as usize) < func.instructions.len() => {
1432 return func.instr(id).ty;
1433 }
1434 ValueRef::Argument(id) if (id.0 as usize) < func.args.len() => {
1435 return func.arg(id).ty;
1436 }
1437 _ => {}
1438 }
1439 }
1440 }
1441 match vref {
1442 ValueRef::Constant(c) => self.ctx.type_of_const(c),
1443 _ => self.ctx.ptr_ty,
1444 }
1445 }
1446
1447 fn get_or_create_block(&mut self, name: &str) -> Result<BlockId, ParseError> {
1448 let fid = self
1449 .current_func
1450 .ok_or_else(|| self.err("block reference outside function"))?;
1451 if let Some(&bid) = self.pending_blocks.get(name) {
1452 return Ok(bid);
1453 }
1454 let bb = BasicBlock::new(name);
1455 let bid = self.module.functions[fid].add_block(bb);
1456 self.pending_blocks.insert(name.to_string(), bid);
1457 Ok(bid)
1458 }
1459
1460 fn parse_int_arith_flags(&mut self) -> IntArithFlags {
1465 let mut flags = IntArithFlags::default();
1466 loop {
1467 if self.lex.eat_kw(Keyword::Nuw) {
1468 flags.nuw = true;
1469 } else if self.lex.eat_kw(Keyword::Nsw) {
1470 flags.nsw = true;
1471 } else {
1472 break;
1473 }
1474 }
1475 flags
1476 }
1477
1478 fn parse_fast_math_flags(&mut self) -> FastMathFlags {
1479 let mut f = FastMathFlags::default();
1480 loop {
1481 if self.lex.eat_kw(Keyword::Fast) {
1482 f.fast = true;
1483 break;
1484 } else if self.lex.eat_kw(Keyword::Nnan) {
1485 f.nnan = true;
1486 } else if self.lex.eat_kw(Keyword::Ninf) {
1487 f.ninf = true;
1488 } else if self.lex.eat_kw(Keyword::Nsz) {
1489 f.nsz = true;
1490 } else if self.lex.eat_kw(Keyword::Arcp) {
1491 f.arcp = true;
1492 } else if self.lex.eat_kw(Keyword::Contract) {
1493 f.contract = true;
1494 } else if self.lex.eat_kw(Keyword::Afn) {
1495 f.afn = true;
1496 } else if self.lex.eat_kw(Keyword::Reassoc) {
1497 f.reassoc = true;
1498 } else {
1499 break;
1500 }
1501 }
1502 f
1503 }
1504
1505 fn parse_int_pred(&mut self) -> Result<IntPredicate, ParseError> {
1506 match self.lex.next()? {
1507 Token::Kw(Keyword::Eq) => Ok(IntPredicate::Eq),
1508 Token::Kw(Keyword::Ne) => Ok(IntPredicate::Ne),
1509 Token::Kw(Keyword::Ugt) => Ok(IntPredicate::Ugt),
1510 Token::Kw(Keyword::Uge) => Ok(IntPredicate::Uge),
1511 Token::Kw(Keyword::Ult) => Ok(IntPredicate::Ult),
1512 Token::Kw(Keyword::Ule) => Ok(IntPredicate::Ule),
1513 Token::Kw(Keyword::Sgt) => Ok(IntPredicate::Sgt),
1514 Token::Kw(Keyword::Sge) => Ok(IntPredicate::Sge),
1515 Token::Kw(Keyword::Slt) => Ok(IntPredicate::Slt),
1516 Token::Kw(Keyword::Sle) => Ok(IntPredicate::Sle),
1517 t => Err(self.err(format!("expected icmp predicate, got {:?}", t))),
1518 }
1519 }
1520
1521 fn parse_float_pred(&mut self) -> Result<FloatPredicate, ParseError> {
1522 match self.lex.next()? {
1523 Token::Kw(Keyword::False) => Ok(FloatPredicate::False),
1524 Token::Kw(Keyword::Oeq) => Ok(FloatPredicate::Oeq),
1525 Token::Kw(Keyword::Ogt) => Ok(FloatPredicate::Ogt),
1526 Token::Kw(Keyword::Oge) => Ok(FloatPredicate::Oge),
1527 Token::Kw(Keyword::Olt) => Ok(FloatPredicate::Olt),
1528 Token::Kw(Keyword::Ole) => Ok(FloatPredicate::Ole),
1529 Token::Kw(Keyword::One) => Ok(FloatPredicate::One),
1530 Token::Kw(Keyword::Ord) => Ok(FloatPredicate::Ord),
1531 Token::Kw(Keyword::Uno) => Ok(FloatPredicate::Uno),
1532 Token::Kw(Keyword::Ueq) => Ok(FloatPredicate::Ueq),
1533 Token::Kw(Keyword::Ugt) => Ok(FloatPredicate::Ugt),
1534 Token::Kw(Keyword::Uge) => Ok(FloatPredicate::Uge),
1535 Token::Kw(Keyword::Ult) => Ok(FloatPredicate::Ult),
1536 Token::Kw(Keyword::Ule) => Ok(FloatPredicate::Ule),
1537 Token::Kw(Keyword::Une) => Ok(FloatPredicate::Une),
1538 Token::Kw(Keyword::True) => Ok(FloatPredicate::True),
1539 t => Err(self.err(format!("expected fcmp predicate, got {:?}", t))),
1540 }
1541 }
1542
1543 fn parse_optional_align(&mut self) -> Result<Option<u32>, ParseError> {
1544 if self.lex.eat(&Token::Comma) {
1545 self.lex.expect_kw(&Keyword::Align)?;
1546 let a = self.lex.expect_uint_lit()? as u32;
1547 Ok(Some(a))
1548 } else {
1549 Ok(None)
1550 }
1551 }
1552
1553 fn parse_shuffle_mask(&mut self) -> Result<Vec<i32>, ParseError> {
1554 if self.lex.eat_kw(Keyword::Undef) {
1559 return Ok(vec![]);
1560 }
1561 if matches!(self.lex.peek()?, Token::LAngle) {
1563 let _outer_ty = self.parse_type()?;
1569 }
1575 self.lex.expect(&Token::LAngle)?;
1576 let mut mask = Vec::new();
1577 loop {
1578 let _ = self.parse_type()?;
1580 let n = self.lex.expect_int_lit()? as i32;
1581 mask.push(n);
1582 if !self.lex.eat(&Token::Comma) {
1583 break;
1584 }
1585 }
1586 self.lex.expect(&Token::RAngle)?;
1587 Ok(mask)
1588 }
1589
1590 fn skip_fn_attrs(&mut self) -> Result<(), ParseError> {
1595 loop {
1598 match self.lex.peek()? {
1599 Token::Kw(Keyword::Void)
1601 | Token::Kw(Keyword::Half)
1602 | Token::Kw(Keyword::Bfloat)
1603 | Token::Kw(Keyword::Float)
1604 | Token::Kw(Keyword::Double)
1605 | Token::Kw(Keyword::Fp128)
1606 | Token::Kw(Keyword::X86Fp80)
1607 | Token::Kw(Keyword::Ptr)
1608 | Token::IntType(_)
1609 | Token::LBracket
1610 | Token::LAngle
1611 | Token::LBrace
1612 | Token::LocalIdent(_) => break,
1613 Token::Kw(Keyword::Private)
1615 | Token::Kw(Keyword::Internal)
1616 | Token::Kw(Keyword::External)
1617 | Token::Kw(Keyword::Weak) => {
1618 self.lex.next()?;
1619 }
1620 Token::Hash => {
1621 self.lex.next()?;
1622 self.lex.next()?; }
1624 _ => break,
1625 }
1626 }
1627 Ok(())
1628 }
1629
1630 fn skip_trailing_fn_attrs(&mut self) -> Result<(), ParseError> {
1631 loop {
1635 match self.lex.peek()? {
1636 Token::LBrace
1637 | Token::Eof
1638 | Token::Kw(Keyword::Define)
1639 | Token::Kw(Keyword::Declare)
1640 | Token::GlobalIdent(_)
1641 | Token::LocalIdent(_)
1642 | Token::Kw(Keyword::Target)
1643 | Token::Kw(Keyword::Source) => break,
1644 Token::Hash => {
1645 self.lex.next()?;
1646 self.lex.next()?;
1647 }
1648 Token::Bang => {
1649 self.parse_metadata_definition_or_skip()?;
1650 break;
1651 }
1652 _ => {
1653 self.lex.next()?;
1654 }
1655 }
1656 }
1657 Ok(())
1658 }
1659
1660 fn skip_param_attrs(&mut self) -> Result<(), ParseError> {
1661 loop {
1668 match self.lex.peek()? {
1669 Token::Comma
1670 | Token::RParen
1671 | Token::LocalIdent(_)
1672 | Token::Eof
1673 | Token::Kw(Keyword::Define)
1674 | Token::Kw(Keyword::Declare)
1675 | Token::Kw(Keyword::Source)
1676 | Token::Kw(Keyword::Target)
1677 | Token::GlobalIdent(_)
1678 | Token::Bang => break,
1679 Token::Kw(Keyword::Align) => {
1680 self.lex.next()?;
1681 self.lex.next()?; }
1683 Token::Hash => {
1684 self.lex.next()?;
1685 self.lex.next()?;
1686 }
1687 _ => {
1688 self.lex.next()?;
1689 }
1690 }
1691 }
1692 Ok(())
1693 }
1694
1695 fn parse_optional_metadata_attachments(&mut self) -> Result<Vec<(String, String)>, ParseError> {
1696 let mut attachments = Vec::new();
1697 while self.lex.eat(&Token::Comma) {
1698 if !self.lex.eat(&Token::Bang) {
1699 break;
1700 }
1701 let key = self.lex.expect_local_ident()?;
1702 let value = self.parse_metadata_value_text()?;
1703 attachments.push((key, value));
1704 }
1705 Ok(attachments)
1706 }
1707
1708 fn parse_metadata_definition_or_skip(&mut self) -> Result<(), ParseError> {
1709 self.lex.expect(&Token::Bang)?;
1713 let lhs = match self.lex.peek()? {
1714 Token::IntLit(_) | Token::UIntLit(_) => Some((Some(self.lex.expect_uint_lit()? as u32), None)),
1715 Token::LocalIdent(_) => Some((None, Some(self.lex.expect_local_ident()?))),
1716 _ => {
1717 self.skip_one_metadata_value()?;
1718 return Ok(());
1719 }
1720 };
1721 if !self.lex.eat(&Token::Equal) {
1722 self.skip_one_metadata_value()?;
1723 return Ok(());
1724 }
1725 let value = self.parse_metadata_value_text()?;
1726 if let Some((maybe_id, maybe_name)) = lhs {
1727 if let Some(id) = maybe_id {
1728 self.module.set_metadata_node(id, value.clone());
1729 if let Some(loc) = Self::parse_dilocation_from_text(&value) {
1730 self.module.set_debug_location(id, loc);
1731 }
1732 } else if let Some(name) = maybe_name {
1733 self.module.set_named_metadata(name, value);
1734 }
1735 }
1736 Ok(())
1737 }
1738
1739 fn parse_metadata_ref_id(value: &str) -> Option<u32> {
1740 let rest = value.strip_prefix('!')?;
1741 if !rest.is_empty() && rest.chars().all(|c| c.is_ascii_digit()) {
1742 return rest.parse().ok();
1743 }
1744 None
1745 }
1746
1747 fn parse_dilocation_from_text(text: &str) -> Option<llvm_ir::DebugLocation> {
1748 let mut s = text.trim();
1749 if let Some(rest) = s.strip_prefix('!') {
1750 s = rest;
1751 }
1752 if !s.starts_with("DILocation") {
1753 return None;
1754 }
1755 let open = s.find('(')?;
1756 let close = s.rfind(')')?;
1757 if close <= open {
1758 return None;
1759 }
1760 let body = &s[open + 1..close];
1761 let line = Self::parse_named_u32(body, "line")?;
1762 let column = Self::parse_named_u32(body, "column").unwrap_or(0);
1763 Some(llvm_ir::DebugLocation { line, column })
1764 }
1765
1766 fn parse_named_u32(body: &str, name: &str) -> Option<u32> {
1767 let needle = format!("{name}:");
1768 let idx = body.find(&needle)?;
1769 let mut i = idx + needle.len();
1770 while i < body.len() && body.as_bytes()[i].is_ascii_whitespace() {
1771 i += 1;
1772 }
1773 let start = i;
1774 while i < body.len() && body.as_bytes()[i].is_ascii_digit() {
1775 i += 1;
1776 }
1777 if i == start {
1778 None
1779 } else {
1780 body[start..i].parse().ok()
1781 }
1782 }
1783
1784 fn parse_metadata_value_text(&mut self) -> Result<String, ParseError> {
1785 let mut out = String::new();
1786 let mut prev: Option<Token> = None;
1787 let mut depth = 0usize;
1788
1789 if matches!(self.lex.peek()?, Token::LocalIdent(s) if s == "distinct") {
1790 let tok = self.lex.next()?;
1791 Self::push_token_text(&mut out, prev.as_ref(), &tok);
1792 prev = Some(tok);
1793 }
1794
1795 loop {
1796 let tok = self.lex.next()?;
1797 if matches!(tok, Token::Eof) {
1798 break;
1799 }
1800 if Self::is_open_delim(&tok) {
1801 depth += 1;
1802 } else if Self::is_close_delim(&tok) {
1803 if depth == 0 {
1804 return Err(self.err(format!("unbalanced metadata token {:?}", tok)));
1805 }
1806 depth -= 1;
1807 }
1808 Self::push_token_text(&mut out, prev.as_ref(), &tok);
1809 prev = Some(tok);
1810
1811 if depth == 0 {
1812 let peek = self.lex.peek()?;
1813 if matches!(
1814 peek,
1815 Token::Comma
1816 | Token::Eof
1817 | Token::RParen
1818 | Token::RBracket
1819 | Token::RBrace
1820 | Token::RAngle
1821 | Token::Kw(Keyword::Define)
1822 | Token::Kw(Keyword::Declare)
1823 | Token::Kw(Keyword::Source)
1824 | Token::Kw(Keyword::Target)
1825 ) {
1826 break;
1827 }
1828 if matches!(peek, Token::Bang) && !matches!(prev.as_ref(), Some(Token::Bang)) {
1829 break;
1830 }
1831 if matches!(peek, Token::LocalIdent(_) | Token::GlobalIdent(_))
1832 && matches!(
1833 prev.as_ref(),
1834 Some(
1835 Token::RParen
1836 | Token::RBracket
1837 | Token::RBrace
1838 | Token::RAngle
1839 | Token::IntLit(_)
1840 | Token::UIntLit(_)
1841 | Token::StringLit(_)
1842 | Token::Kw(_)
1843 | Token::LocalIdent(_)
1844 | Token::GlobalIdent(_)
1845 )
1846 )
1847 {
1848 break;
1849 }
1850 }
1851 }
1852 Ok(out)
1853 }
1854
1855 fn is_open_delim(tok: &Token) -> bool {
1856 matches!(
1857 tok,
1858 Token::LParen | Token::LBrace | Token::LBracket | Token::LAngle
1859 )
1860 }
1861
1862 fn is_close_delim(tok: &Token) -> bool {
1863 matches!(
1864 tok,
1865 Token::RParen | Token::RBrace | Token::RBracket | Token::RAngle
1866 )
1867 }
1868
1869 fn push_token_text(out: &mut String, prev: Option<&Token>, tok: &Token) {
1870 if let Some(p) = prev {
1871 if Self::needs_space_between(p, tok) {
1872 out.push(' ');
1873 }
1874 }
1875 out.push_str(&Self::token_text(tok));
1876 }
1877
1878 fn needs_space_between(prev: &Token, cur: &Token) -> bool {
1879 if matches!(prev, Token::Bang) {
1880 return false;
1881 }
1882 if matches!(
1883 cur,
1884 Token::Comma | Token::Colon | Token::RParen | Token::RBracket | Token::RBrace | Token::RAngle
1885 ) {
1886 return false;
1887 }
1888 if matches!(
1889 prev,
1890 Token::LParen
1891 | Token::LBracket
1892 | Token::LBrace
1893 | Token::LAngle
1894 | Token::Comma
1895 | Token::Colon
1896 | Token::Bang
1897 ) {
1898 return false;
1899 }
1900 if matches!(cur, Token::LParen) {
1901 return false;
1902 }
1903 true
1904 }
1905
1906 fn token_text(tok: &Token) -> String {
1907 match tok {
1908 Token::LocalIdent(s) => s.clone(),
1909 Token::GlobalIdent(s) => format!("@{}", s),
1910 Token::IntType(bits) => format!("i{}", bits),
1911 Token::IntLit(n) => n.to_string(),
1912 Token::UIntLit(n) => n.to_string(),
1913 Token::FloatLit(n) => n.to_string(),
1914 Token::StringLit(s) => format!("{:?}", s),
1915 Token::Kw(k) => Self::keyword_text(k).to_string(),
1916 Token::Equal => "=".to_string(),
1917 Token::Comma => ",".to_string(),
1918 Token::Colon => ":".to_string(),
1919 Token::Star => "*".to_string(),
1920 Token::LParen => "(".to_string(),
1921 Token::RParen => ")".to_string(),
1922 Token::LBracket => "[".to_string(),
1923 Token::RBracket => "]".to_string(),
1924 Token::LBrace => "{".to_string(),
1925 Token::RBrace => "}".to_string(),
1926 Token::LAngle => "<".to_string(),
1927 Token::RAngle => ">".to_string(),
1928 Token::Ellipsis => "...".to_string(),
1929 Token::Bang => "!".to_string(),
1930 Token::Hash => "#".to_string(),
1931 Token::Eof => String::new(),
1932 }
1933 }
1934
1935 fn keyword_text(kw: &Keyword) -> &'static str {
1936 match kw {
1937 Keyword::Source => "source_filename",
1938 Keyword::Target => "target",
1939 Keyword::Triple => "triple",
1940 Keyword::Datalayout => "datalayout",
1941 Keyword::Define => "define",
1942 Keyword::Declare => "declare",
1943 Keyword::Type => "type",
1944 Keyword::Private => "private",
1945 Keyword::Internal => "internal",
1946 Keyword::External => "external",
1947 Keyword::Weak => "weak",
1948 Keyword::WeakOdr => "weak_odr",
1949 Keyword::Linkonce => "linkonce",
1950 Keyword::LinkonceOdr => "linkonce_odr",
1951 Keyword::Common => "common",
1952 Keyword::AvailableExternally => "available_externally",
1953 Keyword::Void => "void",
1954 Keyword::Half => "half",
1955 Keyword::Bfloat => "bfloat",
1956 Keyword::Float => "float",
1957 Keyword::Double => "double",
1958 Keyword::Fp128 => "fp128",
1959 Keyword::X86Fp80 => "x86_fp80",
1960 Keyword::Label => "label",
1961 Keyword::Metadata => "metadata",
1962 Keyword::Ptr => "ptr",
1963 Keyword::Global => "global",
1964 Keyword::Constant => "constant",
1965 Keyword::Inbounds => "inbounds",
1966 Keyword::Exact => "exact",
1967 Keyword::Nuw => "nuw",
1968 Keyword::Nsw => "nsw",
1969 Keyword::Volatile => "volatile",
1970 Keyword::Tail => "tail",
1971 Keyword::Musttail => "musttail",
1972 Keyword::Notail => "notail",
1973 Keyword::Fast => "fast",
1974 Keyword::Nnan => "nnan",
1975 Keyword::Ninf => "ninf",
1976 Keyword::Nsz => "nsz",
1977 Keyword::Arcp => "arcp",
1978 Keyword::Contract => "contract",
1979 Keyword::Afn => "afn",
1980 Keyword::Reassoc => "reassoc",
1981 Keyword::Add => "add",
1982 Keyword::Sub => "sub",
1983 Keyword::Mul => "mul",
1984 Keyword::Udiv => "udiv",
1985 Keyword::Sdiv => "sdiv",
1986 Keyword::Urem => "urem",
1987 Keyword::Srem => "srem",
1988 Keyword::And => "and",
1989 Keyword::Or => "or",
1990 Keyword::Xor => "xor",
1991 Keyword::Shl => "shl",
1992 Keyword::Lshr => "lshr",
1993 Keyword::Ashr => "ashr",
1994 Keyword::Fadd => "fadd",
1995 Keyword::Fsub => "fsub",
1996 Keyword::Fmul => "fmul",
1997 Keyword::Fdiv => "fdiv",
1998 Keyword::Frem => "frem",
1999 Keyword::Fneg => "fneg",
2000 Keyword::Icmp => "icmp",
2001 Keyword::Fcmp => "fcmp",
2002 Keyword::Alloca => "alloca",
2003 Keyword::Load => "load",
2004 Keyword::Store => "store",
2005 Keyword::Getelementptr => "getelementptr",
2006 Keyword::Trunc => "trunc",
2007 Keyword::Zext => "zext",
2008 Keyword::Sext => "sext",
2009 Keyword::Fptrunc => "fptrunc",
2010 Keyword::Fpext => "fpext",
2011 Keyword::Fptoui => "fptoui",
2012 Keyword::Fptosi => "fptosi",
2013 Keyword::Uitofp => "uitofp",
2014 Keyword::Sitofp => "sitofp",
2015 Keyword::Ptrtoint => "ptrtoint",
2016 Keyword::Inttoptr => "inttoptr",
2017 Keyword::Bitcast => "bitcast",
2018 Keyword::Addrspacecast => "addrspacecast",
2019 Keyword::Freeze => "freeze",
2020 Keyword::Select => "select",
2021 Keyword::Phi => "phi",
2022 Keyword::Extractvalue => "extractvalue",
2023 Keyword::Insertvalue => "insertvalue",
2024 Keyword::Extractelement => "extractelement",
2025 Keyword::Insertelement => "insertelement",
2026 Keyword::Shufflevector => "shufflevector",
2027 Keyword::Call => "call",
2028 Keyword::Ret => "ret",
2029 Keyword::Br => "br",
2030 Keyword::Switch => "switch",
2031 Keyword::Unreachable => "unreachable",
2032 Keyword::Eq => "eq",
2033 Keyword::Ne => "ne",
2034 Keyword::Ugt => "ugt",
2035 Keyword::Uge => "uge",
2036 Keyword::Ult => "ult",
2037 Keyword::Ule => "ule",
2038 Keyword::Sgt => "sgt",
2039 Keyword::Sge => "sge",
2040 Keyword::Slt => "slt",
2041 Keyword::Sle => "sle",
2042 Keyword::False => "false",
2043 Keyword::Oeq => "oeq",
2044 Keyword::Ogt => "ogt",
2045 Keyword::Oge => "oge",
2046 Keyword::Olt => "olt",
2047 Keyword::Ole => "ole",
2048 Keyword::One => "one",
2049 Keyword::Ord => "ord",
2050 Keyword::Uno => "uno",
2051 Keyword::Ueq => "ueq",
2052 Keyword::Une => "une",
2053 Keyword::True => "true",
2054 Keyword::Zeroinitializer => "zeroinitializer",
2055 Keyword::Undef => "undef",
2056 Keyword::Poison => "poison",
2057 Keyword::Null => "null",
2058 Keyword::Align => "align",
2059 Keyword::To => "to",
2060 Keyword::X => "x",
2061 Keyword::Vscale => "vscale",
2062 }
2063 }
2064
2065 fn skip_one_metadata_value(&mut self) -> Result<(), ParseError> {
2066 let _ = self.parse_metadata_value_text()?;
2067 Ok(())
2068 }
2069
2070}
2071
2072pub fn parse(src: &str) -> Result<(Context, Module), ParseError> {
2078 let mut parser = Parser::new(src);
2079 parser.parse_module()?;
2080 Ok((parser.ctx, parser.module))
2081}
2082
2083#[cfg(test)]
2084mod tests {
2085 use super::*;
2086 use llvm_ir::printer::Printer;
2087
2088 #[test]
2089 fn parse_empty_function() {
2090 let src = r#"
2091define void @empty() {
2092entry:
2093 ret void
2094}
2095"#;
2096 let (_ctx, module) = parse(src).expect("parse failed");
2097 assert_eq!(module.functions.len(), 1);
2098 let f = &module.functions[0];
2099 assert_eq!(f.name, "empty");
2100 assert!(!f.is_declaration);
2101 assert_eq!(f.blocks.len(), 1);
2102 assert_eq!(f.blocks[0].name, "entry");
2103 }
2104
2105 #[test]
2106 fn parse_add_function() {
2107 let src = r#"
2108define i32 @add(i32 %a, i32 %b) {
2109entry:
2110 %result = add i32 %a, %b
2111 ret i32 %result
2112}
2113"#;
2114 let (_ctx, module) = parse(src).expect("parse failed");
2115 let f = &module.functions[0];
2116 assert_eq!(f.name, "add");
2117 assert_eq!(f.args.len(), 2);
2118 let bb = &f.blocks[0];
2119 assert_eq!(bb.body.len(), 1);
2120 assert!(bb.is_complete());
2121 }
2122
2123 #[test]
2124 fn parse_declaration() {
2125 let src = "declare i32 @printf(ptr, ...)";
2126 let (_ctx, module) = parse(src).expect("parse failed");
2127 assert_eq!(module.functions.len(), 1);
2128 assert!(module.functions[0].is_declaration);
2129 }
2130
2131 #[test]
2132 fn malformed_param_attrs_stop_at_module_boundaries() {
2133 let src = "; ModuleID = '/tmp/autogen.bc'\n\
2137source_filename = \"/tmp/autogen.bc\"\n\n\
2138define void @autogen_SD0(ptr; ModuleID = '/tmp/autogen %0, ptr %1, ptr %2, i32 .bc'\n\
2139source_filename = \"/tmp/autogen.bc\"\n\n\
2140define void %3, i64@au";
2141
2142 let err = match parse(src) {
2143 Ok(_) => panic!("malformed input should fail"),
2144 Err(err) => err,
2145 };
2146 assert!(err.message.contains("expected RParen"));
2147 }
2148
2149 #[test]
2150 fn parse_global() {
2151 let src = "@x = global i32 42";
2152 let (_ctx, module) = parse(src).expect("parse failed");
2153 assert_eq!(module.globals.len(), 1);
2154 assert_eq!(module.globals[0].name, "x");
2155 }
2156
2157 #[test]
2158 fn parse_target_metadata() {
2159 let src = r#"
2160source_filename = "test.c"
2161target triple = "x86_64-unknown-linux-gnu"
2162target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
2163"#;
2164 let (_ctx, module) = parse(src).expect("parse failed");
2165 assert_eq!(module.source_filename.as_deref(), Some("test.c"));
2166 assert_eq!(
2167 module.target_triple.as_deref(),
2168 Some("x86_64-unknown-linux-gnu")
2169 );
2170 }
2171
2172 #[test]
2173 fn parse_cond_br() {
2174 let src = r#"
2175define void @check(i1 %cond) {
2176entry:
2177 br i1 %cond, label %then, label %else
2178then:
2179 ret void
2180else:
2181 ret void
2182}
2183"#;
2184 let (_ctx, module) = parse(src).expect("parse failed");
2185 let f = &module.functions[0];
2186 assert_eq!(f.blocks.len(), 3);
2187 }
2188
2189 #[test]
2190 fn parse_dbg_attachment_and_dilocation() {
2191 let src = r#"
2192source_filename = "dbg.ll"
2193define i32 @f() {
2194entry:
2195 ret i32 0, !dbg !12, !tbaa !14
2196}
2197!12 = !DILocation(line: 27, column: 3, scope: !1)
2198!14 = !{!"int", !15}
2199!15 = !{!"omnipotent char", !16}
2200!16 = !{!"Simple C/C++ TBAA"}
2201"#;
2202 let (_ctx, module) = parse(src).expect("parse failed");
2203 let f = &module.functions[0];
2204 let tid = f.blocks[0].terminator.expect("terminator");
2205 assert_eq!(f.instr_dbg_loc(tid), Some(12));
2206 let attachments = f.instr_metadata(tid).expect("metadata attachments");
2207 assert_eq!(attachments.len(), 2);
2208 assert_eq!(attachments[0].0, "dbg");
2209 assert_eq!(attachments[0].1, "!12");
2210 assert_eq!(attachments[1].0, "tbaa");
2211 assert_eq!(attachments[1].1, "!14");
2212 let loc = module.debug_location(12).expect("dilocation");
2213 assert_eq!(loc.line, 27);
2214 assert_eq!(loc.column, 3);
2215 assert_eq!(
2216 module.metadata_node(14),
2217 Some("!{!\"int\",!15}")
2218 );
2219 }
2220
2221 #[test]
2222 fn metadata_roundtrip_preserves_named_and_numbered_nodes() {
2223 let src = r#"
2224define i32 @f() {
2225entry:
2226 ret i32 0, !dbg !12
2227}
2228!llvm.dbg.cu = !{!0}
2229!0 = distinct !DICompileUnit(language: 12, file: !1, producer: !"codex", isOptimized: false, runtimeVersion: 0, emissionKind: 1)
2230!1 = !DIFile(filename: !"a.c", directory: !"/tmp")
2231!12 = !DILocation(line: 7, column: 2, scope: !0)
2232"#;
2233 let (ctx, module) = parse(src).expect("parse failed");
2234 let printed = Printer::new(&ctx).print_module(&module);
2235 let (_ctx2, module2) = parse(&printed).expect("roundtrip parse failed");
2236 assert_eq!(
2237 module2.named_metadata,
2238 vec![("llvm.dbg.cu".to_string(), "!{!0}".to_string())]
2239 );
2240 assert_eq!(module2.metadata_node(0).map(|s| s.contains("DICompileUnit")), Some(true));
2241 assert_eq!(module2.metadata_node(1).map(|s| s.contains("DIFile")), Some(true));
2242 assert_eq!(module2.metadata_node(12), Some("!DILocation(line:7,column:2,scope:!0)"));
2243 let loc = module2.debug_location(12).expect("dilocation");
2244 assert_eq!(loc.line, 7);
2245 assert_eq!(loc.column, 2);
2246 }
2247}