GlobalValue *Ret = 0;
if (I != GlobalRefs.end()) {
Ret = I->second;
+ I->first.second.destroy();
GlobalRefs.erase(I);
}
return Ret;
}
std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D);
- if (I != CurModule.LateResolveTypes.end())
+ if (I != CurModule.LateResolveTypes.end()) {
+ D.destroy();
return I->second;
+ }
Type *Typ = OpaqueType::get();
CurModule.LateResolveTypes.insert(std::make_pair(D, Typ));
{
APSInt Tmp = *D.ConstPoolInt;
+ D.destroy();
Tmp.extOrTrunc(Ty->getPrimitiveSizeInBits());
return ConstantInt::get(Tmp);
}
// Lexer has no type info, so builds all float and double FP constants
// as double. Fix this here. Long double does not need this.
if (&D.ConstPoolFP->getSemantics() == &APFloat::IEEEdouble &&
- Ty==Type::FloatTy)
- D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(*D.ConstPoolFP);
+ Ty==Type::FloatTy) {
+ bool ignored;
+ D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
+ &ignored);
+ }
+ {
+ ConstantFP *tmp = ConstantFP::get(*D.ConstPoolFP);
+ D.destroy();
+ return tmp;
+ }
case ValID::ConstNullVal: // Is it a null value?
if (!isa<PointerType>(Ty)) {
CurModule.LateResolveTypes.find(D);
if (I != CurModule.LateResolveTypes.end()) {
((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy);
+ I->first.destroy();
CurModule.LateResolveTypes.erase(I);
}
+ D.destroy();
}
// setValueName - Set the specified value to the name given. The name may be
GV->setConstant(isConstantGlobal);
GV->setThreadLocal(IsThreadLocal);
InsertValue(GV, CurModule.Values);
+ ID.destroy();
return GV;
}
+ ID.destroy();
+
// If this global has a name
if (!Name.empty()) {
// if the global we're parsing has an initializer (is a definition) and
// Built in types...
%type <TypeVal> Types ResultTypes
-%type <PrimType> IntType FPType PrimType // Classifications
+%type <PrimType> PrimType // Classifications
%token <PrimType> VOID INTTYPE
%token <PrimType> FLOAT DOUBLE X86_FP80 FP128 PPC_FP128 LABEL
%token TYPE
%type <UIntVal> OptCallingConv LocalNumber
%type <Attributes> OptAttributes Attribute
%type <Attributes> OptFuncAttrs FuncAttr
-%type <Attributes> OptFuncNotes FuncNote
-%type <Attributes> FuncNoteList
+%type <Attributes> OptRetAttrs RetAttr
// Basic Block Terminating Operators
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
// Function Attributes
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
-%token READNONE READONLY GC
-
-// Function Notes
-%token FNNOTE INLINE ALWAYS NEVER OPTIMIZEFORSIZE
+%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ
// Visibility Styles
%token DEFAULT HIDDEN PROTECTED
| FALSETOK { $$ = FCmpInst::FCMP_FALSE; }
;
-// These are some types that allow classification if we only want a particular
-// thing... for example, only a signed, unsigned, or integral type.
-IntType : INTTYPE;
-FPType : FLOAT | DOUBLE | PPC_FP128 | FP128 | X86_FP80;
-
LocalName : LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ;
OptLocalName : LocalName | /*empty*/ { $$ = 0; };
}
;
+RetAttr : INREG { $$ = Attribute::InReg; }
+ | ZEROEXT { $$ = Attribute::ZExt; }
+ | SIGNEXT { $$ = Attribute::SExt; }
+ ;
+
+OptRetAttrs : /* empty */ { $$ = Attribute::None; }
+ | OptRetAttrs RetAttr {
+ $$ = $1 | $2;
+ }
+ ;
+
+
FuncAttr : NORETURN { $$ = Attribute::NoReturn; }
| NOUNWIND { $$ = Attribute::NoUnwind; }
| INREG { $$ = Attribute::InReg; }
| SIGNEXT { $$ = Attribute::SExt; }
| READNONE { $$ = Attribute::ReadNone; }
| READONLY { $$ = Attribute::ReadOnly; }
+ | NOINLINE { $$ = Attribute::NoInline; }
+ | ALWAYSINLINE { $$ = Attribute::AlwaysInline; }
+ | OPTSIZE { $$ = Attribute::OptimizeForSize; }
+ | SSP { $$ = Attribute::StackProtect; }
+ | SSPREQ { $$ = Attribute::StackProtectReq; }
;
OptFuncAttrs : /* empty */ { $$ = Attribute::None; }
}
;
-FuncNoteList : FuncNote { $$ = $1; }
- | FuncNoteList ',' FuncNote {
- unsigned tmp = $1 | $3;
- if ($3 == Attribute::NoInline
- && ($1 & Attribute::AlwaysInline))
- GEN_ERROR("Function Notes may include only one inline notes!")
- if ($3 == Attribute::AlwaysInline
- && ($1 & Attribute::NoInline))
- GEN_ERROR("Function Notes may include only one inline notes!")
- $$ = tmp;
- CHECK_FOR_ERROR
- }
- ;
-
-FuncNote : INLINE '=' NEVER { $$ = Attribute::NoInline; }
- | INLINE '=' ALWAYS { $$ = Attribute::AlwaysInline; }
- | OPTIMIZEFORSIZE { $$ = Attribute::OptimizeForSize; }
- ;
-
-OptFuncNotes : /* empty */ { $$ = Attribute::None; }
- | FNNOTE '(' FuncNoteList ')' {
- $$ = $3;
- }
- ;
OptGC : /* empty */ { $$ = 0; }
| GC STRINGCONSTANT {
CHECK_FOR_ERROR
FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg);
- delete $3; // Delete the argument list
delete $1; // Delete the return type handle
$$ = new PATypeHolder(HandleUpRefs(FT));
+
+ // Delete the argument list
+ for (I = $3->begin() ; I != E; ++I ) {
+ delete I->Ty;
+ }
+ delete $3;
+
CHECK_FOR_ERROR
}
| VOID '(' ArgTypeListI ')' OptFuncAttrs {
CHECK_FOR_ERROR
FunctionType *FT = FunctionType::get($1, Params, isVarArg);
- delete $3; // Delete the argument list
$$ = new PATypeHolder(HandleUpRefs(FT));
+
+ // Delete the argument list
+ for (I = $3->begin() ; I != E; ++I ) {
+ delete I->Ty;
+ }
+ delete $3;
+
CHECK_FOR_ERROR
}
delete $1;
CHECK_FOR_ERROR
}
- | IntType ESINT64VAL { // integral constants
- if (!ConstantInt::isValueValidForType($1, $2))
- GEN_ERROR("Constant value doesn't fit in type");
- $$ = ConstantInt::get($1, $2, true);
+ | Types ESINT64VAL { // integral constants
+ if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+ if (!ConstantInt::isValueValidForType(IT, $2))
+ GEN_ERROR("Constant value doesn't fit in type");
+ $$ = ConstantInt::get(IT, $2, true);
+ } else {
+ GEN_ERROR("integer constant must have integer type");
+ }
+ delete $1;
CHECK_FOR_ERROR
}
- | IntType ESAPINTVAL { // arbitrary precision integer constants
- uint32_t BitWidth = cast<IntegerType>($1)->getBitWidth();
- if ($2->getBitWidth() > BitWidth) {
- GEN_ERROR("Constant value does not fit in type");
+ | Types ESAPINTVAL { // arbitrary precision integer constants
+ if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+ if ($2->getBitWidth() > IT->getBitWidth())
+ GEN_ERROR("Constant value does not fit in type");
+ $2->sextOrTrunc(IT->getBitWidth());
+ $$ = ConstantInt::get(*$2);
+ } else {
+ GEN_ERROR("integer constant must have integer type");
}
- $2->sextOrTrunc(BitWidth);
- $$ = ConstantInt::get(*$2);
+ delete $1;
delete $2;
CHECK_FOR_ERROR
}
- | IntType EUINT64VAL { // integral constants
- if (!ConstantInt::isValueValidForType($1, $2))
- GEN_ERROR("Constant value doesn't fit in type");
- $$ = ConstantInt::get($1, $2, false);
+ | Types EUINT64VAL { // integral constants
+ if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+ if (!ConstantInt::isValueValidForType(IT, $2))
+ GEN_ERROR("Constant value doesn't fit in type");
+ $$ = ConstantInt::get(IT, $2, false);
+ } else {
+ GEN_ERROR("integer constant must have integer type");
+ }
+ delete $1;
CHECK_FOR_ERROR
}
- | IntType EUAPINTVAL { // arbitrary precision integer constants
- uint32_t BitWidth = cast<IntegerType>($1)->getBitWidth();
- if ($2->getBitWidth() > BitWidth) {
- GEN_ERROR("Constant value does not fit in type");
+ | Types EUAPINTVAL { // arbitrary precision integer constants
+ if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+ if ($2->getBitWidth() > IT->getBitWidth())
+ GEN_ERROR("Constant value does not fit in type");
+ $2->zextOrTrunc(IT->getBitWidth());
+ $$ = ConstantInt::get(*$2);
+ } else {
+ GEN_ERROR("integer constant must have integer type");
}
- $2->zextOrTrunc(BitWidth);
- $$ = ConstantInt::get(*$2);
+
delete $2;
+ delete $1;
CHECK_FOR_ERROR
}
- | INTTYPE TRUETOK { // Boolean constants
- if (cast<IntegerType>($1)->getBitWidth() != 1)
+ | Types TRUETOK { // Boolean constants
+ if ($1->get() != Type::Int1Ty)
GEN_ERROR("Constant true must have type i1");
$$ = ConstantInt::getTrue();
+ delete $1;
CHECK_FOR_ERROR
}
- | INTTYPE FALSETOK { // Boolean constants
- if (cast<IntegerType>($1)->getBitWidth() != 1)
+ | Types FALSETOK { // Boolean constants
+ if ($1->get() != Type::Int1Ty)
GEN_ERROR("Constant false must have type i1");
$$ = ConstantInt::getFalse();
+ delete $1;
CHECK_FOR_ERROR
}
- | FPType FPVAL { // Floating point constants
- if (!ConstantFP::isValueValidForType($1, *$2))
+ | Types FPVAL { // Floating point constants
+ if (!ConstantFP::isValueValidForType($1->get(), *$2))
GEN_ERROR("Floating point constant invalid for type");
+
// Lexer has no type info, so builds all float and double FP constants
// as double. Fix this here. Long double is done right.
- if (&$2->getSemantics()==&APFloat::IEEEdouble && $1==Type::FloatTy)
- $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
+ if (&$2->getSemantics()==&APFloat::IEEEdouble && $1->get()==Type::FloatTy) {
+ bool ignored;
+ $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
+ &ignored);
+ }
$$ = ConstantFP::get(*$2);
+ delete $1;
delete $2;
CHECK_FOR_ERROR
};
CHECK_FOR_ERROR
};
-FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
- OptFuncAttrs OptSection OptAlign OptGC OptFuncNotes {
- std::string FunctionName(*$3);
- delete $3; // Free strdup'd memory!
+FunctionHeaderH : OptCallingConv OptRetAttrs ResultTypes GlobalName '(' ArgList ')'
+ OptFuncAttrs OptSection OptAlign OptGC {
+ std::string FunctionName(*$4);
+ delete $4; // Free strdup'd memory!
// Check the function result for abstractness if this is a define. We should
// have no abstract types at this point
- if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($2))
- GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
+ if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($3))
+ GEN_ERROR("Reference to abstract result: "+ $3->get()->getDescription());
- if (!FunctionType::isValidReturnType(*$2))
+ if (!FunctionType::isValidReturnType(*$3))
GEN_ERROR("Invalid result type for LLVM function");
std::vector<const Type*> ParamTypeList;
SmallVector<AttributeWithIndex, 8> Attrs;
- if ($7 != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(0, $7));
- if ($5) { // If there are arguments...
+ //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function
+ //attributes.
+ Attributes RetAttrs = $2;
+ if ($8 != Attribute::None) {
+ if ($8 & Attribute::ZExt) {
+ RetAttrs = RetAttrs | Attribute::ZExt;
+ $8 = $8 ^ Attribute::ZExt;
+ }
+ if ($8 & Attribute::SExt) {
+ RetAttrs = RetAttrs | Attribute::SExt;
+ $8 = $8 ^ Attribute::SExt;
+ }
+ if ($8 & Attribute::InReg) {
+ RetAttrs = RetAttrs | Attribute::InReg;
+ $8 = $8 ^ Attribute::InReg;
+ }
+ }
+ if (RetAttrs != Attribute::None)
+ Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+ if ($6) { // If there are arguments...
unsigned index = 1;
- for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
+ for (ArgListType::iterator I = $6->begin(); I != $6->end(); ++I, ++index) {
const Type* Ty = I->Ty->get();
if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty))
GEN_ERROR("Reference to abstract argument: " + Ty->getDescription());
Attrs.push_back(AttributeWithIndex::get(index, I->Attrs));
}
}
+ if ($8 != Attribute::None)
+ Attrs.push_back(AttributeWithIndex::get(~0, $8));
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
if (isVarArg) ParamTypeList.pop_back();
if (!Attrs.empty())
PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
- FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg);
+ FunctionType *FT = FunctionType::get(*$3, ParamTypeList, isVarArg);
const PointerType *PFT = PointerType::getUnqual(FT);
- delete $2;
+ delete $3;
ValID ID;
if (!FunctionName.empty()) {
InsertValue(Fn, CurModule.Values);
}
+ ID.destroy();
CurFun.FunctionStart(Fn);
if (CurFun.isDeclare) {
}
Fn->setCallingConv($1);
Fn->setAttributes(PAL);
- Fn->setAlignment($9);
- if ($8) {
- Fn->setSection(*$8);
- delete $8;
- }
- if ($10) {
- Fn->setGC($10->c_str());
- delete $10;
+ Fn->setAlignment($10);
+ if ($9) {
+ Fn->setSection(*$9);
+ delete $9;
}
if ($11) {
- Fn->setNotes($11);
+ Fn->setGC($11->c_str());
+ delete $11;
}
// Add all of the arguments we parsed to the function...
- if ($5) { // Is null if empty...
+ if ($6) { // Is null if empty...
if (isVarArg) { // Nuke the last entry
- assert($5->back().Ty->get() == Type::VoidTy && $5->back().Name == 0 &&
+ assert($6->back().Ty->get() == Type::VoidTy && $6->back().Name == 0 &&
"Not a varargs marker!");
- delete $5->back().Ty;
- $5->pop_back(); // Delete the last entry
+ delete $6->back().Ty;
+ $6->pop_back(); // Delete the last entry
}
Function::arg_iterator ArgIt = Fn->arg_begin();
Function::arg_iterator ArgEnd = Fn->arg_end();
unsigned Idx = 1;
- for (ArgListType::iterator I = $5->begin();
- I != $5->end() && ArgIt != ArgEnd; ++I, ++ArgIt) {
+ for (ArgListType::iterator I = $6->begin();
+ I != $6->end() && ArgIt != ArgEnd; ++I, ++ArgIt) {
delete I->Ty; // Delete the typeholder...
setValueName(ArgIt, I->Name); // Insert arg into symtab...
CHECK_FOR_ERROR
Idx++;
}
- delete $5; // We're now done with the argument list
+ delete $6; // We're now done with the argument list
}
CHECK_FOR_ERROR
};
CHECK_FOR_ERROR
$$ = BranchInst::Create(tmpBBA, tmpBBB, tmpVal);
}
- | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
+ | SWITCH INTTYPE ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
Value* tmpVal = getVal($2, $3);
CHECK_FOR_ERROR
BasicBlock* tmpBB = getBBVal($6);
delete $8;
CHECK_FOR_ERROR
}
- | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
+ | SWITCH INTTYPE ValueRef ',' LABEL ValueRef '[' ']' {
Value* tmpVal = getVal($2, $3);
CHECK_FOR_ERROR
BasicBlock* tmpBB = getBBVal($6);
$$ = S;
CHECK_FOR_ERROR
}
- | INVOKE OptCallingConv ResultTypes ValueRef '(' ParamList ')' OptFuncAttrs
- TO LABEL ValueRef UNWIND LABEL ValueRef {
+ | INVOKE OptCallingConv OptRetAttrs ResultTypes ValueRef '(' ParamList ')'
+ OptFuncAttrs TO LABEL ValueRef UNWIND LABEL ValueRef {
// Handle the short syntax
const PointerType *PFTy = 0;
const FunctionType *Ty = 0;
- if (!(PFTy = dyn_cast<PointerType>($3->get())) ||
+ if (!(PFTy = dyn_cast<PointerType>($4->get())) ||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments...
std::vector<const Type*> ParamTypes;
- ParamList::iterator I = $6->begin(), E = $6->end();
+ ParamList::iterator I = $7->begin(), E = $7->end();
for (; I != E; ++I) {
const Type *Ty = I->Val->getType();
if (Ty == Type::VoidTy)
ParamTypes.push_back(Ty);
}
- if (!FunctionType::isValidReturnType(*$3))
+ if (!FunctionType::isValidReturnType(*$4))
GEN_ERROR("Invalid result type for LLVM function");
- Ty = FunctionType::get($3->get(), ParamTypes, false);
+ Ty = FunctionType::get($4->get(), ParamTypes, false);
PFTy = PointerType::getUnqual(Ty);
}
- delete $3;
+ delete $4;
- Value *V = getVal(PFTy, $4); // Get the function we're calling...
+ Value *V = getVal(PFTy, $5); // Get the function we're calling...
CHECK_FOR_ERROR
- BasicBlock *Normal = getBBVal($11);
+ BasicBlock *Normal = getBBVal($12);
CHECK_FOR_ERROR
- BasicBlock *Except = getBBVal($14);
+ BasicBlock *Except = getBBVal($15);
CHECK_FOR_ERROR
SmallVector<AttributeWithIndex, 8> Attrs;
- if ($8 != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(0, $8));
-
+ //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function
+ //attributes.
+ Attributes RetAttrs = $3;
+ if ($9 != Attribute::None) {
+ if ($9 & Attribute::ZExt) {
+ RetAttrs = RetAttrs | Attribute::ZExt;
+ $9 = $9 ^ Attribute::ZExt;
+ }
+ if ($9 & Attribute::SExt) {
+ RetAttrs = RetAttrs | Attribute::SExt;
+ $9 = $9 ^ Attribute::SExt;
+ }
+ if ($9 & Attribute::InReg) {
+ RetAttrs = RetAttrs | Attribute::InReg;
+ $9 = $9 ^ Attribute::InReg;
+ }
+ }
+ if (RetAttrs != Attribute::None)
+ Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+
// Check the arguments
ValueList Args;
- if ($6->empty()) { // Has no arguments?
+ if ($7->empty()) { // Has no arguments?
// Make sure no arguments is a good thing!
if (Ty->getNumParams() != 0)
GEN_ERROR("No arguments passed to a function that "
// correctly!
FunctionType::param_iterator I = Ty->param_begin();
FunctionType::param_iterator E = Ty->param_end();
- ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
+ ParamList::iterator ArgI = $7->begin(), ArgE = $7->end();
unsigned index = 1;
for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) {
} else if (I != E || ArgI != ArgE)
GEN_ERROR("Invalid number of parameters detected");
}
-
+ if ($9 != Attribute::None)
+ Attrs.push_back(AttributeWithIndex::get(~0, $9));
AttrListPtr PAL;
if (!Attrs.empty())
PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
II->setCallingConv($2);
II->setAttributes(PAL);
$$ = II;
- delete $6;
+ delete $7;
CHECK_FOR_ERROR
}
| UNWIND {
-JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
+JumpTable : JumpTable INTTYPE ConstValueRef ',' LABEL ValueRef {
$$ = $1;
Constant *V = cast<Constant>(getExistingVal($2, $3));
CHECK_FOR_ERROR
CHECK_FOR_ERROR
$$->push_back(std::make_pair(V, tmpBB));
}
- | IntType ConstValueRef ',' LABEL ValueRef {
+ | INTTYPE ConstValueRef ',' LABEL ValueRef {
$$ = new std::vector<std::pair<Constant*, BasicBlock*> >();
Constant *V = cast<Constant>(getExistingVal($1, $2));
CHECK_FOR_ERROR
delete $2; // Free the list...
CHECK_FOR_ERROR
}
- | OptTailCall OptCallingConv ResultTypes ValueRef '(' ParamList ')'
+ | OptTailCall OptCallingConv OptRetAttrs ResultTypes ValueRef '(' ParamList ')'
OptFuncAttrs {
// Handle the short syntax
const PointerType *PFTy = 0;
const FunctionType *Ty = 0;
- if (!(PFTy = dyn_cast<PointerType>($3->get())) ||
+ if (!(PFTy = dyn_cast<PointerType>($4->get())) ||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments...
std::vector<const Type*> ParamTypes;
- ParamList::iterator I = $6->begin(), E = $6->end();
+ ParamList::iterator I = $7->begin(), E = $7->end();
for (; I != E; ++I) {
const Type *Ty = I->Val->getType();
if (Ty == Type::VoidTy)
ParamTypes.push_back(Ty);
}
- if (!FunctionType::isValidReturnType(*$3))
+ if (!FunctionType::isValidReturnType(*$4))
GEN_ERROR("Invalid result type for LLVM function");
- Ty = FunctionType::get($3->get(), ParamTypes, false);
+ Ty = FunctionType::get($4->get(), ParamTypes, false);
PFTy = PointerType::getUnqual(Ty);
}
- Value *V = getVal(PFTy, $4); // Get the function we're calling...
+ Value *V = getVal(PFTy, $5); // Get the function we're calling...
CHECK_FOR_ERROR
// Check for call to invalid intrinsic to avoid crashing later.
// Set up the Attributes for the function
SmallVector<AttributeWithIndex, 8> Attrs;
- if ($8 != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(0, $8));
+ //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function
+ //attributes.
+ Attributes RetAttrs = $3;
+ if ($9 != Attribute::None) {
+ if ($9 & Attribute::ZExt) {
+ RetAttrs = RetAttrs | Attribute::ZExt;
+ $9 = $9 ^ Attribute::ZExt;
+ }
+ if ($9 & Attribute::SExt) {
+ RetAttrs = RetAttrs | Attribute::SExt;
+ $9 = $9 ^ Attribute::SExt;
+ }
+ if ($9 & Attribute::InReg) {
+ RetAttrs = RetAttrs | Attribute::InReg;
+ $9 = $9 ^ Attribute::InReg;
+ }
+ }
+ if (RetAttrs != Attribute::None)
+ Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+
// Check the arguments
ValueList Args;
- if ($6->empty()) { // Has no arguments?
+ if ($7->empty()) { // Has no arguments?
// Make sure no arguments is a good thing!
if (Ty->getNumParams() != 0)
GEN_ERROR("No arguments passed to a function that "
// correctly. Also, gather any parameter attributes.
FunctionType::param_iterator I = Ty->param_begin();
FunctionType::param_iterator E = Ty->param_end();
- ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
+ ParamList::iterator ArgI = $7->begin(), ArgE = $7->end();
unsigned index = 1;
for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) {
} else if (I != E || ArgI != ArgE)
GEN_ERROR("Invalid number of parameters detected");
}
+ if ($9 != Attribute::None)
+ Attrs.push_back(AttributeWithIndex::get(~0, $9));
// Finish off the Attributes and check them
AttrListPtr PAL;
CI->setCallingConv($2);
CI->setAttributes(PAL);
$$ = CI;
- delete $6;
- delete $3;
+ delete $7;
+ delete $4;
CHECK_FOR_ERROR
}
| MemoryInst {