Skip to content

Commit

Permalink
[CIR][CIRGen] Emit required vtables (#1054)
Browse files Browse the repository at this point in the history
We were missing an override for this previously and thus not emitting
vtables when key functions were defined.
  • Loading branch information
smeenai authored Nov 5, 2024
1 parent 815dfaa commit fca6e2c
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 0 deletions.
1 change: 1 addition & 0 deletions clang/include/clang/CIR/CIRGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class CIRGenerator : public clang::ASTConsumer {
void HandleTagDeclRequiredDefinition(const clang::TagDecl *D) override;
void HandleCXXStaticMemberVarInstantiation(clang::VarDecl *D) override;
void CompleteTentativeDefinition(clang::VarDecl *D) override;
void HandleVTable(clang::CXXRecordDecl *rd) override;

mlir::ModuleOp getModule();
std::unique_ptr<mlir::MLIRContext> takeContext() {
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ class CIRGenModule : public CIRGenTypeCache {
void buildDeferredVTables();
bool shouldOpportunisticallyEmitVTables();

void buildVTable(CXXRecordDecl *rd);

void setDSOLocal(mlir::cir::CIRGlobalValueInterface GV) const;

/// Return the appropriate linkage for the vtable, VTT, and type information
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenVTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,16 @@ void CIRGenModule::buildDeferredVTables() {
DeferredVTables.clear();
}

/// This is a callback from Sema to tell us that a particular vtable is
/// required to be emitted in this translation unit.
///
/// This is only called for vtables that _must_ be emitted (mainly due to key
/// functions). For weak vtables, CodeGen tracks when they are needed and
/// emits them as-needed.
void CIRGenModule::buildVTable(CXXRecordDecl *rd) {
VTables.GenerateClassData(rd);
}

void CIRGenVTables::GenerateClassData(const CXXRecordDecl *RD) {
assert(!MissingFeatures::generateDebugInfo());

Expand Down
7 changes: 7 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,10 @@ void CIRGenerator::CompleteTentativeDefinition(VarDecl *D) {

CGM->buildTentativeDefinition(D);
}

void CIRGenerator::HandleVTable(CXXRecordDecl *rd) {
if (Diags.hasErrorOccurred())
return;

CGM->buildVTable(rd);
}
15 changes: 15 additions & 0 deletions clang/test/CIR/CodeGen/vtable-emission.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s

struct S {
virtual void key();
virtual void nonKey() {}
};

void S::key() {}

// The definition of the key function should result in the vtable being emitted.
// CHECK: cir.global external @_ZTV1S = #cir.vtable

// The reference from the vtable should result in nonKey being emitted.
// CHECK: cir.func linkonce_odr @_ZN1S6nonKeyEv({{.*}} {

0 comments on commit fca6e2c

Please sign in to comment.