From 2c261789d3f6826b42a010b8ff0115519ba31525 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Fri, 5 Jan 2007 17:06:19 +0000 Subject: [PATCH] Change the syntax for parameter attributes: 1. The @ sign is no longer necessary. 2. We now support "function attributes" as parameter attribute 0. 3. Instead of locating the return type attributes after the type of a function result, they are now located after the function header's closing paranthesis and before any alignment or section options. 4. The way has been prepared for a new "noreturn" function attribute but there is no support for recognizing it in the lexer nor doing anything with it if it does get set. 5. The FunctionType::getParamAttrsText method now has support for returning multiple attributes. This required a change in its interface. I'm unhappy that this change leads to 6 new shift/reduce conflicts, but in each case bison's decision to choose the shift is correct so there shouldn't be any damage from these conflicts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32904 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DerivedTypes.h | 9 ++-- lib/AsmParser/llvmAsmParser.y | 97 +++++++++++++++++++---------------- lib/VMCore/AsmWriter.cpp | 28 +++++----- lib/VMCore/Type.cpp | 26 +++++----- 4 files changed, 84 insertions(+), 76 deletions(-) diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index 25c66a63819..f8d9a1bf946 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -81,9 +81,10 @@ public: /// set of possible attributes. /// @brief Function parameter attributes enumeration. enum ParameterAttributes { - NoAttributeSet = 0, ///< No attribute value has been set on the parameter - ZExtAttribute = 1, ///< The parameter should be zero extended before call - SExtAttribute = 2 ///< The parameter should be sign extended before call + NoAttributeSet = 0, ///< No attribute value has been set + ZExtAttribute = 1, ///< zero extended before/after call + SExtAttribute = 1 << 1, ///< sign extended before/after call + NoReturnAttribute = 1 << 2 ///< mark the function as not returning }; typedef std::vector ParamAttrsList; private: @@ -142,7 +143,7 @@ public: } /// @brief Convert a ParameterAttribute into its assembly text - static const char * getParamAttrsText(ParameterAttributes Attr); + static std::string getParamAttrsText(ParameterAttributes Attr); // Implement the AbstractTypeUser interface. virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index bc09675898c..133c534c91e 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -951,7 +951,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %type IndexList // For GEP indices %type TypeListI %type ArgTypeList ArgTypeListI -%type ArgType ResultType +%type ArgType %type JumpTable %type GlobalType // GLOBAL or CONSTANT? %type OptVolatile // 'volatile' or not @@ -978,7 +978,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %token FPVAL // Float or Double constant // Built in types... -%type Types +%type Types ResultTypes %type IntType FPType PrimType // Classifications %token VOID BOOL INT8 INT16 INT32 INT64 %token FLOAT DOUBLE LABEL @@ -999,7 +999,8 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %token X86_STDCALLCC_TOK X86_FASTCALLCC_TOK %token DATALAYOUT %type OptCallingConv -%type OptParamAttrs ParamAttrList ParamAttr +%type OptParamAttrs ParamAttr +%type OptFuncAttrs FuncAttr // Basic Block Terminating Operators %token RET BR SWITCH INVOKE UNWIND UNREACHABLE @@ -1026,6 +1027,8 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %token PHI_TOK SELECT SHL LSHR ASHR VAARG %token EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR +// Function Attributes +%token NORETURN %start Module %% @@ -1129,15 +1132,20 @@ ParamAttr : ZEXT { $$ = FunctionType::ZExtAttribute; } | SEXT { $$ = FunctionType::SExtAttribute; } ; -ParamAttrList : ParamAttr { $$ = $1; } - | ParamAttrList ',' ParamAttr { - $$ = FunctionType::ParameterAttributes($1 | $3); +OptParamAttrs : /* empty */ { $$ = FunctionType::NoAttributeSet; } + | OptParamAttrs ParamAttr { + $$ = FunctionType::ParameterAttributes($1 | $2); } ; -OptParamAttrs : /* empty */ { $$ = FunctionType::NoAttributeSet; } - | '@' ParamAttr { $$ = $2; } - | '@' '(' ParamAttrList ')' { $$ = $3; } +FuncAttr : NORETURN { $$ = FunctionType::NoReturnAttribute; } + | ParamAttr + ; + +OptFuncAttrs : /* empty */ { $$ = FunctionType::NoAttributeSet; } + | OptFuncAttrs FuncAttr { + $$ = FunctionType::ParameterAttributes($1 | $2); + } ; // OptAlign/OptCAlign - An optional alignment, and an optional alignment with @@ -1223,11 +1231,11 @@ Types UR_OUT("New Upreference!\n"); CHECK_FOR_ERROR } - | Types OptParamAttrs '(' ArgTypeListI ')' { + | Types '(' ArgTypeListI ')' OptFuncAttrs { std::vector Params; std::vector Attrs; - Attrs.push_back($2); - for (TypeWithAttrsList::iterator I=$4->begin(), E=$4->end(); I != E; ++I) { + Attrs.push_back($5); + for (TypeWithAttrsList::iterator I=$3->begin(), E=$3->end(); I != E; ++I) { Params.push_back(I->Ty->get()); if (I->Ty->get() != Type::VoidTy) Attrs.push_back(I->Attrs); @@ -1236,16 +1244,16 @@ Types if (isVarArg) Params.pop_back(); FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, Attrs); - delete $4; // Delete the argument list + delete $3; // Delete the argument list delete $1; // Delete the return type handle $$ = new PATypeHolder(HandleUpRefs(FT)); CHECK_FOR_ERROR } - | VOID OptParamAttrs '(' ArgTypeListI ')' { + | VOID '(' ArgTypeListI ')' OptFuncAttrs { std::vector Params; std::vector Attrs; - Attrs.push_back($2); - for (TypeWithAttrsList::iterator I=$4->begin(), E=$4->end(); I != E; ++I) { + Attrs.push_back($5); + for (TypeWithAttrsList::iterator I=$3->begin(), E=$3->end(); I != E; ++I) { Params.push_back(I->Ty->get()); if (I->Ty->get() != Type::VoidTy) Attrs.push_back(I->Attrs); @@ -1254,7 +1262,7 @@ Types if (isVarArg) Params.pop_back(); FunctionType *FT = FunctionType::get($1, Params, isVarArg, Attrs); - delete $4; // Delete the argument list + delete $3; // Delete the argument list $$ = new PATypeHolder(HandleUpRefs(FT)); CHECK_FOR_ERROR } @@ -1313,18 +1321,16 @@ ArgType } ; -ResultType - : Types OptParamAttrs { +ResultTypes + : Types { if (!UpRefs.empty()) GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); if (!(*$1)->isFirstClassType()) GEN_ERROR("LLVM functions cannot return aggregate types!"); - $$.Ty = $1; - $$.Attrs = $2; + $$ = $1; } - | VOID OptParamAttrs { - $$.Ty = new PATypeHolder(Type::VoidTy); - $$.Attrs = $2; + | VOID { + $$ = new PATypeHolder(Type::VoidTy); } ; @@ -1990,20 +1996,20 @@ ArgList : ArgListH { CHECK_FOR_ERROR }; -FunctionHeaderH : OptCallingConv ResultType Name '(' ArgList ')' - OptSection OptAlign { +FunctionHeaderH : OptCallingConv ResultTypes Name '(' ArgList ')' + OptFuncAttrs OptSection OptAlign { UnEscapeLexed($3); std::string FunctionName($3); free($3); // 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.Ty)) - GEN_ERROR("Reference to abstract result: "+ $2.Ty->get()->getDescription()); + if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($2)) + GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription()); std::vector ParamTypeList; std::vector ParamAttrs; - ParamAttrs.push_back($2.Attrs); + ParamAttrs.push_back($7); if ($5) { // If there are arguments... for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I) { const Type* Ty = I->Ty->get(); @@ -2018,10 +2024,10 @@ FunctionHeaderH : OptCallingConv ResultType Name '(' ArgList ')' bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; if (isVarArg) ParamTypeList.pop_back(); - FunctionType *FT = FunctionType::get(*$2.Ty, ParamTypeList, isVarArg, + FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg, ParamAttrs); const PointerType *PFT = PointerType::get(FT); - delete $2.Ty; + delete $2; ValID ID; if (!FunctionName.empty()) { @@ -2066,10 +2072,10 @@ FunctionHeaderH : OptCallingConv ResultType Name '(' ArgList ')' Fn->setLinkage(CurFun.Linkage); } Fn->setCallingConv($1); - Fn->setAlignment($8); - if ($7) { - Fn->setSection($7); - free($7); + Fn->setAlignment($9); + if ($8) { + Fn->setSection($8); + free($8); } // Add all of the arguments we parsed to the function... @@ -2340,18 +2346,18 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... $$ = S; CHECK_FOR_ERROR } - | INVOKE OptCallingConv ResultType ValueRef '(' ValueRefList ')' + | INVOKE OptCallingConv ResultTypes ValueRef '(' ValueRefList ')' OptFuncAttrs TO LABEL ValueRef UNWIND LABEL ValueRef { // Handle the short syntax const PointerType *PFTy = 0; const FunctionType *Ty = 0; - if (!(PFTy = dyn_cast($3.Ty->get())) || + if (!(PFTy = dyn_cast($3->get())) || !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector ParamTypes; FunctionType::ParamAttrsList ParamAttrs; - ParamAttrs.push_back($3.Attrs); + ParamAttrs.push_back($8); for (ValueRefList::iterator I = $6->begin(), E = $6->end(); I != E; ++I) { const Type *Ty = I->Val->getType(); if (Ty == Type::VoidTy) @@ -2360,15 +2366,15 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... ParamAttrs.push_back(I->Attrs); } - Ty = FunctionType::get($3.Ty->get(), ParamTypes, false, ParamAttrs); + Ty = FunctionType::get($3->get(), ParamTypes, false, ParamAttrs); PFTy = PointerType::get(Ty); } Value *V = getVal(PFTy, $4); // Get the function we're calling... CHECK_FOR_ERROR - BasicBlock *Normal = getBBVal($10); + BasicBlock *Normal = getBBVal($11); CHECK_FOR_ERROR - BasicBlock *Except = getBBVal($13); + BasicBlock *Except = getBBVal($14); CHECK_FOR_ERROR // Check the arguments @@ -2655,17 +2661,18 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { delete $2; // Free the list... CHECK_FOR_ERROR } - | OptTailCall OptCallingConv ResultType ValueRef '(' ValueRefList ')' { + | OptTailCall OptCallingConv ResultTypes ValueRef '(' ValueRefList ')' + OptFuncAttrs { // Handle the short syntax const PointerType *PFTy = 0; const FunctionType *Ty = 0; - if (!(PFTy = dyn_cast($3.Ty->get())) || + if (!(PFTy = dyn_cast($3->get())) || !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector ParamTypes; FunctionType::ParamAttrsList ParamAttrs; - ParamAttrs.push_back($3.Attrs); + ParamAttrs.push_back($8); for (ValueRefList::iterator I = $6->begin(), E = $6->end(); I != E; ++I) { const Type *Ty = I->Val->getType(); if (Ty == Type::VoidTy) @@ -2674,7 +2681,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { ParamAttrs.push_back(I->Attrs); } - Ty = FunctionType::get($3.Ty->get(), ParamTypes, false, ParamAttrs); + Ty = FunctionType::get($3->get(), ParamTypes, false, ParamAttrs); PFTy = PointerType::get(Ty); } diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index a46adabd1e1..f5b24844295 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -271,10 +271,6 @@ static void calcTypeName(const Type *Ty, case Type::FunctionTyID: { const FunctionType *FTy = cast(Ty); calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result); - if (FTy->getParamAttrs(0)) { - Result += " "; - Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(0)); - } Result += " ("; unsigned Idx = 1; for (FunctionType::param_iterator I = FTy->param_begin(), @@ -293,6 +289,10 @@ static void calcTypeName(const Type *Ty, Result += "..."; } Result += ")"; + if (FTy->getParamAttrs(0)) { + Result += " "; + Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(0)); + } break; } case Type::StructTyID: { @@ -698,8 +698,6 @@ private: std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { if (const FunctionType *FTy = dyn_cast(Ty)) { printType(FTy->getReturnType()); - if (FTy->getParamAttrs(0)) - Out << ' ' << FunctionType::getParamAttrsText(FTy->getParamAttrs(0)); Out << " ("; unsigned Idx = 1; for (FunctionType::param_iterator I = FTy->param_begin(), @@ -717,6 +715,8 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { Out << "..."; } Out << ')'; + if (FTy->getParamAttrs(0)) + Out << ' ' << FunctionType::getParamAttrsText(FTy->getParamAttrs(0)); } else if (const StructType *STy = dyn_cast(Ty)) { if (STy->isPacked()) Out << '<'; @@ -969,8 +969,6 @@ void AssemblyWriter::printFunction(const Function *F) { const FunctionType *FT = F->getFunctionType(); printType(F->getReturnType()) << ' '; - if (FT->getParamAttrs(0)) - Out << FunctionType::getParamAttrsText(FT->getParamAttrs(0)) << ' '; if (!F->getName().empty()) Out << getLLVMName(F->getName()); else @@ -995,7 +993,8 @@ void AssemblyWriter::printFunction(const Function *F) { Out << "..."; // Output varargs portion of signature! } Out << ')'; - + if (FT->getParamAttrs(0)) + Out << ' ' << FunctionType::getParamAttrsText(FT->getParamAttrs(0)); if (F->hasSection()) Out << " section \"" << F->getSection() << '"'; if (F->getAlignment()) @@ -1186,8 +1185,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) { (!isa(RetTy) || !isa(cast(RetTy)->getElementType()))) { Out << ' '; printType(RetTy); - if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet) - Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(0)); writeOperand(Operand, false); } else { writeOperand(Operand, true); @@ -1201,6 +1198,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(op)); } Out << " )"; + if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet) + Out << ' ' << FTy->getParamAttrsText(FTy->getParamAttrs(0)); } else if (const InvokeInst *II = dyn_cast(&I)) { const PointerType *PTy = cast(Operand->getType()); const FunctionType *FTy = cast(PTy->getElementType()); @@ -1225,8 +1224,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) { (!isa(RetTy) || !isa(cast(RetTy)->getElementType()))) { Out << ' '; printType(RetTy); - if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet) - Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(0)); writeOperand(Operand, false); } else { writeOperand(Operand, true); @@ -1241,7 +1238,10 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(op-2)); } - Out << " )\n\t\t\tto"; + Out << " )"; + if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet) + Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(0)); + Out << "\n\t\t\tto"; writeOperand(II->getNormalDest(), true); Out << " unwind"; writeOperand(II->getUnwindDest(), true); diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index e328369d90c..25da1e3a851 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -245,7 +245,6 @@ static std::string getTypeDescription(const Type *Ty, switch (Ty->getTypeID()) { case Type::FunctionTyID: { const FunctionType *FTy = cast(Ty); - Result = FunctionType::getParamAttrsText(FTy->getParamAttrs(0)); if (!Result.empty()) Result += " "; Result += getTypeDescription(FTy->getReturnType(), TypeStack) + " ("; @@ -254,11 +253,7 @@ static std::string getTypeDescription(const Type *Ty, E = FTy->param_end(); I != E; ++I) { if (I != FTy->param_begin()) Result += ", "; - const char *PA = FunctionType::getParamAttrsText(FTy->getParamAttrs(Idx)); - if (PA[0] != 0) { - Result += PA; - Result += " "; - } + Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(Idx)); Idx++; Result += getTypeDescription(*I, TypeStack); } @@ -267,6 +262,9 @@ static std::string getTypeDescription(const Type *Ty, Result += "..."; } Result += ")"; + if (FTy->getParamAttrs(0)) { + Result += " " + FunctionType::getParamAttrsText(FTy->getParamAttrs(0)); + } break; } case Type::StructTyID: { @@ -1021,13 +1019,15 @@ FunctionType::getParamAttrs(unsigned Idx) const { return (*ParamAttrs)[Idx]; } -const char *FunctionType::getParamAttrsText(ParameterAttributes Attr) { - switch (Attr) { - default: assert(0 && "Invalid ParameterAttribute value"); - case 0: return ""; - case ZExtAttribute: return "@zext"; - case SExtAttribute: return "@sext"; - } +std::string FunctionType::getParamAttrsText(ParameterAttributes Attr) { + std::string Result; + if (Attr & ZExtAttribute) + Result += "zext "; + if (Attr & SExtAttribute) + Result += "sext "; + if (Attr & NoReturnAttribute) + Result += "noreturn "; + return Result; } //===----------------------------------------------------------------------===// -- 2.34.1