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