13
13
#include " clang/AST/ASTContext.h"
14
14
#include " clang/AST/RecordLayout.h"
15
15
#include " clang/AST/UnresolvedSet.h"
16
+ #include " clang/AST/VTableBuilder.h"
16
17
#include " clang/Basic/FileManager.h"
17
18
#include " clang/Frontend/ASTUnit.h"
18
19
#include " clang/Frontend/CompilerInstance.h"
@@ -598,8 +599,7 @@ static auto IsDeclInjectedClassName(const Context& context,
598
599
CARBON_CHECK (ast_context.getCanonicalTagType (scope_record_decl) ==
599
600
ast_context.getCanonicalTagType (record_decl));
600
601
601
- auto class_decl =
602
- context.sem_ir ().insts ().GetAs <SemIR::ClassDecl>(clang_decl.inst_id );
602
+ auto class_decl = context.insts ().GetAs <SemIR::ClassDecl>(clang_decl.inst_id );
603
603
CARBON_CHECK (name_id ==
604
604
context.sem_ir ().classes ().Get (class_decl.class_id ).name_id );
605
605
return true ;
@@ -1623,6 +1623,21 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id,
1623
1623
AddPlaceholderInstInNoBlock (context, Parse::NodeId::None, function_decl);
1624
1624
context.imports ().push_back (decl_id);
1625
1625
1626
+ auto virtual_modifier = SemIR::Function::VirtualModifier::None;
1627
+ int32_t virtual_index = -1 ;
1628
+ if (auto * method_decl = dyn_cast<clang::CXXMethodDecl>(clang_decl)) {
1629
+ if (method_decl->size_overridden_methods ()) {
1630
+ virtual_modifier = SemIR::Function::VirtualModifier::Override;
1631
+ } else if (method_decl->isVirtual ()) {
1632
+ virtual_modifier = SemIR::Function::VirtualModifier::Virtual;
1633
+ }
1634
+ if (virtual_modifier != SemIR::Function::VirtualModifier::None) {
1635
+ // TODO: Add support for Microsoft/non-Itanium vtables.
1636
+ virtual_index = dyn_cast<clang::ItaniumVTableContext>(
1637
+ context.ast_context ().getVTableContext ())
1638
+ ->getMethodVTableIndex (method_decl);
1639
+ }
1640
+ }
1626
1641
auto function_info = SemIR::Function{
1627
1642
{.name_id = GetFunctionName (context, clang_decl),
1628
1643
.parent_scope_id = GetParentNameScopeId (context, clang_decl),
@@ -1640,7 +1655,8 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id,
1640
1655
.definition_id = SemIR::InstId::None},
1641
1656
{.call_params_id = function_params_insts->call_params_id ,
1642
1657
.return_slot_pattern_id = function_params_insts->return_slot_pattern_id ,
1643
- .virtual_modifier = SemIR::FunctionFields::VirtualModifier::None,
1658
+ .virtual_modifier = virtual_modifier,
1659
+ .virtual_index = virtual_index,
1644
1660
.self_param_id = FindSelfPattern (
1645
1661
context, function_params_insts->implicit_param_patterns_id ),
1646
1662
.clang_decl_id = context.sem_ir ().clang_decls ().Add (
@@ -1675,14 +1691,6 @@ auto ImportCppFunctionDecl(Context& context, SemIR::LocId loc_id,
1675
1691
return SemIR::ErrorInst::InstId;
1676
1692
}
1677
1693
1678
- if (auto * method_decl = dyn_cast<clang::CXXMethodDecl>(clang_decl)) {
1679
- if (method_decl->isVirtual ()) {
1680
- context.TODO (loc_id, " Unsupported: Virtual function" );
1681
- MarkFailedDecl (context, clang_decl);
1682
- return SemIR::ErrorInst::InstId;
1683
- }
1684
- }
1685
-
1686
1694
CARBON_CHECK (clang_decl->getFunctionType ()->isFunctionProtoType (),
1687
1695
" Not Prototype function (non-C++ code)" );
1688
1696
@@ -2142,6 +2150,15 @@ auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
2142
2150
builder.Note (loc_id, InCppNameLookup, name_id);
2143
2151
});
2144
2152
2153
+ if (auto class_decl = context.insts ().TryGetAs <SemIR::ClassDecl>(
2154
+ context.name_scopes ().Get (scope_id).inst_id ());
2155
+ class_decl.has_value ()) {
2156
+ if (!context.types ().IsComplete (
2157
+ context.classes ().Get (class_decl->class_id ).self_type_id )) {
2158
+ return SemIR::ScopeLookupResult::MakeError ();
2159
+ }
2160
+ }
2161
+
2145
2162
auto lookup = ClangLookupName (context, scope_id, name_id);
2146
2163
if (!lookup) {
2147
2164
SemIR::InstId builtin_inst_id =
0 commit comments