blob: 0e89e83c128a5cab61a4a7ac374db285b86e44d3 [file] [log] [blame]
Mike Stumpde050572009-12-02 18:57:08 +00001//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
Anders Carlsson656e4c12009-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 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 Stump92f2fe22009-12-02 19:07:44 +000020namespace {
Mike Stumpde050572009-12-02 18:57:08 +000021class RTTIBuilder {
Mike Stump2b1bf312009-11-14 14:25:18 +000022 CodeGenModule &CGM; // Per-module state.
23 llvm::LLVMContext &VMContext;
24 const llvm::Type *Int8PtrTy;
Mike Stumpa8285a82009-11-15 03:28:10 +000025 llvm::SmallSet<const CXXRecordDecl *, 16> SeenVBase;
26 llvm::SmallSet<const CXXRecordDecl *, 32> SeenBase;
Anders Carlssond6baec82009-12-11 01:27:37 +000027
28 // Type info flags.
29 enum {
30 /// TI_Const - Type has const qualifier.
31 TI_Const = 0x1,
32
33 /// TI_Volatile - Type has volatile qualifier.
34 TI_Volatile = 0x2,
35
36 /// TI_Restrict - Type has restrict qualifier.
37 TI_Restrict = 0x4,
38
39 /// TI_Incomplete - Type is incomplete.
40 TI_Incomplete = 0x8,
41
42 /// TI_ContainingClassIncomplete - Containing class is incomplete.
43 /// (in pointer to member).
44 TI_ContainingClassIncomplete = 0x10
45 };
46
Mike Stump2b1bf312009-11-14 14:25:18 +000047public:
Mike Stumpde050572009-12-02 18:57:08 +000048 RTTIBuilder(CodeGenModule &cgm)
Mike Stump2b1bf312009-11-14 14:25:18 +000049 : CGM(cgm), VMContext(cgm.getModule().getContext()),
50 Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)) { }
51
Mike Stumpcbcd4e52009-11-14 23:32:21 +000052 /// BuildVtableRef - Build a reference to a vtable.
53 llvm::Constant *BuildVtableRef(const char *Name) {
54 // Build a descriptor for Name
Mike Stumpc7a05bd2009-11-14 15:55:18 +000055 llvm::Constant *GV = CGM.getModule().getGlobalVariable(Name);
56 if (GV)
57 GV = llvm::ConstantExpr::getBitCast(GV,
58 llvm::PointerType::get(Int8PtrTy, 0));
59 else {
60 llvm::GlobalVariable::LinkageTypes linktype;
61 linktype = llvm::GlobalValue::ExternalLinkage;
62 GV = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy,
63 true, linktype, 0, Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +000064 }
Mike Stumpc7a05bd2009-11-14 15:55:18 +000065 llvm::Constant *C;
66 C = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), 2);
67 C = llvm::ConstantExpr::getInBoundsGetElementPtr(GV, &C, 1);
68 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
69 }
Mike Stumpcbcd4e52009-11-14 23:32:21 +000070
Mike Stump58588942009-11-19 01:08:19 +000071 llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
Mike Stump2b1bf312009-11-14 14:25:18 +000072 llvm::SmallString<256> OutName;
Mike Stumpde050572009-12-02 18:57:08 +000073 CGM.getMangleContext().mangleCXXRTTIName(Ty, OutName);
Daniel Dunbar94fd26d2009-11-21 09:06:22 +000074 llvm::StringRef Name = OutName.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +000075
Mike Stump2b1bf312009-11-14 14:25:18 +000076 llvm::GlobalVariable::LinkageTypes linktype;
77 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump58588942009-11-19 01:08:19 +000078 if (!Extern)
79 linktype = llvm::GlobalValue::InternalLinkage;
80
81 llvm::GlobalVariable *GV;
82 GV = CGM.getModule().getGlobalVariable(Name);
83 if (GV && !GV->isDeclaration())
84 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump2b1bf312009-11-14 14:25:18 +000085
86 llvm::Constant *C;
Mike Stump58588942009-11-19 01:08:19 +000087 C = llvm::ConstantArray::get(VMContext, Name.substr(4));
Mike Stumpcbcd4e52009-11-14 23:32:21 +000088
Mike Stump58588942009-11-19 01:08:19 +000089 llvm::GlobalVariable *OGV = GV;
90 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
91 C, Name);
92 if (OGV) {
93 GV->takeName(OGV);
94 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
95 OGV->getType());
96 OGV->replaceAllUsesWith(NewPtr);
97 OGV->eraseFromParent();
98 }
Mike Stump582b0372009-11-18 03:46:51 +000099 if (Hidden)
100 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
101 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
Mike Stump2b1bf312009-11-14 14:25:18 +0000102 };
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000103
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000104 /// - BuildFlags - Build a psABI __flags value for __vmi_class_type_info.
105 llvm::Constant *BuildFlags(int f) {
106 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), f);
107 }
108
109 /// BuildBaseCount - Build a psABI __base_count value for
110 /// __vmi_class_type_info.
111 llvm::Constant *BuildBaseCount(unsigned c) {
112 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), c);
113 }
114
Mike Stumpea2c0b52009-11-17 02:16:21 +0000115 llvm::Constant *BuildTypeRef(QualType Ty) {
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000116 llvm::Constant *C;
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000117
Mike Stumpde050572009-12-02 18:57:08 +0000118 if (!CGM.getContext().getLangOptions().RTTI)
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000119 return llvm::Constant::getNullValue(Int8PtrTy);
120
121 llvm::SmallString<256> OutName;
Mike Stumpde050572009-12-02 18:57:08 +0000122 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000123 llvm::StringRef Name = OutName.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000124
Mike Stump58588942009-11-19 01:08:19 +0000125 C = CGM.getModule().getGlobalVariable(Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000126 if (C)
127 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
128
129 llvm::GlobalVariable::LinkageTypes linktype;
130 linktype = llvm::GlobalValue::ExternalLinkage;;
131
132 C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
Mike Stump58588942009-11-19 01:08:19 +0000133 0, Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000134 return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
135 }
136
Mike Stumpea2c0b52009-11-17 02:16:21 +0000137 llvm::Constant *Buildclass_type_infoRef(const CXXRecordDecl *RD) {
138 return BuildTypeRef(CGM.getContext().getTagDeclType(RD));
139 }
140
Mike Stumpa8285a82009-11-15 03:28:10 +0000141 /// CalculateFlags - Calculate the flags for the __vmi_class_type_info
142 /// datastructure. 1 for non-diamond repeated inheritance, 2 for a dimond
143 /// shaped class.
144 int CalculateFlags(const CXXRecordDecl*RD) {
145 int flags = 0;
146 if (SeenBase.count(RD))
147 flags |= 1;
148 else
149 SeenBase.insert(RD);
150 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
151 e = RD->bases_end(); i != e; ++i) {
152 const CXXRecordDecl *Base =
153 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
154 if (i->isVirtual()) {
155 if (SeenVBase.count(Base))
156 flags |= 2;
157 else
158 SeenVBase.insert(Base);
159 }
160 flags |= CalculateFlags(Base);
161 }
162 return flags;
163 }
164
165 bool SimpleInheritance(const CXXRecordDecl *RD) {
166 if (RD->getNumBases() != 1)
167 return false;
168 CXXRecordDecl::base_class_const_iterator i = RD->bases_begin();
169 if (i->isVirtual())
170 return false;
171 if (i->getAccessSpecifier() != AS_public)
172 return false;
173
174 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
175 const CXXRecordDecl *Base =
176 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
177 if (Layout.getBaseClassOffset(Base) != 0)
178 return false;
179 return true;
180 }
181
Mike Stump64989f02009-11-17 23:11:22 +0000182 llvm::Constant *finish(std::vector<llvm::Constant *> &info,
183 llvm::GlobalVariable *GV,
Mike Stump58588942009-11-19 01:08:19 +0000184 llvm::StringRef Name, bool Hidden, bool Extern) {
Mike Stump64989f02009-11-17 23:11:22 +0000185 llvm::GlobalVariable::LinkageTypes linktype;
186 linktype = llvm::GlobalValue::LinkOnceODRLinkage;
Mike Stump58588942009-11-19 01:08:19 +0000187 if (!Extern)
188 linktype = llvm::GlobalValue::InternalLinkage;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000189
Mike Stump64989f02009-11-17 23:11:22 +0000190 llvm::Constant *C;
191 C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
192
Mike Stump58588942009-11-19 01:08:19 +0000193 llvm::GlobalVariable *OGV = GV;
194 GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
195 C, Name);
196 if (OGV) {
Mike Stump64989f02009-11-17 23:11:22 +0000197 GV->takeName(OGV);
198 llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
199 OGV->getType());
200 OGV->replaceAllUsesWith(NewPtr);
201 OGV->eraseFromParent();
202 }
Mike Stump582b0372009-11-18 03:46:51 +0000203 if (Hidden)
Mike Stump88a4a622009-11-18 03:21:29 +0000204 GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
Mike Stump64989f02009-11-17 23:11:22 +0000205 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
206 }
207
208
209 llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) {
Mike Stumpde050572009-12-02 18:57:08 +0000210 if (!CGM.getContext().getLangOptions().RTTI)
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000211 return llvm::Constant::getNullValue(Int8PtrTy);
212
Mike Stump64989f02009-11-17 23:11:22 +0000213 llvm::Constant *C;
214
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000215 llvm::SmallString<256> OutName;
Mike Stumpde050572009-12-02 18:57:08 +0000216 CGM.getMangleContext().mangleCXXRTTI(CGM.getContext().getTagDeclType(RD),
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000217 OutName);
218 llvm::StringRef Name = OutName.str();
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000219
220 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000221 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000222 if (GV && !GV->isDeclaration())
223 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
224
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000225 std::vector<llvm::Constant *> info;
226
Mike Stump582b0372009-11-18 03:46:51 +0000227 bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
Mike Stump58588942009-11-19 01:08:19 +0000228 bool Extern = !RD->isInAnonymousNamespace();
Mike Stump582b0372009-11-18 03:46:51 +0000229
Mike Stumpa8285a82009-11-15 03:28:10 +0000230 bool simple = false;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000231 if (RD->getNumBases() == 0)
232 C = BuildVtableRef("_ZTVN10__cxxabiv117__class_type_infoE");
Mike Stumpa8285a82009-11-15 03:28:10 +0000233 else if (SimpleInheritance(RD)) {
234 simple = true;
235 C = BuildVtableRef("_ZTVN10__cxxabiv120__si_class_type_infoE");
236 } else
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000237 C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
238 info.push_back(C);
Mike Stump58588942009-11-19 01:08:19 +0000239 info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
240 Extern));
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000241
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000242 // If we have no bases, there are no more fields.
243 if (RD->getNumBases()) {
Mike Stumpa8285a82009-11-15 03:28:10 +0000244 if (!simple) {
245 info.push_back(BuildFlags(CalculateFlags(RD)));
246 info.push_back(BuildBaseCount(RD->getNumBases()));
247 }
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000248
249 const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
250 for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
251 e = RD->bases_end(); i != e; ++i) {
252 const CXXRecordDecl *Base =
253 cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
Mike Stump1c4269a2009-12-04 20:55:13 +0000254 if (Base->isPolymorphic())
255 info.push_back(CGM.GenerateRTTIRef(Base));
256 else
257 info.push_back(CGM.GenerateRTTI(Base));
Mike Stumpa8285a82009-11-15 03:28:10 +0000258 if (simple)
259 break;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000260 int64_t offset;
261 if (!i->isVirtual())
Mike Stumpa8285a82009-11-15 03:28:10 +0000262 offset = Layout.getBaseClassOffset(Base)/8;
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000263 else
264 offset = CGM.getVtableInfo().getVirtualBaseOffsetIndex(RD, Base);
265 offset <<= 8;
266 // Now set the flags.
267 offset += i->isVirtual() ? 1 : 0;;
268 offset += i->getAccessSpecifier() == AS_public ? 2 : 0;
269 const llvm::Type *LongTy =
270 CGM.getTypes().ConvertType(CGM.getContext().LongTy);
271 C = llvm::ConstantInt::get(LongTy, offset);
272 info.push_back(C);
273 }
274 }
275
Mike Stump58588942009-11-19 01:08:19 +0000276 return finish(info, GV, Name, Hidden, Extern);
Mike Stumpc7a05bd2009-11-14 15:55:18 +0000277 }
Mike Stumpea2c0b52009-11-17 02:16:21 +0000278
Mike Stump61c38012009-11-17 21:44:24 +0000279 /// - BuildFlags - Build a __flags value for __pbase_type_info.
Anders Carlssond6baec82009-12-11 01:27:37 +0000280 llvm::Constant *BuildInt(unsigned n) {
281 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), n);
Mike Stump61c38012009-11-17 21:44:24 +0000282 }
283
Mike Stump58588942009-11-19 01:08:19 +0000284 bool DecideExtern(QualType Ty) {
285 // For this type, see if all components are never in an anonymous namespace.
286 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
287 return (DecideExtern(MPT->getPointeeType())
288 && DecideExtern(QualType(MPT->getClass(), 0)));
289 if (const PointerType *PT = Ty->getAs<PointerType>())
290 return DecideExtern(PT->getPointeeType());
291 if (const RecordType *RT = Ty->getAs<RecordType>())
292 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
293 return !RD->isInAnonymousNamespace();
294 return true;
295 }
296
297 bool DecideHidden(QualType Ty) {
298 // For this type, see if all components are never hidden.
299 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
300 return (DecideHidden(MPT->getPointeeType())
301 && DecideHidden(QualType(MPT->getClass(), 0)));
302 if (const PointerType *PT = Ty->getAs<PointerType>())
303 return DecideHidden(PT->getPointeeType());
304 if (const RecordType *RT = Ty->getAs<RecordType>())
305 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
306 return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
307 return false;
308 }
309
Mike Stump61c38012009-11-17 21:44:24 +0000310 llvm::Constant *BuildPointerType(QualType Ty) {
Mike Stump61c38012009-11-17 21:44:24 +0000311 llvm::Constant *C;
312
313 llvm::SmallString<256> OutName;
Mike Stumpde050572009-12-02 18:57:08 +0000314 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000315 llvm::StringRef Name = OutName.str();
Mike Stump61c38012009-11-17 21:44:24 +0000316
317 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000318 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump61c38012009-11-17 21:44:24 +0000319 if (GV && !GV->isDeclaration())
320 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
321
Mike Stump61c38012009-11-17 21:44:24 +0000322 std::vector<llvm::Constant *> info;
323
Mike Stump58588942009-11-19 01:08:19 +0000324 bool Extern = DecideExtern(Ty);
325 bool Hidden = DecideHidden(Ty);
Mike Stump582b0372009-11-18 03:46:51 +0000326
Anders Carlssond6baec82009-12-11 01:27:37 +0000327 const MemberPointerType *PtrMemTy = dyn_cast<MemberPointerType>(Ty);
328 QualType PointeeTy;
329
330 if (PtrMemTy)
331 PointeeTy = PtrMemTy->getPointeeType();
332 else
333 PointeeTy = Ty->getPointeeType();
Mike Stump61c38012009-11-17 21:44:24 +0000334
Anders Carlssond6baec82009-12-11 01:27:37 +0000335 if (PtrMemTy)
Mike Stump61c38012009-11-17 21:44:24 +0000336 C = BuildVtableRef("_ZTVN10__cxxabiv129__pointer_to_member_type_infoE");
337 else
338 C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
Anders Carlssond6baec82009-12-11 01:27:37 +0000339
Mike Stump61c38012009-11-17 21:44:24 +0000340 info.push_back(C);
Mike Stump58588942009-11-19 01:08:19 +0000341 info.push_back(BuildName(Ty, Hidden, Extern));
Anders Carlssond6baec82009-12-11 01:27:37 +0000342 Qualifiers Q = PointeeTy.getQualifiers();
343
344 PointeeTy =
345 CGM.getContext().getCanonicalType(PointeeTy).getUnqualifiedType();
346
347 unsigned Flags = 0;
348 if (Q.hasConst())
349 Flags |= TI_Const;
350 if (Q.hasVolatile())
351 Flags |= TI_Volatile;
352 if (Q.hasRestrict())
353 Flags |= TI_Restrict;
354
355 if (Ty->isIncompleteType())
356 Flags |= TI_Incomplete;
357
358 if (PtrMemTy && PtrMemTy->getClass()->isIncompleteType())
359 Flags |= TI_ContainingClassIncomplete;
360
361 info.push_back(BuildInt(Flags));
Mike Stump61c38012009-11-17 21:44:24 +0000362 info.push_back(BuildInt(0));
Anders Carlssond6baec82009-12-11 01:27:37 +0000363 info.push_back(BuildType(PointeeTy));
Mike Stump61c38012009-11-17 21:44:24 +0000364
Anders Carlssond6baec82009-12-11 01:27:37 +0000365 if (PtrMemTy)
366 info.push_back(BuildType(QualType(PtrMemTy->getClass(), 0)));
Mike Stump265df622009-11-17 23:51:10 +0000367
Mike Stump58588942009-11-19 01:08:19 +0000368 // We always generate these as hidden, only the name isn't hidden.
369 return finish(info, GV, Name, true, Extern);
Mike Stump64989f02009-11-17 23:11:22 +0000370 }
Mike Stump61c38012009-11-17 21:44:24 +0000371
Mike Stumpae9b2be2009-11-17 23:45:57 +0000372 llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
Mike Stump64989f02009-11-17 23:11:22 +0000373 llvm::Constant *C;
374
375 llvm::SmallString<256> OutName;
Mike Stumpde050572009-12-02 18:57:08 +0000376 CGM.getMangleContext().mangleCXXRTTI(Ty, OutName);
Daniel Dunbar94fd26d2009-11-21 09:06:22 +0000377 llvm::StringRef Name = OutName.str();
Mike Stump64989f02009-11-17 23:11:22 +0000378
379 llvm::GlobalVariable *GV;
Mike Stump58588942009-11-19 01:08:19 +0000380 GV = CGM.getModule().getGlobalVariable(Name);
Mike Stump64989f02009-11-17 23:11:22 +0000381 if (GV && !GV->isDeclaration())
382 return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
383
384 std::vector<llvm::Constant *> info;
385
Mike Stump58588942009-11-19 01:08:19 +0000386 bool Extern = DecideExtern(Ty);
387 bool Hidden = DecideHidden(Ty);
Mike Stump582b0372009-11-18 03:46:51 +0000388
Mike Stumpae9b2be2009-11-17 23:45:57 +0000389 C = BuildVtableRef(vtbl);
Mike Stump64989f02009-11-17 23:11:22 +0000390 info.push_back(C);
Mike Stump58588942009-11-19 01:08:19 +0000391 info.push_back(BuildName(Ty, Hidden, Extern));
Mike Stump265df622009-11-17 23:51:10 +0000392
Mike Stump58588942009-11-19 01:08:19 +0000393 // We always generate these as hidden, only the name isn't hidden.
394 return finish(info, GV, Name, true, Extern);
Mike Stump61c38012009-11-17 21:44:24 +0000395 }
396
Mike Stumpea2c0b52009-11-17 02:16:21 +0000397 llvm::Constant *BuildType(QualType Ty) {
398 const clang::Type &Type
399 = *CGM.getContext().getCanonicalType(Ty).getTypePtr();
Mike Stump7e1365a2009-11-20 00:31:50 +0000400
401 if (const RecordType *RT = Ty.getTypePtr()->getAs<RecordType>())
402 if (const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()))
403 return Buildclass_type_info(RD);
404
Mike Stumpea2c0b52009-11-17 02:16:21 +0000405 switch (Type.getTypeClass()) {
406 default: {
Mike Stumpea2c0b52009-11-17 02:16:21 +0000407 assert(0 && "typeid expression");
Mike Stumpea2c0b52009-11-17 02:16:21 +0000408 return llvm::Constant::getNullValue(Int8PtrTy);
409 }
410
411 case Type::Builtin: {
412 // We expect all type_info objects for builtin types to be in the library.
413 return BuildTypeRef(Ty);
414 }
Mike Stump21f5d5d2009-11-17 02:57:13 +0000415
416 case Type::Pointer: {
417 QualType PTy = Ty->getPointeeType();
418 Qualifiers Q = PTy.getQualifiers();
419 Q.removeConst();
420 // T* and const T* for all builtin types T are expected in the library.
421 if (isa<BuiltinType>(PTy) && Q.empty())
422 return BuildTypeRef(Ty);
423
Mike Stump61c38012009-11-17 21:44:24 +0000424 return BuildPointerType(Ty);
Mike Stump21f5d5d2009-11-17 02:57:13 +0000425 }
Mike Stump5fae8562009-11-17 22:33:00 +0000426 case Type::MemberPointer:
427 return BuildPointerType(Ty);
Mike Stump64989f02009-11-17 23:11:22 +0000428 case Type::FunctionProto:
Mike Stumpae9b2be2009-11-17 23:45:57 +0000429 case Type::FunctionNoProto:
430 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv120__function_type_infoE");
431 case Type::ConstantArray:
432 case Type::IncompleteArray:
433 case Type::VariableArray:
434 case Type::Vector:
435 case Type::ExtVector:
436 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
437 case Type::Enum:
438 return BuildSimpleType(Ty, "_ZTVN10__cxxabiv116__enum_type_infoE");
Mike Stumpea2c0b52009-11-17 02:16:21 +0000439 }
440 }
Mike Stump2b1bf312009-11-14 14:25:18 +0000441};
Mike Stump92f2fe22009-12-02 19:07:44 +0000442}
Mike Stump2b1bf312009-11-14 14:25:18 +0000443
Mike Stumpde050572009-12-02 18:57:08 +0000444llvm::Constant *CodeGenModule::GenerateRTTIRef(const CXXRecordDecl *RD) {
445 RTTIBuilder b(*this);
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000446
447 return b.Buildclass_type_infoRef(RD);
448}
449
Mike Stumpde050572009-12-02 18:57:08 +0000450llvm::Constant *CodeGenModule::GenerateRTTI(const CXXRecordDecl *RD) {
451 RTTIBuilder b(*this);
Mike Stump2b1bf312009-11-14 14:25:18 +0000452
Mike Stumpcbcd4e52009-11-14 23:32:21 +0000453 return b.Buildclass_type_info(RD);
Anders Carlsson656e4c12009-10-10 20:49:04 +0000454}
Mike Stumpea2c0b52009-11-17 02:16:21 +0000455
Mike Stumpde050572009-12-02 18:57:08 +0000456llvm::Constant *CodeGenModule::GenerateRTTI(QualType Ty) {
457 RTTIBuilder b(*this);
Mike Stumpea2c0b52009-11-17 02:16:21 +0000458
459 return b.BuildType(Ty);
460}