CGDecl.cpp revision 8bcfc5bef434d7052e28d0ce45182855659ebd3d
1b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
2b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow//
3b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow//                     The LLVM Compiler Infrastructure
4b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow//
5b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow// This file is distributed under the University of Illinois Open Source
6b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow// License. See LICENSE.TXT for details.
7b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow//
8b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow//===----------------------------------------------------------------------===//
9b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow//
10b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow// This contains code to emit Decl nodes as LLVM code.
11b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow//
12b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow//===----------------------------------------------------------------------===//
13b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
14b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow#include "CodeGenFunction.h"
15b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow#include "CodeGenModule.h"
16b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow#include "clang/AST/AST.h"
17b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow#include "llvm/GlobalVariable.h"
18b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow#include "llvm/Type.h"
19b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komowusing namespace clang;
20b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komowusing namespace CodeGen;
21b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
22b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
23b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komowvoid CodeGenFunction::EmitDecl(const Decl &D) {
24b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  switch (D.getKind()) {
25b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  default: assert(0 && "Unknown decl kind!");
26b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case Decl::FileVar:
27b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    assert(0 && "Should not see file-scope variables inside a function!");
28b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case Decl::ParmVar:
29b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    assert(0 && "Parmdecls should not be in declstmts!");
30b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case Decl::Typedef:   // typedef int X;
31b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case Decl::Function:  // void X();
32b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case Decl::Struct:    // struct X;
33b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case Decl::Union:     // union X;
34b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case Decl::Class:     // class X;
35b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case Decl::Enum:      // enum X;
36b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    // None of these decls require codegen support.
37b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    return;
38b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
39b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case Decl::BlockVar:
40b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    return EmitBlockVarDecl(cast<BlockVarDecl>(D));
41b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case Decl::EnumConstant:
42b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    return EmitEnumConstantDecl(cast<EnumConstantDecl>(D));
439696299c6135ceb92285b4692d3f01e2de7fa983Lenny Komow  }
44b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow}
45b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
46b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komowvoid CodeGenFunction::EmitEnumConstantDecl(const EnumConstantDecl &D) {
479696299c6135ceb92285b4692d3f01e2de7fa983Lenny Komow  assert(0 && "FIXME: Enum constant decls not implemented yet!");
48b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow}
49b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
50b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow/// EmitBlockVarDecl - This method handles emission of any variable declaration
51b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow/// inside a function, including static vars etc.
52b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komowvoid CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
53b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  switch (D.getStorageClass()) {
54b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case VarDecl::Static:
55b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    return EmitStaticBlockVarDecl(D);
56b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  case VarDecl::Extern:
579696299c6135ceb92285b4692d3f01e2de7fa983Lenny Komow    // Don't emit it now, allow it to be emitted lazily on its first use.
58b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    return;
59b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  default:
60b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    assert((D.getStorageClass() == VarDecl::None ||
61b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow            D.getStorageClass() == VarDecl::Auto ||
62b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow            D.getStorageClass() == VarDecl::Register) &&
63b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow           "Unknown storage class");
64b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    return EmitLocalBlockVarDecl(D);
65b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  }
66b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow}
67b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
68b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komowvoid CodeGenFunction::EmitStaticBlockVarDecl(const BlockVarDecl &D) {
69b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  QualType Ty = D.getType();
70b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  assert(Ty->isConstantSizeType() && "VLAs can't be static");
71b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
72b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  llvm::Value *&DMEntry = LocalDeclMap[&D];
73b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
74b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
75b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
76b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  llvm::Constant *Init = 0;
77b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  if (D.getInit() == 0) {
78b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    Init = llvm::Constant::getNullValue(LTy);
79b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  } else {
80b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    Init = CGM.EmitConstantExpr(D.getInit(), this);
81b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  }
82b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
83b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  assert(Init && "Unable to create initialiser for static decl");
84b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
85b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  std::string ContextName;
86b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  if (const FunctionDecl * FD = dyn_cast<FunctionDecl>(CurFuncDecl))
87b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    ContextName = FD->getName();
88b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  else
89b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    assert(0 && "Unknown context for block var decl"); // FIXME Handle objc.
90b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
91b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  DMEntry =
92b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    new llvm::GlobalVariable(LTy, false,
93b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow                            llvm::GlobalValue::InternalLinkage,
94b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow                             Init, ContextName + "." + D.getName(),
95b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow                             &CGM.getModule(), 0,
96b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow                             Ty.getAddressSpace());
97b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow}
98b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
99b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
100b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow/// variable declaration with auto, register, or no storage class specifier.
101b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow/// These turn into simple stack objects.
102b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komowvoid CodeGenFunction::EmitLocalBlockVarDecl(const BlockVarDecl &D) {
103b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  QualType Ty = D.getType();
104b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
105b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  llvm::Value *DeclPtr;
106b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  if (Ty->isConstantSizeType()) {
107b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    // A normal fixed sized variable becomes an alloca in the entry block.
108b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    const llvm::Type *LTy = ConvertType(Ty);
109b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    // TODO: Alignment
110b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    DeclPtr = CreateTempAlloca(LTy, D.getName());
111b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  } else {
112b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    // TODO: Create a dynamic alloca.
113b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    assert(0 && "FIXME: Local VLAs not implemented yet");
114b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  }
115b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
116b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  llvm::Value *&DMEntry = LocalDeclMap[&D];
117b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
118b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  DMEntry = DeclPtr;
119b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
120b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  // If this local has an initializer, emit it now.
121b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  if (const Expr *Init = D.getInit()) {
122b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    if (!hasAggregateLLVMType(Init->getType())) {
123b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow      llvm::Value *V = EmitScalarExpr(Init);
124b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow      Builder.CreateStore(V, DeclPtr, D.getType().isVolatileQualified());
125b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    } else if (Init->getType()->isAnyComplexType()) {
126b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow      EmitComplexExprIntoAddr(Init, DeclPtr, D.getType().isVolatileQualified());
127b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    } else {
128b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow      EmitAggExpr(Init, DeclPtr, D.getType().isVolatileQualified());
129b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    }
130b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  }
131b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow}
132b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
133b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow/// Emit an alloca for the specified parameter and set up LocalDeclMap.
134b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komowvoid CodeGenFunction::EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg) {
135b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  QualType Ty = D.getType();
136b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
137b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  llvm::Value *DeclPtr;
138b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  if (!Ty->isConstantSizeType()) {
139b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    // Variable sized values always are passed by-reference.
140b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    DeclPtr = Arg;
141b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  } else {
142b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    // A fixed sized first class variable becomes an alloca in the entry block.
143b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    const llvm::Type *LTy = ConvertType(Ty);
144b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    if (LTy->isFirstClassType()) {
145b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow      // TODO: Alignment
146b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow      DeclPtr = new llvm::AllocaInst(LTy, 0, std::string(D.getName())+".addr",
147b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow                                     AllocaInsertPt);
148b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
149b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow      // Store the initial value into the alloca.
150b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow      Builder.CreateStore(Arg, DeclPtr);
151b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    } else {
152b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow      // Otherwise, if this is an aggregate, just use the input pointer.
153b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow      DeclPtr = Arg;
154b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    }
155b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow    Arg->setName(D.getName());
156b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  }
157b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
158b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  llvm::Value *&DMEntry = LocalDeclMap[&D];
159b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
160b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow  DMEntry = DeclPtr;
161b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow}
162b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow
163b0a17f2ff9e0f5466fa7f9142db8128144175cafLenny Komow