@@ -531,9 +531,83 @@ static ParseResult parseLandingpadOp(OpAsmParser &parser,
531
531
}
532
532
533
533
// ===----------------------------------------------------------------------===//
534
- // Printing/parsing for LLVM::CallOp.
534
+ // Verifying/ Printing/parsing for LLVM::CallOp.
535
535
// ===----------------------------------------------------------------------===//
536
536
537
+ static LogicalResult verify (CallOp &op) {
538
+ if (op.getNumResults () > 1 )
539
+ return op.emitOpError (" must have 0 or 1 result" );
540
+
541
+ // Type for the callee, we'll get it differently depending if it is a direct
542
+ // or indirect call.
543
+ LLVMType fnType;
544
+
545
+ bool isIndirect = false ;
546
+
547
+ // If this is an indirect call, the callee attribute is missing.
548
+ Optional<StringRef> calleeName = op.callee ();
549
+ if (!calleeName) {
550
+ isIndirect = true ;
551
+ if (!op.getNumOperands ())
552
+ return op.emitOpError (
553
+ " must have either a `callee` attribute or at least an operand" );
554
+ fnType = op.getOperand (0 ).getType ().dyn_cast <LLVMType>();
555
+ if (!fnType)
556
+ return op.emitOpError (" indirect call to a non-llvm type: " )
557
+ << op.getOperand (0 ).getType ();
558
+ auto ptrType = fnType.dyn_cast <LLVMPointerType>();
559
+ if (!ptrType)
560
+ return op.emitOpError (" indirect call expects a pointer as callee: " )
561
+ << fnType;
562
+ fnType = ptrType.getElementType ();
563
+ } else {
564
+ Operation *callee = SymbolTable::lookupNearestSymbolFrom (op, *calleeName);
565
+ if (!callee)
566
+ return op.emitOpError ()
567
+ << " '" << *calleeName
568
+ << " ' does not reference a symbol in the current scope" ;
569
+ auto fn = dyn_cast<LLVMFuncOp>(callee);
570
+ if (!fn)
571
+ return op.emitOpError () << " '" << *calleeName
572
+ << " ' does not reference a valid LLVM function" ;
573
+
574
+ fnType = fn.getType ();
575
+ }
576
+ if (!fnType.isFunctionTy ())
577
+ return op.emitOpError (" callee does not have a functional type: " ) << fnType;
578
+
579
+ // Verify that the operand and result types match the callee.
580
+
581
+ if (!fnType.isFunctionVarArg () &&
582
+ fnType.getFunctionNumParams () != (op.getNumOperands () - isIndirect))
583
+ return op.emitOpError ()
584
+ << " incorrect number of operands ("
585
+ << (op.getNumOperands () - isIndirect)
586
+ << " ) for callee (expecting: " << fnType.getFunctionNumParams ()
587
+ << " )" ;
588
+
589
+ if (fnType.getFunctionNumParams () > (op.getNumOperands () - isIndirect))
590
+ return op.emitOpError () << " incorrect number of operands ("
591
+ << (op.getNumOperands () - isIndirect)
592
+ << " ) for varargs callee (expecting at least: "
593
+ << fnType.getFunctionNumParams () << " )" ;
594
+
595
+ for (unsigned i = 0 , e = fnType.getFunctionNumParams (); i != e; ++i)
596
+ if (op.getOperand (i + isIndirect).getType () !=
597
+ fnType.getFunctionParamType (i))
598
+ return op.emitOpError () << " operand type mismatch for operand " << i
599
+ << " : " << op.getOperand (i + isIndirect).getType ()
600
+ << " != " << fnType.getFunctionParamType (i);
601
+
602
+ if (op.getNumResults () &&
603
+ op.getResult (0 ).getType () != fnType.getFunctionResultType ())
604
+ return op.emitOpError ()
605
+ << " result type mismatch: " << op.getResult (0 ).getType ()
606
+ << " != " << fnType.getFunctionResultType ();
607
+
608
+ return success ();
609
+ }
610
+
537
611
static void printCallOp (OpAsmPrinter &p, CallOp &op) {
538
612
auto callee = op.callee ();
539
613
bool isDirect = callee.hasValue ();
0 commit comments