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