diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGCall.h')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGCall.h | 154 |
1 files changed, 116 insertions, 38 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGCall.h b/contrib/llvm/tools/clang/lib/CodeGen/CGCall.h index 24ed366..dead7bd 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGCall.h +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGCall.h @@ -98,6 +98,55 @@ namespace CodeGen { SmallVector<Writeback, 1> Writebacks; }; + /// A class for recording the number of arguments that a function + /// signature requires. + class RequiredArgs { + /// The number of required arguments, or ~0 if the signature does + /// not permit optional arguments. + unsigned NumRequired; + public: + enum All_t { All }; + + RequiredArgs(All_t _) : NumRequired(~0U) {} + explicit RequiredArgs(unsigned n) : NumRequired(n) { + assert(n != ~0U); + } + + /// Compute the arguments required by the given formal prototype, + /// given that there may be some additional, non-formal arguments + /// in play. + static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, + unsigned additional) { + if (!prototype->isVariadic()) return All; + return RequiredArgs(prototype->getNumArgs() + additional); + } + + static RequiredArgs forPrototype(const FunctionProtoType *prototype) { + return forPrototypePlus(prototype, 0); + } + + static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) { + return forPrototype(prototype.getTypePtr()); + } + + static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, + unsigned additional) { + return forPrototypePlus(prototype.getTypePtr(), additional); + } + + bool allowsOptionalArgs() const { return NumRequired != ~0U; } + bool getNumRequiredArgs() const { + assert(allowsOptionalArgs()); + return NumRequired; + } + + unsigned getOpaqueData() const { return NumRequired; } + static RequiredArgs getFromOpaqueData(unsigned value) { + if (value == ~0U) return All; + return RequiredArgs(value); + } + }; + /// FunctionArgList - Type for representing both the decl and type /// of parameters to a function. The decl must be either a /// ParmVarDecl or ImplicitParamDecl. @@ -114,50 +163,71 @@ namespace CodeGen { /// The LLVM::CallingConv to use for this function (as specified by the /// user). - unsigned CallingConvention; + unsigned CallingConvention : 8; /// The LLVM::CallingConv to actually use for this function, which may /// depend on the ABI. - unsigned EffectiveCallingConvention; + unsigned EffectiveCallingConvention : 8; + + /// The clang::CallingConv that this was originally created with. + unsigned ASTCallingConvention : 8; /// Whether this function is noreturn. - bool NoReturn; + unsigned NoReturn : 1; /// Whether this function is returns-retained. - bool ReturnsRetained; + unsigned ReturnsRetained : 1; + + /// How many arguments to pass inreg. + unsigned HasRegParm : 1; + unsigned RegParm : 4; + + RequiredArgs Required; unsigned NumArgs; - ArgInfo *Args; + ArgInfo *getArgsBuffer() { + return reinterpret_cast<ArgInfo*>(this+1); + } + const ArgInfo *getArgsBuffer() const { + return reinterpret_cast<const ArgInfo*>(this + 1); + } - /// How many arguments to pass inreg. - bool HasRegParm; - unsigned RegParm; + CGFunctionInfo() : Required(RequiredArgs::All) {} public: + static CGFunctionInfo *create(unsigned llvmCC, + const FunctionType::ExtInfo &extInfo, + CanQualType resultType, + ArrayRef<CanQualType> argTypes, + RequiredArgs required); + typedef const ArgInfo *const_arg_iterator; typedef ArgInfo *arg_iterator; - CGFunctionInfo(unsigned CallingConvention, bool NoReturn, - bool ReturnsRetained, bool HasRegParm, unsigned RegParm, - CanQualType ResTy, - const CanQualType *ArgTys, unsigned NumArgTys); - ~CGFunctionInfo() { delete[] Args; } - - const_arg_iterator arg_begin() const { return Args + 1; } - const_arg_iterator arg_end() const { return Args + 1 + NumArgs; } - arg_iterator arg_begin() { return Args + 1; } - arg_iterator arg_end() { return Args + 1 + NumArgs; } + const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; } + const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; } + arg_iterator arg_begin() { return getArgsBuffer() + 1; } + arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; } unsigned arg_size() const { return NumArgs; } + bool isVariadic() const { return Required.allowsOptionalArgs(); } + RequiredArgs getRequiredArgs() const { return Required; } + bool isNoReturn() const { return NoReturn; } - /// In ARR, whether this function retains its return value. This + /// In ARC, whether this function retains its return value. This /// is not always reliable for call sites. bool isReturnsRetained() const { return ReturnsRetained; } - /// getCallingConvention - Return the user specified calling + /// getASTCallingConvention() - Return the AST-specified calling /// convention. + CallingConv getASTCallingConvention() const { + return CallingConv(ASTCallingConvention); + } + + /// getCallingConvention - Return the user specified calling + /// convention, which has been translated into an LLVM CC. unsigned getCallingConvention() const { return CallingConvention; } /// getEffectiveCallingConvention - Return the actual calling convention to @@ -172,36 +242,44 @@ namespace CodeGen { bool getHasRegParm() const { return HasRegParm; } unsigned getRegParm() const { return RegParm; } - CanQualType getReturnType() const { return Args[0].type; } + FunctionType::ExtInfo getExtInfo() const { + return FunctionType::ExtInfo(isNoReturn(), + getHasRegParm(), getRegParm(), + getASTCallingConvention(), + isReturnsRetained()); + } + + CanQualType getReturnType() const { return getArgsBuffer()[0].type; } - ABIArgInfo &getReturnInfo() { return Args[0].info; } - const ABIArgInfo &getReturnInfo() const { return Args[0].info; } + ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; } + const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; } void Profile(llvm::FoldingSetNodeID &ID) { - ID.AddInteger(getCallingConvention()); + ID.AddInteger(getASTCallingConvention()); ID.AddBoolean(NoReturn); ID.AddBoolean(ReturnsRetained); ID.AddBoolean(HasRegParm); ID.AddInteger(RegParm); + ID.AddInteger(Required.getOpaqueData()); getReturnType().Profile(ID); for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it) it->type.Profile(ID); } - template<class Iterator> static void Profile(llvm::FoldingSetNodeID &ID, - const FunctionType::ExtInfo &Info, - CanQualType ResTy, - Iterator begin, - Iterator end) { - ID.AddInteger(Info.getCC()); - ID.AddBoolean(Info.getNoReturn()); - ID.AddBoolean(Info.getProducesResult()); - ID.AddBoolean(Info.getHasRegParm()); - ID.AddInteger(Info.getRegParm()); - ResTy.Profile(ID); - for (; begin != end; ++begin) { - CanQualType T = *begin; // force iterator to be over canonical types - T.Profile(ID); + const FunctionType::ExtInfo &info, + RequiredArgs required, + CanQualType resultType, + ArrayRef<CanQualType> argTypes) { + ID.AddInteger(info.getCC()); + ID.AddBoolean(info.getNoReturn()); + ID.AddBoolean(info.getProducesResult()); + ID.AddBoolean(info.getHasRegParm()); + ID.AddInteger(info.getRegParm()); + ID.AddInteger(required.getOpaqueData()); + resultType.Profile(ID); + for (ArrayRef<CanQualType>::iterator + i = argTypes.begin(), e = argTypes.end(); i != e; ++i) { + i->Profile(ID); } } }; |