CGCXX.cpp revision e1b29efab32d02e114046d33cca242a88585bf8a
1e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
2e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
3e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//                     The LLVM Compiler Infrastructure
4e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
5e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// This file is distributed under the University of Illinois Open Source
6e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// License. See LICENSE.TXT for details.
7e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
8e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===----------------------------------------------------------------------===//
9e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
10e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// This contains code dealing with C++ code generation.
11e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//
12e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson//===----------------------------------------------------------------------===//
13e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
14e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// We might split this into multiple files if it gets too unwieldy
15e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
16e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "CodeGenFunction.h"
17e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "CodeGenModule.h"
18e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "clang/AST/ASTContext.h"
19e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "clang/AST/Decl.h"
20e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "llvm/ADT/StringExtras.h"
21e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
22e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace clang;
23e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace CodeGen;
24e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
25e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing llvm::utostr;
26e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
27e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
28e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// FIXME: Name mangling should be moved to a separate class.
29e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
30e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonstatic void mangleDeclContextInternal(const DeclContext *D, std::string &S)
31e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson{
32e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  assert(isa<TranslationUnitDecl>(D->getParent()) &&
33e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson         "Only one level of decl context mangling is currently supported!");
34e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
35e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  if (FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
36e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    S += utostr(FD->getIdentifier()->getLength());
37e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    S += FD->getIdentifier()->getName();
38e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
39e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    if (FD->param_size() == 0)
40e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson      S += 'v';
41e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    else
42e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson      assert(0 && "mangling of types not supported yet!");
43e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  } else
44e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    assert(0 && "Unsupported decl type!");
45e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
46e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
47e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonstatic void mangleVarDeclInternal(const VarDecl &D, std::string &S)
48e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson{
49e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  S += 'Z';
50e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  mangleDeclContextInternal(D.getDeclContext(), S);
51e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  S += 'E';
52e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
53e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  S += utostr(D.getIdentifier()->getLength());
54e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  S += D.getIdentifier()->getName();
55e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
56e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
57e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonstatic std::string mangleVarDecl(const VarDecl& D)
58e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson{
59e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  std::string S = "_Z";
60e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
61e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  mangleVarDeclInternal(D, S);
62e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
63e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  return S;
64e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
65e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
66e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonstatic std::string mangleGuardVariable(const VarDecl& D)
67e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson{
68e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  std::string S = "_ZGV";
69e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
70e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  mangleVarDeclInternal(D, S);
71e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
72e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  return S;
73e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
74e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
75e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonllvm::GlobalValue *
76e1b29efab32d02e114046d33cca242a88585bf8aAnders CarlssonCodeGenFunction::GenerateStaticCXXBlockVarDecl(const VarDecl &D)
77e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson{
78e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  assert(!getContext().getLangOptions().ThreadsafeStatics &&
79e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson         "thread safe statics are currently not supported!");
80e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
81e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
82e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // FIXME: If the function is inline, the linkage should be weak.
83e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::GlobalValue::LinkageTypes linkage = llvm::GlobalValue::InternalLinkage;
84e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
85e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Create the guard variable.
86e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::GlobalValue *GuardV =
87e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    new llvm::GlobalVariable(llvm::Type::Int64Ty, false,
88e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             linkage,
89e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             llvm::Constant::getNullValue(llvm::Type::Int64Ty),
90e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             mangleGuardVariable(D),
91e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             &CGM.getModule());
92e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
93e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // FIXME: Address space.
94e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
95e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
96e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Load the first byte of the guard variable.
97e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
98e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                                      "tmp");
99e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
100e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Compare it against 0.
101e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *nullValue = llvm::Constant::getNullValue(llvm::Type::Int8Ty);
102e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool");
103e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
104e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::BasicBlock *InitBlock = llvm::BasicBlock::Create("init");
105e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::BasicBlock *EndBlock = llvm::BasicBlock::Create("initend");
106e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
107e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // If the guard variable is 0, jump to the initializer code.
108e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  Builder.CreateCondBr(ICmp, InitBlock, EndBlock);
109e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
110e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  EmitBlock(InitBlock);
111e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
112e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::GlobalValue *GV =
113e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    new llvm::GlobalVariable(LTy, false,
114e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             llvm::GlobalValue::InternalLinkage,
115e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             llvm::Constant::getNullValue(LTy),
116e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             mangleVarDecl(D),
117e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             &CGM.getModule(), 0,
118e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             D.getType().getAddressSpace());
119e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
120e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  const Expr *Init = D.getInit();
121e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  if (!hasAggregateLLVMType(Init->getType())) {
122e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    llvm::Value *V = EmitScalarExpr(Init);
123e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    Builder.CreateStore(V, GV, D.getType().isVolatileQualified());
124e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  } else if (Init->getType()->isAnyComplexType()) {
125e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    EmitComplexExprIntoAddr(Init, GV, D.getType().isVolatileQualified());
126e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  } else {
127e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    EmitAggExpr(Init, GV, D.getType().isVolatileQualified());
128e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  }
129e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
130e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::Int8Ty, 1),
131e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                      Builder.CreateBitCast(GuardV, PtrTy));
132e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
133e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  EmitBlock(EndBlock);
134e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  return GV;
135e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
136e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
137