summaryrefslogtreecommitdiff
path: root/lib/VMCore
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-03-31 04:46:47 +0000
committerChris Lattner <sabre@nondot.org>2006-03-31 04:46:47 +0000
commit536a9d5ea54087f72a8f1e9f9b4c5fec80b3844b (patch)
treeb4181138f59e9769afdf05015317d8eecaeca9bf /lib/VMCore
parentc4d9b240b157efa9301d451ac44c12f6b004db8f (diff)
downloadllvm-536a9d5ea54087f72a8f1e9f9b4c5fec80b3844b.tar.gz
llvm-536a9d5ea54087f72a8f1e9f9b4c5fec80b3844b.tar.bz2
llvm-536a9d5ea54087f72a8f1e9f9b4c5fec80b3844b.tar.xz
Add a new method to verify intrinsic function prototypes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27282 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/Verifier.cpp62
1 files changed, 60 insertions, 2 deletions
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 0db7145421..f6fd236bd1 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -55,6 +55,7 @@
#include "llvm/Analysis/Dominators.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/InstVisitor.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>
#include <iostream>
@@ -196,6 +197,7 @@ namespace { // Anonymous namespace for class
void visitUserOp2(Instruction &I) { visitUserOp1(I); }
void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
+ void VerifyIntrinsicPrototype(Function *F, ...);
void WriteValue(const Value *V) {
if (!V) return;
@@ -436,8 +438,7 @@ void Verifier::visitSelectInst(SelectInst &SI) {
/// a pass, if any exist, it's an error.
///
void Verifier::visitUserOp1(Instruction &I) {
- Assert1(0, "User-defined operators should not live outside of a pass!",
- &I);
+ Assert1(0, "User-defined operators should not live outside of a pass!", &I);
}
/// visitPHINode - Ensure that a PHI node is well formed.
@@ -684,6 +685,63 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
#undef GET_INTRINSIC_VERIFIER
}
+/// VerifyIntrinsicPrototype - TableGen emits calls to this function into
+/// Intrinsics.gen. This implements a little state machine that verifies the
+/// prototype of intrinsics.
+void Verifier::VerifyIntrinsicPrototype(Function *F, ...) {
+ va_list VA;
+ va_start(VA, F);
+
+ const FunctionType *FTy = F->getFunctionType();
+
+ // Note that "arg#0" is the return type.
+ for (unsigned ArgNo = 0; 1; ++ArgNo) {
+ int TypeID = va_arg(VA, int);
+
+ if (TypeID == -1) {
+ if (ArgNo != FTy->getNumParams()+1)
+ CheckFailed("Intrinsic prototype has too many arguments!", F);
+ break;
+ }
+
+ if (ArgNo == FTy->getNumParams()+1) {
+ CheckFailed("Intrinsic prototype has too few arguments!", F);
+ break;
+ }
+
+ const Type *Ty;
+ if (ArgNo == 0)
+ Ty = FTy->getReturnType();
+ else
+ Ty = FTy->getParamType(ArgNo-1);
+
+ if (Ty->getTypeID() != TypeID) {
+ if (ArgNo == 0)
+ CheckFailed("Intrinsic prototype has incorrect result type!", F);
+ else
+ CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " is wrong!",F);
+ break;
+ }
+
+ // If this is a packed argument, verify the number and type of elements.
+ if (TypeID == Type::PackedTyID) {
+ const PackedType *PTy = cast<PackedType>(Ty);
+ if (va_arg(VA, int) != PTy->getElementType()->getTypeID()) {
+ CheckFailed("Intrinsic prototype has incorrect vector element type!",F);
+ break;
+ }
+
+ if ((unsigned)va_arg(VA, int) != PTy->getNumElements()) {
+ CheckFailed("Intrinsic prototype has incorrect number of "
+ "vector elements!",F);
+ break;
+ }
+ }
+ }
+
+ va_end(VA);
+}
+
//===----------------------------------------------------------------------===//
// Implement the public interfaces to this file...