blob: 38a17b3c396e0bcc00afd8f494b6cd53df7b6b7a [file] [log] [blame]
Anders Carlsson656e4c12009-10-10 20:49:04 +00001//===--- CGCXXRtti.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
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 of RTTI descriptors.
11//
12//===----------------------------------------------------------------------===//
13
Mike Stumpae9b2be2009-11-17 23:45:57 +000014#include "clang/AST/Type.h"
Mike Stumpcbcd4e52009-11-14 23:32:21 +000015#include "clang/AST/RecordLayout.h"
Mike Stump61c38012009-11-17 21:44:24 +000016#include "CodeGenModule.h"
Anders Carlsson656e4c12009-10-10 20:49:04 +000017using namespace clang;
18using namespace CodeGen;
19
Mike Stump2b1bf312009-11-14 14:25:18 +000020class RttiBuilder {
21 CodeGenModule &CGM; // Per-module state.
22 llvm::LLVMContext &VMContext;
23 const llvm::Type *Int8PtrTy;
Mike Stumpa8285a82009-11-15 03:28:10 +000024 llvm::SmallSet<const CXXRecordDecl *, 16> SeenVBase;
25 llvm::SmallSet<const CXXRecordDecl *, 32> SeenBase;
Mike Stump2b1bf312009-11-14 14:25:18 +000026public:
27 RttiBuilder(CodeGenModule &cgm)
28 : CGM(cgm), VMContext(cgm.getModule().getContext()),
29 Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
30
Mike Stumpcbcd4e52009-11-14 23:32:21 +000031 /// BuildVtableRef - Build a reference to a vtable.
32 llvm::Constant *BuildVtableRef(const char *Name) {
33 // Build a descriptor for Name
Mike Stumpc7a05bd2009-11-14 15:55:18 +000034 llvm::Constant *GV = CGM.getModule().getGlobalVariable(Name);
35 if (GV)
36 GV = llvm::ConstantExpr::getBitCast(GV,
37 llvm::PointerType::get(Int8PtrTy, 0));
38 else {
39 llvm::GlobalVariable::LinkageTypes linktype;
40 linktype = llvm::GlobalValue::ExternalLinkage;
41 GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy,
42 true, linktype, 0, Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +000043 }
Mike Stumpc7a05bd2009-11-14 15:55:18 +000044 llvm::Constant *C;
45 C = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 2);
46 C = llvm::ConstantExpr::getInBoundsGetElementPtr(GV, &C, 1);
47 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
48 }
Mike Stumpcbcd4e52009-11-14 23:32:21 +000049
Mike Stump58588942009-11-19 01:08:19 +000050 llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
Mike Stump2b1bf312009-11-14 14:25:18 +000051 llvm::SmallString<256> OutName;
52 llvm::raw_svector_ostream Out(OutName);
Mike Stump61c38012009-11-17 21:44:24 +000053 mangleCXXRttiName(CGM.getMangleContext(), Ty, Out);
Mike Stump58588942009-11-19 01:08:19 +000054 llvm::StringRef Name = Out.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +000055
Mike Stump2b1bf312009-11-14 14:25:18 +000056 llvm::GlobalVariable::LinkageTypes linktype;
57 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump58588942009-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 Stump2b1bf312009-11-14 14:25:18 +000065
66 llvm::Constant *C;
Mike Stump58588942009-11-19 01:08:19 +000067 C = llvm::ConstantArray::get(VMContext, Name.substr(4));
Mike Stumpcbcd4e52009-11-14 23:32:21 +000068
Mike Stump58588942009-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 Stump582b0372009-11-18 03:46:51 +000079 if (Hidden)
80 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
81 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump2b1bf312009-11-14 14:25:18 +000082 };
Mike Stumpc7a05bd2009-11-14 15:55:18 +000083
Mike Stumpcbcd4e52009-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 Stumpea2c0b52009-11-17 02:16:21 +000095 llvm::Constant *BuildTypeRef(QualType Ty) {
Mike Stumpcbcd4e52009-11-14 23:32:21 +000096 llvm::Constant *C;
Mike Stumpc7a05bd2009-11-14 15:55:18 +000097
98 if (!CGM.getContext().getLangOptions().Rtti)
99 return llvm::Constant::getNullValue(Int8PtrTy);
100
101 llvm::SmallString<256> OutName;
102 llvm::raw_svector_ostream Out(OutName);
Mike Stumpea2c0b52009-11-17 02:16:21 +0000103 mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
Mike Stump58588942009-11-19 01:08:19 +0000104 llvm::StringRef Name = Out.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000105
Mike Stump58588942009-11-19 01:08:19 +0000106 C = CGM.getModule().getGlobalVariable(Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000107 if (C)
108 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
109
110 llvm::GlobalVariable::LinkageTypes linktype;
111 linktype = llvm::GlobalValue::ExternalLinkage;;
112
113 C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
Mike Stump58588942009-11-19 01:08:19 +0000114 0, Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000115 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
116 }
117
Mike Stumpea2c0b52009-11-17 02:16:21 +0000118 llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
119 return BuildTypeRef(CGM.getContext().getTagDeclType(RD));
120 }
121
Mike Stumpa8285a82009-11-15 03:28:10 +0000122 /// CalculateFlags - Calculate the flags for the __vmi_class_type_info
123 /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond
124 /// shaped class.
125 int CalculateFlags(const CXXRecordDecl*RD) {
126 int flags = 0;
127 if (SeenBase.count(RD))
128 flags |= 1;
129 else
130 SeenBase.insert(RD);
131 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
132 e = RD->bases_end(); i != e; ++i) {
133 const CXXRecordDecl *Base =
134 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
135 if (i->isVirtual()) {
136 if (SeenVBase.count(Base))
137 flags |= 2;
138 else
139 SeenVBase.insert(Base);
140 }
141 flags |= CalculateFlags(Base);
142 }
143 return flags;
144 }
145
146 bool SimpleInheritance(const CXXRecordDecl *RD) {
147 if (RD->getNumBases() != 1)
148 return false;
149 CXXRecordDecl::base_class_const_iterator i = RD->bases_begin();
150 if (i->isVirtual())
151 return false;
152 if (i->getAccessSpecifier() != AS_public)
153 return false;
154
155 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
156 const CXXRecordDecl *Base =
157 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
158 if (Layout.getBaseClassOffset(Base) != 0)
159 return false;
160 return true;
161 }
162
Mike Stump64989f02009-11-17 23:11:22 +0000163 llvm::Constant *finish(std::vector<llvm::Constant *> &info,
164 llvm::GlobalVariable *GV,
Mike Stump58588942009-11-19 01:08:19 +0000165 llvm::StringRef Name, bool Hidden, bool Extern) {
Mike Stump64989f02009-11-17 23:11:22 +0000166 llvm::GlobalVariable::LinkageTypes linktype;
167 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump58588942009-11-19 01:08:19 +0000168 if (!Extern)
169 linktype = llvm::GlobalValue::InternalLinkage;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000170
Mike Stump64989f02009-11-17 23:11:22 +0000171 llvm::Constant *C;
172 C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
173
Mike Stump58588942009-11-19 01:08:19 +0000174 llvm::GlobalVariable *OGV = GV;
175 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
176 C, Name);
177 if (OGV) {
Mike Stump64989f02009-11-17 23:11:22 +0000178 GV->takeName(OGV);
179 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
180 OGV->getType());
181 OGV->replaceAllUsesWith(NewPtr);
182 OGV->eraseFromParent();
183 }
Mike Stump582b0372009-11-18 03:46:51 +0000184 if (Hidden)
Mike Stump88a4a622009-11-18 03:21:29 +0000185 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
Mike Stump64989f02009-11-17 23:11:22 +0000186 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
187 }
188
189
190 llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) {
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000191 if (!CGM.getContext().getLangOptions().Rtti)
192 return llvm::Constant::getNullValue(Int8PtrTy);
193
Mike Stump64989f02009-11-17 23:11:22 +0000194 llvm::Constant *C;
195
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000196 llvm::SmallString<256> OutName;
197 llvm::raw_svector_ostream Out(OutName);
198 mangleCXXRtti(CGM.getMangleContext(), CGM.getContext().getTagDeclType(RD),
199 Out);
Mike Stump58588942009-11-19 01:08:19 +0000200 llvm::StringRef Name = Out.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000201
202 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000203 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000204 if (GV && !GV->isDeclaration())
205 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
206
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000207 std::vector<llvm::Constant *> info;
208
Mike Stump582b0372009-11-18 03:46:51 +0000209 bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
Mike Stump58588942009-11-19 01:08:19 +0000210 bool Extern = !RD->isInAnonymousNamespace();
Mike Stump582b0372009-11-18 03:46:51 +0000211
Mike Stumpa8285a82009-11-15 03:28:10 +0000212 bool simple = false;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000213 if (RD->getNumBases() == 0)
214 C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
Mike Stumpa8285a82009-11-15 03:28:10 +0000215 else if (SimpleInheritance(RD)) {
216 simple = true;
217 C = BuildVtableRef("_ZTVN10__cxxabiv120__si_class_type_infoE");
218 } else
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000219 C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
220 info.push_back(C);
Mike Stump58588942009-11-19 01:08:19 +0000221 info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
222 Extern));
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000223
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000224 // If we have no bases, there are no more fields.
225 if (RD->getNumBases()) {
Mike Stumpa8285a82009-11-15 03:28:10 +0000226 if (!simple) {
227 info.push_back(BuildFlags(CalculateFlags(RD)));
228 info.push_back(BuildBaseCount(RD->getNumBases()));
229 }
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000230
231 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
232 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
233 e = RD->bases_end(); i != e; ++i) {
234 const CXXRecordDecl *Base =
235 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Mike Stumpa8285a82009-11-15 03:28:10 +0000236 info.push_back(CGM.GenerateRttiRef(Base));
237 if (simple)
238 break;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000239 int64_t offset;
240 if (!i->isVirtual())
Mike Stumpa8285a82009-11-15 03:28:10 +0000241 offset = Layout.getBaseClassOffset(Base)/8;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000242 else
243 offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
244 offset <<= 8;
245 // Now set the flags.
246 offset += i->isVirtual() ? 1 : 0;;
247 offset += i->getAccessSpecifier() == AS_public ? 2 : 0;
248 const llvm::Type *LongTy =
249 CGM.getTypes().ConvertType(CGM.getContext().LongTy);
250 C = llvm::ConstantInt::get(LongTy, offset);
251 info.push_back(C);
252 }
253 }
254
Mike Stump58588942009-11-19 01:08:19 +0000255 return finish(info, GV, Name, Hidden, Extern);
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000256 }
Mike Stumpea2c0b52009-11-17 02:16:21 +0000257
Mike Stump61c38012009-11-17 21:44:24 +0000258 /// - BuildFlags - Build a __flags value for __pbase_type_info.
259 llvm::Constant *BuildInt(int f) {
260 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
261 }
262
Mike Stump58588942009-11-19 01:08:19 +0000263 bool DecideExtern(QualType Ty) {
264 // For this type, see if all components are never in an anonymous namespace.
265 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
266 return (DecideExtern(MPT->getPointeeType())
267 && DecideExtern(QualType(MPT->getClass(), 0)));
268 if (const PointerType *PT = Ty->getAs<PointerType>())
269 return DecideExtern(PT->getPointeeType());
270 if (const RecordType *RT = Ty->getAs<RecordType>())
271 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
272 return !RD->isInAnonymousNamespace();
273 return true;
274 }
275
276 bool DecideHidden(QualType Ty) {
277 // For this type, see if all components are never hidden.
278 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
279 return (DecideHidden(MPT->getPointeeType())
280 && DecideHidden(QualType(MPT->getClass(), 0)));
281 if (const PointerType *PT = Ty->getAs<PointerType>())
282 return DecideHidden(PT->getPointeeType());
283 if (const RecordType *RT = Ty->getAs<RecordType>())
284 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
285 return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
286 return false;
287 }
288
Mike Stump61c38012009-11-17 21:44:24 +0000289 llvm::Constant *BuildPointerType(QualType Ty) {
Mike Stump61c38012009-11-17 21:44:24 +0000290 llvm::Constant *C;
291
292 llvm::SmallString<256> OutName;
293 llvm::raw_svector_ostream Out(OutName);
294 mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
Mike Stump58588942009-11-19 01:08:19 +0000295 llvm::StringRef Name = Out.str();
Mike Stump61c38012009-11-17 21:44:24 +0000296
297 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000298 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump61c38012009-11-17 21:44:24 +0000299 if (GV && !GV->isDeclaration())
300 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
301
Mike Stump61c38012009-11-17 21:44:24 +0000302 std::vector<llvm::Constant *> info;
303
Mike Stump58588942009-11-19 01:08:19 +0000304 bool Extern = DecideExtern(Ty);
305 bool Hidden = DecideHidden(Ty);
Mike Stump582b0372009-11-18 03:46:51 +0000306
Mike Stump61c38012009-11-17 21:44:24 +0000307 QualType PTy = Ty->getPointeeType();
Mike Stump61c38012009-11-17 21:44:24 +0000308 QualType BTy;
Mike Stump61c38012009-11-17 21:44:24 +0000309 bool PtrMem = false;
Mike Stump5fae8562009-11-17 22:33:00 +0000310 if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(Ty)) {
311 PtrMem = true;
312 BTy = QualType(MPT->getClass(), 0);
313 PTy = MPT->getPointeeType();
314 }
Mike Stump61c38012009-11-17 21:44:24 +0000315
316 if (PtrMem)
317 C = BuildVtableRef("_ZTVN10__cxxabiv129__pointer_to_member_type_infoE");
318 else
319 C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
320 info.push_back(C);
Mike Stump58588942009-11-19 01:08:19 +0000321 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stump61c38012009-11-17 21:44:24 +0000322 Qualifiers Q = PTy.getQualifiers();
323 PTy = CGM.getContext().getCanonicalType(PTy).getUnqualifiedType();
324 int flags = 0;
325 flags += Q.hasConst() ? 0x1 : 0;
326 flags += Q.hasVolatile() ? 0x2 : 0;
327 flags += Q.hasRestrict() ? 0x4 : 0;
328 flags += Ty.getTypePtr()->isIncompleteType() ? 0x8 : 0;
329 if (PtrMem && BTy.getTypePtr()->isIncompleteType())
330 flags += 0x10;
Mike Stump265df622009-11-17 23:51:10 +0000331
Mike Stump61c38012009-11-17 21:44:24 +0000332 info.push_back(BuildInt(flags));
333 info.push_back(BuildInt(0));
Mike Stump7e1365a2009-11-20 00:31:50 +0000334 info.push_back(BuildType(PTy));
Mike Stump61c38012009-11-17 21:44:24 +0000335
336 if (PtrMem)
Mike Stump7e1365a2009-11-20 00:31:50 +0000337 info.push_back(BuildType(BTy));
Mike Stump265df622009-11-17 23:51:10 +0000338
Mike Stump58588942009-11-19 01:08:19 +0000339 // We always generate these as hidden, only the name isn't hidden.
340 return finish(info, GV, Name, true, Extern);
Mike Stump64989f02009-11-17 23:11:22 +0000341 }
Mike Stump61c38012009-11-17 21:44:24 +0000342
Mike Stumpae9b2be2009-11-17 23:45:57 +0000343 llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
Mike Stump64989f02009-11-17 23:11:22 +0000344 llvm::Constant *C;
345
346 llvm::SmallString<256> OutName;
347 llvm::raw_svector_ostream Out(OutName);
348 mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
Mike Stump58588942009-11-19 01:08:19 +0000349 llvm::StringRef Name = Out.str();
Mike Stump64989f02009-11-17 23:11:22 +0000350
351 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000352 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump64989f02009-11-17 23:11:22 +0000353 if (GV && !GV->isDeclaration())
354 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
355
356 std::vector<llvm::Constant *> info;
357
Mike Stump58588942009-11-19 01:08:19 +0000358 bool Extern = DecideExtern(Ty);
359 bool Hidden = DecideHidden(Ty);
Mike Stump582b0372009-11-18 03:46:51 +0000360
Mike Stumpae9b2be2009-11-17 23:45:57 +0000361 C = BuildVtableRef(vtbl);
Mike Stump64989f02009-11-17 23:11:22 +0000362 info.push_back(C);
Mike Stump58588942009-11-19 01:08:19 +0000363 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stump265df622009-11-17 23:51:10 +0000364
Mike Stump58588942009-11-19 01:08:19 +0000365 // We always generate these as hidden, only the name isn't hidden.
366 return finish(info, GV, Name, true, Extern);
Mike Stump61c38012009-11-17 21:44:24 +0000367 }
368
Mike Stumpea2c0b52009-11-17 02:16:21 +0000369 llvm::Constant *BuildType(QualType Ty) {
370 const clang::Type &Type
371 = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
Mike Stump7e1365a2009-11-20 00:31:50 +0000372
373 if (const RecordType *RT = Ty.getTypePtr()->getAs<RecordType>())
374 if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()))
375 return Buildclass_type_info(RD);
376
Mike Stumpea2c0b52009-11-17 02:16:21 +0000377 switch (Type.getTypeClass()) {
378 default: {
Mike Stumpea2c0b52009-11-17 02:16:21 +0000379 assert(0 && "typeid expression");
Mike Stumpea2c0b52009-11-17 02:16:21 +0000380 return llvm::Constant::getNullValue(Int8PtrTy);
381 }
382
383 case Type::Builtin: {
384 // We expect all type_info objects for builtin types to be in the library.
385 return BuildTypeRef(Ty);
386 }
Mike Stump21f5d5d2009-11-17 02:57:13 +0000387
388 case Type::Pointer: {
389 QualType PTy = Ty->getPointeeType();
390 Qualifiers Q = PTy.getQualifiers();
391 Q.removeConst();
392 // T* and const T* for all builtin types T are expected in the library.
393 if (isa<BuiltinType>(PTy) && Q.empty())
394 return BuildTypeRef(Ty);
395
Mike Stump61c38012009-11-17 21:44:24 +0000396 return BuildPointerType(Ty);
Mike Stump21f5d5d2009-11-17 02:57:13 +0000397 }
Mike Stump5fae8562009-11-17 22:33:00 +0000398 case Type::MemberPointer:
399 return BuildPointerType(Ty);
Mike Stump64989f02009-11-17 23:11:22 +0000400 case Type::FunctionProto:
Mike Stumpae9b2be2009-11-17 23:45:57 +0000401 case Type::FunctionNoProto:
402 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv120__function_type_infoE");
403 case Type::ConstantArray:
404 case Type::IncompleteArray:
405 case Type::VariableArray:
406 case Type::Vector:
407 case Type::ExtVector:
408 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
409 case Type::Enum:
410 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv116__enum_type_infoE");
Mike Stumpea2c0b52009-11-17 02:16:21 +0000411 }
412 }
Mike Stump2b1bf312009-11-14 14:25:18 +0000413};
414
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000415llvm::Constant *CodeGenModule::GenerateRttiRef(const CXXRecordDecl *RD) {
416 RttiBuilder b(*this);
417
418 return b.Buildclass_type_infoRef(RD);
419}
420
Anders Carlsson656e4c12009-10-10 20:49:04 +0000421llvm::Constant *CodeGenModule::GenerateRtti(const CXXRecordDecl *RD) {
Mike Stump2b1bf312009-11-14 14:25:18 +0000422 RttiBuilder b(*this);
423
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000424 return b.Buildclass_type_info(RD);
Anders Carlsson656e4c12009-10-10 20:49:04 +0000425}
Mike Stumpea2c0b52009-11-17 02:16:21 +0000426
Mike Stump7e1365a2009-11-20 00:31:50 +0000427llvm::Constant *CodeGenModule::GenerateRtti(QualType Ty) {
Mike Stumpea2c0b52009-11-17 02:16:21 +0000428 RttiBuilder b(*this);
429
430 return b.BuildType(Ty);
431}