diff options
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 50 | ||||
-rw-r--r-- | lib/VMCore/AutoUpgrade.cpp | 18 | ||||
-rw-r--r-- | lib/VMCore/Function.cpp | 37 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 79 | ||||
-rw-r--r-- | lib/VMCore/ParameterAttributes.cpp | 343 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 125 |
6 files changed, 322 insertions, 330 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 438bdad..aba66c8 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -20,7 +20,6 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/ParamAttrsList.h" #include "llvm/InlineAsm.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" @@ -849,7 +848,7 @@ void AssemblyWriter::writeParamOperand(const Value *Operand, printType(Operand->getType()); // Print parameter attributes list if (Attrs != ParamAttr::None) - Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs); + Out << ' ' << ParamAttr::getAsString(Attrs); // Print the operand WriteAsOperandInternal(Out, Operand, TypeNames, &Machine); } @@ -1074,7 +1073,7 @@ void AssemblyWriter::printFunction(const Function *F) { } const FunctionType *FT = F->getFunctionType(); - const ParamAttrsList *Attrs = F->getParamAttrs(); + const PAListPtr &Attrs = F->getParamAttrs(); printType(F->getReturnType()) << ' '; if (!F->getName().empty()) Out << getLLVMName(F->getName(), GlobalPrefix); @@ -1092,8 +1091,7 @@ void AssemblyWriter::printFunction(const Function *F) { I != E; ++I) { // Insert commas as we go... the first arg doesn't get a comma if (I != F->arg_begin()) Out << ", "; - printArgument(I, (Attrs ? Attrs->getParamAttrs(Idx) - : ParamAttr::None)); + printArgument(I, Attrs.getParamAttrs(Idx)); Idx++; } } else { @@ -1105,10 +1103,9 @@ void AssemblyWriter::printFunction(const Function *F) { // Output type... printType(FT->getParamType(i)); - ParameterAttributes ArgAttrs = ParamAttr::None; - if (Attrs) ArgAttrs = Attrs->getParamAttrs(i+1); + ParameterAttributes ArgAttrs = Attrs.getParamAttrs(i+1); if (ArgAttrs != ParamAttr::None) - Out << ' ' << ParamAttrsList::getParamAttrsText(ArgAttrs); + Out << ' ' << ParamAttr::getAsString(ArgAttrs); } } @@ -1118,8 +1115,9 @@ void AssemblyWriter::printFunction(const Function *F) { Out << "..."; // Output varargs portion of signature! } Out << ')'; - if (Attrs && Attrs->getParamAttrs(0) != ParamAttr::None) - Out << ' ' << Attrs->getParamAttrsTextByIndex(0); + ParameterAttributes RetAttrs = Attrs.getParamAttrs(0); + if (RetAttrs != ParamAttr::None) + Out << ' ' << ParamAttr::getAsString(Attrs.getParamAttrs(0)); if (F->hasSection()) Out << " section \"" << F->getSection() << '"'; if (F->getAlignment()) @@ -1152,7 +1150,7 @@ void AssemblyWriter::printArgument(const Argument *Arg, // Output parameter attributes list if (Attrs != ParamAttr::None) - Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs); + Out << ' ' << ParamAttr::getAsString(Attrs); // Output name, if available... if (Arg->hasName()) @@ -1321,7 +1319,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { const PointerType *PTy = cast<PointerType>(Operand->getType()); const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); - const ParamAttrsList *PAL = CI->getParamAttrs(); + const PAListPtr &PAL = CI->getParamAttrs(); // If possible, print out the short form of the call instruction. We can // only do this if the first argument is a pointer to a nonvararg function, @@ -1339,17 +1337,16 @@ void AssemblyWriter::printInstruction(const Instruction &I) { for (unsigned op = 1, Eop = I.getNumOperands(); op < Eop; ++op) { if (op > 1) Out << ','; - writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op) : - ParamAttr::None); + writeParamOperand(I.getOperand(op), PAL.getParamAttrs(op)); } Out << " )"; - if (PAL && PAL->getParamAttrs(0) != ParamAttr::None) - Out << ' ' << PAL->getParamAttrsTextByIndex(0); + if (PAL.getParamAttrs(0) != ParamAttr::None) + Out << ' ' << ParamAttr::getAsString(PAL.getParamAttrs(0)); } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) { const PointerType *PTy = cast<PointerType>(Operand->getType()); const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); - const ParamAttrsList *PAL = II->getParamAttrs(); + const PAListPtr &PAL = II->getParamAttrs(); // Print the calling convention being used. switch (II->getCallingConv()) { @@ -1378,13 +1375,12 @@ void AssemblyWriter::printInstruction(const Instruction &I) { for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) { if (op > 3) Out << ','; - writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op-2) : - ParamAttr::None); + writeParamOperand(I.getOperand(op), PAL.getParamAttrs(op-2)); } Out << " )"; - if (PAL && PAL->getParamAttrs(0) != ParamAttr::None) - Out << " " << PAL->getParamAttrsTextByIndex(0); + if (PAL.getParamAttrs(0) != ParamAttr::None) + Out << " " << ParamAttr::getAsString(PAL.getParamAttrs(0)); Out << "\n\t\t\tto"; writeOperand(II->getNormalDest(), true); Out << " unwind"; @@ -1529,18 +1525,6 @@ void Value::dump() const { print(*cerr.stream()); cerr << '\n'; } // Located here because so much of the needed functionality is here. void Type::dump() const { print(*cerr.stream()); cerr << '\n'; } -void -ParamAttrsList::dump() const { - cerr << "PAL[ "; - for (unsigned i = 0; i < attrs.size(); ++i) { - uint16_t index = getParamIndex(i); - ParameterAttributes attrs = getParamAttrs(index); - cerr << "{" << index << "," << attrs << "} "; - } - - cerr << "]\n"; -} - //===----------------------------------------------------------------------===// // SlotMachine Implementation //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index f322e69..343a4b6 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -17,7 +17,7 @@ #include "llvm/Module.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" -#include "llvm/ParamAttrsList.h" +#include "llvm/ADT/SmallVector.h" #include <cstring> using namespace llvm; @@ -226,18 +226,18 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { case Intrinsic::x86_mmx_psrl_d: case Intrinsic::x86_mmx_psrl_q: case Intrinsic::x86_mmx_psrl_w: { - SmallVector<Value*, 2> Operands; + Value *Operands[2]; - Operands.push_back(CI->getOperand(1)); + Operands[0] = CI->getOperand(1); // Cast the second parameter to the correct type. BitCastInst *BC = new BitCastInst(CI->getOperand(2), NewFn->getFunctionType()->getParamType(1), "upgraded", CI); - Operands.push_back(BC); + Operands[1] = BC; // Construct a new CallInst - CallInst *NewCI = new CallInst(NewFn, Operands.begin(), Operands.end(), + CallInst *NewCI = new CallInst(NewFn, Operands, Operands+2, "upgraded."+CI->getName(), CI); NewCI->setTailCall(CI->isTailCall()); NewCI->setCallingConv(CI->getCallingConv()); @@ -257,7 +257,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { case Intrinsic::cttz: // Build a small vector of the 1..(N-1) operands, which are the // parameters. - SmallVector<Value*, 8> Operands(CI->op_begin()+1, CI->op_end()); + SmallVector<Value*, 8> Operands(CI->op_begin()+1, CI->op_end()); // Construct a new CallInst CallInst *NewCI = new CallInst(NewFn, Operands.begin(), Operands.end(), @@ -268,10 +268,8 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { // Handle any uses of the old CallInst. if (!CI->use_empty()) { // Check for sign extend parameter attributes on the return values. - bool SrcSExt = NewFn->getParamAttrs() && - NewFn->getParamAttrs()->paramHasAttr(0,ParamAttr::SExt); - bool DestSExt = F->getParamAttrs() && - F->getParamAttrs()->paramHasAttr(0,ParamAttr::SExt); + bool SrcSExt = NewFn->getParamAttrs().paramHasAttr(0, ParamAttr::SExt); + bool DestSExt = F->getParamAttrs().paramHasAttr(0, ParamAttr::SExt); // Construct an appropriate cast from the new return type to the old. CastInst *RetCast = CastInst::create( diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index f5712e7..5a69c09 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -14,7 +14,6 @@ #include "llvm/Module.h" #include "llvm/DerivedTypes.h" #include "llvm/IntrinsicInst.h" -#include "llvm/ParamAttrsList.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/StringPool.h" @@ -140,12 +139,12 @@ void Function::eraseFromParent() { /// @brief Determine whether the function has the given attribute. bool Function::paramHasAttr(uint16_t i, ParameterAttributes attr) const { - return ParamAttrs && ParamAttrs->paramHasAttr(i, attr); + return ParamAttrs.paramHasAttr(i, attr); } /// @brief Extract the alignment for a call or parameter (0=unknown). uint16_t Function::getParamAlignment(uint16_t i) const { - return ParamAttrs ? ParamAttrs->getParamAlignment(i) : 0; + return ParamAttrs.getParamAlignment(i); } /// @brief Determine if the function cannot return. @@ -181,8 +180,7 @@ bool Function::hasStructRetAttr() const { Function::Function(const FunctionType *Ty, LinkageTypes Linkage, const std::string &name, Module *ParentModule) : GlobalValue(PointerType::getUnqual(Ty), - Value::FunctionVal, 0, 0, Linkage, name), - ParamAttrs(0) { + Value::FunctionVal, 0, 0, Linkage, name) { SymTab = new ValueSymbolTable(); assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy @@ -207,10 +205,6 @@ Function::~Function() { ArgumentList.clear(); delete SymTab; - // Drop our reference to the parameter attributes, if any. - if (ParamAttrs) - ParamAttrs->dropRef(); - // Remove the function from the on-the-side collector table. clearCollector(); } @@ -243,24 +237,6 @@ void Function::setParent(Module *parent) { LeakDetector::removeGarbageObject(this); } -void Function::setParamAttrs(const ParamAttrsList *attrs) { - // Avoid deleting the ParamAttrsList if they are setting the - // attributes to the same list. - if (ParamAttrs == attrs) - return; - - // Drop reference on the old ParamAttrsList - if (ParamAttrs) - ParamAttrs->dropRef(); - - // Add reference to the new ParamAttrsList - if (attrs) - attrs->addRef(); - - // Set the new ParamAttrsList. - ParamAttrs = attrs; -} - // dropAllReferences() - This function causes all the subinstructions to "let // go" of all references that they are maintaining. This allows one to // 'delete' a whole class at a time, even though there may be circular @@ -370,8 +346,7 @@ const FunctionType *Intrinsic::getType(ID id, const Type **Tys, return FunctionType::get(ResultTy, ArgTys, IsVarArg); } -const ParamAttrsList *Intrinsic::getParamAttrs(ID id) { - ParamAttrsVector Attrs; +PAListPtr Intrinsic::getParamAttrs(ID id) { ParameterAttributes Attr = ParamAttr::None; #define GET_INTRINSIC_ATTRIBUTES @@ -381,8 +356,8 @@ const ParamAttrsList *Intrinsic::getParamAttrs(ID id) { // Intrinsics cannot throw exceptions. Attr |= ParamAttr::NoUnwind; - Attrs.push_back(ParamAttrsWithIndex::get(0, Attr)); - return ParamAttrsList::get(Attrs); + ParamAttrsWithIndex PAWI = ParamAttrsWithIndex::get(0, Attr); + return PAListPtr::get(&PAWI, 1); } Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys, diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index f7401ec..ee9a02e 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -17,7 +17,6 @@ #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/Instructions.h" -#include "llvm/ParamAttrsList.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/ConstantRange.h" #include "llvm/Support/MathExtras.h" @@ -43,13 +42,13 @@ void CallSite::setCallingConv(unsigned CC) { else cast<InvokeInst>(I)->setCallingConv(CC); } -const ParamAttrsList* CallSite::getParamAttrs() const { +const PAListPtr &CallSite::getParamAttrs() const { if (CallInst *CI = dyn_cast<CallInst>(I)) return CI->getParamAttrs(); else return cast<InvokeInst>(I)->getParamAttrs(); } -void CallSite::setParamAttrs(const ParamAttrsList *PAL) { +void CallSite::setParamAttrs(const PAListPtr &PAL) { if (CallInst *CI = dyn_cast<CallInst>(I)) CI->setParamAttrs(PAL); else @@ -243,12 +242,9 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const { CallInst::~CallInst() { delete [] OperandList; - if (ParamAttrs) - ParamAttrs->dropRef(); } void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { - ParamAttrs = 0; NumOperands = NumParams+1; Use *OL = OperandList = new Use[NumParams+1]; OL[0].init(Func, this); @@ -269,7 +265,6 @@ void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { } void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) { - ParamAttrs = 0; NumOperands = 3; Use *OL = OperandList = new Use[3]; OL[0].init(Func, this); @@ -292,7 +287,6 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) { } void CallInst::init(Value *Func, Value *Actual) { - ParamAttrs = 0; NumOperands = 2; Use *OL = OperandList = new Use[2]; OL[0].init(Func, this); @@ -311,7 +305,6 @@ void CallInst::init(Value *Func, Value *Actual) { } void CallInst::init(Value *Func) { - ParamAttrs = 0; NumOperands = 1; Use *OL = OperandList = new Use[1]; OL[0].init(Func, this); @@ -360,8 +353,7 @@ CallInst::CallInst(Value *Func, const std::string &Name, CallInst::CallInst(const CallInst &CI) : Instruction(CI.getType(), Instruction::Call, new Use[CI.getNumOperands()], - CI.getNumOperands()), - ParamAttrs(0) { + CI.getNumOperands()) { setParamAttrs(CI.getParamAttrs()); SubclassData = CI.SubclassData; Use *OL = OperandList; @@ -370,21 +362,8 @@ CallInst::CallInst(const CallInst &CI) OL[i].init(InOL[i], this); } -void CallInst::setParamAttrs(const ParamAttrsList *newAttrs) { - if (ParamAttrs == newAttrs) - return; - - if (ParamAttrs) - ParamAttrs->dropRef(); - - if (newAttrs) - newAttrs->addRef(); - - ParamAttrs = newAttrs; -} - bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const { - if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr)) + if (ParamAttrs.paramHasAttr(i, attr)) return true; if (const Function *F = getCalledFunction()) return F->paramHasAttr(i, attr); @@ -392,11 +371,7 @@ bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const { } uint16_t CallInst::getParamAlignment(uint16_t i) const { - if (ParamAttrs && ParamAttrs->getParamAlignment(i)) - return ParamAttrs->getParamAlignment(i); - if (const Function *F = getCalledFunction()) - return F->getParamAlignment(i); - return 0; + return ParamAttrs.getParamAlignment(i); } /// @brief Determine if the call does not access memory. @@ -428,21 +403,20 @@ bool CallInst::hasStructRetAttr() const { /// @brief Determine if any call argument is an aggregate passed by value. bool CallInst::hasByValArgument() const { - if (ParamAttrs && ParamAttrs->hasAttrSomewhere(ParamAttr::ByVal)) + if (ParamAttrs.hasAttrSomewhere(ParamAttr::ByVal)) return true; // Be consistent with other methods and check the callee too. if (const Function *F = getCalledFunction()) - if (const ParamAttrsList *PAL = F->getParamAttrs()) - return PAL->hasAttrSomewhere(ParamAttr::ByVal); + return F->getParamAttrs().hasAttrSomewhere(ParamAttr::ByVal); return false; } void CallInst::setDoesNotThrow(bool doesNotThrow) { - const ParamAttrsList *PAL = getParamAttrs(); + PAListPtr PAL = getParamAttrs(); if (doesNotThrow) - PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind); + PAL = PAL.addAttr(0, ParamAttr::NoUnwind); else - PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind); + PAL = PAL.removeAttr(0, ParamAttr::NoUnwind); setParamAttrs(PAL); } @@ -453,13 +427,10 @@ void CallInst::setDoesNotThrow(bool doesNotThrow) { InvokeInst::~InvokeInst() { delete [] OperandList; - if (ParamAttrs) - ParamAttrs->dropRef(); } void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, Value* const *Args, unsigned NumArgs) { - ParamAttrs = 0; NumOperands = 3+NumArgs; Use *OL = OperandList = new Use[3+NumArgs]; OL[0].init(Fn, this); @@ -484,8 +455,7 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, InvokeInst::InvokeInst(const InvokeInst &II) : TerminatorInst(II.getType(), Instruction::Invoke, - new Use[II.getNumOperands()], II.getNumOperands()), - ParamAttrs(0) { + new Use[II.getNumOperands()], II.getNumOperands()) { setParamAttrs(II.getParamAttrs()); SubclassData = II.SubclassData; Use *OL = OperandList, *InOL = II.OperandList; @@ -503,21 +473,8 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) { return setSuccessor(idx, B); } -void InvokeInst::setParamAttrs(const ParamAttrsList *newAttrs) { - if (ParamAttrs == newAttrs) - return; - - if (ParamAttrs) - ParamAttrs->dropRef(); - - if (newAttrs) - newAttrs->addRef(); - - ParamAttrs = newAttrs; -} - bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const { - if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr)) + if (ParamAttrs.paramHasAttr(i, attr)) return true; if (const Function *F = getCalledFunction()) return F->paramHasAttr(i, attr); @@ -525,11 +482,7 @@ bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const { } uint16_t InvokeInst::getParamAlignment(uint16_t i) const { - if (ParamAttrs && ParamAttrs->getParamAlignment(i)) - return ParamAttrs->getParamAlignment(i); - if (const Function *F = getCalledFunction()) - return F->getParamAlignment(i); - return 0; + return ParamAttrs.getParamAlignment(i); } /// @brief Determine if the call does not access memory. @@ -553,11 +506,11 @@ bool InvokeInst::doesNotThrow() const { } void InvokeInst::setDoesNotThrow(bool doesNotThrow) { - const ParamAttrsList *PAL = getParamAttrs(); + PAListPtr PAL = getParamAttrs(); if (doesNotThrow) - PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind); + PAL = PAL.addAttr(0, ParamAttr::NoUnwind); else - PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind); + PAL = PAL.removeAttr(0, ParamAttr::NoUnwind); setParamAttrs(PAL); } diff --git a/lib/VMCore/ParameterAttributes.cpp b/lib/VMCore/ParameterAttributes.cpp index bebee3e..7501a35 100644 --- a/lib/VMCore/ParameterAttributes.cpp +++ b/lib/VMCore/ParameterAttributes.cpp @@ -11,41 +11,19 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ParamAttrsList.h" -#include "llvm/DerivedTypes.h" +#include "llvm/ParameterAttributes.h" +#include "llvm/Type.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/Streams.h" #include "llvm/Support/ManagedStatic.h" - using namespace llvm; -static ManagedStatic<FoldingSet<ParamAttrsList> > ParamAttrsLists; - -ParamAttrsList::ParamAttrsList(const ParamAttrsVector &attrVec) - : attrs(attrVec), refCount(0) { -} - -ParamAttrsList::~ParamAttrsList() { - ParamAttrsLists->RemoveNode(this); -} - -ParameterAttributes -ParamAttrsList::getParamAttrs(uint16_t Index) const { - unsigned limit = attrs.size(); - for (unsigned i = 0; i < limit && attrs[i].index <= Index; ++i) - if (attrs[i].index == Index) - return attrs[i].attrs; - return ParamAttr::None; -} - -bool ParamAttrsList::hasAttrSomewhere(ParameterAttributes attr) const { - for (unsigned i = 0, e = attrs.size(); i < e; ++i) - if (attrs[i].attrs & attr) - return true; - return false; -} +//===----------------------------------------------------------------------===// +// ParamAttr Function Definitions +//===----------------------------------------------------------------------===// -std::string -ParamAttrsList::getParamAttrsText(ParameterAttributes Attrs) { +std::string ParamAttr::getAsString(ParameterAttributes Attrs) { std::string Result; if (Attrs & ParamAttr::ZExt) Result += "zeroext "; @@ -77,155 +55,240 @@ ParamAttrsList::getParamAttrsText(ParameterAttributes Attrs) { return Result; } -void ParamAttrsList::Profile(FoldingSetNodeID &ID, - const ParamAttrsVector &Attrs) { - for (unsigned i = 0; i < Attrs.size(); ++i) - ID.AddInteger(uint64_t(Attrs[i].attrs) << 16 | unsigned(Attrs[i].index)); +ParameterAttributes ParamAttr::typeIncompatible(const Type *Ty) { + ParameterAttributes Incompatible = None; + + if (!Ty->isInteger()) + // Attributes that only apply to integers. + Incompatible |= SExt | ZExt; + + if (!isa<PointerType>(Ty)) + // Attributes that only apply to pointers. + Incompatible |= ByVal | Nest | NoAlias | StructRet; + + return Incompatible; } -const ParamAttrsList * -ParamAttrsList::get(const ParamAttrsVector &attrVec) { - // If there are no attributes then return a null ParamAttrsList pointer. - if (attrVec.empty()) - return 0; +//===----------------------------------------------------------------------===// +// ParamAttributeListImpl Definition +//===----------------------------------------------------------------------===// + +namespace llvm { +class ParamAttributeListImpl : public FoldingSetNode { + unsigned RefCount; + + // ParamAttrsList is uniqued, these should not be publicly available + void operator=(const ParamAttributeListImpl &); // Do not implement + ParamAttributeListImpl(const ParamAttributeListImpl &); // Do not implement + ~ParamAttributeListImpl(); // Private implementation +public: + SmallVector<ParamAttrsWithIndex, 4> Attrs; + + ParamAttributeListImpl(const ParamAttrsWithIndex *Attr, unsigned NumAttrs) + : Attrs(Attr, Attr+NumAttrs) { + RefCount = 0; + } + + void AddRef() { ++RefCount; } + void DropRef() { if (--RefCount == 0) delete this; } + + void Profile(FoldingSetNodeID &ID) const { + Profile(ID, &Attrs[0], Attrs.size()); + } + static void Profile(FoldingSetNodeID &ID, const ParamAttrsWithIndex *Attr, + unsigned NumAttrs) { + for (unsigned i = 0; i != NumAttrs; ++i) + ID.AddInteger(uint64_t(Attr[i].Attrs) << 32 | unsigned(Attr[i].Index)); + } +}; +} +static ManagedStatic<FoldingSet<ParamAttributeListImpl> > ParamAttrsLists; + +ParamAttributeListImpl::~ParamAttributeListImpl() { + ParamAttrsLists->RemoveNode(this); +} + + +PAListPtr PAListPtr::get(const ParamAttrsWithIndex *Attrs, unsigned NumAttrs) { + // If there are no attributes then return a null ParamAttrsList pointer. + if (NumAttrs == 0) + return PAListPtr(); + #ifndef NDEBUG - for (unsigned i = 0, e = attrVec.size(); i < e; ++i) { - assert(attrVec[i].attrs != ParamAttr::None - && "Pointless parameter attribute!"); - assert((!i || attrVec[i-1].index < attrVec[i].index) - && "Misordered ParamAttrsList!"); + for (unsigned i = 0; i != NumAttrs; ++i) { + assert(Attrs[i].Attrs != ParamAttr::None && + "Pointless parameter attribute!"); + assert((!i || Attrs[i-1].Index < Attrs[i].Index) && + "Misordered ParamAttrsList!"); } #endif - + // Otherwise, build a key to look up the existing attributes. FoldingSetNodeID ID; - ParamAttrsList::Profile(ID, attrVec); + ParamAttributeListImpl::Profile(ID, Attrs, NumAttrs); void *InsertPos; - ParamAttrsList *PAL = ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos); - + ParamAttributeListImpl *PAL = + ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos); + // If we didn't find any existing attributes of the same shape then // create a new one and insert it. if (!PAL) { - PAL = new ParamAttrsList(attrVec); + PAL = new ParamAttributeListImpl(Attrs, NumAttrs); ParamAttrsLists->InsertNode(PAL, InsertPos); } - + // Return the ParamAttrsList that we found or created. - return PAL; + return PAListPtr(PAL); } -const ParamAttrsList * -ParamAttrsList::getModified(const ParamAttrsList *PAL, - const ParamAttrsVector &modVec) { - if (modVec.empty()) - return PAL; -#ifndef NDEBUG - for (unsigned i = 0, e = modVec.size(); i < e; ++i) - assert((!i || modVec[i-1].index < modVec[i].index) - && "Misordered ParamAttrsList!"); -#endif +//===----------------------------------------------------------------------===// +// PAListPtr Method Implementations +//===----------------------------------------------------------------------===// - if (!PAL) { - // Strip any instances of ParamAttr::None from modVec before calling 'get'. - ParamAttrsVector newVec; - newVec.reserve(modVec.size()); - for (unsigned i = 0, e = modVec.size(); i < e; ++i) - if (modVec[i].attrs != ParamAttr::None) - newVec.push_back(modVec[i]); - return get(newVec); - } +PAListPtr::PAListPtr(ParamAttributeListImpl *LI) : PAList(LI) { + if (LI) LI->AddRef(); +} - const ParamAttrsVector &oldVec = PAL->attrs; - - ParamAttrsVector newVec; - unsigned oldI = 0; - unsigned modI = 0; - unsigned oldE = oldVec.size(); - unsigned modE = modVec.size(); - - while (oldI < oldE && modI < modE) { - uint16_t oldIndex = oldVec[oldI].index; - uint16_t modIndex = modVec[modI].index; - - if (oldIndex < modIndex) { - newVec.push_back(oldVec[oldI]); - ++oldI; - } else if (modIndex < oldIndex) { - if (modVec[modI].attrs != ParamAttr::None) - newVec.push_back(modVec[modI]); - ++modI; - } else { - // Same index - overwrite or delete existing attributes. - if (modVec[modI].attrs != ParamAttr::None) - newVec.push_back(modVec[modI]); - ++oldI; - ++modI; - } - } +PAListPtr::PAListPtr(const PAListPtr &P) : PAList(P.PAList) { + if (PAList) PAList->AddRef(); +} + +const PAListPtr &PAListPtr::operator=(const PAListPtr &RHS) { + if (PAList == RHS.PAList) return *this; + if (PAList) PAList->DropRef(); + PAList = RHS.PAList; + if (PAList) PAList->AddRef(); + return *this; +} + +PAListPtr::~PAListPtr() { + if (PAList) PAList->DropRef(); +} + +/// getNumSlots - Return the number of slots used in this attribute list. +/// This is the number of arguments that have an attribute set on them +/// (including the function itself). +unsigned PAListPtr::getNumSlots() const { + return PAList ? PAList->Attrs.size() : 0; +} - for (; oldI < oldE; ++oldI) - newVec.push_back(oldVec[oldI]); - for (; modI < modE; ++modI) - if (modVec[modI].attrs != ParamAttr::None) - newVec.push_back(modVec[modI]); +/// getSlot - Return the ParamAttrsWithIndex at the specified slot. This +/// holds a parameter number plus a set of attributes. +const ParamAttrsWithIndex &PAListPtr::getSlot(unsigned Slot) const { + assert(PAList && Slot < PAList->Attrs.size() && "Slot # out of range!"); + return PAList->Attrs[Slot]; +} + + +/// getParamAttrs - The parameter attributes for the specified parameter are +/// returned. Parameters for the result are denoted with Idx = 0. +ParameterAttributes PAListPtr::getParamAttrs(unsigned Idx) const { + if (PAList == 0) return ParamAttr::None; + + const SmallVector<ParamAttrsWithIndex, 4> &Attrs = PAList->Attrs; + for (unsigned i = 0, e = Attrs.size(); i != e && Attrs[i].Index <= Idx; ++i) + if (Attrs[i].Index == Idx) + return Attrs[i].Attrs; + return ParamAttr::None; +} - return get(newVec); +/// hasAttrSomewhere - Return true if the specified attribute is set for at +/// least one parameter or for the return value. +bool PAListPtr::hasAttrSomewhere(ParameterAttributes Attr) const { + if (PAList == 0) return false; + + const SmallVector<ParamAttrsWithIndex, 4> &Attrs = PAList->Attrs; + for (unsigned i = 0, e = Attrs.size(); i != e; ++i) + if (Attrs[i].Attrs & Attr) + return true; + return false; } -const ParamAttrsList * -ParamAttrsList::includeAttrs(const ParamAttrsList *PAL, - uint16_t idx, ParameterAttributes attrs) { - ParameterAttributes OldAttrs = PAL ? PAL->getParamAttrs(idx) : - ParamAttr::None; + +PAListPtr PAListPtr::addAttr(unsigned Idx, ParameterAttributes Attrs) const { + ParameterAttributes OldAttrs = getParamAttrs(Idx); #ifndef NDEBUG // FIXME it is not obvious how this should work for alignment. // For now, say we can't change a known alignment. ParameterAttributes OldAlign = OldAttrs & ParamAttr::Alignment; - ParameterAttributes NewAlign = attrs & ParamAttr::Alignment; + ParameterAttributes NewAlign = Attrs & ParamAttr::Alignment; assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && "Attempt to change alignment!"); #endif - - ParameterAttributes NewAttrs = OldAttrs | attrs; + + ParameterAttributes NewAttrs = OldAttrs | Attrs; if (NewAttrs == OldAttrs) - return PAL; - - ParamAttrsVector modVec(1); - modVec[0] = ParamAttrsWithIndex::get(idx, NewAttrs); - return getModified(PAL, modVec); + return *this; + + SmallVector<ParamAttrsWithIndex, 8> NewAttrList; + if (PAList == 0) + NewAttrList.push_back(ParamAttrsWithIndex::get(Idx, Attrs)); + else { + const SmallVector<ParamAttrsWithIndex, 4> &OldAttrList = PAList->Attrs; + unsigned i = 0, e = OldAttrList.size(); + // Copy attributes for arguments before this one. + for (; i != e && OldAttrList[i].Index < Idx; ++i) + NewAttrList.push_back(OldAttrList[i]); + + // If there are attributes already at this index, merge them in. + if (i != e && OldAttrList[i].Index == Idx) { + Attrs |= OldAttrList[i].Attrs; + ++i; + } + + NewAttrList.push_back(ParamAttrsWithIndex::get(Idx, Attrs)); + + // Copy attributes for arguments after this one. + NewAttrList.insert(NewAttrList.end(), + OldAttrList.begin()+i, OldAttrList.end()); + } + + return get(&NewAttrList[0], NewAttrList.size()); } -const ParamAttrsList * -ParamAttrsList::excludeAttrs(const ParamAttrsList *PAL, - uint16_t idx, ParameterAttributes attrs) { +PAListPtr PAListPtr::removeAttr(unsigned Idx, ParameterAttributes Attrs) const { #ifndef NDEBUG // FIXME it is not obvious how this should work for alignment. // For now, say we can't pass in alignment, which no current use does. - assert(!(attrs & ParamAttr::Alignment) && "Attempt to exclude alignment!"); + assert(!(Attrs & ParamAttr::Alignment) && "Attempt to exclude alignment!"); #endif - ParameterAttributes OldAttrs = PAL ? PAL->getParamAttrs(idx) : - ParamAttr::None; - ParameterAttributes NewAttrs = OldAttrs & ~attrs; + if (PAList == 0) return PAListPtr(); + + ParameterAttributes OldAttrs = getParamAttrs(Idx); + ParameterAttributes NewAttrs = OldAttrs & ~Attrs; if (NewAttrs == OldAttrs) - return PAL; - - ParamAttrsVector modVec(1); - modVec[0] = ParamAttrsWithIndex::get(idx, NewAttrs); - return getModified(PAL, modVec); + return *this; + + SmallVector<ParamAttrsWithIndex, 8> NewAttrList; + const SmallVector<ParamAttrsWithIndex, 4> &OldAttrList = PAList->Attrs; + unsigned i = 0, e = OldAttrList.size(); + + // Copy attributes for arguments before this one. + for (; i != e && OldAttrList[i].Index < Idx; ++i) + NewAttrList.push_back(OldAttrList[i]); + + // If there are attributes already at this index, merge them in. + assert(OldAttrList[i].Index == Idx && "Attribute isn't set?"); + Attrs = OldAttrList[i].Attrs & ~Attrs; + ++i; + if (Attrs) // If any attributes left for this parameter, add them. + NewAttrList.push_back(ParamAttrsWithIndex::get(Idx, Attrs)); + + // Copy attributes for arguments after this one. + NewAttrList.insert(NewAttrList.end(), + OldAttrList.begin()+i, OldAttrList.end()); + + return get(&NewAttrList[0], NewAttrList.size()); } -ParameterAttributes ParamAttr::typeIncompatible (const Type *Ty) { - ParameterAttributes Incompatible = None; - - if (!Ty->isInteger()) - // Attributes that only apply to integers. - Incompatible |= SExt | ZExt; - - if (!isa<PointerType>(Ty)) - // Attributes that only apply to pointers. - Incompatible |= ByVal | Nest | NoAlias | StructRet; - - return Incompatible; +void PAListPtr::dump() const { + cerr << "PAL[ "; + for (unsigned i = 0; i < getNumSlots(); ++i) { + const ParamAttrsWithIndex &PAWI = getSlot(i); + cerr << "{" << PAWI.Index << "," << PAWI.Attrs << "} "; + } + + cerr << "]\n"; } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 01a4a94..6126253 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -40,18 +40,17 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/Verifier.h" -#include "llvm/Assembly/Writer.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" -#include "llvm/Pass.h" -#include "llvm/Module.h" -#include "llvm/ModuleProvider.h" -#include "llvm/ParamAttrsList.h" #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/IntrinsicInst.h" +#include "llvm/Module.h" +#include "llvm/ModuleProvider.h" +#include "llvm/Pass.h" #include "llvm/PassManager.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/CFG.h" @@ -264,7 +263,7 @@ namespace { // Anonymous namespace for class unsigned Count, ...); void VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, bool isReturnValue, const Value *V); - void VerifyFunctionAttrs(const FunctionType *FT, const ParamAttrsList *Attrs, + void VerifyFunctionAttrs(const FunctionType *FT, const PAListPtr &Attrs, const Value *V); void WriteValue(const Value *V) { @@ -394,11 +393,11 @@ void Verifier::VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, if (isReturnValue) { ParameterAttributes RetI = Attrs & ParamAttr::ParameterOnly; - Assert1(!RetI, "Attribute " + ParamAttrsList::getParamAttrsText(RetI) + + Assert1(!RetI, "Attribute " + ParamAttr::getAsString(RetI) + "does not apply to return values!", V); } else { ParameterAttributes ParmI = Attrs & ParamAttr::ReturnOnly; - Assert1(!ParmI, "Attribute " + ParamAttrsList::getParamAttrsText(ParmI) + + Assert1(!ParmI, "Attribute " + ParamAttr::getAsString(ParmI) + "only applies to return values!", V); } @@ -406,37 +405,44 @@ void Verifier::VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) { ParameterAttributes MutI = Attrs & ParamAttr::MutuallyIncompatible[i]; Assert1(!(MutI & (MutI - 1)), "Attributes " + - ParamAttrsList::getParamAttrsText(MutI) + "are incompatible!", V); + ParamAttr::getAsString(MutI) + "are incompatible!", V); } ParameterAttributes TypeI = Attrs & ParamAttr::typeIncompatible(Ty); Assert1(!TypeI, "Wrong type for attribute " + - ParamAttrsList::getParamAttrsText(TypeI), V); + ParamAttr::getAsString(TypeI), V); } // VerifyFunctionAttrs - Check parameter attributes against a function type. // The value V is printed in error messages. void Verifier::VerifyFunctionAttrs(const FunctionType *FT, - const ParamAttrsList *Attrs, + const PAListPtr &Attrs, const Value *V) { - if (!Attrs) + if (Attrs.isEmpty()) return; bool SawNest = false; - for (unsigned Idx = 0; Idx <= FT->getNumParams(); ++Idx) { - ParameterAttributes Attr = Attrs->getParamAttrs(Idx); + for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) { + const ParamAttrsWithIndex &Attr = Attrs.getSlot(i); - VerifyAttrs(Attr, FT->getParamType(Idx-1), !Idx, V); + const Type *Ty; + if (Attr.Index == 0) + Ty = FT->getReturnType(); + else if (Attr.Index-1 < FT->getNumParams()) + Ty = FT->getParamType(Attr.Index-1); + else + break; // VarArgs attributes, don't verify. + + VerifyAttrs(Attr.Attrs, Ty, Attr.Index == 0, V); - if (Attr & ParamAttr::Nest) { + if (Attr.Attrs & ParamAttr::Nest) { Assert1(!SawNest, "More than one parameter has attribute nest!", V); SawNest = true; } - if (Attr & ParamAttr::StructRet) { - Assert1(Idx == 1, "Attribute sret not on first parameter!", V); - } + if (Attr.Attrs & ParamAttr::StructRet) + Assert1(Attr.Index == 1, "Attribute sret not on first parameter!", V); } } @@ -458,11 +464,10 @@ void Verifier::visitFunction(Function &F) { Assert1(!F.hasStructRetAttr() || F.getReturnType() == Type::VoidTy, "Invalid struct return type!", &F); - const ParamAttrsList *Attrs = F.getParamAttrs(); + const PAListPtr &Attrs = F.getParamAttrs(); - Assert1(!Attrs || - (Attrs->size() && - Attrs->getParamIndex(Attrs->size()-1) <= FT->getNumParams()), + Assert1(Attrs.isEmpty() || + Attrs.getSlot(Attrs.getNumSlots()-1).Index <= FT->getNumParams(), "Attributes after last parameter!", &F); // Check function attributes. @@ -712,15 +717,19 @@ void Verifier::visitUIToFPInst(UIToFPInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); - bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; - bool DstVec = DestTy->getTypeID() == Type::VectorTyID; + bool SrcVec = isa<VectorType>(SrcTy); + bool DstVec = isa<VectorType>(DestTy); - Assert1(SrcVec == DstVec,"UIToFP source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isIntOrIntVector(),"UIToFP source must be integer or integer vector", &I); - Assert1(DestTy->isFPOrFPVector(),"UIToFP result must be FP or FP vector", &I); + Assert1(SrcVec == DstVec, + "UIToFP source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isIntOrIntVector(), + "UIToFP source must be integer or integer vector", &I); + Assert1(DestTy->isFPOrFPVector(), + "UIToFP result must be FP or FP vector", &I); if (SrcVec && DstVec) - Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(), + Assert1(cast<VectorType>(SrcTy)->getNumElements() == + cast<VectorType>(DestTy)->getNumElements(), "UIToFP source and dest vector length mismatch", &I); visitInstruction(I); @@ -734,12 +743,16 @@ void Verifier::visitSIToFPInst(SIToFPInst &I) { bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; bool DstVec = DestTy->getTypeID() == Type::VectorTyID; - Assert1(SrcVec == DstVec,"SIToFP source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isIntOrIntVector(),"SIToFP source must be integer or integer vector", &I); - Assert1(DestTy->isFPOrFPVector(),"SIToFP result must be FP or FP vector", &I); + Assert1(SrcVec == DstVec, + "SIToFP source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isIntOrIntVector(), + "SIToFP source must be integer or integer vector", &I); + Assert1(DestTy->isFPOrFPVector(), + "SIToFP result must be FP or FP vector", &I); if (SrcVec && DstVec) - Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(), + Assert1(cast<VectorType>(SrcTy)->getNumElements() == + cast<VectorType>(DestTy)->getNumElements(), "SIToFP source and dest vector length mismatch", &I); visitInstruction(I); @@ -750,15 +763,18 @@ void Verifier::visitFPToUIInst(FPToUIInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); - bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; - bool DstVec = DestTy->getTypeID() == Type::VectorTyID; + bool SrcVec = isa<VectorType>(SrcTy); + bool DstVec = isa<VectorType>(DestTy); - Assert1(SrcVec == DstVec,"FPToUI source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isFPOrFPVector(),"FPToUI source must be FP or FP vector", &I); - Assert1(DestTy->isIntOrIntVector(),"FPToUI result must be integer or integer vector", &I); + Assert1(SrcVec == DstVec, + "FPToUI source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isFPOrFPVector(), "FPToUI source must be FP or FP vector", &I); + Assert1(DestTy->isIntOrIntVector(), + "FPToUI result must be integer or integer vector", &I); if (SrcVec && DstVec) - Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(), + Assert1(cast<VectorType>(SrcTy)->getNumElements() == + cast<VectorType>(DestTy)->getNumElements(), "FPToUI source and dest vector length mismatch", &I); visitInstruction(I); @@ -769,15 +785,19 @@ void Verifier::visitFPToSIInst(FPToSIInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); - bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; - bool DstVec = DestTy->getTypeID() == Type::VectorTyID; + bool SrcVec = isa<VectorType>(SrcTy); + bool DstVec = isa<VectorType>(DestTy); - Assert1(SrcVec == DstVec,"FPToSI source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isFPOrFPVector(),"FPToSI source must be FP or FP vector", &I); - Assert1(DestTy->isIntOrIntVector(),"FPToSI result must be integer or integer vector", &I); + Assert1(SrcVec == DstVec, + "FPToSI source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isFPOrFPVector(), + "FPToSI source must be FP or FP vector", &I); + Assert1(DestTy->isIntOrIntVector(), + "FPToSI result must be integer or integer vector", &I); if (SrcVec && DstVec) - Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(), + Assert1(cast<VectorType>(SrcTy)->getNumElements() == + cast<VectorType>(DestTy)->getNumElements(), "FPToSI source and dest vector length mismatch", &I); visitInstruction(I); @@ -871,25 +891,24 @@ void Verifier::VerifyCallSite(CallSite CS) { "Call parameter type does not match function signature!", CS.getArgument(i), FTy->getParamType(i), I); - const ParamAttrsList *Attrs = CS.getParamAttrs(); + const PAListPtr &Attrs = CS.getParamAttrs(); - Assert1(!Attrs || - (Attrs->size() && - Attrs->getParamIndex(Attrs->size()-1) <= CS.arg_size()), - "Attributes after last argument!", I); + Assert1(Attrs.isEmpty() || + Attrs.getSlot(Attrs.getNumSlots()-1).Index <= CS.arg_size(), + "Attributes after last parameter!", I); // Verify call attributes. VerifyFunctionAttrs(FTy, Attrs, I); - if (Attrs && FTy->isVarArg()) + if (FTy->isVarArg()) // Check attributes on the varargs part. for (unsigned Idx = 1 + FTy->getNumParams(); Idx <= CS.arg_size(); ++Idx) { - ParameterAttributes Attr = Attrs->getParamAttrs(Idx); + ParameterAttributes Attr = Attrs.getParamAttrs(Idx); VerifyAttrs(Attr, CS.getArgument(Idx-1)->getType(), false, I); ParameterAttributes VArgI = Attr & ParamAttr::VarArgsIncompatible; - Assert1(!VArgI, "Attribute " + ParamAttrsList::getParamAttrsText(VArgI) + + Assert1(!VArgI, "Attribute " + ParamAttr::getAsString(VArgI) + "cannot be used for vararg call arguments!", I); } |