blob: ff31a835ce95552b30e93a7b220c44bf2ee1cf3b [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"
18#include "llvm/DerivedTypes.h"
Chris Lattner308f4312007-05-29 23:50:05 +000019#include "llvm/Function.h"
Chris Lattnerbed31442007-05-28 01:07:47 +000020using namespace llvm;
21using namespace clang;
22using namespace CodeGen;
23
Chris Lattnerd1af2d22007-05-29 23:17:50 +000024CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
25 : CGM(cgm), Target(CGM.getContext().Target) {}
26
27
28/// ConvertType - Convert the specified type to its LLVM form.
29const llvm::Type *CodeGenFunction::ConvertType(QualType T, SourceLocation Loc) {
30 // FIXME: Cache these, move the CodeGenModule, expand, etc.
31 const clang::Type &Ty = *T.getCanonicalType();
32
33 switch (Ty.getTypeClass()) {
34 case Type::Builtin: {
35 switch (cast<BuiltinType>(Ty).getKind()) {
36 case BuiltinType::Void:
37 // LLVM void type can only be used as the result of a function call. Just
38 // map to the same as char.
39 case BuiltinType::Char:
40 case BuiltinType::SChar:
41 case BuiltinType::UChar:
42 return IntegerType::get(Target.getCharWidth(Loc));
43
44 case BuiltinType::Bool:
45 return IntegerType::get(Target.getBoolWidth(Loc));
46
47 case BuiltinType::Short:
48 case BuiltinType::UShort:
49 return IntegerType::get(Target.getShortWidth(Loc));
50
51 case BuiltinType::Int:
52 case BuiltinType::UInt:
53 return IntegerType::get(Target.getIntWidth(Loc));
54
55 case BuiltinType::Long:
56 case BuiltinType::ULong:
57 return IntegerType::get(Target.getLongWidth(Loc));
58
59 case BuiltinType::LongLong:
60 case BuiltinType::ULongLong:
61 return IntegerType::get(Target.getLongLongWidth(Loc));
62
63 case BuiltinType::Float: return llvm::Type::FloatTy;
64 case BuiltinType::Double: return llvm::Type::DoubleTy;
65 case BuiltinType::LongDouble:
66 case BuiltinType::FloatComplex:
67 case BuiltinType::DoubleComplex:
68 case BuiltinType::LongDoubleComplex:
69 ;
70 }
71 break;
72 }
73 case Type::Pointer:
74 case Type::Reference:
75 case Type::Array:
76 break;
77 case Type::FunctionNoProto:
78 case Type::FunctionProto: {
79 const FunctionType &FP = cast<FunctionType>(Ty);
80 const llvm::Type *ResultType;
81
82 if (FP.getResultType()->isVoidType())
83 ResultType = llvm::Type::VoidTy; // Result of function uses llvm void.
84 else
85 ResultType = ConvertType(FP.getResultType(), Loc);
86
87 // FIXME: Convert argument types.
88
89 return llvm::FunctionType::get(ResultType,
90 std::vector<const llvm::Type*>(),
91 false,
92 0);
93 }
94 case Type::TypeName:
95 case Type::Tagged:
96 break;
97 }
98
99 // FIXME: implement.
100 return OpaqueType::get();
101}
102
103
Chris Lattner308f4312007-05-29 23:50:05 +0000104void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000105 const llvm::Type *Ty = ConvertType(FD->getType(), FD->getLocation());
106
Chris Lattner308f4312007-05-29 23:50:05 +0000107 llvm::Function *F = new Function(cast<llvm::FunctionType>(Ty),
108 Function::ExternalLinkage,
109 FD->getName(), &CGM.getModule());
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000110
Chris Lattner308f4312007-05-29 23:50:05 +0000111 BasicBlock *EntryBB = new BasicBlock("entry", F);
112
113 // TODO: Walk the decls, creating allocas etc.
114
115 Builder.SetInsertPoint(EntryBB);
116
117 EmitStmt(FD->getBody());
Chris Lattnerd1af2d22007-05-29 23:17:50 +0000118}
Chris Lattner308f4312007-05-29 23:50:05 +0000119
120
121//===----------------------------------------------------------------------===//
122// Statement Emission
123//===----------------------------------------------------------------------===//
124
125void CodeGenFunction::EmitStmt(const Stmt *S) {
126 assert(S && "Null statement?");
127
128 switch (S->getStmtClass()) {
129 default:
130 printf("Unimplemented stmt!\n");
131 S->dump();
132 break;
133 case Stmt::NullStmtClass: break;
134 case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
135 }
136}
137
138void CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S) {
139 // FIXME: handle vla's etc.
140
141 for (CompoundStmt::const_body_iterator I = S.body_begin(), E = S.body_end();
142 I != E; ++I)
143 EmitStmt(*I);
144}
145