Type ASTContext::GetBuiltinType(unsigned Id, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs) const { const char *TypeStr = BuiltinInfo.GetTypeString(Id); SmallVector<Type, 8> ArgTypes; bool RequiresICE = false; Error = GE_None; Type ResType = DecodeTypeFromStr(TypeStr, *this, Error, RequiresICE, true); if (Error != GE_None) return Type(); assert(!RequiresICE && "Result of intrinsic cannot be required to be an ICE"); while (TypeStr[0] && TypeStr[0] != '.') { Type Ty = DecodeTypeFromStr(TypeStr, *this, Error, RequiresICE, true); if (Error != GE_None) return Type(); // If this argument is required to be an IntegerConstantExpression and the // caller cares, fill in the bitmask we return. if (RequiresICE && IntegerConstantArgs) *IntegerConstantArgs |= 1 << ArgTypes.size(); // Do array -> pointer decay. The builtin should use the decayed type. // if (Ty->isArrayType()) // Ty = getArrayDecayedType(Ty); ArgTypes.push_back(Ty); } assert((TypeStr[0] != '.' || TypeStr[1] == 0) && "'.' should only occur at end of builtin type list!"); FunctionType::ExtInfo EI; if (BuiltinInfo.isNoReturn(Id)) EI = EI.withNoReturn(true); bool Variadic = (TypeStr[0] == '.'); // We really shouldn't be making a no-proto type here, especially in C++. if (ArgTypes.empty() && Variadic) { return getFunctionNoProtoType(ResType, EI); } FunctionProtoType::ExtProtoInfo EPI; EPI.ExtInfo = EI; EPI.Variadic = Variadic; return getFunctionType(ResType, ArgTypes.data(), ArgTypes.size(), EPI); }
Type ASTContext::getFunctionNoProtoType(Type ResultTy, FunctionType::ExtInfo Info) const { const CallingConv DefaultCC = Info.getCC(); const CallingConv CallConv = (DefaultCC == CC_Default) ? CC_X86StdCall : DefaultCC; // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; FunctionNoProtoType::Profile(ID, ResultTy, Info); void *InsertPos = 0; if (FunctionNoProtoType *FT = FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) return Type(FT, 0); FunctionProtoType::ExtInfo newInfo = Info.withCallingConv(CallConv); FunctionNoProtoType *New; New = new (*this, TypeAlignment) FunctionNoProtoType(ResultTy, newInfo); Types.push_back(New); FunctionNoProtoTypes.InsertNode(New, InsertPos); return Type(New, 0); }
void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, raw_ostream &OS) { // If needed for precedence reasons, wrap the inner part in grouping parens. if (!HasEmptyPlaceHolder) OS << ')'; SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); OS << '('; { ParamPolicyRAII ParamPolicy(Policy); for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { if (i) OS << ", "; print(T->getArgType(i), OS, StringRef()); } } if (T->isVariadic()) { if (T->getNumArgs()) OS << ", "; OS << "..."; } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) { // Do not emit int() if we have a proto, emit 'int(void)'. OS << "void"; } OS << ')'; FunctionType::ExtInfo Info = T->getExtInfo(); switch(Info.getCC()) { case CC_Default: break; case CC_C: OS << " __attribute__((cdecl))"; break; case CC_X86StdCall: OS << " __attribute__((stdcall))"; break; case CC_X86FastCall: OS << " __attribute__((fastcall))"; break; case CC_X86ThisCall: OS << " __attribute__((thiscall))"; break; case CC_X86Pascal: OS << " __attribute__((pascal))"; break; case CC_AAPCS: OS << " __attribute__((pcs(\"aapcs\")))"; break; case CC_AAPCS_VFP: OS << " __attribute__((pcs(\"aapcs-vfp\")))"; break; case CC_PnaclCall: OS << " __attribute__((pnaclcall))"; break; case CC_IntelOclBicc: OS << " __attribute__((intel_ocl_bicc))"; break; } if (Info.getNoReturn()) OS << " __attribute__((noreturn))"; if (Info.getRegParm()) OS << " __attribute__((regparm (" << Info.getRegParm() << ")))"; if (unsigned quals = T->getTypeQuals()) { OS << ' '; AppendTypeQualList(OS, quals); } switch (T->getRefQualifier()) { case RQ_None: break; case RQ_LValue: OS << " &"; break; case RQ_RValue: OS << " &&"; break; } if (T->hasTrailingReturn()) { OS << " -> "; print(T->getResultType(), OS, StringRef()); } else printAfter(T->getResultType(), OS); }
void TypePrinter::PrintFunctionProto(const FunctionProtoType *T, std::string &S) { // If needed for precedence reasons, wrap the inner part in grouping parens. if (!S.empty()) S = "(" + S + ")"; S += "("; std::string Tmp; PrintingPolicy ParamPolicy(Policy); ParamPolicy.SuppressSpecifiers = false; for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { if (i) S += ", "; Print(T->getArgType(i), Tmp); S += Tmp; Tmp.clear(); } if (T->isVariadic()) { if (T->getNumArgs()) S += ", "; S += "..."; } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) { // Do not emit int() if we have a proto, emit 'int(void)'. S += "void"; } S += ")"; FunctionType::ExtInfo Info = T->getExtInfo(); switch(Info.getCC()) { case CC_Default: default: break; case CC_C: S += " __attribute__((cdecl))"; break; case CC_X86StdCall: S += " __attribute__((stdcall))"; break; case CC_X86FastCall: S += " __attribute__((fastcall))"; break; case CC_X86ThisCall: S += " __attribute__((thiscall))"; break; } if (Info.getNoReturn()) S += " __attribute__((noreturn))"; if (Info.getRegParm()) S += " __attribute__((regparm (" + llvm::utostr_32(Info.getRegParm()) + ")))"; if (T->hasExceptionSpec()) { S += " throw("; if (T->hasAnyExceptionSpec()) S += "..."; else for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) { if (I) S += ", "; std::string ExceptionType; Print(T->getExceptionType(I), ExceptionType); S += ExceptionType; } S += ")"; } AppendTypeQualList(S, T->getTypeQuals()); Print(T->getResultType(), S); }
void TypePrinter::printFunctionProto(const FunctionProtoType *T, std::string &S) { // If needed for precedence reasons, wrap the inner part in grouping parens. if (!S.empty()) S = "(" + S + ")"; S += "("; std::string Tmp; PrintingPolicy ParamPolicy(Policy); ParamPolicy.SuppressSpecifiers = false; for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { if (i) S += ", "; print(T->getArgType(i), Tmp); S += Tmp; Tmp.clear(); } if (T->isVariadic()) { if (T->getNumArgs()) S += ", "; S += "..."; } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) { // Do not emit int() if we have a proto, emit 'int(void)'. S += "void"; } S += ")"; FunctionType::ExtInfo Info = T->getExtInfo(); switch(Info.getCC()) { case CC_Default: default: break; case CC_C: S += " __attribute__((cdecl))"; break; case CC_X86StdCall: S += " __attribute__((stdcall))"; break; case CC_X86FastCall: S += " __attribute__((fastcall))"; break; case CC_X86ThisCall: S += " __attribute__((thiscall))"; break; case CC_X86Pascal: S += " __attribute__((pascal))"; break; case CC_AAPCS: S += " __attribute__((pcs(\"aapcs\")))"; break; case CC_AAPCS_VFP: S += " __attribute__((pcs(\"aapcs-vfp\")))"; break; } if (Info.getNoReturn()) S += " __attribute__((noreturn))"; if (Info.getRegParm()) S += " __attribute__((regparm (" + llvm::utostr_32(Info.getRegParm()) + ")))"; AppendTypeQualList(S, T->getTypeQuals()); switch (T->getRefQualifier()) { case RQ_None: break; case RQ_LValue: S += " &"; break; case RQ_RValue: S += " &&"; break; } if (T->hasDynamicExceptionSpec()) { S += " throw("; if (T->getExceptionSpecType() == EST_MSAny) S += "..."; else for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) { if (I) S += ", "; std::string ExceptionType; print(T->getExceptionType(I), ExceptionType); S += ExceptionType; } S += ")"; } else if (isNoexceptExceptionSpec(T->getExceptionSpecType())) { S += " noexcept"; if (T->getExceptionSpecType() == EST_ComputedNoexcept) { S += "("; llvm::raw_string_ostream EOut(S); T->getNoexceptExpr()->printPretty(EOut, 0, Policy); EOut.flush(); S += EOut.str(); S += ")"; } } print(T->getResultType(), S); }
void TypePrinter::printFunctionProto(const FunctionProtoType *T, std::string &S) { // If needed for precedence reasons, wrap the inner part in grouping parens. if (!S.empty()) S = "(" + S + ")"; S += "("; std::string Tmp; PrintingPolicy ParamPolicy(Policy); ParamPolicy.SuppressSpecifiers = false; for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { if (i) S += ", "; print(T->getArgType(i), Tmp); S += Tmp; Tmp.clear(); } if (T->isVariadic()) { if (T->getNumArgs()) S += ", "; S += "..."; } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) { // Do not emit int() if we have a proto, emit 'int(void)'. S += "void"; } S += ")"; FunctionType::ExtInfo Info = T->getExtInfo(); switch(Info.getCC()) { case CC_Default: break; case CC_C: S += " __attribute__((cdecl))"; break; case CC_X86StdCall: S += " __attribute__((stdcall))"; break; case CC_X86FastCall: S += " __attribute__((fastcall))"; break; case CC_X86ThisCall: S += " __attribute__((thiscall))"; break; case CC_X86Pascal: S += " __attribute__((pascal))"; break; case CC_AAPCS: S += " __attribute__((pcs(\"aapcs\")))"; break; case CC_AAPCS_VFP: S += " __attribute__((pcs(\"aapcs-vfp\")))"; break; } if (Info.getNoReturn()) S += " __attribute__((noreturn))"; if (Info.getRegParm()) S += " __attribute__((regparm (" + llvm::utostr_32(Info.getRegParm()) + ")))"; AppendTypeQualList(S, T->getTypeQuals()); switch (T->getRefQualifier()) { case RQ_None: break; case RQ_LValue: S += " &"; break; case RQ_RValue: S += " &&"; break; } T->printExceptionSpecification(S, Policy); if (T->hasTrailingReturn()) { std::string ResultS; print(T->getResultType(), ResultS); S = "auto " + S + " -> " + ResultS; } else print(T->getResultType(), S); }