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