blob: 6c7b714fb7ff06662ccf09f29ff1aabe5f510c89 [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
29
Chris Lattnerac248202007-05-30 00:13:02 +000030llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
31 BasicBlock *&BB = LabelMap[S];
32 if (BB) return BB;
33
34 // Create, but don't insert, the new block.
35 return BB = new BasicBlock(S->getName());
36}
37
38
Chris Lattnerd1af2d22007-05-29 23:17:50 +000039/// ConvertType - Convert the specified type to its LLVM form.
40const llvm::Type *CodeGenFunction::ConvertType(QualType T, SourceLocation Loc) {
41 // FIXME: Cache these, move the CodeGenModule, expand, etc.
42 const clang::Type &Ty = *T.getCanonicalType();
43
44 switch (Ty.getTypeClass()) {
45 case Type::Builtin: {
46 switch (cast<BuiltinType>(Ty).getKind()) {
47 case BuiltinType::Void:
48 // LLVM void type can only be used as the result of a function call. Just
49 // map to the same as char.
50 case BuiltinType::Char:
51 case BuiltinType::SChar:
52 case BuiltinType::UChar:
53 return IntegerType::get(Target.getCharWidth(Loc));
54
55 case BuiltinType::Bool:
56 return IntegerType::get(Target.getBoolWidth(Loc));
57
58 case BuiltinType::Short:
59 case BuiltinType::UShort:
60 return IntegerType::get(Target.getShortWidth(Loc));
61
62 case BuiltinType::Int:
63 case BuiltinType::UInt:
64 return IntegerType::get(Target.getIntWidth(Loc));
65
66 case BuiltinType::Long:
67 case BuiltinType::ULong:
68 return IntegerType::get(Target.getLongWidth(Loc));
69
70 case BuiltinType::LongLong:
71 case BuiltinType::ULongLong:
72 return IntegerType::get(Target.getLongLongWidth(Loc));
73
74 case BuiltinType::Float: return llvm::Type::FloatTy;
75 case BuiltinType::Double: return llvm::Type::DoubleTy;
76 case BuiltinType::LongDouble:
77 case BuiltinType::FloatComplex:
78 case BuiltinType::DoubleComplex:
79 case BuiltinType::LongDoubleComplex:
80 ;
81 }
82 break;
83 }
84 case Type::Pointer:
85 case Type::Reference:
86 case Type::Array:
87 break;
88 case Type::FunctionNoProto:
89 case Type::FunctionProto: {
90 const FunctionType &FP = cast<FunctionType>(Ty);
91 const llvm::Type *ResultType;
92
93 if (FP.getResultType()->isVoidType())
94 ResultType = llvm::Type::VoidTy; // Result of function uses llvm void.
95 else
96 ResultType = ConvertType(FP.getResultType(), Loc);
97
98 // FIXME: Convert argument types.
99
100 return llvm::FunctionType::get(ResultType,
101 std::vector<const llvm::Type*>(),
102 false,
103 0);
104 }
105 case Type::TypeName:
106 case Type::Tagged:
107 break;
108 }
109
110 // FIXME: implement.
111 return OpaqueType::get();
112}
113
114
Chris Lattner308f4312007-05-29 23:50:05 +0000115void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
Chris Lattneradb63722007-06-02 03:02:07 +0000116 const llvm::FunctionType *Ty =
117 cast<llvm::FunctionType>(ConvertType(FD->getType(), FD->getLocation()));
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000118
Chris Lattneradb63722007-06-02 03:02:07 +0000119 CurFn = new Function(Ty, Function::ExternalLinkage,
Chris Lattnerac248202007-05-30 00:13:02 +0000120 FD->getName(), &CGM.getModule());
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000121
Chris Lattnerac248202007-05-30 00:13:02 +0000122 BasicBlock *EntryBB = new BasicBlock("entry", CurFn);
Chris Lattner308f4312007-05-29 23:50:05 +0000123
124 // TODO: Walk the decls, creating allocas etc.
125
126 Builder.SetInsertPoint(EntryBB);
127
128 EmitStmt(FD->getBody());
Chris Lattnerdc6e3fe2007-05-30 22:55:31 +0000129
Chris Lattneradb63722007-06-02 03:02:07 +0000130 // Emit a return for code that falls off the end.
131 // FIXME: if this is C++ main, this should return 0.
132 if (Ty->getReturnType() == llvm::Type::VoidTy)
133 Builder.CreateRetVoid();
134 else
135 Builder.CreateRet(UndefValue::get(Ty->getReturnType()));
136
Chris Lattnerdc6e3fe2007-05-30 22:55:31 +0000137
138
139 // Verify that the function is well formed.
140 assert(!verifyFunction(*CurFn));
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000141}
Chris Lattner308f4312007-05-29 23:50:05 +0000142