19eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===//
29eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar//
39eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar//                     The LLVM Compiler Infrastructure
49eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar//
59eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar// This file is distributed under the University of Illinois Open Source
69eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar// License. See LICENSE.TXT for details.
79eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar//
89eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar//===----------------------------------------------------------------------===//
99eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar
109eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar#ifndef CLANG_CODEGEN_ABIINFO_H
119eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar#define CLANG_CODEGEN_ABIINFO_H
129eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar
13c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov#include "clang/AST/Type.h"
14958c53c369b2e96b7638f170a3fcb4ff43382ff1Chris Lattner#include "llvm/Type.h"
15c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov
1688c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbarnamespace llvm {
17c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov  class Value;
18f21efe9088a0b3eda1209d1706529f6cb2073092Benjamin Kramer  class LLVMContext;
19ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner  class TargetData;
2088c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar}
2188c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar
229eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbarnamespace clang {
236bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar  class ASTContext;
246bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar
256bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar  namespace CodeGen {
266bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar    class CGFunctionInfo;
27b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar    class CodeGenFunction;
28ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner    class CodeGenTypes;
296bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar  }
306bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar
312eb9cdd5922c6fe48af185bee1988dabb5bd644eChris Lattner  // FIXME: All of this stuff should be part of the target interface
322eb9cdd5922c6fe48af185bee1988dabb5bd644eChris Lattner  // somehow. It is currently here because it is not clear how to factor
332eb9cdd5922c6fe48af185bee1988dabb5bd644eChris Lattner  // the targets to support this, since the Targets currently live in a
342eb9cdd5922c6fe48af185bee1988dabb5bd644eChris Lattner  // layer below types n'stuff.
359eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar
369eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  /// ABIArgInfo - Helper class to encapsulate information about how a
379eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  /// specific C type should be passed to or returned from a function.
389eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  class ABIArgInfo {
399eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  public:
409eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    enum Kind {
41117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// Direct - Pass the argument directly using the normal converted LLVM
42117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// type, or by coercing to another specified type stored in
43117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// 'CoerceToType').  If an offset is specified (in UIntData), then the
44117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// argument passed is offset by some number of bytes in the memory
45f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka      /// representation. A dummy argument is emitted before the real argument
46f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka      /// if the specified type stored in "PaddingType" is not zero.
47117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      Direct,
48117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner
49117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// Extend - Valid only for integer argument types. Same as 'direct'
50117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// but also emit a zero/sign extension attribute.
51117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      Extend,
52117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner
53117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// Indirect - Pass the argument indirectly via a hidden pointer
54117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// with the specified alignment (0 indicates default alignment).
55117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      Indirect,
56117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner
57117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// Ignore - Ignore the argument (treat as void). Useful for void and
58117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// empty structs.
59117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      Ignore,
60117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner
61117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// Expand - Only valid for aggregate argument types. The structure should
62117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// be expanded into consecutive arguments for its constituent fields.
63117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// Currently expand is only allowed on structures whose fields
64117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      /// are all scalar types or are themselves expandable types.
65117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      Expand,
66c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov
670bcc52114e37a8d152d9a05095ee7f7687c9aa94Daniel Dunbar      KindFirst=Direct, KindLast=Expand
689eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    };
69c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov
709eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  private:
719eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    Kind TheKind;
729cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *TypeData;
73f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka    llvm::Type *PaddingType; // Currently allowed only for Direct.
749eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    unsigned UIntData;
75cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar    bool BoolData0;
76cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar    bool BoolData1;
77b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola    bool InReg;
78c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov
79b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola    ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR,
8057bc51cfec0f39376ad78c03432a12137cd26c2aRafael Espindola               llvm::Type* P)
81f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka      : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0),
82b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola        BoolData1(B1), InReg(IR) {}
830a8f847e97f40cce51dc69051b964732333dc028Anders Carlsson
849eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  public:
850bcc52114e37a8d152d9a05095ee7f7687c9aa94Daniel Dunbar    ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
8688c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar
87f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka    static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0,
88f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka                                llvm::Type *Padding = 0) {
89b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola      return ABIArgInfo(Direct, T, Offset, false, false, false, Padding);
90b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola    }
91b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola    static ABIArgInfo getDirectInReg(llvm::Type *T) {
92b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola      return ABIArgInfo(Direct, T, 0, false, false, true, 0);
9346327aaf031529be2cf8bb21bc76d7a5ae0d43cdDaniel Dunbar    }
949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    static ABIArgInfo getExtend(llvm::Type *T = 0) {
95b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola      return ABIArgInfo(Extend, T, 0, false, false, false, 0);
96b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola    }
97b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola    static ABIArgInfo getExtendInReg(llvm::Type *T = 0) {
98b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola      return ABIArgInfo(Extend, T, 0, false, false, true, 0);
99cc6fa88666ca2f287df4a600eb31a4087bab9c13Anton Korobeynikov    }
1009eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    static ABIArgInfo getIgnore() {
101b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola      return ABIArgInfo(Ignore, 0, 0, false, false, false, 0);
1029eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    }
103cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar    static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true
104cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar                                  , bool Realign = false) {
105b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, 0);
106b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola    }
107b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola    static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true
108b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola                                  , bool Realign = false) {
109b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, 0);
1109eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    }
1119eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    static ABIArgInfo getExpand() {
112b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola      return ABIArgInfo(Expand, 0, 0, false, false, false, 0);
1139eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    }
114c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov
1159eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    Kind getKind() const { return TheKind; }
11646327aaf031529be2cf8bb21bc76d7a5ae0d43cdDaniel Dunbar    bool isDirect() const { return TheKind == Direct; }
117cc6fa88666ca2f287df4a600eb31a4087bab9c13Anton Korobeynikov    bool isExtend() const { return TheKind == Extend; }
1189eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    bool isIgnore() const { return TheKind == Ignore; }
11911e383aa491a23ebd4a49688a09984c5e16a2e34Daniel Dunbar    bool isIndirect() const { return TheKind == Indirect; }
1209eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    bool isExpand() const { return TheKind == Expand; }
121c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov
122800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner    bool canHaveCoerceToType() const {
123800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner      return TheKind == Direct || TheKind == Extend;
124800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner    }
1259cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer
126800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner    // Direct/Extend accessors
127117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner    unsigned getDirectOffset() const {
128117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      assert((isDirect() || isExtend()) && "Not a direct or extend kind");
129117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner      return UIntData;
130117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner    }
131f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka
132f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka    llvm::Type *getPaddingType() const {
133f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka      return PaddingType;
134f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka    }
135f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka
1369cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *getCoerceToType() const {
137800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner      assert(canHaveCoerceToType() && "Invalid kind!");
1389eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar      return TypeData;
1399eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    }
1409cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer
1419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    void setCoerceToType(llvm::Type *T) {
142800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner      assert(canHaveCoerceToType() && "Invalid kind!");
143800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner      TypeData = T;
144800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner    }
1459cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer
146b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola    bool getInReg() const {
147b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola      assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
148b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola      return InReg;
149b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola    }
150b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola
1510a8f847e97f40cce51dc69051b964732333dc028Anders Carlsson    // Indirect accessors
15211e383aa491a23ebd4a49688a09984c5e16a2e34Daniel Dunbar    unsigned getIndirectAlign() const {
15311e383aa491a23ebd4a49688a09984c5e16a2e34Daniel Dunbar      assert(TheKind == Indirect && "Invalid kind!");
1549eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar      return UIntData;
1559eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    }
1566f7279bf98e31356306386b2c200820a76b491cfDaniel Dunbar
1570a8f847e97f40cce51dc69051b964732333dc028Anders Carlsson    bool getIndirectByVal() const {
1580a8f847e97f40cce51dc69051b964732333dc028Anders Carlsson      assert(TheKind == Indirect && "Invalid kind!");
159cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar      return BoolData0;
160cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar    }
161cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar
162cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar    bool getIndirectRealign() const {
163cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar      assert(TheKind == Indirect && "Invalid kind!");
164cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar      return BoolData1;
1650a8f847e97f40cce51dc69051b964732333dc028Anders Carlsson    }
1669cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer
1676f7279bf98e31356306386b2c200820a76b491cfDaniel Dunbar    void dump() const;
1689eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  };
1699eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar
1709eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  /// ABIInfo - Target specific hooks for defining how a type should be
1719eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  /// passed or returned from functions.
1729eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  class ABIInfo {
1739eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  public:
174ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner    CodeGen::CodeGenTypes &CGT;
1759cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer
176ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner    ABIInfo(CodeGen::CodeGenTypes &cgt) : CGT(cgt) {}
1779eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar    virtual ~ABIInfo();
1789cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer
179ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner    ASTContext &getContext() const;
180ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner    llvm::LLVMContext &getVMContext() const;
181ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner    const llvm::TargetData &getTargetData() const;
1826bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar
183ee5dcd064a811edc90f6c1fb31a837b6c961fed7Chris Lattner    virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0;
184b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar
185b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar    /// EmitVAArg - Emit the target dependent code to load a value of
186b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar    /// \arg Ty from the va_list pointed to by \arg VAListAddr.
187c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov
188b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar    // FIXME: This is a gaping layering violation if we wanted to drop
189b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar    // the ABI information any lower than CodeGen. Of course, for
190b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar    // VAArg handling it has to be at this level; there is no way to
191b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar    // abstract this out.
192b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar    virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
193b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar                                   CodeGen::CodeGenFunction &CGF) const = 0;
1949eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar  };
1959eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar}  // end namespace clang
1969eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar
1979eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar#endif
198