@@ -1088,67 +1088,6 @@ static auto BuildEnumDefinition(Context& context,
1088
1088
class_info.body_block_id = context.inst_block_stack ().Pop ();
1089
1089
}
1090
1090
1091
- auto ImportClassDefinitionForClangDecl (Context& context, SemIR::LocId loc_id,
1092
- SemIR::ClassId class_id,
1093
- SemIR::ClangDeclId clang_decl_id)
1094
- -> bool {
1095
- clang::ASTUnit* ast = context.sem_ir ().clang_ast_unit ();
1096
- CARBON_CHECK (ast);
1097
-
1098
- auto * clang_decl = cast<clang::TagDecl>(
1099
- context.sem_ir ().clang_decls ().Get (clang_decl_id).decl );
1100
- auto class_inst_id = context.types ().GetAsTypeInstId (
1101
- context.classes ().Get (class_id).first_owning_decl_id );
1102
-
1103
- // TODO: Map loc_id into a clang location and use it for diagnostics if
1104
- // instantiation fails, instead of annotating the diagnostic with another
1105
- // location.
1106
- clang::SourceLocation loc = clang_decl->getLocation ();
1107
- Diagnostics::AnnotationScope annotate_diagnostics (
1108
- &context.emitter (), [&](auto & builder) {
1109
- CARBON_DIAGNOSTIC (InCppTypeCompletion, Note,
1110
- " while completing C++ type {0}" , SemIR::TypeId);
1111
- builder.Note (loc_id, InCppTypeCompletion,
1112
- context.classes ().Get (class_id).self_type_id );
1113
- });
1114
-
1115
- // Ask Clang whether the type is complete. This triggers template
1116
- // instantiation if necessary.
1117
- clang::DiagnosticErrorTrap trap (ast->getDiagnostics ());
1118
- if (!ast->getSema ().isCompleteType (
1119
- loc, context.ast_context ().getCanonicalTagType (clang_decl))) {
1120
- // Type is incomplete. Nothing more to do, but tell the caller if we
1121
- // produced an error.
1122
- return !trap.hasErrorOccurred ();
1123
- }
1124
-
1125
- auto import_ir_inst_id =
1126
- context.insts ().GetCanonicalLocId (class_inst_id).import_ir_inst_id ();
1127
-
1128
- if (auto * class_decl = dyn_cast<clang::CXXRecordDecl>(clang_decl)) {
1129
- auto * class_def = class_decl->getDefinition ();
1130
- CARBON_CHECK (class_def, " Complete type has no definition" );
1131
-
1132
- if (class_def->getNumVBases ()) {
1133
- // TODO: Handle virtual bases. We don't actually know where they go in the
1134
- // layout. We may also want to use a different size in the layout for
1135
- // `partial C`, excluding the virtual base. It's also not entirely safe to
1136
- // just skip over the virtual base, as the type we would construct would
1137
- // have a misleading size. For now, treat a C++ class with vbases as
1138
- // incomplete in Carbon.
1139
- context.TODO (loc_id, " class with virtual bases" );
1140
- return false ;
1141
- }
1142
-
1143
- BuildClassDefinition (context, import_ir_inst_id, class_id, class_inst_id,
1144
- class_def);
1145
- } else if (auto * enum_decl = dyn_cast<clang::EnumDecl>(clang_decl)) {
1146
- BuildEnumDefinition (context, import_ir_inst_id, class_id, class_inst_id,
1147
- enum_decl);
1148
- }
1149
- return true ;
1150
- }
1151
-
1152
1091
// Imports an enumerator declaration from Clang to Carbon.
1153
1092
static auto ImportEnumConstantDecl (Context& context,
1154
1093
clang::EnumConstantDecl* enumerator_decl)
@@ -2253,4 +2192,65 @@ auto ImportOperatorFromCpp(Context& context, SemIR::LocId loc_id,
2253
2192
access_kind);
2254
2193
}
2255
2194
2195
+ auto ImportClassDefinitionForClangDecl (Context& context, SemIR::LocId loc_id,
2196
+ SemIR::ClassId class_id,
2197
+ SemIR::ClangDeclId clang_decl_id)
2198
+ -> bool {
2199
+ clang::ASTUnit* ast = context.sem_ir ().clang_ast_unit ();
2200
+ CARBON_CHECK (ast);
2201
+
2202
+ auto * clang_decl = cast<clang::TagDecl>(
2203
+ context.sem_ir ().clang_decls ().Get (clang_decl_id).decl );
2204
+ auto class_inst_id = context.types ().GetAsTypeInstId (
2205
+ context.classes ().Get (class_id).first_owning_decl_id );
2206
+
2207
+ // TODO: Map loc_id into a clang location and use it for diagnostics if
2208
+ // instantiation fails, instead of annotating the diagnostic with another
2209
+ // location.
2210
+ clang::SourceLocation loc = clang_decl->getLocation ();
2211
+ Diagnostics::AnnotationScope annotate_diagnostics (
2212
+ &context.emitter (), [&](auto & builder) {
2213
+ CARBON_DIAGNOSTIC (InCppTypeCompletion, Note,
2214
+ " while completing C++ type {0}" , SemIR::TypeId);
2215
+ builder.Note (loc_id, InCppTypeCompletion,
2216
+ context.classes ().Get (class_id).self_type_id );
2217
+ });
2218
+
2219
+ // Ask Clang whether the type is complete. This triggers template
2220
+ // instantiation if necessary.
2221
+ clang::DiagnosticErrorTrap trap (ast->getDiagnostics ());
2222
+ if (!ast->getSema ().isCompleteType (
2223
+ loc, context.ast_context ().getCanonicalTagType (clang_decl))) {
2224
+ // Type is incomplete. Nothing more to do, but tell the caller if we
2225
+ // produced an error.
2226
+ return !trap.hasErrorOccurred ();
2227
+ }
2228
+
2229
+ auto import_ir_inst_id =
2230
+ context.insts ().GetCanonicalLocId (class_inst_id).import_ir_inst_id ();
2231
+
2232
+ if (auto * class_decl = dyn_cast<clang::CXXRecordDecl>(clang_decl)) {
2233
+ auto * class_def = class_decl->getDefinition ();
2234
+ CARBON_CHECK (class_def, " Complete type has no definition" );
2235
+
2236
+ if (class_def->getNumVBases ()) {
2237
+ // TODO: Handle virtual bases. We don't actually know where they go in the
2238
+ // layout. We may also want to use a different size in the layout for
2239
+ // `partial C`, excluding the virtual base. It's also not entirely safe to
2240
+ // just skip over the virtual base, as the type we would construct would
2241
+ // have a misleading size. For now, treat a C++ class with vbases as
2242
+ // incomplete in Carbon.
2243
+ context.TODO (loc_id, " class with virtual bases" );
2244
+ return false ;
2245
+ }
2246
+
2247
+ BuildClassDefinition (context, import_ir_inst_id, class_id, class_inst_id,
2248
+ class_def);
2249
+ } else if (auto * enum_decl = dyn_cast<clang::EnumDecl>(clang_decl)) {
2250
+ BuildEnumDefinition (context, import_ir_inst_id, class_id, class_inst_id,
2251
+ enum_decl);
2252
+ }
2253
+ return true ;
2254
+ }
2255
+
2256
2256
} // namespace Carbon::Check
0 commit comments