Fix PR1146: parameter attributes are longer part of
the function type, instead they belong to functions
and function calls. This is an updated and slightly
corrected version of Reid Spencer's original patch.
The only known problem is that auto-upgrading of
bitcode files doesn't seem to work properly (see
test/Bitcode/AutoUpgradeIntrinsics.ll). Hopefully
a bitcode guru (who might that be? :) ) will fix it.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44359 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index a1373ce..683b95b 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -1328,61 +1328,36 @@
CHECK_FOR_ERROR
}
| Types '(' ArgTypeListI ')' OptFuncAttrs {
+ // Allow but ignore attributes on function types; this permits auto-upgrade.
+ // FIXME: remove in LLVM 3.0.
std::vector<const Type*> Params;
- ParamAttrsVector Attrs;
- if ($5 != ParamAttr::None) {
- ParamAttrsWithIndex X; X.index = 0; X.attrs = $5;
- Attrs.push_back(X);
- }
- unsigned index = 1;
TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
- for (; I != E; ++I, ++index) {
+ for (; I != E; ++I ) {
const Type *Ty = I->Ty->get();
Params.push_back(Ty);
- if (Ty != Type::VoidTy)
- if (I->Attrs != ParamAttr::None) {
- ParamAttrsWithIndex X; X.index = index; X.attrs = I->Attrs;
- Attrs.push_back(X);
- }
}
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
if (isVarArg) Params.pop_back();
- ParamAttrsList *ActualAttrs = 0;
- if (!Attrs.empty())
- ActualAttrs = ParamAttrsList::get(Attrs);
- FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, ActualAttrs);
+ FunctionType *FT = FunctionType::get(*$1, Params, isVarArg);
delete $3; // Delete the argument list
delete $1; // Delete the return type handle
$$ = new PATypeHolder(HandleUpRefs(FT));
CHECK_FOR_ERROR
}
| VOID '(' ArgTypeListI ')' OptFuncAttrs {
+ // Allow but ignore attributes on function types; this permits auto-upgrade.
+ // FIXME: remove in LLVM 3.0.
std::vector<const Type*> Params;
- ParamAttrsVector Attrs;
- if ($5 != ParamAttr::None) {
- ParamAttrsWithIndex X; X.index = 0; X.attrs = $5;
- Attrs.push_back(X);
- }
TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
- unsigned index = 1;
- for ( ; I != E; ++I, ++index) {
+ for ( ; I != E; ++I ) {
const Type* Ty = I->Ty->get();
Params.push_back(Ty);
- if (Ty != Type::VoidTy)
- if (I->Attrs != ParamAttr::None) {
- ParamAttrsWithIndex X; X.index = index; X.attrs = I->Attrs;
- Attrs.push_back(X);
- }
}
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
if (isVarArg) Params.pop_back();
- ParamAttrsList *ActualAttrs = 0;
- if (!Attrs.empty())
- ActualAttrs = ParamAttrsList::get(Attrs);
-
- FunctionType *FT = FunctionType::get($1, Params, isVarArg, ActualAttrs);
+ FunctionType *FT = FunctionType::get($1, Params, isVarArg);
delete $3; // Delete the argument list
$$ = new PATypeHolder(HandleUpRefs(FT));
CHECK_FOR_ERROR
@@ -1434,9 +1409,11 @@
;
ArgType
- : Types OptParamAttrs {
+ : Types OptParamAttrs {
+ // Allow but ignore attributes on function types; this permits auto-upgrade.
+ // FIXME: remove in LLVM 3.0.
$$.Ty = $1;
- $$.Attrs = $2;
+ $$.Attrs = ParamAttr::None;
}
;
@@ -2241,7 +2218,9 @@
std::vector<const Type*> ParamTypeList;
ParamAttrsVector Attrs;
if ($7 != ParamAttr::None) {
- ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $7;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 0;
+ PAWI.attrs = $7;
Attrs.push_back(PAWI);
}
if ($5) { // If there are arguments...
@@ -2253,7 +2232,9 @@
ParamTypeList.push_back(Ty);
if (Ty != Type::VoidTy)
if (I->Attrs != ParamAttr::None) {
- ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = index;
+ PAWI.attrs = I->Attrs;
Attrs.push_back(PAWI);
}
}
@@ -2266,7 +2247,7 @@
if (!Attrs.empty())
PAL = ParamAttrsList::get(Attrs);
- FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg, PAL);
+ FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg);
const PointerType *PFT = PointerType::get(FT);
delete $2;
@@ -2283,19 +2264,24 @@
// Move the function to the end of the list, from whereever it was
// previously inserted.
Fn = cast<Function>(FWRef);
+ assert(!Fn->getParamAttrs() && "Forward reference has parameter attributes!");
CurModule.CurrentModule->getFunctionList().remove(Fn);
CurModule.CurrentModule->getFunctionList().push_back(Fn);
} else if (!FunctionName.empty() && // Merge with an earlier prototype?
(Fn = CurModule.CurrentModule->getFunction(FunctionName))) {
- if (Fn->getFunctionType() != FT) {
+ if (Fn->getFunctionType() != FT ) {
// The existing function doesn't have the same type. This is an overload
// error.
GEN_ERROR("Overload of function '" + FunctionName + "' not permitted.");
+ } else if (Fn->getParamAttrs() != PAL) {
+ // The existing function doesn't have the same parameter attributes.
+ // This is an overload error.
+ GEN_ERROR("Overload of function '" + FunctionName + "' not permitted.");
} else if (!CurFun.isDeclare && !Fn->isDeclaration()) {
// Neither the existing or the current function is a declaration and they
// have the same name and same type. Clearly this is a redefinition.
GEN_ERROR("Redefinition of function '" + FunctionName + "'");
- } if (Fn->isDeclaration()) {
+ } else if (Fn->isDeclaration()) {
// Make sure to strip off any argument names so we can't get conflicts.
for (Function::arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end();
AI != AE; ++AI)
@@ -2304,7 +2290,6 @@
} else { // Not already defined?
Fn = new Function(FT, GlobalValue::ExternalWeakLinkage, FunctionName,
CurModule.CurrentModule);
-
InsertValue(Fn, CurModule.Values);
}
@@ -2318,6 +2303,7 @@
Fn->setVisibility(CurFun.Visibility);
}
Fn->setCallingConv($1);
+ Fn->setParamAttrs(PAL);
Fn->setAlignment($9);
if ($8) {
Fn->setSection(*$8);
@@ -2597,28 +2583,14 @@
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments...
std::vector<const Type*> ParamTypes;
- ParamAttrsVector Attrs;
- if ($8 != ParamAttr::None) {
- ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
- Attrs.push_back(PAWI);
- }
ParamList::iterator I = $6->begin(), E = $6->end();
- unsigned index = 1;
- for (; I != E; ++I, ++index) {
+ for (; I != E; ++I) {
const Type *Ty = I->Val->getType();
if (Ty == Type::VoidTy)
GEN_ERROR("Short call syntax cannot be used with varargs");
ParamTypes.push_back(Ty);
- if (I->Attrs != ParamAttr::None) {
- ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
- Attrs.push_back(PAWI);
- }
}
-
- ParamAttrsList *PAL = 0;
- if (!Attrs.empty())
- PAL = ParamAttrsList::get(Attrs);
- Ty = FunctionType::get($3->get(), ParamTypes, false, PAL);
+ Ty = FunctionType::get($3->get(), ParamTypes, false);
PFTy = PointerType::get(Ty);
}
@@ -2631,6 +2603,12 @@
BasicBlock *Except = getBBVal($14);
CHECK_FOR_ERROR
+ ParamAttrsVector Attrs;
+ if ($8 != ParamAttr::None) {
+ ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
+ Attrs.push_back(PAWI);
+ }
+
// Check the arguments
ValueList Args;
if ($6->empty()) { // Has no arguments?
@@ -2644,12 +2622,19 @@
FunctionType::param_iterator I = Ty->param_begin();
FunctionType::param_iterator E = Ty->param_end();
ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
+ unsigned index = 1;
- for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
+ for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) {
if (ArgI->Val->getType() != *I)
GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" +
(*I)->getDescription() + "'");
Args.push_back(ArgI->Val);
+ if (ArgI->Attrs != ParamAttr::None) {
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = index;
+ PAWI.attrs = ArgI->Attrs;
+ Attrs.push_back(PAWI);
+ }
}
if (Ty->isVarArg()) {
@@ -2660,9 +2645,14 @@
GEN_ERROR("Invalid number of parameters detected");
}
+ ParamAttrsList *PAL = 0;
+ if (!Attrs.empty())
+ PAL = ParamAttrsList::get(Attrs);
+
// Create the InvokeInst
InvokeInst *II = new InvokeInst(V, Normal, Except, Args.begin(), Args.end());
II->setCallingConv($2);
+ II->setParamAttrs(PAL);
$$ = II;
delete $6;
CHECK_FOR_ERROR
@@ -2733,33 +2723,39 @@
};
-ParamList : Types ValueRef OptParamAttrs {
+ParamList : Types OptParamAttrs ValueRef OptParamAttrs {
+ // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
// Used for call and invoke instructions
$$ = new ParamList();
- ParamListEntry E; E.Attrs = $3; E.Val = getVal($1->get(), $2);
+ ParamListEntry E; E.Attrs = $2 | $4; E.Val = getVal($1->get(), $3);
$$->push_back(E);
delete $1;
+ CHECK_FOR_ERROR
}
- | LABEL ValueRef OptParamAttrs {
+ | LABEL OptParamAttrs ValueRef OptParamAttrs {
+ // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
// Labels are only valid in ASMs
$$ = new ParamList();
- ParamListEntry E; E.Attrs = $3; E.Val = getBBVal($2);
+ ParamListEntry E; E.Attrs = $2 | $4; E.Val = getBBVal($3);
$$->push_back(E);
+ CHECK_FOR_ERROR
}
- | ParamList ',' Types ValueRef OptParamAttrs {
+ | ParamList ',' Types OptParamAttrs ValueRef OptParamAttrs {
+ // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
$$ = $1;
- ParamListEntry E; E.Attrs = $5; E.Val = getVal($3->get(), $4);
+ ParamListEntry E; E.Attrs = $4 | $6; E.Val = getVal($3->get(), $5);
$$->push_back(E);
delete $3;
CHECK_FOR_ERROR
}
- | ParamList ',' LABEL ValueRef OptParamAttrs {
+ | ParamList ',' LABEL OptParamAttrs ValueRef OptParamAttrs {
+ // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
$$ = $1;
- ParamListEntry E; E.Attrs = $5; E.Val = getBBVal($4);
+ ParamListEntry E; E.Attrs = $4 | $6; E.Val = getBBVal($5);
$$->push_back(E);
CHECK_FOR_ERROR
}
@@ -2914,29 +2910,14 @@
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments...
std::vector<const Type*> ParamTypes;
- ParamAttrsVector Attrs;
- if ($8 != ParamAttr::None) {
- ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
- Attrs.push_back(PAWI);
- }
- unsigned index = 1;
ParamList::iterator I = $6->begin(), E = $6->end();
- for (; I != E; ++I, ++index) {
+ for (; I != E; ++I) {
const Type *Ty = I->Val->getType();
if (Ty == Type::VoidTy)
GEN_ERROR("Short call syntax cannot be used with varargs");
ParamTypes.push_back(Ty);
- if (I->Attrs != ParamAttr::None) {
- ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
- Attrs.push_back(PAWI);
- }
}
-
- ParamAttrsList *PAL = 0;
- if (!Attrs.empty())
- PAL = ParamAttrsList::get(Attrs);
-
- Ty = FunctionType::get($3->get(), ParamTypes, false, PAL);
+ Ty = FunctionType::get($3->get(), ParamTypes, false);
PFTy = PointerType::get(Ty);
}
@@ -2952,6 +2933,14 @@
theF->getName() + "'");
}
+ // Set up the ParamAttrs for the function
+ ParamAttrsVector Attrs;
+ if ($8 != ParamAttr::None) {
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 0;
+ PAWI.attrs = $8;
+ Attrs.push_back(PAWI);
+ }
// Check the arguments
ValueList Args;
if ($6->empty()) { // Has no arguments?
@@ -2961,17 +2950,23 @@
"expects arguments");
} else { // Has arguments?
// Loop through FunctionType's arguments and ensure they are specified
- // correctly!
- //
+ // 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();
+ unsigned index = 1;
- for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
+ for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) {
if (ArgI->Val->getType() != *I)
GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" +
(*I)->getDescription() + "'");
Args.push_back(ArgI->Val);
+ if (ArgI->Attrs != ParamAttr::None) {
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = index;
+ PAWI.attrs = ArgI->Attrs;
+ Attrs.push_back(PAWI);
+ }
}
if (Ty->isVarArg()) {
if (I == E)
@@ -2980,10 +2975,17 @@
} else if (I != E || ArgI != ArgE)
GEN_ERROR("Invalid number of parameters detected");
}
+
+ // Finish off the ParamAttrs and check them
+ ParamAttrsList *PAL = 0;
+ if (!Attrs.empty())
+ PAL = ParamAttrsList::get(Attrs);
+
// Create the call node
CallInst *CI = new CallInst(V, Args.begin(), Args.end());
CI->setTailCall($1);
CI->setCallingConv($2);
+ CI->setParamAttrs(PAL);
$$ = CI;
delete $6;
delete $3;