summaryrefslogtreecommitdiff
path: root/lib/CodeGen/ABIInfo.h
blob: 259b6142bf4a17250e92da98d884a7968bcd24f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef FLANG_CODEGEN_ABIINFO_H
#define FLANG_CODEGEN_ABIINFO_H

#include "flang/AST/Type.h"

namespace llvm {

class Type;

}

namespace flang {

/// ABIArgInfo - Helper class to encapsulate information about how a
/// specific Fortran type should be passed to a function.
class ABIArgInfo {
public:
  enum Kind {
    /// Passes by value.
    /// scalar - simple value.
    /// complex - aggregate value (real, im)
    /// character - aggregate value (ptr, len)
    Value,

    /// Passes a scalar/complex by reference
    /// Passes an array without shape info as a
    /// pointer to the elements
    Reference,

    /// Passes a scalar/complex as two arguments
    /// pointer argument - void*
    /// size argument - int32 (sizeof type)
    ReferenceAsVoidExtraSize,

    /// Passes an aggregate as separate arguments
    /// complex - two arguments (real, im)
    /// character - two arguments (ptr, len)
    Expand,

    /// Passes a character aggregate as two separate
    /// arguments. The pointer is passed in place of
    /// the actual argument, and the length is passed
    /// in the additional arguments as an integer.
    ExpandCharacterPutLengthToAdditionalArgsAsInt,

    /// Passes a complex by value using a vector type.
    ComplexValueAsVector
  };

private:
  Kind TheKind;
public:

  ABIArgInfo(Kind K) :
    TheKind(K) {}

  Kind getKind() const { return TheKind; }
};

/// ABIRetInfo - Helper class to encapsulate information about how a
/// specific Fortran type should be returned from a function.
class ABIRetInfo {
public:
  enum Kind {
    /// Returns void
    Nothing,

    /// Returns a value
    /// scalar - simple value
    /// complex - aggregate value (real, im)
    Value,

    /// Returns a character value using an argument
    CharacterValueAsArg,

    /// Returns an aggregate value(complex or struct) using an argument
    AggregateValueAsArg
  };
private:
  Kind  TheKind;
  llvm::Type *AggT;
public:

  ABIRetInfo(Kind K = Nothing) :
    TheKind(K), AggT(nullptr) {}
  ABIRetInfo(Kind K, llvm::Type *T) :
    TheKind(K), AggT(T) {}

  Kind getKind() const { return TheKind; }

  llvm::Type *getAggregateReturnType() const {
    return AggT;
  }

  bool hasAggregateReturnType() const {
    return AggT != nullptr;
  }
};

/// ABIInfo - Target specific hooks for defining how a type should be
/// passed or returned from functions.
class ABIInfo {
public:
  virtual void computeReturnTypeInfo(QualType T, ABIRetInfo &Info) const = 0;
};

}  // end namespace flang

#endif