summaryrefslogtreecommitdiffstats
path: root/clang/CodeGen/CodeGenFunction.h
blob: ff6ac655acd37a9e6ffc4da2c07a588ce9c06f91 (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
//===--- CodeGenFunction.h - Per-Function state for LLVM CodeGen ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the internal per-function state used for llvm translation. 
//
//===----------------------------------------------------------------------===//

#ifndef CODEGEN_CODEGENFUNCTION_H
#define CODEGEN_CODEGENFUNCTION_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/LLVMBuilder.h"

namespace llvm {
  class Module;
namespace clang {
  class ASTContext;
  class Decl;
  class FunctionDecl;
  class QualType;
  class SourceLocation;
  class TargetInfo;
  
  class Stmt;
  class CompoundStmt;
  class LabelStmt;
  class GotoStmt;
  class IfStmt;
  class WhileStmt;
  class DoStmt;
  class ForStmt;
  class ReturnStmt;
  class DeclStmt;
  
  class Expr;
  class DeclRefExpr;
  class StringLiteral;
  class IntegerLiteral;
  class CastExpr;
  class UnaryOperator;
  class BinaryOperator;
  
  class BlockVarDecl;
  class EnumConstantDecl;
namespace CodeGen {
  class CodeGenModule;
  

/// RValue - This trivial value class is used to represent the result of an
/// expression that is evaluated.  It can be one of two things: either a simple
/// LLVM SSA value, or the address of an aggregate value in memory.  These two
/// possibilities are discriminated by isAggregate/isScalar.
class RValue {
  Value *V;
  // TODO: Encode this into the low bit of pointer for more efficient
  // return-by-value.
  bool IsAggregate;
public:
  
  bool isAggregate() const { return IsAggregate; }
  bool isScalar() const { return !IsAggregate; }
  
  /// getVal() - Return the Value* of this scalar value.
  Value *getVal() const {
    assert(!isAggregate() && "Not a scalar!");
    return V;
  }

  /// getAggregateVal() - Return the Value* of the address of the aggregate.
  Value *getAggregateVal() const {
    assert(isAggregate() && "Not an aggregate!");
    return V;
  }
  
  static RValue get(Value *V) {
    RValue ER;
    ER.V = V;
    ER.IsAggregate = false;
    return ER;
  }
  static RValue getAggregate(Value *V) {
    RValue ER;
    ER.V = V;
    ER.IsAggregate = true;
    return ER;
  }
};


/// LValue - This represents an lvalue references.  Because C/C++ allow
/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
/// bitrange.
class LValue {
  // FIXME: Volatility.  Restrict?
  // alignment?
  llvm::Value *V;
public:
  bool isBitfield() const { return false; }
  
  llvm::Value *getAddress() const { assert(!isBitfield()); return V; }
  
  static LValue getAddr(Value *V) {
    LValue R;
    R.V = V;
    return R;
  }
};

/// CodeGenFunction - This class organizes the per-function state that is used
/// while generating LLVM code.
class CodeGenFunction {
  CodeGenModule &CGM;  // Per-module state.
  TargetInfo &Target;
  LLVMBuilder Builder;
  
  const FunctionDecl *CurFuncDecl;
  llvm::Function *CurFn;

  /// AllocaInsertPoint - This is an instruction in the entry block before which
  /// we prefer to insert allocas.
  llvm::Instruction *AllocaInsertPt;
  
  const llvm::Type *LLVMIntTy;
  
  /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
  /// decls.
  DenseMap<const Decl*, llvm::Value*> LocalDeclMap;

  /// LabelMap - This keeps track of the LLVM basic block for each C label.
  DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap;
public:
  CodeGenFunction(CodeGenModule &cgm);
  
  ASTContext &getContext() const;

  const llvm::Type *ConvertType(QualType T, SourceLocation Loc);
  
  void GenerateCode(const FunctionDecl *FD);
  
  
  /// getBasicBlockForLabel - Return the LLVM basicblock that the specified
  /// label maps to.
  llvm::BasicBlock *getBasicBlockForLabel(const LabelStmt *S);
  
  
  void EmitBlock(BasicBlock *BB);


  /// EvaluateExprAsBool - Perform the usual unary conversions on the specified
  /// expression and compare the result against zero, returning an Int1Ty value.
  Value *EvaluateExprAsBool(const Expr *E);
  
  //===--------------------------------------------------------------------===//
  //                                Conversions
  //===--------------------------------------------------------------------===//
  
  /// EmitConversion - Convert the value specied by Val, whose type is ValTy, to
  /// the type specified by DstTy, following the rules of C99 6.3.
  RValue EmitConversion(RValue Val, QualType ValTy, QualType DstTy,
                        SourceLocation Loc);
  
  /// ConvertScalarValueToBool - Convert the specified expression value to a
  /// boolean (i1) truth value.  This is equivalent to "Val == 0".
  Value *ConvertScalarValueToBool(RValue Val, QualType Ty);
  
  //===--------------------------------------------------------------------===//
  //                        Local Declaration Emission
  //===--------------------------------------------------------------------===//
  
  void EmitDeclStmt(const DeclStmt &S);
  void EmitEnumConstantDecl(const EnumConstantDecl &D);
  void EmitBlockVarDecl(const BlockVarDecl &D);
  void EmitLocalBlockVarDecl(const BlockVarDecl &D);
  
  //===--------------------------------------------------------------------===//
  //                             Statement Emission
  //===--------------------------------------------------------------------===//

  void EmitStmt(const Stmt *S);
  void EmitCompoundStmt(const CompoundStmt &S);
  void EmitLabelStmt(const LabelStmt &S);
  void EmitGotoStmt(const GotoStmt &S);
  void EmitIfStmt(const IfStmt &S);
  void EmitWhileStmt(const WhileStmt &S);
  void EmitDoStmt(const DoStmt &S);
  void EmitForStmt(const ForStmt &S);
  void EmitReturnStmt(const ReturnStmt &S);
  
  //===--------------------------------------------------------------------===//
  //                         LValue Expression Emission
  //===--------------------------------------------------------------------===//

  /// EmitLValue - Emit code to compute a designator that specifies the location
  /// of the expression.
  ///
  /// This can return one of two things: a simple address or a bitfield
  /// reference.  In either case, the LLVM Value* in the LValue structure is
  /// guaranteed to be an LLVM pointer type.
  ///
  /// If this returns a bitfield reference, nothing about the pointee type of
  /// the LLVM value is known: For example, it may not be a pointer to an
  /// integer.
  ///
  /// If this returns a normal address, and if the lvalue's C type is fixed
  /// size, this method guarantees that the returned pointer type will point to
  /// an LLVM type of the same size of the lvalue's type.  If the lvalue has a
  /// variable length type, this is not possible.
  ///
  LValue EmitLValue(const Expr *E);
  
  /// EmitLoadOfLValue - Given an expression that represents a value lvalue,
  /// this method emits the address of the lvalue, then loads the result as an
  /// rvalue, returning the rvalue.
  RValue EmitLoadOfLValue(const Expr *E);
  
  /// EmitStoreThroughLValue - Store the specified rvalue into the specified
  /// lvalue, where both are guaranteed to the have the same type, and that type
  /// is 'Ty'.
  void EmitStoreThroughLValue(RValue Src, LValue Dst, QualType Ty);
  
  LValue EmitDeclRefLValue(const DeclRefExpr *E);
  LValue EmitStringLiteralLValue(const StringLiteral *E);
  LValue EmitUnaryOpLValue(const UnaryOperator *E);
    
  //===--------------------------------------------------------------------===//
  //                             Expression Emission
  //===--------------------------------------------------------------------===//

  RValue EmitExprWithUsualUnaryConversions(const Expr *E, QualType &ResTy);
  QualType EmitUsualArithmeticConversions(const BinaryOperator *E,
                                          RValue &LHS, RValue &RHS);
  
  RValue EmitExpr(const Expr *E);
  RValue EmitIntegerLiteral(const IntegerLiteral *E);
  
  RValue EmitCastExpr(const CastExpr *E);

  // Unary Operators.
  RValue EmitUnaryOperator(const UnaryOperator *E);
  // FIXME: pre/post inc/dec
  RValue EmitUnaryAddrOf  (const UnaryOperator *E);
  RValue EmitUnaryPlus    (const UnaryOperator *E);
  RValue EmitUnaryMinus   (const UnaryOperator *E);
  RValue EmitUnaryNot     (const UnaryOperator *E);
  RValue EmitUnaryLNot    (const UnaryOperator *E);
  // FIXME: SIZEOF/ALIGNOF(expr).
  // FIXME: real/imag
  
  // Binary Operators.
  RValue EmitBinaryOperator(const BinaryOperator *E);
  RValue EmitBinaryMul(const BinaryOperator *E);
  RValue EmitBinaryDiv(const BinaryOperator *E);
  RValue EmitBinaryRem(const BinaryOperator *E);
  RValue EmitBinaryAdd(const BinaryOperator *E);
  RValue EmitBinarySub(const BinaryOperator *E);
  RValue EmitBinaryShl(const BinaryOperator *E);
  RValue EmitBinaryShr(const BinaryOperator *E);
  
  // FIXME: relational
  
  RValue EmitBinaryAnd(const BinaryOperator *E);
  RValue EmitBinaryXor(const BinaryOperator *E);
  RValue EmitBinaryOr (const BinaryOperator *E);
  RValue EmitBinaryLAnd(const BinaryOperator *E);
  RValue EmitBinaryLOr(const BinaryOperator *E);
  
  RValue EmitBinaryAssign(const BinaryOperator *E);
  // FIXME: Assignment.
  
  RValue EmitBinaryComma(const BinaryOperator *E);
};
}  // end namespace CodeGen
}  // end namespace clang
}  // end namespace llvm

#endif
OpenPOWER on IntegriCloud