CGFunctionInfo.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //==-- CGFunctionInfo.h - Representation of function argument/return types -==//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // Defines CGFunctionInfo and associated types used in representing the
  15. // LLVM source types and ABI-coerced types for function arguments and
  16. // return values.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
  20. #define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H
  21. #include "clang/AST/CanonicalType.h"
  22. #include "clang/AST/CharUnits.h"
  23. #include "clang/AST/Decl.h"
  24. #include "clang/AST/Type.h"
  25. #include "llvm/IR/DerivedTypes.h"
  26. #include "llvm/ADT/FoldingSet.h"
  27. #include "llvm/Support/TrailingObjects.h"
  28. #include <cassert>
  29. namespace clang {
  30. namespace CodeGen {
  31. /// ABIArgInfo - Helper class to encapsulate information about how a
  32. /// specific C type should be passed to or returned from a function.
  33. class ABIArgInfo {
  34. public:
  35. enum Kind : uint8_t {
  36. /// Direct - Pass the argument directly using the normal converted LLVM
  37. /// type, or by coercing to another specified type stored in
  38. /// 'CoerceToType'). If an offset is specified (in UIntData), then the
  39. /// argument passed is offset by some number of bytes in the memory
  40. /// representation. A dummy argument is emitted before the real argument
  41. /// if the specified type stored in "PaddingType" is not zero.
  42. Direct,
  43. /// Extend - Valid only for integer argument types. Same as 'direct'
  44. /// but also emit a zero/sign extension attribute.
  45. Extend,
  46. /// Indirect - Pass the argument indirectly via a hidden pointer with the
  47. /// specified alignment (0 indicates default alignment) and address space.
  48. Indirect,
  49. /// IndirectAliased - Similar to Indirect, but the pointer may be to an
  50. /// object that is otherwise referenced. The object is known to not be
  51. /// modified through any other references for the duration of the call, and
  52. /// the callee must not itself modify the object. Because C allows
  53. /// parameter variables to be modified and guarantees that they have unique
  54. /// addresses, the callee must defensively copy the object into a local
  55. /// variable if it might be modified or its address might be compared.
  56. /// Since those are uncommon, in principle this convention allows programs
  57. /// to avoid copies in more situations. However, it may introduce *extra*
  58. /// copies if the callee fails to prove that a copy is unnecessary and the
  59. /// caller naturally produces an unaliased object for the argument.
  60. IndirectAliased,
  61. /// Ignore - Ignore the argument (treat as void). Useful for void and
  62. /// empty structs.
  63. Ignore,
  64. /// Expand - Only valid for aggregate argument types. The structure should
  65. /// be expanded into consecutive arguments for its constituent fields.
  66. /// Currently expand is only allowed on structures whose fields
  67. /// are all scalar types or are themselves expandable types.
  68. Expand,
  69. /// CoerceAndExpand - Only valid for aggregate argument types. The
  70. /// structure should be expanded into consecutive arguments corresponding
  71. /// to the non-array elements of the type stored in CoerceToType.
  72. /// Array elements in the type are assumed to be padding and skipped.
  73. CoerceAndExpand,
  74. /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
  75. /// This is similar to indirect with byval, except it only applies to
  76. /// arguments stored in memory and forbids any implicit copies. When
  77. /// applied to a return type, it means the value is returned indirectly via
  78. /// an implicit sret parameter stored in the argument struct.
  79. InAlloca,
  80. KindFirst = Direct,
  81. KindLast = InAlloca
  82. };
  83. private:
  84. llvm::Type *TypeData; // canHaveCoerceToType()
  85. union {
  86. llvm::Type *PaddingType; // canHavePaddingType()
  87. llvm::Type *UnpaddedCoerceAndExpandType; // isCoerceAndExpand()
  88. };
  89. struct DirectAttrInfo {
  90. unsigned Offset;
  91. unsigned Align;
  92. };
  93. struct IndirectAttrInfo {
  94. unsigned Align;
  95. unsigned AddrSpace;
  96. };
  97. union {
  98. DirectAttrInfo DirectAttr; // isDirect() || isExtend()
  99. IndirectAttrInfo IndirectAttr; // isIndirect()
  100. unsigned AllocaFieldIndex; // isInAlloca()
  101. };
  102. Kind TheKind;
  103. bool PaddingInReg : 1;
  104. bool InAllocaSRet : 1; // isInAlloca()
  105. bool InAllocaIndirect : 1;// isInAlloca()
  106. bool IndirectByVal : 1; // isIndirect()
  107. bool IndirectRealign : 1; // isIndirect()
  108. bool SRetAfterThis : 1; // isIndirect()
  109. bool InReg : 1; // isDirect() || isExtend() || isIndirect()
  110. bool CanBeFlattened: 1; // isDirect()
  111. bool SignExt : 1; // isExtend()
  112. bool canHavePaddingType() const {
  113. return isDirect() || isExtend() || isIndirect() || isIndirectAliased() ||
  114. isExpand();
  115. }
  116. void setPaddingType(llvm::Type *T) {
  117. assert(canHavePaddingType());
  118. PaddingType = T;
  119. }
  120. void setUnpaddedCoerceToType(llvm::Type *T) {
  121. assert(isCoerceAndExpand());
  122. UnpaddedCoerceAndExpandType = T;
  123. }
  124. public:
  125. ABIArgInfo(Kind K = Direct)
  126. : TypeData(nullptr), PaddingType(nullptr), DirectAttr{0, 0}, TheKind(K),
  127. PaddingInReg(false), InAllocaSRet(false),
  128. InAllocaIndirect(false), IndirectByVal(false), IndirectRealign(false),
  129. SRetAfterThis(false), InReg(false), CanBeFlattened(false),
  130. SignExt(false) {}
  131. static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
  132. llvm::Type *Padding = nullptr,
  133. bool CanBeFlattened = true, unsigned Align = 0) {
  134. auto AI = ABIArgInfo(Direct);
  135. AI.setCoerceToType(T);
  136. AI.setPaddingType(Padding);
  137. AI.setDirectOffset(Offset);
  138. AI.setDirectAlign(Align);
  139. AI.setCanBeFlattened(CanBeFlattened);
  140. return AI;
  141. }
  142. static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
  143. auto AI = getDirect(T);
  144. AI.setInReg(true);
  145. return AI;
  146. }
  147. static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T = nullptr) {
  148. assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
  149. auto AI = ABIArgInfo(Extend);
  150. AI.setCoerceToType(T);
  151. AI.setPaddingType(nullptr);
  152. AI.setDirectOffset(0);
  153. AI.setDirectAlign(0);
  154. AI.setSignExt(true);
  155. return AI;
  156. }
  157. static ABIArgInfo getZeroExtend(QualType Ty, llvm::Type *T = nullptr) {
  158. assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
  159. auto AI = ABIArgInfo(Extend);
  160. AI.setCoerceToType(T);
  161. AI.setPaddingType(nullptr);
  162. AI.setDirectOffset(0);
  163. AI.setDirectAlign(0);
  164. AI.setSignExt(false);
  165. return AI;
  166. }
  167. // ABIArgInfo will record the argument as being extended based on the sign
  168. // of its type.
  169. static ABIArgInfo getExtend(QualType Ty, llvm::Type *T = nullptr) {
  170. assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
  171. if (Ty->hasSignedIntegerRepresentation())
  172. return getSignExtend(Ty, T);
  173. return getZeroExtend(Ty, T);
  174. }
  175. static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T = nullptr) {
  176. auto AI = getExtend(Ty, T);
  177. AI.setInReg(true);
  178. return AI;
  179. }
  180. static ABIArgInfo getIgnore() {
  181. return ABIArgInfo(Ignore);
  182. }
  183. static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true,
  184. bool Realign = false,
  185. llvm::Type *Padding = nullptr) {
  186. auto AI = ABIArgInfo(Indirect);
  187. AI.setIndirectAlign(Alignment);
  188. AI.setIndirectByVal(ByVal);
  189. AI.setIndirectRealign(Realign);
  190. AI.setSRetAfterThis(false);
  191. AI.setPaddingType(Padding);
  192. return AI;
  193. }
  194. /// Pass this in memory using the IR byref attribute.
  195. static ABIArgInfo getIndirectAliased(CharUnits Alignment, unsigned AddrSpace,
  196. bool Realign = false,
  197. llvm::Type *Padding = nullptr) {
  198. auto AI = ABIArgInfo(IndirectAliased);
  199. AI.setIndirectAlign(Alignment);
  200. AI.setIndirectRealign(Realign);
  201. AI.setPaddingType(Padding);
  202. AI.setIndirectAddrSpace(AddrSpace);
  203. return AI;
  204. }
  205. static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true,
  206. bool Realign = false) {
  207. auto AI = getIndirect(Alignment, ByVal, Realign);
  208. AI.setInReg(true);
  209. return AI;
  210. }
  211. static ABIArgInfo getInAlloca(unsigned FieldIndex, bool Indirect = false) {
  212. auto AI = ABIArgInfo(InAlloca);
  213. AI.setInAllocaFieldIndex(FieldIndex);
  214. AI.setInAllocaIndirect(Indirect);
  215. return AI;
  216. }
  217. static ABIArgInfo getExpand() {
  218. auto AI = ABIArgInfo(Expand);
  219. AI.setPaddingType(nullptr);
  220. return AI;
  221. }
  222. static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
  223. llvm::Type *Padding) {
  224. auto AI = getExpand();
  225. AI.setPaddingInReg(PaddingInReg);
  226. AI.setPaddingType(Padding);
  227. return AI;
  228. }
  229. /// \param unpaddedCoerceToType The coerce-to type with padding elements
  230. /// removed, canonicalized to a single element if it would otherwise
  231. /// have exactly one element.
  232. static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
  233. llvm::Type *unpaddedCoerceToType) {
  234. #ifndef NDEBUG
  235. // Check that unpaddedCoerceToType has roughly the right shape.
  236. // Assert that we only have a struct type if there are multiple elements.
  237. auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType);
  238. assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1);
  239. // Assert that all the non-padding elements have a corresponding element
  240. // in the unpadded type.
  241. unsigned unpaddedIndex = 0;
  242. for (auto eltType : coerceToType->elements()) {
  243. if (isPaddingForCoerceAndExpand(eltType)) continue;
  244. if (unpaddedStruct) {
  245. assert(unpaddedStruct->getElementType(unpaddedIndex) == eltType);
  246. } else {
  247. assert(unpaddedIndex == 0 && unpaddedCoerceToType == eltType);
  248. }
  249. unpaddedIndex++;
  250. }
  251. // Assert that there aren't extra elements in the unpadded type.
  252. if (unpaddedStruct) {
  253. assert(unpaddedStruct->getNumElements() == unpaddedIndex);
  254. } else {
  255. assert(unpaddedIndex == 1);
  256. }
  257. #endif
  258. auto AI = ABIArgInfo(CoerceAndExpand);
  259. AI.setCoerceToType(coerceToType);
  260. AI.setUnpaddedCoerceToType(unpaddedCoerceToType);
  261. return AI;
  262. }
  263. static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) {
  264. if (eltType->isArrayTy()) {
  265. assert(eltType->getArrayElementType()->isIntegerTy(8));
  266. return true;
  267. } else {
  268. return false;
  269. }
  270. }
  271. Kind getKind() const { return TheKind; }
  272. bool isDirect() const { return TheKind == Direct; }
  273. bool isInAlloca() const { return TheKind == InAlloca; }
  274. bool isExtend() const { return TheKind == Extend; }
  275. bool isIgnore() const { return TheKind == Ignore; }
  276. bool isIndirect() const { return TheKind == Indirect; }
  277. bool isIndirectAliased() const { return TheKind == IndirectAliased; }
  278. bool isExpand() const { return TheKind == Expand; }
  279. bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; }
  280. bool canHaveCoerceToType() const {
  281. return isDirect() || isExtend() || isCoerceAndExpand();
  282. }
  283. // Direct/Extend accessors
  284. unsigned getDirectOffset() const {
  285. assert((isDirect() || isExtend()) && "Not a direct or extend kind");
  286. return DirectAttr.Offset;
  287. }
  288. void setDirectOffset(unsigned Offset) {
  289. assert((isDirect() || isExtend()) && "Not a direct or extend kind");
  290. DirectAttr.Offset = Offset;
  291. }
  292. unsigned getDirectAlign() const {
  293. assert((isDirect() || isExtend()) && "Not a direct or extend kind");
  294. return DirectAttr.Align;
  295. }
  296. void setDirectAlign(unsigned Align) {
  297. assert((isDirect() || isExtend()) && "Not a direct or extend kind");
  298. DirectAttr.Align = Align;
  299. }
  300. bool isSignExt() const {
  301. assert(isExtend() && "Invalid kind!");
  302. return SignExt;
  303. }
  304. void setSignExt(bool SExt) {
  305. assert(isExtend() && "Invalid kind!");
  306. SignExt = SExt;
  307. }
  308. llvm::Type *getPaddingType() const {
  309. return (canHavePaddingType() ? PaddingType : nullptr);
  310. }
  311. bool getPaddingInReg() const {
  312. return PaddingInReg;
  313. }
  314. void setPaddingInReg(bool PIR) {
  315. PaddingInReg = PIR;
  316. }
  317. llvm::Type *getCoerceToType() const {
  318. assert(canHaveCoerceToType() && "Invalid kind!");
  319. return TypeData;
  320. }
  321. void setCoerceToType(llvm::Type *T) {
  322. assert(canHaveCoerceToType() && "Invalid kind!");
  323. TypeData = T;
  324. }
  325. llvm::StructType *getCoerceAndExpandType() const {
  326. assert(isCoerceAndExpand());
  327. return cast<llvm::StructType>(TypeData);
  328. }
  329. llvm::Type *getUnpaddedCoerceAndExpandType() const {
  330. assert(isCoerceAndExpand());
  331. return UnpaddedCoerceAndExpandType;
  332. }
  333. ArrayRef<llvm::Type *>getCoerceAndExpandTypeSequence() const {
  334. assert(isCoerceAndExpand());
  335. if (auto structTy =
  336. dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) {
  337. return structTy->elements();
  338. } else {
  339. return llvm::makeArrayRef(&UnpaddedCoerceAndExpandType, 1);
  340. }
  341. }
  342. bool getInReg() const {
  343. assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
  344. return InReg;
  345. }
  346. void setInReg(bool IR) {
  347. assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
  348. InReg = IR;
  349. }
  350. // Indirect accessors
  351. CharUnits getIndirectAlign() const {
  352. assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
  353. return CharUnits::fromQuantity(IndirectAttr.Align);
  354. }
  355. void setIndirectAlign(CharUnits IA) {
  356. assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
  357. IndirectAttr.Align = IA.getQuantity();
  358. }
  359. bool getIndirectByVal() const {
  360. assert(isIndirect() && "Invalid kind!");
  361. return IndirectByVal;
  362. }
  363. void setIndirectByVal(bool IBV) {
  364. assert(isIndirect() && "Invalid kind!");
  365. IndirectByVal = IBV;
  366. }
  367. unsigned getIndirectAddrSpace() const {
  368. assert(isIndirectAliased() && "Invalid kind!");
  369. return IndirectAttr.AddrSpace;
  370. }
  371. void setIndirectAddrSpace(unsigned AddrSpace) {
  372. assert(isIndirectAliased() && "Invalid kind!");
  373. IndirectAttr.AddrSpace = AddrSpace;
  374. }
  375. bool getIndirectRealign() const {
  376. assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
  377. return IndirectRealign;
  378. }
  379. void setIndirectRealign(bool IR) {
  380. assert((isIndirect() || isIndirectAliased()) && "Invalid kind!");
  381. IndirectRealign = IR;
  382. }
  383. bool isSRetAfterThis() const {
  384. assert(isIndirect() && "Invalid kind!");
  385. return SRetAfterThis;
  386. }
  387. void setSRetAfterThis(bool AfterThis) {
  388. assert(isIndirect() && "Invalid kind!");
  389. SRetAfterThis = AfterThis;
  390. }
  391. unsigned getInAllocaFieldIndex() const {
  392. assert(isInAlloca() && "Invalid kind!");
  393. return AllocaFieldIndex;
  394. }
  395. void setInAllocaFieldIndex(unsigned FieldIndex) {
  396. assert(isInAlloca() && "Invalid kind!");
  397. AllocaFieldIndex = FieldIndex;
  398. }
  399. unsigned getInAllocaIndirect() const {
  400. assert(isInAlloca() && "Invalid kind!");
  401. return InAllocaIndirect;
  402. }
  403. void setInAllocaIndirect(bool Indirect) {
  404. assert(isInAlloca() && "Invalid kind!");
  405. InAllocaIndirect = Indirect;
  406. }
  407. /// Return true if this field of an inalloca struct should be returned
  408. /// to implement a struct return calling convention.
  409. bool getInAllocaSRet() const {
  410. assert(isInAlloca() && "Invalid kind!");
  411. return InAllocaSRet;
  412. }
  413. void setInAllocaSRet(bool SRet) {
  414. assert(isInAlloca() && "Invalid kind!");
  415. InAllocaSRet = SRet;
  416. }
  417. bool getCanBeFlattened() const {
  418. assert(isDirect() && "Invalid kind!");
  419. return CanBeFlattened;
  420. }
  421. void setCanBeFlattened(bool Flatten) {
  422. assert(isDirect() && "Invalid kind!");
  423. CanBeFlattened = Flatten;
  424. }
  425. void dump() const;
  426. };
  427. /// A class for recording the number of arguments that a function
  428. /// signature requires.
  429. class RequiredArgs {
  430. /// The number of required arguments, or ~0 if the signature does
  431. /// not permit optional arguments.
  432. unsigned NumRequired;
  433. public:
  434. enum All_t { All };
  435. RequiredArgs(All_t _) : NumRequired(~0U) {}
  436. explicit RequiredArgs(unsigned n) : NumRequired(n) {
  437. assert(n != ~0U);
  438. }
  439. /// Compute the arguments required by the given formal prototype,
  440. /// given that there may be some additional, non-formal arguments
  441. /// in play.
  442. ///
  443. /// If FD is not null, this will consider pass_object_size params in FD.
  444. static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
  445. unsigned additional) {
  446. if (!prototype->isVariadic()) return All;
  447. if (prototype->hasExtParameterInfos())
  448. additional += llvm::count_if(
  449. prototype->getExtParameterInfos(),
  450. [](const FunctionProtoType::ExtParameterInfo &ExtInfo) {
  451. return ExtInfo.hasPassObjectSize();
  452. });
  453. return RequiredArgs(prototype->getNumParams() + additional);
  454. }
  455. static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
  456. unsigned additional) {
  457. return forPrototypePlus(prototype.getTypePtr(), additional);
  458. }
  459. static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
  460. return forPrototypePlus(prototype, 0);
  461. }
  462. static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) {
  463. return forPrototypePlus(prototype.getTypePtr(), 0);
  464. }
  465. bool allowsOptionalArgs() const { return NumRequired != ~0U; }
  466. unsigned getNumRequiredArgs() const {
  467. assert(allowsOptionalArgs());
  468. return NumRequired;
  469. }
  470. unsigned getOpaqueData() const { return NumRequired; }
  471. static RequiredArgs getFromOpaqueData(unsigned value) {
  472. if (value == ~0U) return All;
  473. return RequiredArgs(value);
  474. }
  475. };
  476. // Implementation detail of CGFunctionInfo, factored out so it can be named
  477. // in the TrailingObjects base class of CGFunctionInfo.
  478. struct CGFunctionInfoArgInfo {
  479. CanQualType type;
  480. ABIArgInfo info;
  481. };
  482. /// CGFunctionInfo - Class to encapsulate the information about a
  483. /// function definition.
  484. class CGFunctionInfo final
  485. : public llvm::FoldingSetNode,
  486. private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo,
  487. FunctionProtoType::ExtParameterInfo> {
  488. typedef CGFunctionInfoArgInfo ArgInfo;
  489. typedef FunctionProtoType::ExtParameterInfo ExtParameterInfo;
  490. /// The LLVM::CallingConv to use for this function (as specified by the
  491. /// user).
  492. unsigned CallingConvention : 8;
  493. /// The LLVM::CallingConv to actually use for this function, which may
  494. /// depend on the ABI.
  495. unsigned EffectiveCallingConvention : 8;
  496. /// The clang::CallingConv that this was originally created with.
  497. unsigned ASTCallingConvention : 6;
  498. /// Whether this is an instance method.
  499. unsigned InstanceMethod : 1;
  500. /// Whether this is a chain call.
  501. unsigned ChainCall : 1;
  502. /// Whether this function is a CMSE nonsecure call
  503. unsigned CmseNSCall : 1;
  504. /// Whether this function is noreturn.
  505. unsigned NoReturn : 1;
  506. /// Whether this function is returns-retained.
  507. unsigned ReturnsRetained : 1;
  508. /// Whether this function saved caller registers.
  509. unsigned NoCallerSavedRegs : 1;
  510. /// How many arguments to pass inreg.
  511. unsigned HasRegParm : 1;
  512. unsigned RegParm : 3;
  513. /// Whether this function has nocf_check attribute.
  514. unsigned NoCfCheck : 1;
  515. RequiredArgs Required;
  516. /// The struct representing all arguments passed in memory. Only used when
  517. /// passing non-trivial types with inalloca. Not part of the profile.
  518. llvm::StructType *ArgStruct;
  519. unsigned ArgStructAlign : 31;
  520. unsigned HasExtParameterInfos : 1;
  521. unsigned NumArgs;
  522. ArgInfo *getArgsBuffer() {
  523. return getTrailingObjects<ArgInfo>();
  524. }
  525. const ArgInfo *getArgsBuffer() const {
  526. return getTrailingObjects<ArgInfo>();
  527. }
  528. ExtParameterInfo *getExtParameterInfosBuffer() {
  529. return getTrailingObjects<ExtParameterInfo>();
  530. }
  531. const ExtParameterInfo *getExtParameterInfosBuffer() const{
  532. return getTrailingObjects<ExtParameterInfo>();
  533. }
  534. CGFunctionInfo() : Required(RequiredArgs::All) {}
  535. public:
  536. static CGFunctionInfo *create(unsigned llvmCC,
  537. bool instanceMethod,
  538. bool chainCall,
  539. const FunctionType::ExtInfo &extInfo,
  540. ArrayRef<ExtParameterInfo> paramInfos,
  541. CanQualType resultType,
  542. ArrayRef<CanQualType> argTypes,
  543. RequiredArgs required);
  544. void operator delete(void *p) { ::operator delete(p); }
  545. // Friending class TrailingObjects is apparently not good enough for MSVC,
  546. // so these have to be public.
  547. friend class TrailingObjects;
  548. size_t numTrailingObjects(OverloadToken<ArgInfo>) const {
  549. return NumArgs + 1;
  550. }
  551. size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
  552. return (HasExtParameterInfos ? NumArgs : 0);
  553. }
  554. typedef const ArgInfo *const_arg_iterator;
  555. typedef ArgInfo *arg_iterator;
  556. MutableArrayRef<ArgInfo> arguments() {
  557. return MutableArrayRef<ArgInfo>(arg_begin(), NumArgs);
  558. }
  559. ArrayRef<ArgInfo> arguments() const {
  560. return ArrayRef<ArgInfo>(arg_begin(), NumArgs);
  561. }
  562. const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
  563. const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
  564. arg_iterator arg_begin() { return getArgsBuffer() + 1; }
  565. arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
  566. unsigned arg_size() const { return NumArgs; }
  567. bool isVariadic() const { return Required.allowsOptionalArgs(); }
  568. RequiredArgs getRequiredArgs() const { return Required; }
  569. unsigned getNumRequiredArgs() const {
  570. return isVariadic() ? getRequiredArgs().getNumRequiredArgs() : arg_size();
  571. }
  572. bool isInstanceMethod() const { return InstanceMethod; }
  573. bool isChainCall() const { return ChainCall; }
  574. bool isCmseNSCall() const { return CmseNSCall; }
  575. bool isNoReturn() const { return NoReturn; }
  576. /// In ARC, whether this function retains its return value. This
  577. /// is not always reliable for call sites.
  578. bool isReturnsRetained() const { return ReturnsRetained; }
  579. /// Whether this function no longer saves caller registers.
  580. bool isNoCallerSavedRegs() const { return NoCallerSavedRegs; }
  581. /// Whether this function has nocf_check attribute.
  582. bool isNoCfCheck() const { return NoCfCheck; }
  583. /// getASTCallingConvention() - Return the AST-specified calling
  584. /// convention.
  585. CallingConv getASTCallingConvention() const {
  586. return CallingConv(ASTCallingConvention);
  587. }
  588. /// getCallingConvention - Return the user specified calling
  589. /// convention, which has been translated into an LLVM CC.
  590. unsigned getCallingConvention() const { return CallingConvention; }
  591. /// getEffectiveCallingConvention - Return the actual calling convention to
  592. /// use, which may depend on the ABI.
  593. unsigned getEffectiveCallingConvention() const {
  594. return EffectiveCallingConvention;
  595. }
  596. void setEffectiveCallingConvention(unsigned Value) {
  597. EffectiveCallingConvention = Value;
  598. }
  599. bool getHasRegParm() const { return HasRegParm; }
  600. unsigned getRegParm() const { return RegParm; }
  601. FunctionType::ExtInfo getExtInfo() const {
  602. return FunctionType::ExtInfo(isNoReturn(), getHasRegParm(), getRegParm(),
  603. getASTCallingConvention(), isReturnsRetained(),
  604. isNoCallerSavedRegs(), isNoCfCheck(),
  605. isCmseNSCall());
  606. }
  607. CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
  608. ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
  609. const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
  610. ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
  611. if (!HasExtParameterInfos) return {};
  612. return llvm::makeArrayRef(getExtParameterInfosBuffer(), NumArgs);
  613. }
  614. ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
  615. assert(argIndex <= NumArgs);
  616. if (!HasExtParameterInfos) return ExtParameterInfo();
  617. return getExtParameterInfos()[argIndex];
  618. }
  619. /// Return true if this function uses inalloca arguments.
  620. bool usesInAlloca() const { return ArgStruct; }
  621. /// Get the struct type used to represent all the arguments in memory.
  622. llvm::StructType *getArgStruct() const { return ArgStruct; }
  623. CharUnits getArgStructAlignment() const {
  624. return CharUnits::fromQuantity(ArgStructAlign);
  625. }
  626. void setArgStruct(llvm::StructType *Ty, CharUnits Align) {
  627. ArgStruct = Ty;
  628. ArgStructAlign = Align.getQuantity();
  629. }
  630. void Profile(llvm::FoldingSetNodeID &ID) {
  631. ID.AddInteger(getASTCallingConvention());
  632. ID.AddBoolean(InstanceMethod);
  633. ID.AddBoolean(ChainCall);
  634. ID.AddBoolean(NoReturn);
  635. ID.AddBoolean(ReturnsRetained);
  636. ID.AddBoolean(NoCallerSavedRegs);
  637. ID.AddBoolean(HasRegParm);
  638. ID.AddInteger(RegParm);
  639. ID.AddBoolean(NoCfCheck);
  640. ID.AddBoolean(CmseNSCall);
  641. ID.AddInteger(Required.getOpaqueData());
  642. ID.AddBoolean(HasExtParameterInfos);
  643. if (HasExtParameterInfos) {
  644. for (auto paramInfo : getExtParameterInfos())
  645. ID.AddInteger(paramInfo.getOpaqueValue());
  646. }
  647. getReturnType().Profile(ID);
  648. for (const auto &I : arguments())
  649. I.type.Profile(ID);
  650. }
  651. static void Profile(llvm::FoldingSetNodeID &ID,
  652. bool InstanceMethod,
  653. bool ChainCall,
  654. const FunctionType::ExtInfo &info,
  655. ArrayRef<ExtParameterInfo> paramInfos,
  656. RequiredArgs required,
  657. CanQualType resultType,
  658. ArrayRef<CanQualType> argTypes) {
  659. ID.AddInteger(info.getCC());
  660. ID.AddBoolean(InstanceMethod);
  661. ID.AddBoolean(ChainCall);
  662. ID.AddBoolean(info.getNoReturn());
  663. ID.AddBoolean(info.getProducesResult());
  664. ID.AddBoolean(info.getNoCallerSavedRegs());
  665. ID.AddBoolean(info.getHasRegParm());
  666. ID.AddInteger(info.getRegParm());
  667. ID.AddBoolean(info.getNoCfCheck());
  668. ID.AddBoolean(info.getCmseNSCall());
  669. ID.AddInteger(required.getOpaqueData());
  670. ID.AddBoolean(!paramInfos.empty());
  671. if (!paramInfos.empty()) {
  672. for (auto paramInfo : paramInfos)
  673. ID.AddInteger(paramInfo.getOpaqueValue());
  674. }
  675. resultType.Profile(ID);
  676. for (ArrayRef<CanQualType>::iterator
  677. i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
  678. i->Profile(ID);
  679. }
  680. }
  681. };
  682. } // end namespace CodeGen
  683. } // end namespace clang
  684. #endif
  685. #ifdef __GNUC__
  686. #pragma GCC diagnostic pop
  687. #endif