CGCXX.cpp revision 86e9644199d91a33d0090395395bc718bd3a4981
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"
2086e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson#include "clang/AST/DeclObjC.h"
21e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson#include "llvm/ADT/StringExtras.h"
22e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
23e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace clang;
24e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing namespace CodeGen;
25e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
26e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonusing llvm::utostr;
27e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
28e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
29e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson// FIXME: Name mangling should be moved to a separate class.
30e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
31e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonstatic void mangleDeclContextInternal(const DeclContext *D, std::string &S)
32e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson{
3386e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson  // FIXME: Should ObjcMethodDecl have the TranslationUnitDecl as its parent?
3486e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson  assert(!D->getParent() || isa<TranslationUnitDecl>(D->getParent()) &&
35e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson         "Only one level of decl context mangling is currently supported!");
36e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
3786e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson  if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
38e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    S += utostr(FD->getIdentifier()->getLength());
39e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    S += FD->getIdentifier()->getName();
40e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
41e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    if (FD->param_size() == 0)
42e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson      S += 'v';
43e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    else
44e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson      assert(0 && "mangling of types not supported yet!");
4586e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson  } else if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D)) {
4686e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson
4786e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson    // FIXME: This should really use GetNameForMethod from CGObjCMac.
4886e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson    std::string Name;
4986e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson    Name += MD->isInstance() ? '-' : '+';
5086e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson    Name += '[';
5186e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson    Name += MD->getClassInterface()->getName();
5286e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson    Name += ' ';
5386e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson    Name += MD->getSelector().getName();
5486e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson    Name += ']';
5586e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson    S += utostr(Name.length());
5686e9644199d91a33d0090395395bc718bd3a4981Anders Carlsson    S += Name;
57e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  } else
58e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    assert(0 && "Unsupported decl type!");
59e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
60e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
61e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonstatic void mangleVarDeclInternal(const VarDecl &D, std::string &S)
62e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson{
63e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  S += 'Z';
64e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  mangleDeclContextInternal(D.getDeclContext(), S);
65e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  S += 'E';
66e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
67e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  S += utostr(D.getIdentifier()->getLength());
68e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  S += D.getIdentifier()->getName();
69e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
70e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
71e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonstatic std::string mangleVarDecl(const VarDecl& D)
72e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson{
73e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  std::string S = "_Z";
74e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
75e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  mangleVarDeclInternal(D, S);
76e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
77e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  return S;
78e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
79e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
80e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonstatic std::string mangleGuardVariable(const VarDecl& D)
81e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson{
82e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  std::string S = "_ZGV";
83e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
84e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  mangleVarDeclInternal(D, S);
85e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
86e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  return S;
87e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
88e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
89e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlssonllvm::GlobalValue *
90e1b29efab32d02e114046d33cca242a88585bf8aAnders CarlssonCodeGenFunction::GenerateStaticCXXBlockVarDecl(const VarDecl &D)
91e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson{
92e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  assert(!getContext().getLangOptions().ThreadsafeStatics &&
93e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson         "thread safe statics are currently not supported!");
94e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
95e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
96e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // FIXME: If the function is inline, the linkage should be weak.
97e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::GlobalValue::LinkageTypes linkage = llvm::GlobalValue::InternalLinkage;
98e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
99e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Create the guard variable.
100e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::GlobalValue *GuardV =
101e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    new llvm::GlobalVariable(llvm::Type::Int64Ty, false,
102e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             linkage,
103e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             llvm::Constant::getNullValue(llvm::Type::Int64Ty),
104e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             mangleGuardVariable(D),
105e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             &CGM.getModule());
106e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
107e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // FIXME: Address space.
108e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  const llvm::Type *PtrTy = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
109e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
110e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Load the first byte of the guard variable.
111e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
112e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                                      "tmp");
113e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
114e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // Compare it against 0.
115e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *nullValue = llvm::Constant::getNullValue(llvm::Type::Int8Ty);
116e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool");
117e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
118e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::BasicBlock *InitBlock = llvm::BasicBlock::Create("init");
119e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::BasicBlock *EndBlock = llvm::BasicBlock::Create("initend");
120e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
121e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  // If the guard variable is 0, jump to the initializer code.
122e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  Builder.CreateCondBr(ICmp, InitBlock, EndBlock);
123e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
124e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  EmitBlock(InitBlock);
125e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
126e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  llvm::GlobalValue *GV =
127e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    new llvm::GlobalVariable(LTy, false,
128e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             llvm::GlobalValue::InternalLinkage,
129e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             llvm::Constant::getNullValue(LTy),
130e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             mangleVarDecl(D),
131e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             &CGM.getModule(), 0,
132e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                             D.getType().getAddressSpace());
133e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
134e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  const Expr *Init = D.getInit();
135e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  if (!hasAggregateLLVMType(Init->getType())) {
136e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    llvm::Value *V = EmitScalarExpr(Init);
137e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    Builder.CreateStore(V, GV, D.getType().isVolatileQualified());
138e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  } else if (Init->getType()->isAnyComplexType()) {
139e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    EmitComplexExprIntoAddr(Init, GV, D.getType().isVolatileQualified());
140e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  } else {
141e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson    EmitAggExpr(Init, GV, D.getType().isVolatileQualified());
142e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  }
143e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
144e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::Int8Ty, 1),
145e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson                      Builder.CreateBitCast(GuardV, PtrTy));
146e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
147e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  EmitBlock(EndBlock);
148e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson  return GV;
149e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson}
150e1b29efab32d02e114046d33cca242a88585bf8aAnders Carlsson
151