blob: 6b6f3cbbdc77926ced9f0afdcfb796110263d941 [file] [log] [blame]
Chris Lattnerbed31442007-05-28 01:07:47 +00001//===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This coordinates the per-function state used while generating code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15#include "CodeGenModule.h"
Chris Lattnerd1af2d22007-05-29 23:17:50 +000016#include "clang/Basic/TargetInfo.h"
17#include "clang/AST/AST.h"
Chris Lattner208ae962007-05-30 17:57:17 +000018#include "llvm/Constants.h"
Chris Lattnerd1af2d22007-05-29 23:17:50 +000019#include "llvm/DerivedTypes.h"
Chris Lattner308f4312007-05-29 23:50:05 +000020#include "llvm/Function.h"
Chris Lattnerdc6e3fe2007-05-30 22:55:31 +000021#include "llvm/Analysis/Verifier.h"
Chris Lattnerbed31442007-05-28 01:07:47 +000022using namespace llvm;
23using namespace clang;
24using namespace CodeGen;
25
Chris Lattnerd1af2d22007-05-29 23:17:50 +000026CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
27 : CGM(cgm), Target(CGM.getContext().Target) {}
28
Chris Lattner6db1fb82007-06-02 22:49:07 +000029ASTContext &CodeGenFunction::getContext() const {
30 return CGM.getContext();
31}
32
Chris Lattnerd1af2d22007-05-29 23:17:50 +000033
Chris Lattnerac248202007-05-30 00:13:02 +000034llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
35 BasicBlock *&BB = LabelMap[S];
36 if (BB) return BB;
37
38 // Create, but don't insert, the new block.
39 return BB = new BasicBlock(S->getName());
40}
41
42
Chris Lattnerd1af2d22007-05-29 23:17:50 +000043/// ConvertType - Convert the specified type to its LLVM form.
44const llvm::Type *CodeGenFunction::ConvertType(QualType T, SourceLocation Loc) {
45 // FIXME: Cache these, move the CodeGenModule, expand, etc.
46 const clang::Type &Ty = *T.getCanonicalType();
47
48 switch (Ty.getTypeClass()) {
49 case Type::Builtin: {
50 switch (cast<BuiltinType>(Ty).getKind()) {
51 case BuiltinType::Void:
52 // LLVM void type can only be used as the result of a function call. Just
53 // map to the same as char.
Chris Lattnerb16f4552007-06-03 07:25:34 +000054 case BuiltinType::Char_S:
55 case BuiltinType::Char_U:
Chris Lattnerd1af2d22007-05-29 23:17:50 +000056 case BuiltinType::SChar:
57 case BuiltinType::UChar:
58 return IntegerType::get(Target.getCharWidth(Loc));
59
60 case BuiltinType::Bool:
Chris Lattner8394d792007-06-05 20:53:16 +000061 // FIXME: This is very strange. We want scalars to be i1, but in memory
62 // they can be i1 or i32. Should the codegen handle this issue?
63 return llvm::Type::Int1Ty;
Chris Lattnerd1af2d22007-05-29 23:17:50 +000064
65 case BuiltinType::Short:
66 case BuiltinType::UShort:
67 return IntegerType::get(Target.getShortWidth(Loc));
68
69 case BuiltinType::Int:
70 case BuiltinType::UInt:
71 return IntegerType::get(Target.getIntWidth(Loc));
72
73 case BuiltinType::Long:
74 case BuiltinType::ULong:
75 return IntegerType::get(Target.getLongWidth(Loc));
76
77 case BuiltinType::LongLong:
78 case BuiltinType::ULongLong:
79 return IntegerType::get(Target.getLongLongWidth(Loc));
80
81 case BuiltinType::Float: return llvm::Type::FloatTy;
82 case BuiltinType::Double: return llvm::Type::DoubleTy;
83 case BuiltinType::LongDouble:
84 case BuiltinType::FloatComplex:
85 case BuiltinType::DoubleComplex:
86 case BuiltinType::LongDoubleComplex:
87 ;
88 }
89 break;
90 }
Chris Lattner2b4e21a2007-06-02 19:52:24 +000091 case Type::Pointer: {
92 const PointerType &P = cast<PointerType>(Ty);
93 return llvm::PointerType::get(ConvertType(P.getPointeeType(), Loc));
94 }
95 case Type::Reference: {
96 const ReferenceType &R = cast<ReferenceType>(Ty);
97 return llvm::PointerType::get(ConvertType(R.getReferenceeType(), Loc));
98 }
99
100 case Type::Array: {
101 const ArrayType &A = cast<ArrayType>(Ty);
102 assert(A.getSizeModifier() == ArrayType::Normal &&
103 A.getIndexTypeQualifier() == 0 &&
104 "FIXME: We only handle trivial array types so far!");
105 // FIXME: are there any promotions etc here?
Chris Lattner8394d792007-06-05 20:53:16 +0000106 RValue Size = EmitExpr(A.getSize());
Chris Lattner2b4e21a2007-06-02 19:52:24 +0000107 assert(Size.isScalar() && isa<llvm::ConstantInt>(Size.getVal()) &&
108 "FIXME: Only handle fixed-size arrays so far");
109 const llvm::Type *EltTy = ConvertType(A.getElementType(), Loc);
110 return llvm::ArrayType::get(EltTy,
111 cast<llvm::ConstantInt>(Size.getVal())->getZExtValue());
112 }
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000113 case Type::FunctionNoProto:
114 case Type::FunctionProto: {
115 const FunctionType &FP = cast<FunctionType>(Ty);
116 const llvm::Type *ResultType;
117
118 if (FP.getResultType()->isVoidType())
119 ResultType = llvm::Type::VoidTy; // Result of function uses llvm void.
120 else
121 ResultType = ConvertType(FP.getResultType(), Loc);
122
123 // FIXME: Convert argument types.
Chris Lattner45bb9142007-06-09 02:28:57 +0000124 bool isVarArg;
125 std::vector<const llvm::Type*> ArgTys;
126 if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(&FP)) {
127 DecodeArgumentTypes(*FTP, ArgTys, Loc);
128 isVarArg = FTP->isVariadic();
129 } else {
130 isVarArg = true;
131 }
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000132
Chris Lattner45bb9142007-06-09 02:28:57 +0000133 return llvm::FunctionType::get(ResultType, ArgTys, isVarArg, 0);
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000134 }
135 case Type::TypeName:
136 case Type::Tagged:
137 break;
138 }
139
140 // FIXME: implement.
141 return OpaqueType::get();
142}
143
Chris Lattner53621a52007-06-13 20:44:40 +0000144void CodeGenFunction::DecodeArgumentTypes(const FunctionTypeProto &FTP,
145 std::vector<const llvm::Type*> &
146 ArgTys, SourceLocation Loc) {
147 for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) {
148 const llvm::Type *Ty = ConvertType(FTP.getArgType(i), Loc);
149 if (Ty->isFirstClassType())
150 ArgTys.push_back(Ty);
151 else
152 ArgTys.push_back(llvm::PointerType::get(Ty));
153 }
Chris Lattner45bb9142007-06-09 02:28:57 +0000154}
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000155
Chris Lattner308f4312007-05-29 23:50:05 +0000156void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
Chris Lattner6db1fb82007-06-02 22:49:07 +0000157 LLVMIntTy = ConvertType(getContext().IntTy, FD->getLocation());
Chris Lattnerd9d2fb12007-06-08 23:31:14 +0000158 LLVMPointerWidth = Target.getPointerWidth(FD->getLocation());
Chris Lattner6db1fb82007-06-02 22:49:07 +0000159
Chris Lattneradb63722007-06-02 03:02:07 +0000160 const llvm::FunctionType *Ty =
161 cast<llvm::FunctionType>(ConvertType(FD->getType(), FD->getLocation()));
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000162
Chris Lattner53621a52007-06-13 20:44:40 +0000163 // FIXME: param attributes for sext/zext etc.
164
Chris Lattner3f3dbee2007-06-02 03:19:07 +0000165 CurFuncDecl = FD;
Chris Lattneradb63722007-06-02 03:02:07 +0000166 CurFn = new Function(Ty, Function::ExternalLinkage,
Chris Lattnerac248202007-05-30 00:13:02 +0000167 FD->getName(), &CGM.getModule());
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000168
Chris Lattnerac248202007-05-30 00:13:02 +0000169 BasicBlock *EntryBB = new BasicBlock("entry", CurFn);
Chris Lattner308f4312007-05-29 23:50:05 +0000170
Chris Lattner308f4312007-05-29 23:50:05 +0000171 Builder.SetInsertPoint(EntryBB);
Chris Lattner03df1222007-06-02 04:53:11 +0000172
173 // Create a marker to make it easy to insert allocas into the entryblock
174 // later.
175 AllocaInsertPt = Builder.CreateBitCast(UndefValue::get(llvm::Type::Int32Ty),
176 llvm::Type::Int32Ty, "allocapt");
Chris Lattner308f4312007-05-29 23:50:05 +0000177
Chris Lattner53621a52007-06-13 20:44:40 +0000178 // Emit allocs for param decls.
179 llvm::Function::arg_iterator AI = CurFn->arg_begin();
180 for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) {
181 assert(AI != CurFn->arg_end() && "Argument mismatch!");
182 EmitParmDecl(*FD->getParamDecl(i), AI);
183 }
Chris Lattner84915fa2007-06-02 04:16:21 +0000184
185 // Emit the function body.
Chris Lattner308f4312007-05-29 23:50:05 +0000186 EmitStmt(FD->getBody());
Chris Lattnerdc6e3fe2007-05-30 22:55:31 +0000187
Chris Lattneradb63722007-06-02 03:02:07 +0000188 // Emit a return for code that falls off the end.
189 // FIXME: if this is C++ main, this should return 0.
190 if (Ty->getReturnType() == llvm::Type::VoidTy)
191 Builder.CreateRetVoid();
192 else
193 Builder.CreateRet(UndefValue::get(Ty->getReturnType()));
194
Chris Lattnerdc6e3fe2007-05-30 22:55:31 +0000195
196
197 // Verify that the function is well formed.
198 assert(!verifyFunction(*CurFn));
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000199}
Chris Lattner308f4312007-05-29 23:50:05 +0000200