+ bool SawSRet = false;
+
+ if (const ParamAttrsList *Attrs = F.getParamAttrs()) {
+ Assert1(Attrs->size() &&
+ Attrs->getParamIndex(Attrs->size()-1) <= FT->getNumParams(),
+ "Function has excess attributes!", &F);
+
+ bool SawNest = false;
+
+ for (unsigned Idx = 0; Idx <= FT->getNumParams(); ++Idx) {
+ uint16_t Attr = Attrs->getParamAttrs(Idx);
+
+ if (!Idx) {
+ uint16_t RetI = Attr & ParamAttr::ParameterOnly;
+ Assert1(!RetI, "Attribute " + Attrs->getParamAttrsText(RetI) +
+ "should not apply to functions!", &F);
+ } else {
+ uint16_t ParmI = Attr & ParamAttr::ReturnOnly;
+ Assert1(!ParmI, "Attribute " + Attrs->getParamAttrsText(ParmI) +
+ "should only be applied to function!", &F);
+
+ }
+
+ for (unsigned i = 0;
+ i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) {
+ uint16_t MutI = Attr & ParamAttr::MutuallyIncompatible[i];
+ Assert1(!(MutI & (MutI - 1)), "Attributes " +
+ Attrs->getParamAttrsText(MutI) + "are incompatible!", &F);
+ }
+
+ uint16_t IType = Attr & ParamAttr::IntegerTypeOnly;
+ Assert1(!IType || FT->getParamType(Idx-1)->isInteger(),
+ "Attribute " + Attrs->getParamAttrsText(IType) +
+ "should only apply to Integer type!", &F);
+
+ uint16_t PType = Attr & ParamAttr::PointerTypeOnly;
+ Assert1(!PType || isa<PointerType>(FT->getParamType(Idx-1)),
+ "Attribute " + Attrs->getParamAttrsText(PType) +
+ "should only apply to Pointer type!", &F);
+
+ if (Attr & ParamAttr::ByVal) {
+ const PointerType *Ty =
+ dyn_cast<PointerType>(FT->getParamType(Idx-1));
+ Assert1(!Ty || isa<StructType>(Ty->getElementType()),
+ "Attribute byval should only apply to pointer to structs!", &F);
+ }
+
+ if (Attr & ParamAttr::Nest) {
+ Assert1(!SawNest, "More than one parameter has attribute nest!", &F);
+ SawNest = true;
+ }
+
+ if (Attr & ParamAttr::StructRet) {
+ SawSRet = true;
+ Assert1(Idx == 1, "Attribute sret not on first parameter!", &F);
+ }
+ }
+ }
+
+ Assert1(SawSRet == F.isStructReturn(),
+ "StructReturn function with no sret attribute!", &F);
+