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