blob: 9da66c635bdd06c1145f4f2cd9892763e2484ba6 [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.
54 case BuiltinType::Char:
55 case BuiltinType::SChar:
56 case BuiltinType::UChar:
57 return IntegerType::get(Target.getCharWidth(Loc));
58
59 case BuiltinType::Bool:
60 return IntegerType::get(Target.getBoolWidth(Loc));
61
62 case BuiltinType::Short:
63 case BuiltinType::UShort:
64 return IntegerType::get(Target.getShortWidth(Loc));
65
66 case BuiltinType::Int:
67 case BuiltinType::UInt:
68 return IntegerType::get(Target.getIntWidth(Loc));
69
70 case BuiltinType::Long:
71 case BuiltinType::ULong:
72 return IntegerType::get(Target.getLongWidth(Loc));
73
74 case BuiltinType::LongLong:
75 case BuiltinType::ULongLong:
76 return IntegerType::get(Target.getLongLongWidth(Loc));
77
78 case BuiltinType::Float: return llvm::Type::FloatTy;
79 case BuiltinType::Double: return llvm::Type::DoubleTy;
80 case BuiltinType::LongDouble:
81 case BuiltinType::FloatComplex:
82 case BuiltinType::DoubleComplex:
83 case BuiltinType::LongDoubleComplex:
84 ;
85 }
86 break;
87 }
Chris Lattner2b4e21a2007-06-02 19:52:24 +000088 case Type::Pointer: {
89 const PointerType &P = cast<PointerType>(Ty);
90 return llvm::PointerType::get(ConvertType(P.getPointeeType(), Loc));
91 }
92 case Type::Reference: {
93 const ReferenceType &R = cast<ReferenceType>(Ty);
94 return llvm::PointerType::get(ConvertType(R.getReferenceeType(), Loc));
95 }
96
97 case Type::Array: {
98 const ArrayType &A = cast<ArrayType>(Ty);
99 assert(A.getSizeModifier() == ArrayType::Normal &&
100 A.getIndexTypeQualifier() == 0 &&
101 "FIXME: We only handle trivial array types so far!");
102 // FIXME: are there any promotions etc here?
103 ExprResult Size = EmitExpr(A.getSize());
104 assert(Size.isScalar() && isa<llvm::ConstantInt>(Size.getVal()) &&
105 "FIXME: Only handle fixed-size arrays so far");
106 const llvm::Type *EltTy = ConvertType(A.getElementType(), Loc);
107 return llvm::ArrayType::get(EltTy,
108 cast<llvm::ConstantInt>(Size.getVal())->getZExtValue());
109 }
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000110 case Type::FunctionNoProto:
111 case Type::FunctionProto: {
112 const FunctionType &FP = cast<FunctionType>(Ty);
113 const llvm::Type *ResultType;
114
115 if (FP.getResultType()->isVoidType())
116 ResultType = llvm::Type::VoidTy; // Result of function uses llvm void.
117 else
118 ResultType = ConvertType(FP.getResultType(), Loc);
119
120 // FIXME: Convert argument types.
121
122 return llvm::FunctionType::get(ResultType,
123 std::vector<const llvm::Type*>(),
124 false,
125 0);
126 }
127 case Type::TypeName:
128 case Type::Tagged:
129 break;
130 }
131
132 // FIXME: implement.
133 return OpaqueType::get();
134}
135
136
Chris Lattner308f4312007-05-29 23:50:05 +0000137void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
Chris Lattner6db1fb82007-06-02 22:49:07 +0000138 LLVMIntTy = ConvertType(getContext().IntTy, FD->getLocation());
139
Chris Lattneradb63722007-06-02 03:02:07 +0000140 const llvm::FunctionType *Ty =
141 cast<llvm::FunctionType>(ConvertType(FD->getType(), FD->getLocation()));
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000142
Chris Lattner3f3dbee2007-06-02 03:19:07 +0000143 CurFuncDecl = FD;
Chris Lattneradb63722007-06-02 03:02:07 +0000144 CurFn = new Function(Ty, Function::ExternalLinkage,
Chris Lattnerac248202007-05-30 00:13:02 +0000145 FD->getName(), &CGM.getModule());
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000146
Chris Lattnerac248202007-05-30 00:13:02 +0000147 BasicBlock *EntryBB = new BasicBlock("entry", CurFn);
Chris Lattner308f4312007-05-29 23:50:05 +0000148
149 // TODO: Walk the decls, creating allocas etc.
150
151 Builder.SetInsertPoint(EntryBB);
Chris Lattner03df1222007-06-02 04:53:11 +0000152
153 // Create a marker to make it easy to insert allocas into the entryblock
154 // later.
155 AllocaInsertPt = Builder.CreateBitCast(UndefValue::get(llvm::Type::Int32Ty),
156 llvm::Type::Int32Ty, "allocapt");
Chris Lattner308f4312007-05-29 23:50:05 +0000157
Chris Lattner84915fa2007-06-02 04:16:21 +0000158 // TODO: handle params.
159
160 // Emit the function body.
Chris Lattner308f4312007-05-29 23:50:05 +0000161 EmitStmt(FD->getBody());
Chris Lattnerdc6e3fe2007-05-30 22:55:31 +0000162
Chris Lattneradb63722007-06-02 03:02:07 +0000163 // Emit a return for code that falls off the end.
164 // FIXME: if this is C++ main, this should return 0.
165 if (Ty->getReturnType() == llvm::Type::VoidTy)
166 Builder.CreateRetVoid();
167 else
168 Builder.CreateRet(UndefValue::get(Ty->getReturnType()));
169
Chris Lattnerdc6e3fe2007-05-30 22:55:31 +0000170
171
172 // Verify that the function is well formed.
173 assert(!verifyFunction(*CurFn));
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000174}
Chris Lattner308f4312007-05-29 23:50:05 +0000175