+ Assert1(!FT->isStructReturn() ||
+ (FT->getReturnType() == Type::VoidTy &&
+ FT->getNumParams() > 0 && isa<PointerType>(FT->getParamType(0))),
+ "Invalid struct-return function!", &F);
+
+ if (const ParamAttrsList *Attrs = FT->getParamAttrs()) {
+ unsigned Idx = 1;
+
+ Assert1(!Attrs->paramHasAttr(0, ParamAttr::ByVal),
+ "Attribute ByVal should not apply to functions!", &F);
+ Assert1(!Attrs->paramHasAttr(0, ParamAttr::StructRet),
+ "Attribute SRet should not apply to functions!", &F);
+ Assert1(!Attrs->paramHasAttr(0, ParamAttr::InReg),
+ "Attribute InReg should not apply to functions!", &F);
+
+ for (FunctionType::param_iterator I = FT->param_begin(),
+ E = FT->param_end(); I != E; ++I, ++Idx) {
+ if (Attrs->paramHasAttr(Idx, ParamAttr::ZExt) ||
+ Attrs->paramHasAttr(Idx, ParamAttr::SExt))
+ Assert1(FT->getParamType(Idx-1)->isInteger(),
+ "Attribute ZExt should only apply to Integer type!", &F);
+ if (Attrs->paramHasAttr(Idx, ParamAttr::NoAlias))
+ Assert1(isa<PointerType>(FT->getParamType(Idx-1)),
+ "Attribute NoAlias should only apply to Pointer type!", &F);
+ if (Attrs->paramHasAttr(Idx, ParamAttr::ByVal)) {
+ Assert1(isa<PointerType>(FT->getParamType(Idx-1)),
+ "Attribute ByVal should only apply to pointer to structs!", &F);
+
+ Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::StructRet),
+ "Attributes ByVal and StructRet are incompatible!", &F);
+
+ const PointerType *Ty =
+ cast<PointerType>(FT->getParamType(Idx-1));
+ Assert1(isa<StructType>(Ty->getElementType()),
+ "Attribute ByVal should only apply to pointer to structs!", &F);
+ }
+
+ Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::NoReturn),
+ "Attribute NoReturn should only be applied to function", &F);
+ Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::NoUnwind),
+ "Attribute NoUnwind should only be applied to function", &F);
+ }
+ }
+