parse new calling conv specifiers

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21748 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-05-06 20:27:19 +00:00
parent 28caccff30
commit a8e8f16714
2 changed files with 65 additions and 43 deletions

View File

@ -204,6 +204,11 @@ little { return LITTLE; }
big { return BIG; } big { return BIG; }
volatile { return VOLATILE; } volatile { return VOLATILE; }
cc { return CC_TOK; }
ccc { return CCC_TOK; }
fastcc { return FASTCC_TOK; }
coldcc { return COLDCC_TOK; }
void { llvmAsmlval.PrimType = Type::VoidTy ; return VOID; } void { llvmAsmlval.PrimType = Type::VoidTy ; return VOID; }
bool { llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; } bool { llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; }
sbyte { llvmAsmlval.PrimType = Type::SByteTy ; return SBYTE; } sbyte { llvmAsmlval.PrimType = Type::SByteTy ; return SBYTE; }

View File

@ -13,6 +13,7 @@
%{ %{
#include "ParserInternals.h" #include "ParserInternals.h"
#include "llvm/CallingConv.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/SymbolTable.h" #include "llvm/SymbolTable.h"
@ -831,6 +832,8 @@ Module *llvm::RunVMAsmParser(const std::string &Filename, FILE *F) {
%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING %token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
%token DEPLIBS CALL TAIL %token DEPLIBS CALL TAIL
%token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK
%type <UIntVal> OptCallingConv
// Basic Block Terminating Operators // Basic Block Terminating Operators
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE %token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
@ -901,6 +904,16 @@ OptLinkage : INTERNAL { $$ = GlobalValue::InternalLinkage; } |
APPENDING { $$ = GlobalValue::AppendingLinkage; } | APPENDING { $$ = GlobalValue::AppendingLinkage; } |
/*empty*/ { $$ = GlobalValue::ExternalLinkage; }; /*empty*/ { $$ = GlobalValue::ExternalLinkage; };
OptCallingConv : /*empty*/ { $$ = CallingConv::C; } |
CCC_TOK { $$ = CallingConv::C; } |
FASTCC_TOK { $$ = CallingConv::Fast; } |
COLDCC_TOK { $$ = CallingConv::Cold; } |
CC_TOK EUINT64VAL {
if ((unsigned)$2 != $2)
ThrowException("Calling conv too large!");
$$ = $2;
};
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Types includes all predefined types... except void, because it can only be // Types includes all predefined types... except void, because it can only be
// used in specific contexts (function returning void for example). To have // used in specific contexts (function returning void for example). To have
@ -1499,27 +1512,27 @@ ArgList : ArgListH {
$$ = 0; $$ = 0;
}; };
FunctionHeaderH : TypesV Name '(' ArgList ')' { FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')' {
UnEscapeLexed($2); UnEscapeLexed($3);
std::string FunctionName($2); std::string FunctionName($3);
free($2); // Free strdup'd memory! free($3); // Free strdup'd memory!
if (!(*$1)->isFirstClassType() && *$1 != Type::VoidTy) if (!(*$2)->isFirstClassType() && *$2 != Type::VoidTy)
ThrowException("LLVM functions cannot return aggregate types!"); ThrowException("LLVM functions cannot return aggregate types!");
std::vector<const Type*> ParamTypeList; std::vector<const Type*> ParamTypeList;
if ($4) { // If there are arguments... if ($5) { // If there are arguments...
for (std::vector<std::pair<PATypeHolder*,char*> >::iterator I = $4->begin(); for (std::vector<std::pair<PATypeHolder*,char*> >::iterator I = $5->begin();
I != $4->end(); ++I) I != $5->end(); ++I)
ParamTypeList.push_back(I->first->get()); ParamTypeList.push_back(I->first->get());
} }
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
if (isVarArg) ParamTypeList.pop_back(); if (isVarArg) ParamTypeList.pop_back();
const FunctionType *FT = FunctionType::get(*$1, ParamTypeList, isVarArg); const FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg);
const PointerType *PFT = PointerType::get(FT); const PointerType *PFT = PointerType::get(FT);
delete $1; delete $2;
ValID ID; ValID ID;
if (!FunctionName.empty()) { if (!FunctionName.empty()) {
@ -1556,25 +1569,26 @@ FunctionHeaderH : TypesV Name '(' ArgList ')' {
} }
CurFun.FunctionStart(Fn); CurFun.FunctionStart(Fn);
Fn->setCallingConv($1);
// Add all of the arguments we parsed to the function... // Add all of the arguments we parsed to the function...
if ($4) { // Is null if empty... if ($5) { // Is null if empty...
if (isVarArg) { // Nuke the last entry if (isVarArg) { // Nuke the last entry
assert($4->back().first->get() == Type::VoidTy && $4->back().second == 0&& assert($5->back().first->get() == Type::VoidTy && $5->back().second == 0&&
"Not a varargs marker!"); "Not a varargs marker!");
delete $4->back().first; delete $5->back().first;
$4->pop_back(); // Delete the last entry $5->pop_back(); // Delete the last entry
} }
Function::arg_iterator ArgIt = Fn->arg_begin(); Function::arg_iterator ArgIt = Fn->arg_begin();
for (std::vector<std::pair<PATypeHolder*, char*> >::iterator I =$4->begin(); for (std::vector<std::pair<PATypeHolder*,char*> >::iterator I = $5->begin();
I != $4->end(); ++I, ++ArgIt) { I != $5->end(); ++I, ++ArgIt) {
delete I->first; // Delete the typeholder... delete I->first; // Delete the typeholder...
setValueName(ArgIt, I->second); // Insert arg into symtab... setValueName(ArgIt, I->second); // Insert arg into symtab...
InsertValue(ArgIt); InsertValue(ArgIt);
} }
delete $4; // We're now done with the argument list delete $5; // We're now done with the argument list
} }
}; };
@ -1748,17 +1762,17 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
SwitchInst *S = new SwitchInst(getVal($2, $3), getBBVal($6), 0); SwitchInst *S = new SwitchInst(getVal($2, $3), getBBVal($6), 0);
$$ = S; $$ = S;
} }
| INVOKE TypesV ValueRef '(' ValueRefListE ')' TO LABEL ValueRef | INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
UNWIND LABEL ValueRef { TO LABEL ValueRef UNWIND LABEL ValueRef {
const PointerType *PFTy; const PointerType *PFTy;
const FunctionType *Ty; const FunctionType *Ty;
if (!(PFTy = dyn_cast<PointerType>($2->get())) || if (!(PFTy = dyn_cast<PointerType>($3->get())) ||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) { !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments... // Pull out the types of all of the arguments...
std::vector<const Type*> ParamTypes; std::vector<const Type*> ParamTypes;
if ($5) { if ($6) {
for (std::vector<Value*>::iterator I = $5->begin(), E = $5->end(); for (std::vector<Value*>::iterator I = $6->begin(), E = $6->end();
I != E; ++I) I != E; ++I)
ParamTypes.push_back((*I)->getType()); ParamTypes.push_back((*I)->getType());
} }
@ -1766,17 +1780,17 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
if (isVarArg) ParamTypes.pop_back(); if (isVarArg) ParamTypes.pop_back();
Ty = FunctionType::get($2->get(), ParamTypes, isVarArg); Ty = FunctionType::get($3->get(), ParamTypes, isVarArg);
PFTy = PointerType::get(Ty); PFTy = PointerType::get(Ty);
} }
Value *V = getVal(PFTy, $3); // Get the function we're calling... Value *V = getVal(PFTy, $4); // Get the function we're calling...
BasicBlock *Normal = getBBVal($9); BasicBlock *Normal = getBBVal($10);
BasicBlock *Except = getBBVal($12); BasicBlock *Except = getBBVal($13);
// Create the call node... // Create the call node...
if (!$5) { // Has no arguments? if (!$6) { // Has no arguments?
$$ = new InvokeInst(V, Normal, Except, std::vector<Value*>()); $$ = new InvokeInst(V, Normal, Except, std::vector<Value*>());
} else { // Has arguments? } else { // Has arguments?
// Loop through FunctionType's arguments and ensure they are specified // Loop through FunctionType's arguments and ensure they are specified
@ -1784,7 +1798,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
// //
FunctionType::param_iterator I = Ty->param_begin(); FunctionType::param_iterator I = Ty->param_begin();
FunctionType::param_iterator E = Ty->param_end(); FunctionType::param_iterator E = Ty->param_end();
std::vector<Value*>::iterator ArgI = $5->begin(), ArgE = $5->end(); std::vector<Value*>::iterator ArgI = $6->begin(), ArgE = $6->end();
for (; ArgI != ArgE && I != E; ++ArgI, ++I) for (; ArgI != ArgE && I != E; ++ArgI, ++I)
if ((*ArgI)->getType() != *I) if ((*ArgI)->getType() != *I)
@ -1794,10 +1808,12 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
if (I != E || (ArgI != ArgE && !Ty->isVarArg())) if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
ThrowException("Invalid number of parameters detected!"); ThrowException("Invalid number of parameters detected!");
$$ = new InvokeInst(V, Normal, Except, *$5); $$ = new InvokeInst(V, Normal, Except, *$6);
} }
delete $2; cast<InvokeInst>($$)->setCallingConv($2);
delete $5;
delete $3;
delete $6;
} }
| UNWIND { | UNWIND {
$$ = new UnwindInst(); $$ = new UnwindInst();
@ -1953,16 +1969,16 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
} }
delete $2; // Free the list... delete $2; // Free the list...
} }
| OptTailCall TypesV ValueRef '(' ValueRefListE ')' { | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
const PointerType *PFTy; const PointerType *PFTy;
const FunctionType *Ty; const FunctionType *Ty;
if (!(PFTy = dyn_cast<PointerType>($2->get())) || if (!(PFTy = dyn_cast<PointerType>($3->get())) ||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) { !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments... // Pull out the types of all of the arguments...
std::vector<const Type*> ParamTypes; std::vector<const Type*> ParamTypes;
if ($5) { if ($6) {
for (std::vector<Value*>::iterator I = $5->begin(), E = $5->end(); for (std::vector<Value*>::iterator I = $6->begin(), E = $6->end();
I != E; ++I) I != E; ++I)
ParamTypes.push_back((*I)->getType()); ParamTypes.push_back((*I)->getType());
} }
@ -1970,17 +1986,17 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
if (isVarArg) ParamTypes.pop_back(); if (isVarArg) ParamTypes.pop_back();
if (!(*$2)->isFirstClassType() && *$2 != Type::VoidTy) if (!(*$3)->isFirstClassType() && *$3 != Type::VoidTy)
ThrowException("LLVM functions cannot return aggregate types!"); ThrowException("LLVM functions cannot return aggregate types!");
Ty = FunctionType::get($2->get(), ParamTypes, isVarArg); Ty = FunctionType::get($3->get(), ParamTypes, isVarArg);
PFTy = PointerType::get(Ty); PFTy = PointerType::get(Ty);
} }
Value *V = getVal(PFTy, $3); // Get the function we're calling... Value *V = getVal(PFTy, $4); // Get the function we're calling...
// Create the call node... // Create the call node...
if (!$5) { // Has no arguments? if (!$6) { // Has no arguments?
// Make sure no arguments is a good thing! // Make sure no arguments is a good thing!
if (Ty->getNumParams() != 0) if (Ty->getNumParams() != 0)
ThrowException("No arguments passed to a function that " ThrowException("No arguments passed to a function that "
@ -1993,7 +2009,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
// //
FunctionType::param_iterator I = Ty->param_begin(); FunctionType::param_iterator I = Ty->param_begin();
FunctionType::param_iterator E = Ty->param_end(); FunctionType::param_iterator E = Ty->param_end();
std::vector<Value*>::iterator ArgI = $5->begin(), ArgE = $5->end(); std::vector<Value*>::iterator ArgI = $6->begin(), ArgE = $6->end();
for (; ArgI != ArgE && I != E; ++ArgI, ++I) for (; ArgI != ArgE && I != E; ++ArgI, ++I)
if ((*ArgI)->getType() != *I) if ((*ArgI)->getType() != *I)
@ -2003,11 +2019,12 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
if (I != E || (ArgI != ArgE && !Ty->isVarArg())) if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
ThrowException("Invalid number of parameters detected!"); ThrowException("Invalid number of parameters detected!");
$$ = new CallInst(V, *$5); $$ = new CallInst(V, *$6);
} }
cast<CallInst>($$)->setTailCall($1); cast<CallInst>($$)->setTailCall($1);
delete $2; cast<CallInst>($$)->setCallingConv($2);
delete $5; delete $3;
delete $6;
} }
| MemoryInst { | MemoryInst {
$$ = $1; $$ = $1;