blob: bebf6752fb3537b567aa3c3505c1119da73f5951 [file] [log] [blame]
Chris Lattner84915fa2007-06-02 04:16:21 +00001//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
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 contains code to emit Decl nodes as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15#include "clang/AST/AST.h"
Chris Lattner53621a52007-06-13 20:44:40 +000016#include "llvm/Type.h"
Chris Lattner84915fa2007-06-02 04:16:21 +000017using namespace llvm;
18using namespace clang;
19using namespace CodeGen;
20
21
Chris Lattner1ad38f82007-06-09 01:20:56 +000022void CodeGenFunction::EmitDecl(const Decl &D) {
Chris Lattner84915fa2007-06-02 04:16:21 +000023
Chris Lattner1ad38f82007-06-09 01:20:56 +000024 switch (D.getKind()) {
Chris Lattner84915fa2007-06-02 04:16:21 +000025 default: assert(0 && "Unknown decl kind!");
26 case Decl::FileVariable:
27 assert(0 && "Should not see file-scope variables inside a function!");
28 case Decl::ParmVariable:
29 assert(0 && "Parmdecls should not be in declstmts!");
30 case Decl::Typedef: // typedef int X;
31 case Decl::Function: // void X();
32 case Decl::Struct: // struct X;
33 case Decl::Union: // union X;
34 case Decl::Class: // class X;
35 case Decl::Enum: // enum X;
36 // None of these decls require codegen support.
37 return;
38
39 case Decl::BlockVariable:
Chris Lattner1ad38f82007-06-09 01:20:56 +000040 return EmitBlockVarDecl(cast<BlockVarDecl>(D));
Chris Lattner84915fa2007-06-02 04:16:21 +000041 case Decl::EnumConstant:
Chris Lattner1ad38f82007-06-09 01:20:56 +000042 return EmitEnumConstantDecl(cast<EnumConstantDecl>(D));
Chris Lattner84915fa2007-06-02 04:16:21 +000043 }
44}
45
Chris Lattner84915fa2007-06-02 04:16:21 +000046void CodeGenFunction::EmitEnumConstantDecl(const EnumConstantDecl &D) {
47 assert(0 && "FIXME: Enum constant decls not implemented yet!");
48}
Chris Lattner03df1222007-06-02 04:53:11 +000049
50/// EmitBlockVarDecl - This method handles emission of any variable declaration
51/// inside a function, including static vars etc.
52void CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
53 switch (D.getStorageClass()) {
54 case VarDecl::Static:
55 assert(0 && "FIXME: local static vars not implemented yet");
56 case VarDecl::Extern:
57 assert(0 && "FIXME: should call up to codegenmodule");
58 default:
59 assert((D.getStorageClass() == VarDecl::None ||
60 D.getStorageClass() == VarDecl::Auto ||
61 D.getStorageClass() == VarDecl::Register) &&
62 "Unknown storage class");
63 return EmitLocalBlockVarDecl(D);
64 }
65}
66
67/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
68/// variable declaration with auto, register, or no storage class specifier.
69/// These turn into simple stack objects.
70void CodeGenFunction::EmitLocalBlockVarDecl(const BlockVarDecl &D) {
71 QualType Ty = D.getCanonicalType();
72
73 llvm::Value *DeclPtr;
74 if (Ty->isConstantSizeType()) {
75 // A normal fixed sized variable becomes an alloca in the entry block.
76 const llvm::Type *LTy = ConvertType(Ty, D.getLocation());
77 // TODO: Alignment
78 DeclPtr = new AllocaInst(LTy, 0, D.getName(), AllocaInsertPt);
79 } else {
80 // TODO: Create a dynamic alloca.
81 assert(0 && "FIXME: Local VLAs not implemented yet");
82 }
83
84 llvm::Value *&DMEntry = LocalDeclMap[&D];
85 assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
86 DMEntry = DeclPtr;
87
88 // FIXME: Evaluate initializer.
89}
Chris Lattner53621a52007-06-13 20:44:40 +000090
91/// Emit an alloca for the specified parameter and set up LocalDeclMap.
92void CodeGenFunction::EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg) {
93 QualType Ty = D.getCanonicalType();
94
95 llvm::Value *DeclPtr;
96 if (!Ty->isConstantSizeType()) {
97 // Variable sized values always are passed by-reference.
98 DeclPtr = Arg;
99 Arg->setName(DeclPtr->getName());
100 } else {
101 // A fixed sized first class variable becomes an alloca in the entry block.
102 const llvm::Type *LTy = ConvertType(Ty, D.getLocation());
103 if (LTy->isFirstClassType()) {
104 // TODO: Alignment
105 DeclPtr = new AllocaInst(LTy, 0,
106 std::string(D.getName())+".addr",AllocaInsertPt);
107
108 // Store the initial value into the alloca.
109 Builder.CreateStore(Arg, DeclPtr);
110
111 Arg->setName(D.getName());
112 } else {
113 // Otherwise, if this is an aggregate, just use the input pointer.
114 DeclPtr = Arg;
115 Arg->setName(DeclPtr->getName());
116 }
117 }
118
119 llvm::Value *&DMEntry = LocalDeclMap[&D];
120 assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
121 DMEntry = DeclPtr;
122}
123