|
13 | 13 | #include "CIRGenCXXABI.h"
|
14 | 14 | #include "CIRGenFunction.h"
|
15 | 15 | #include "CIRGenModule.h"
|
| 16 | +#include "mlir/IR/Attributes.h" |
16 | 17 | #include "clang/AST/Attr.h"
|
17 | 18 | #include "clang/AST/CXXInheritance.h"
|
18 | 19 | #include "clang/AST/RecordLayout.h"
|
| 20 | +#include "clang/AST/VTTBuilder.h" |
19 | 21 | #include "clang/Basic/CodeGenOptions.h"
|
20 | 22 | #include "clang/CIR/Dialect/IR/CIRAttrs.h"
|
21 | 23 | #include "clang/CIR/Dialect/IR/CIRTypes.h"
|
22 | 24 | #include "clang/CodeGen/CGFunctionInfo.h"
|
23 | 25 | #include "clang/CodeGen/ConstantInitBuilder.h"
|
| 26 | +#include "llvm/Support/ErrorHandling.h" |
24 | 27 | #include "llvm/Support/Format.h"
|
25 | 28 | #include "llvm/Transforms/Utils/Cloning.h"
|
26 | 29 | #include <algorithm>
|
@@ -151,17 +154,17 @@ void CIRGenVTables::GenerateClassData(const CXXRecordDecl *RD) {
|
151 | 154 | assert(!UnimplementedFeature::generateDebugInfo());
|
152 | 155 |
|
153 | 156 | if (RD->getNumVBases())
|
154 |
| - llvm_unreachable("NYI"); |
| 157 | + CGM.getCXXABI().emitVirtualInheritanceTables(RD); |
155 | 158 |
|
156 | 159 | CGM.getCXXABI().emitVTableDefinitions(*this, RD);
|
157 | 160 | }
|
158 | 161 |
|
159 | 162 | static void AddPointerLayoutOffset(CIRGenModule &CGM,
|
160 | 163 | ConstantArrayBuilder &builder,
|
161 | 164 | CharUnits offset) {
|
162 |
| - assert(offset.getQuantity() == 0 && "NYI"); |
163 |
| - builder.add(mlir::cir::ConstPtrAttr::get( |
164 |
| - CGM.getBuilder().getContext(), CGM.getBuilder().getUInt8PtrTy(), 0)); |
| 165 | + builder.add(mlir::cir::ConstPtrAttr::get(CGM.getBuilder().getContext(), |
| 166 | + CGM.getBuilder().getUInt8PtrTy(), |
| 167 | + offset.getQuantity())); |
165 | 168 | }
|
166 | 169 |
|
167 | 170 | static void AddRelativeLayoutOffset(CIRGenModule &CGM,
|
@@ -415,6 +418,118 @@ CIRGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
|
415 | 418 | llvm_unreachable("Invalid TemplateSpecializationKind!");
|
416 | 419 | }
|
417 | 420 |
|
| 421 | +mlir::cir::GlobalOp |
| 422 | +getAddrOfVTTVTable(CIRGenVTables &CGVT, CIRGenModule &CGM, |
| 423 | + const CXXRecordDecl *MostDerivedClass, |
| 424 | + const VTTVTable &vtable, |
| 425 | + mlir::cir::GlobalLinkageKind linkage, |
| 426 | + VTableLayout::AddressPointsMapTy &addressPoints) { |
| 427 | + if (vtable.getBase() == MostDerivedClass) { |
| 428 | + assert(vtable.getBaseOffset().isZero() && |
| 429 | + "Most derived class vtable must have a zero offset!"); |
| 430 | + // This is a regular vtable. |
| 431 | + return CGM.getCXXABI().getAddrOfVTable(MostDerivedClass, CharUnits()); |
| 432 | + } |
| 433 | + |
| 434 | + llvm_unreachable("generateConstructionVTable NYI"); |
| 435 | +} |
| 436 | + |
| 437 | +mlir::cir::GlobalOp CIRGenVTables::getAddrOfVTT(const CXXRecordDecl *RD) |
| 438 | +{ |
| 439 | + assert(RD->getNumVBases() && "Only classes with virtual bases need a VTT"); |
| 440 | + |
| 441 | + SmallString<256> OutName; |
| 442 | + llvm::raw_svector_ostream Out(OutName); |
| 443 | + cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext()) |
| 444 | + .mangleCXXVTT(RD, Out); |
| 445 | + StringRef Name = OutName.str(); |
| 446 | + |
| 447 | + // This will also defer the definition of the VTT. |
| 448 | + (void)CGM.getCXXABI().getAddrOfVTable(RD, CharUnits()); |
| 449 | + |
| 450 | + VTTBuilder Builder(CGM.getASTContext(), RD, /*GenerateDefinition=*/false); |
| 451 | + |
| 452 | + auto ArrayType = mlir::cir::ArrayType::get(CGM.getBuilder().getContext(), |
| 453 | + CGM.getBuilder().getUInt8PtrTy(), |
| 454 | + Builder.getVTTComponents().size()); |
| 455 | + auto Align = |
| 456 | + CGM.getDataLayout().getABITypeAlign(CGM.getBuilder().getUInt8PtrTy()); |
| 457 | + auto VTT = CGM.createOrReplaceCXXRuntimeVariable( |
| 458 | + CGM.getLoc(RD->getSourceRange()), Name, ArrayType, |
| 459 | + mlir::cir::GlobalLinkageKind::ExternalLinkage, |
| 460 | + CharUnits::fromQuantity(Align)); |
| 461 | + CGM.setGVProperties(VTT, RD); |
| 462 | + return VTT; |
| 463 | +} |
| 464 | + |
| 465 | +/// Emit the definition of the given vtable. |
| 466 | +void CIRGenVTables::buildVTTDefinition(mlir::cir::GlobalOp VTT, |
| 467 | + mlir::cir::GlobalLinkageKind Linkage, |
| 468 | + const CXXRecordDecl *RD) { |
| 469 | + VTTBuilder Builder(CGM.getASTContext(), RD, /*GenerateDefinition=*/true); |
| 470 | + |
| 471 | + auto ArrayType = mlir::cir::ArrayType::get(CGM.getBuilder().getContext(), |
| 472 | + CGM.getBuilder().getUInt8PtrTy(), |
| 473 | + Builder.getVTTComponents().size()); |
| 474 | + |
| 475 | + SmallVector<mlir::cir::GlobalOp, 8> VTables; |
| 476 | + SmallVector<VTableAddressPointsMapTy, 8> VTableAddressPoints; |
| 477 | + for (const VTTVTable *i = Builder.getVTTVTables().begin(), |
| 478 | + *e = Builder.getVTTVTables().end(); |
| 479 | + i != e; ++i) { |
| 480 | + VTableAddressPoints.push_back(VTableAddressPointsMapTy()); |
| 481 | + VTables.push_back(getAddrOfVTTVTable(*this, CGM, RD, *i, Linkage, |
| 482 | + VTableAddressPoints.back())); |
| 483 | + } |
| 484 | + |
| 485 | + SmallVector<mlir::Attribute, 8> VTTComponents; |
| 486 | + for (const VTTComponent *i = Builder.getVTTComponents().begin(), |
| 487 | + *e = Builder.getVTTComponents().end(); |
| 488 | + i != e; ++i) { |
| 489 | + const VTTVTable &VTTVT = Builder.getVTTVTables()[i->VTableIndex]; |
| 490 | + mlir::cir::GlobalOp VTable = VTables[i->VTableIndex]; |
| 491 | + VTableLayout::AddressPointLocation AddressPoint; |
| 492 | + if (VTTVT.getBase() == RD) { |
| 493 | + // Just get the address point for the regular vtable. |
| 494 | + AddressPoint = |
| 495 | + getItaniumVTableContext().getVTableLayout(RD).getAddressPoint( |
| 496 | + i->VTableBase); |
| 497 | + } else { |
| 498 | + AddressPoint = VTableAddressPoints[i->VTableIndex].lookup(i->VTableBase); |
| 499 | + assert(AddressPoint.AddressPointIndex != 0 && |
| 500 | + "Did not find ctor vtable address point!"); |
| 501 | + } |
| 502 | + |
| 503 | + mlir::Attribute Idxs[3] = { |
| 504 | + CGM.getBuilder().getI32IntegerAttr(0), |
| 505 | + CGM.getBuilder().getI32IntegerAttr(AddressPoint.VTableIndex), |
| 506 | + CGM.getBuilder().getI32IntegerAttr(AddressPoint.AddressPointIndex), |
| 507 | + }; |
| 508 | + |
| 509 | + auto Init = mlir::cir::GlobalViewAttr::get( |
| 510 | + CGM.getBuilder().getUInt8PtrTy(), |
| 511 | + mlir::FlatSymbolRefAttr::get(VTable.getSymNameAttr()), |
| 512 | + mlir::ArrayAttr::get(CGM.getBuilder().getContext(), Idxs)); |
| 513 | + |
| 514 | + VTTComponents.push_back(Init); |
| 515 | + } |
| 516 | + |
| 517 | + auto Init = CGM.getBuilder().getConstArray( |
| 518 | + mlir::ArrayAttr::get(CGM.getBuilder().getContext(), VTTComponents), |
| 519 | + ArrayType); |
| 520 | + |
| 521 | + VTT.setInitialValueAttr(Init); |
| 522 | + |
| 523 | + // Set the correct linkage. |
| 524 | + VTT.setLinkage(Linkage); |
| 525 | + mlir::SymbolTable::setSymbolVisibility(VTT, |
| 526 | + CIRGenModule::getMLIRVisibility(VTT)); |
| 527 | + |
| 528 | + if (CGM.supportsCOMDAT() && VTT.isWeakForLinker()) { |
| 529 | + assert(!UnimplementedFeature::setComdat()); |
| 530 | + } |
| 531 | +} |
| 532 | + |
418 | 533 | void CIRGenVTables::buildThunks(GlobalDecl GD) {
|
419 | 534 | const CXXMethodDecl *MD =
|
420 | 535 | cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl();
|
|
0 commit comments