blob: f43920c13f1907d1a27f267795ed7923e67cd5ba [file] [log] [blame]
Mike Stumpc01c2b82009-12-02 18:57:08 +00001//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
Anders Carlsson6ce51fd2009-10-10 20:49:04 +00002//
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 of RTTI descriptors.
11//
12//===----------------------------------------------------------------------===//
13
Mike Stump103a0842009-11-17 23:45:57 +000014#include "clang/AST/Type.h"
Mike Stumpf5b28692009-11-14 23:32:21 +000015#include "clang/AST/RecordLayout.h"
Mike Stumpdb72c892009-11-17 21:44:24 +000016#include "CodeGenModule.h"
Anders Carlsson6ce51fd2009-10-10 20:49:04 +000017using namespace clang;
18using namespace CodeGen;
19
Mike Stumpae1b85d2009-12-02 19:07:44 +000020namespace {
Mike Stumpc01c2b82009-12-02 18:57:08 +000021class RTTIBuilder {
Mike Stump14718422009-11-14 14:25:18 +000022 CodeGenModule &CGM; // Per-module state.
23 llvm::LLVMContext &VMContext;
24 const llvm::Type *Int8PtrTy;
Mike Stump4c808df2009-11-15 03:28:10 +000025 llvm::SmallSet<const CXXRecordDecl *, 16> SeenVBase;
26 llvm::SmallSet<const CXXRecordDecl *, 32> SeenBase;
Mike Stump14718422009-11-14 14:25:18 +000027public:
Mike Stumpc01c2b82009-12-02 18:57:08 +000028 RTTIBuilder(CodeGenModule &cgm)
Mike Stump14718422009-11-14 14:25:18 +000029 : CGM(cgm), VMContext(cgm.getModule().getContext()),
30 Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
31
Mike Stumpf5b28692009-11-14 23:32:21 +000032 /// BuildVtableRef - Build a reference to a vtable.
33 llvm::Constant *BuildVtableRef(const char *Name) {
34 // Build a descriptor for Name
Mike Stump1acec6a2009-11-14 15:55:18 +000035 llvm::Constant *GV = CGM.getModule().getGlobalVariable(Name);
36 if (GV)
37 GV = llvm::ConstantExpr::getBitCast(GV,
38 llvm::PointerType::get(Int8PtrTy, 0));
39 else {
40 llvm::GlobalVariable::LinkageTypes linktype;
41 linktype = llvm::GlobalValue::ExternalLinkage;
42 GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy,
43 true, linktype, 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +000044 }
Mike Stump1acec6a2009-11-14 15:55:18 +000045 llvm::Constant *C;
46 C = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 2);
47 C = llvm::ConstantExpr::getInBoundsGetElementPtr(GV, &C, 1);
48 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
49 }
Mike Stumpf5b28692009-11-14 23:32:21 +000050
Mike Stump1a139f82009-11-19 01:08:19 +000051 llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
Mike Stump14718422009-11-14 14:25:18 +000052 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +000053 CGM.getMangleContext().mangleCXXRTTIName(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +000054 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +000055
Mike Stump14718422009-11-14 14:25:18 +000056 llvm::GlobalVariable::LinkageTypes linktype;
57 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump1a139f82009-11-19 01:08:19 +000058 if (!Extern)
59 linktype = llvm::GlobalValue::InternalLinkage;
60
61 llvm::GlobalVariable *GV;
62 GV = CGM.getModule().getGlobalVariable(Name);
63 if (GV && !GV->isDeclaration())
64 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump14718422009-11-14 14:25:18 +000065
66 llvm::Constant *C;
Mike Stump1a139f82009-11-19 01:08:19 +000067 C = llvm::ConstantArray::get(VMContext, Name.substr(4));
Mike Stumpf5b28692009-11-14 23:32:21 +000068
Mike Stump1a139f82009-11-19 01:08:19 +000069 llvm::GlobalVariable *OGV = GV;
70 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
71 C, Name);
72 if (OGV) {
73 GV->takeName(OGV);
74 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
75 OGV->getType());
76 OGV->replaceAllUsesWith(NewPtr);
77 OGV->eraseFromParent();
78 }
Mike Stump83d5e002009-11-18 03:46:51 +000079 if (Hidden)
80 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
81 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump14718422009-11-14 14:25:18 +000082 };
Mike Stump1acec6a2009-11-14 15:55:18 +000083
Mike Stumpf5b28692009-11-14 23:32:21 +000084 /// - BuildFlags - Build a psABI __flags value for __vmi_class_type_info.
85 llvm::Constant *BuildFlags(int f) {
86 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
87 }
88
89 /// BuildBaseCount - Build a psABI __base_count value for
90 /// __vmi_class_type_info.
91 llvm::Constant *BuildBaseCount(unsigned c) {
92 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), c);
93 }
94
Mike Stump3f75d552009-11-17 02:16:21 +000095 llvm::Constant *BuildTypeRef(QualType Ty) {
Mike Stumpf5b28692009-11-14 23:32:21 +000096 llvm::Constant *C;
Mike Stump1acec6a2009-11-14 15:55:18 +000097
Mike Stumpc01c2b82009-12-02 18:57:08 +000098 if (!CGM.getContext().getLangOptions().RTTI)
Mike Stump1acec6a2009-11-14 15:55:18 +000099 return llvm::Constant::getNullValue(Int8PtrTy);
100
101 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000102 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000103 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000104
Mike Stump1a139f82009-11-19 01:08:19 +0000105 C = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000106 if (C)
107 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
108
109 llvm::GlobalVariable::LinkageTypes linktype;
110 linktype = llvm::GlobalValue::ExternalLinkage;;
111
112 C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
Mike Stump1a139f82009-11-19 01:08:19 +0000113 0, Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000114 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
115 }
116
Mike Stump3f75d552009-11-17 02:16:21 +0000117 llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
118 return BuildTypeRef(CGM.getContext().getTagDeclType(RD));
119 }
120
Mike Stump4c808df2009-11-15 03:28:10 +0000121 /// CalculateFlags - Calculate the flags for the __vmi_class_type_info
122 /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond
123 /// shaped class.
124 int CalculateFlags(const CXXRecordDecl*RD) {
125 int flags = 0;
126 if (SeenBase.count(RD))
127 flags |= 1;
128 else
129 SeenBase.insert(RD);
130 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
131 e = RD->bases_end(); i != e; ++i) {
132 const CXXRecordDecl *Base =
133 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
134 if (i->isVirtual()) {
135 if (SeenVBase.count(Base))
136 flags |= 2;
137 else
138 SeenVBase.insert(Base);
139 }
140 flags |= CalculateFlags(Base);
141 }
142 return flags;
143 }
144
145 bool SimpleInheritance(const CXXRecordDecl *RD) {
146 if (RD->getNumBases() != 1)
147 return false;
148 CXXRecordDecl::base_class_const_iterator i = RD->bases_begin();
149 if (i->isVirtual())
150 return false;
151 if (i->getAccessSpecifier() != AS_public)
152 return false;
153
154 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
155 const CXXRecordDecl *Base =
156 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
157 if (Layout.getBaseClassOffset(Base) != 0)
158 return false;
159 return true;
160 }
161
Mike Stump96b96d52009-11-17 23:11:22 +0000162 llvm::Constant *finish(std::vector<llvm::Constant *> &info,
163 llvm::GlobalVariable *GV,
Mike Stump1a139f82009-11-19 01:08:19 +0000164 llvm::StringRef Name, bool Hidden, bool Extern) {
Mike Stump96b96d52009-11-17 23:11:22 +0000165 llvm::GlobalVariable::LinkageTypes linktype;
166 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump1a139f82009-11-19 01:08:19 +0000167 if (!Extern)
168 linktype = llvm::GlobalValue::InternalLinkage;
Mike Stumpf5b28692009-11-14 23:32:21 +0000169
Mike Stump96b96d52009-11-17 23:11:22 +0000170 llvm::Constant *C;
171 C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
172
Mike Stump1a139f82009-11-19 01:08:19 +0000173 llvm::GlobalVariable *OGV = GV;
174 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
175 C, Name);
176 if (OGV) {
Mike Stump96b96d52009-11-17 23:11:22 +0000177 GV->takeName(OGV);
178 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
179 OGV->getType());
180 OGV->replaceAllUsesWith(NewPtr);
181 OGV->eraseFromParent();
182 }
Mike Stump83d5e002009-11-18 03:46:51 +0000183 if (Hidden)
Mike Stumpc5d2ed72009-11-18 03:21:29 +0000184 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
Mike Stump96b96d52009-11-17 23:11:22 +0000185 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
186 }
187
188
189 llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) {
Mike Stumpc01c2b82009-12-02 18:57:08 +0000190 if (!CGM.getContext().getLangOptions().RTTI)
Mike Stumpf5b28692009-11-14 23:32:21 +0000191 return llvm::Constant::getNullValue(Int8PtrTy);
192
Mike Stump96b96d52009-11-17 23:11:22 +0000193 llvm::Constant *C;
194
Mike Stumpf5b28692009-11-14 23:32:21 +0000195 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000196 CGM.getMangleContext().mangleCXXRTTI(CGM.getContext().getTagDeclType(RD),
Daniel Dunbare128dd12009-11-21 09:06:22 +0000197 OutName);
198 llvm::StringRef Name = OutName.str();
Mike Stumpf5b28692009-11-14 23:32:21 +0000199
200 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000201 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpf5b28692009-11-14 23:32:21 +0000202 if (GV && !GV->isDeclaration())
203 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
204
Mike Stump1acec6a2009-11-14 15:55:18 +0000205 std::vector<llvm::Constant *> info;
206
Mike Stump83d5e002009-11-18 03:46:51 +0000207 bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
Mike Stump1a139f82009-11-19 01:08:19 +0000208 bool Extern = !RD->isInAnonymousNamespace();
Mike Stump83d5e002009-11-18 03:46:51 +0000209
Mike Stump4c808df2009-11-15 03:28:10 +0000210 bool simple = false;
Mike Stumpf5b28692009-11-14 23:32:21 +0000211 if (RD->getNumBases() == 0)
212 C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
Mike Stump4c808df2009-11-15 03:28:10 +0000213 else if (SimpleInheritance(RD)) {
214 simple = true;
215 C = BuildVtableRef("_ZTVN10__cxxabiv120__si_class_type_infoE");
216 } else
Mike Stumpf5b28692009-11-14 23:32:21 +0000217 C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
218 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000219 info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
220 Extern));
Mike Stump1acec6a2009-11-14 15:55:18 +0000221
Mike Stumpf5b28692009-11-14 23:32:21 +0000222 // If we have no bases, there are no more fields.
223 if (RD->getNumBases()) {
Mike Stump4c808df2009-11-15 03:28:10 +0000224 if (!simple) {
225 info.push_back(BuildFlags(CalculateFlags(RD)));
226 info.push_back(BuildBaseCount(RD->getNumBases()));
227 }
Mike Stumpf5b28692009-11-14 23:32:21 +0000228
229 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
230 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
231 e = RD->bases_end(); i != e; ++i) {
232 const CXXRecordDecl *Base =
233 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Mike Stumpc01c2b82009-12-02 18:57:08 +0000234 info.push_back(CGM.GenerateRTTIRef(Base));
Mike Stump4c808df2009-11-15 03:28:10 +0000235 if (simple)
236 break;
Mike Stumpf5b28692009-11-14 23:32:21 +0000237 int64_t offset;
238 if (!i->isVirtual())
Mike Stump4c808df2009-11-15 03:28:10 +0000239 offset = Layout.getBaseClassOffset(Base)/8;
Mike Stumpf5b28692009-11-14 23:32:21 +0000240 else
241 offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
242 offset <<= 8;
243 // Now set the flags.
244 offset += i->isVirtual() ? 1 : 0;;
245 offset += i->getAccessSpecifier() == AS_public ? 2 : 0;
246 const llvm::Type *LongTy =
247 CGM.getTypes().ConvertType(CGM.getContext().LongTy);
248 C = llvm::ConstantInt::get(LongTy, offset);
249 info.push_back(C);
250 }
251 }
252
Mike Stump1a139f82009-11-19 01:08:19 +0000253 return finish(info, GV, Name, Hidden, Extern);
Mike Stump1acec6a2009-11-14 15:55:18 +0000254 }
Mike Stump3f75d552009-11-17 02:16:21 +0000255
Mike Stumpdb72c892009-11-17 21:44:24 +0000256 /// - BuildFlags - Build a __flags value for __pbase_type_info.
257 llvm::Constant *BuildInt(int f) {
258 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
259 }
260
Mike Stump1a139f82009-11-19 01:08:19 +0000261 bool DecideExtern(QualType Ty) {
262 // For this type, see if all components are never in an anonymous namespace.
263 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
264 return (DecideExtern(MPT->getPointeeType())
265 && DecideExtern(QualType(MPT->getClass(), 0)));
266 if (const PointerType *PT = Ty->getAs<PointerType>())
267 return DecideExtern(PT->getPointeeType());
268 if (const RecordType *RT = Ty->getAs<RecordType>())
269 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
270 return !RD->isInAnonymousNamespace();
271 return true;
272 }
273
274 bool DecideHidden(QualType Ty) {
275 // For this type, see if all components are never hidden.
276 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
277 return (DecideHidden(MPT->getPointeeType())
278 && DecideHidden(QualType(MPT->getClass(), 0)));
279 if (const PointerType *PT = Ty->getAs<PointerType>())
280 return DecideHidden(PT->getPointeeType());
281 if (const RecordType *RT = Ty->getAs<RecordType>())
282 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
283 return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
284 return false;
285 }
286
Mike Stumpdb72c892009-11-17 21:44:24 +0000287 llvm::Constant *BuildPointerType(QualType Ty) {
Mike Stumpdb72c892009-11-17 21:44:24 +0000288 llvm::Constant *C;
289
290 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000291 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000292 llvm::StringRef Name = OutName.str();
Mike Stumpdb72c892009-11-17 21:44:24 +0000293
294 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000295 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpdb72c892009-11-17 21:44:24 +0000296 if (GV && !GV->isDeclaration())
297 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
298
Mike Stumpdb72c892009-11-17 21:44:24 +0000299 std::vector<llvm::Constant *> info;
300
Mike Stump1a139f82009-11-19 01:08:19 +0000301 bool Extern = DecideExtern(Ty);
302 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000303
Mike Stumpdb72c892009-11-17 21:44:24 +0000304 QualType PTy = Ty->getPointeeType();
Mike Stumpdb72c892009-11-17 21:44:24 +0000305 QualType BTy;
Mike Stumpdb72c892009-11-17 21:44:24 +0000306 bool PtrMem = false;
Mike Stump6fdfea62009-11-17 22:33:00 +0000307 if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(Ty)) {
308 PtrMem = true;
309 BTy = QualType(MPT->getClass(), 0);
310 PTy = MPT->getPointeeType();
311 }
Mike Stumpdb72c892009-11-17 21:44:24 +0000312
313 if (PtrMem)
314 C = BuildVtableRef("_ZTVN10__cxxabiv129__pointer_to_member_type_infoE");
315 else
316 C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
317 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000318 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stumpdb72c892009-11-17 21:44:24 +0000319 Qualifiers Q = PTy.getQualifiers();
320 PTy = CGM.getContext().getCanonicalType(PTy).getUnqualifiedType();
321 int flags = 0;
322 flags += Q.hasConst() ? 0x1 : 0;
323 flags += Q.hasVolatile() ? 0x2 : 0;
324 flags += Q.hasRestrict() ? 0x4 : 0;
325 flags += Ty.getTypePtr()->isIncompleteType() ? 0x8 : 0;
326 if (PtrMem && BTy.getTypePtr()->isIncompleteType())
327 flags += 0x10;
Mike Stump4aaf79a2009-11-17 23:51:10 +0000328
Mike Stumpdb72c892009-11-17 21:44:24 +0000329 info.push_back(BuildInt(flags));
330 info.push_back(BuildInt(0));
Mike Stump101f0522009-11-20 00:31:50 +0000331 info.push_back(BuildType(PTy));
Mike Stumpdb72c892009-11-17 21:44:24 +0000332
333 if (PtrMem)
Mike Stump101f0522009-11-20 00:31:50 +0000334 info.push_back(BuildType(BTy));
Mike Stump4aaf79a2009-11-17 23:51:10 +0000335
Mike Stump1a139f82009-11-19 01:08:19 +0000336 // We always generate these as hidden, only the name isn't hidden.
337 return finish(info, GV, Name, true, Extern);
Mike Stump96b96d52009-11-17 23:11:22 +0000338 }
Mike Stumpdb72c892009-11-17 21:44:24 +0000339
Mike Stump103a0842009-11-17 23:45:57 +0000340 llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
Mike Stump96b96d52009-11-17 23:11:22 +0000341 llvm::Constant *C;
342
343 llvm::SmallString<256> OutName;
Mike Stumpc01c2b82009-12-02 18:57:08 +0000344 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbare128dd12009-11-21 09:06:22 +0000345 llvm::StringRef Name = OutName.str();
Mike Stump96b96d52009-11-17 23:11:22 +0000346
347 llvm::GlobalVariable *GV;
Mike Stump1a139f82009-11-19 01:08:19 +0000348 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump96b96d52009-11-17 23:11:22 +0000349 if (GV && !GV->isDeclaration())
350 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
351
352 std::vector<llvm::Constant *> info;
353
Mike Stump1a139f82009-11-19 01:08:19 +0000354 bool Extern = DecideExtern(Ty);
355 bool Hidden = DecideHidden(Ty);
Mike Stump83d5e002009-11-18 03:46:51 +0000356
Mike Stump103a0842009-11-17 23:45:57 +0000357 C = BuildVtableRef(vtbl);
Mike Stump96b96d52009-11-17 23:11:22 +0000358 info.push_back(C);
Mike Stump1a139f82009-11-19 01:08:19 +0000359 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stump4aaf79a2009-11-17 23:51:10 +0000360
Mike Stump1a139f82009-11-19 01:08:19 +0000361 // We always generate these as hidden, only the name isn't hidden.
362 return finish(info, GV, Name, true, Extern);
Mike Stumpdb72c892009-11-17 21:44:24 +0000363 }
364
Mike Stump3f75d552009-11-17 02:16:21 +0000365 llvm::Constant *BuildType(QualType Ty) {
366 const clang::Type &Type
367 = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
Mike Stump101f0522009-11-20 00:31:50 +0000368
369 if (const RecordType *RT = Ty.getTypePtr()->getAs<RecordType>())
370 if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()))
371 return Buildclass_type_info(RD);
372
Mike Stump3f75d552009-11-17 02:16:21 +0000373 switch (Type.getTypeClass()) {
374 default: {
Mike Stump3f75d552009-11-17 02:16:21 +0000375 assert(0 && "typeid expression");
Mike Stump3f75d552009-11-17 02:16:21 +0000376 return llvm::Constant::getNullValue(Int8PtrTy);
377 }
378
379 case Type::Builtin: {
380 // We expect all type_info objects for builtin types to be in the library.
381 return BuildTypeRef(Ty);
382 }
Mike Stump8f5e6772009-11-17 02:57:13 +0000383
384 case Type::Pointer: {
385 QualType PTy = Ty->getPointeeType();
386 Qualifiers Q = PTy.getQualifiers();
387 Q.removeConst();
388 // T* and const T* for all builtin types T are expected in the library.
389 if (isa<BuiltinType>(PTy) && Q.empty())
390 return BuildTypeRef(Ty);
391
Mike Stumpdb72c892009-11-17 21:44:24 +0000392 return BuildPointerType(Ty);
Mike Stump8f5e6772009-11-17 02:57:13 +0000393 }
Mike Stump6fdfea62009-11-17 22:33:00 +0000394 case Type::MemberPointer:
395 return BuildPointerType(Ty);
Mike Stump96b96d52009-11-17 23:11:22 +0000396 case Type::FunctionProto:
Mike Stump103a0842009-11-17 23:45:57 +0000397 case Type::FunctionNoProto:
398 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv120__function_type_infoE");
399 case Type::ConstantArray:
400 case Type::IncompleteArray:
401 case Type::VariableArray:
402 case Type::Vector:
403 case Type::ExtVector:
404 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
405 case Type::Enum:
406 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv116__enum_type_infoE");
Mike Stump3f75d552009-11-17 02:16:21 +0000407 }
408 }
Mike Stump14718422009-11-14 14:25:18 +0000409};
Mike Stumpae1b85d2009-12-02 19:07:44 +0000410}
Mike Stump14718422009-11-14 14:25:18 +0000411
Mike Stumpc01c2b82009-12-02 18:57:08 +0000412llvm::Constant *CodeGenModule::GenerateRTTIRef(const CXXRecordDecl *RD) {
413 RTTIBuilder b(*this);
Mike Stumpf5b28692009-11-14 23:32:21 +0000414
415 return b.Buildclass_type_infoRef(RD);
416}
417
Mike Stumpc01c2b82009-12-02 18:57:08 +0000418llvm::Constant *CodeGenModule::GenerateRTTI(const CXXRecordDecl *RD) {
419 RTTIBuilder b(*this);
Mike Stump14718422009-11-14 14:25:18 +0000420
Mike Stumpf5b28692009-11-14 23:32:21 +0000421 return b.Buildclass_type_info(RD);
Anders Carlsson6ce51fd2009-10-10 20:49:04 +0000422}
Mike Stump3f75d552009-11-17 02:16:21 +0000423
Mike Stumpc01c2b82009-12-02 18:57:08 +0000424llvm::Constant *CodeGenModule::GenerateRTTI(QualType Ty) {
425 RTTIBuilder b(*this);
Mike Stump3f75d552009-11-17 02:16:21 +0000426
427 return b.BuildType(Ty);
428}