@@ -618,6 +618,12 @@ static auto ImportCXXRecordDecl(Context& context, SemIR::LocId loc_id,
618
618
return SemIR::ErrorInst::InstId;
619
619
}
620
620
621
+ if (clang_def->isUnion () && !clang_def->fields ().empty ()) {
622
+ context.TODO (loc_id, " Unsupported: Non-empty union" );
623
+ MarkFailedDecl (context, clang_decl);
624
+ return SemIR::ErrorInst::InstId;
625
+ }
626
+
621
627
auto [class_id, class_def_id] =
622
628
BuildClassDefinition (context, parent_scope_id, name_id, clang_def);
623
629
@@ -662,61 +668,60 @@ static auto MapBuiltinType(Context& context, const clang::BuiltinType& type)
662
668
default :
663
669
break ;
664
670
}
665
- return {.inst_id = SemIR::ErrorInst::TypeInstId,
666
- .type_id = SemIR::ErrorInst::TypeId};
671
+ return {.inst_id = SemIR::TypeInstId::None, .type_id = SemIR::TypeId::None};
667
672
}
668
673
669
674
// Maps a C++ record type to a Carbon type.
670
675
// TODO: Support more record types.
671
676
static auto MapRecordType (Context& context, SemIR::LocId loc_id,
672
677
const clang::RecordType& type) -> TypeExpr {
673
678
auto * record_decl = clang::dyn_cast<clang::CXXRecordDecl>(type.getDecl ());
674
- if (record_decl && !record_decl->isUnion ()) {
675
- auto & clang_decls = context.sem_ir ().clang_decls ();
676
- SemIR::InstId record_inst_id = SemIR::InstId::None;
677
- if (auto record_clang_decl_id = clang_decls.Lookup (record_decl);
678
- record_clang_decl_id.has_value ()) {
679
- record_inst_id = clang_decls.Get (record_clang_decl_id).inst_id ;
680
- } else {
681
- auto parent_inst_id =
682
- AsCarbonNamespace (context, record_decl->getDeclContext ());
683
- auto parent_name_scope_id =
684
- context.insts ().GetAs <SemIR::Namespace>(parent_inst_id).name_scope_id ;
685
- SemIR::NameId record_name_id =
686
- AddIdentifierName (context, record_decl->getName ());
687
- record_inst_id = ImportCXXRecordDecl (
688
- context, loc_id, parent_name_scope_id, record_name_id, record_decl);
689
- AddNameToScope (context, parent_name_scope_id, record_name_id,
690
- record_inst_id);
691
- }
692
- SemIR::TypeInstId record_type_inst_id =
693
- context.types ().GetAsTypeInstId (record_inst_id);
694
- return {
695
- .inst_id = record_type_inst_id,
696
- .type_id = context.types ().GetTypeIdForTypeInstId (record_type_inst_id)};
679
+ if (!record_decl) {
680
+ return {.inst_id = SemIR::TypeInstId::None, .type_id = SemIR::TypeId::None};
697
681
}
698
682
699
- return {.inst_id = SemIR::ErrorInst::TypeInstId,
700
- .type_id = SemIR::ErrorInst::TypeId};
683
+ auto & clang_decls = context.sem_ir ().clang_decls ();
684
+ SemIR::InstId record_inst_id = SemIR::InstId::None;
685
+ if (auto record_clang_decl_id = clang_decls.Lookup (record_decl);
686
+ record_clang_decl_id.has_value ()) {
687
+ record_inst_id = clang_decls.Get (record_clang_decl_id).inst_id ;
688
+ } else {
689
+ auto parent_inst_id =
690
+ AsCarbonNamespace (context, record_decl->getDeclContext ());
691
+ auto parent_name_scope_id =
692
+ context.insts ().GetAs <SemIR::Namespace>(parent_inst_id).name_scope_id ;
693
+ SemIR::NameId record_name_id =
694
+ AddIdentifierName (context, record_decl->getName ());
695
+ record_inst_id = ImportCXXRecordDecl (context, loc_id, parent_name_scope_id,
696
+ record_name_id, record_decl);
697
+ }
698
+ SemIR::TypeInstId record_type_inst_id =
699
+ context.types ().GetAsTypeInstId (record_inst_id);
700
+ return {
701
+ .inst_id = record_type_inst_id,
702
+ .type_id = context.types ().GetTypeIdForTypeInstId (record_type_inst_id)};
701
703
}
702
704
703
705
// Maps a C++ non-pointer type to a Carbon type.
704
706
// TODO: Support more types.
705
707
static auto MapNonPointerType (Context& context, SemIR::LocId loc_id,
706
708
clang::QualType type) -> TypeExpr {
707
- type = type.getCanonicalType ();
709
+ if (type.hasQualifiers ()) {
710
+ // TODO: Support type qualifiers.
711
+ return {.inst_id = SemIR::TypeInstId::None, .type_id = SemIR::TypeId::None};
712
+ }
713
+
708
714
CARBON_CHECK (!type->isPointerType ());
709
715
710
- if (const auto * builtin_type = dyn_cast <clang::BuiltinType>(type )) {
716
+ if (const auto * builtin_type = type-> getAs <clang::BuiltinType>()) {
711
717
return MapBuiltinType (context, *builtin_type);
712
718
}
713
719
714
- if (const auto * record_type = clang::dyn_cast <clang::RecordType>(type )) {
720
+ if (const auto * record_type = type-> getAs <clang::RecordType>()) {
715
721
return MapRecordType (context, loc_id, *record_type);
716
722
}
717
723
718
- return {.inst_id = SemIR::ErrorInst::TypeInstId,
719
- .type_id = SemIR::ErrorInst::TypeId};
724
+ return {.inst_id = SemIR::TypeInstId::None, .type_id = SemIR::TypeId::None};
720
725
}
721
726
722
727
// Maps a C++ pointer type to a Carbon pointer type.
@@ -744,10 +749,8 @@ static auto MapPointerType(Context& context, SemIR::LocId loc_id,
744
749
}
745
750
746
751
TypeExpr pointee_type_expr = MapNonPointerType (context, loc_id, pointee_type);
747
- if (pointee_type_expr.inst_id == SemIR::ErrorInst::InstId ||
748
- pointee_type_expr.type_id == SemIR::ErrorInst::TypeId) {
749
- return {.inst_id = SemIR::ErrorInst::TypeInstId,
750
- .type_id = SemIR::ErrorInst::TypeId};
752
+ if (!pointee_type_expr.inst_id .has_value ()) {
753
+ return {.inst_id = SemIR::TypeInstId::None, .type_id = SemIR::TypeId::None};
751
754
}
752
755
753
756
SemIR::TypeId pointer_type_id =
@@ -770,7 +773,7 @@ static auto MapType(Context& context, SemIR::LocId loc_id, clang::QualType type)
770
773
// Returns a block id for the explicit parameters of the given function
771
774
// declaration. If the function declaration has no parameters, it returns
772
775
// `SemIR::InstBlockId::Empty`. In the case of an unsupported parameter type, it
773
- // returns `SemIR::InstBlockId::None`.
776
+ // produces an error and returns `SemIR::InstBlockId::None`.
774
777
// TODO: Consider refactoring to extract and reuse more logic from
775
778
// `HandleAnyBindingPattern()`.
776
779
static auto MakeParamPatternsBlockId (Context& context, SemIR::LocId loc_id,
@@ -794,7 +797,7 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id,
794
797
SemIR::ExprRegionId type_expr_region_id =
795
798
EndSubpatternAsExpr (context, type_inst_id);
796
799
797
- if (type_id == SemIR::ErrorInst::TypeId ) {
800
+ if (! type_id. has_value () ) {
798
801
context.TODO (loc_id, llvm::formatv (" Unsupported: parameter type: {0}" ,
799
802
param_type.getAsString ()));
800
803
return SemIR::InstBlockId::None;
@@ -830,7 +833,8 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id,
830
833
}
831
834
832
835
// Returns the return type of the given function declaration. In case of an
833
- // unsupported return type, it returns `SemIR::ErrorInst::InstId`.
836
+ // unsupported return type, it produces a diagnostic and returns
837
+ // `SemIR::ErrorInst::InstId`.
834
838
// TODO: Support more return types.
835
839
static auto GetReturnType (Context& context, SemIR::LocId loc_id,
836
840
const clang::FunctionDecl* clang_decl)
@@ -841,7 +845,7 @@ static auto GetReturnType(Context& context, SemIR::LocId loc_id,
841
845
}
842
846
843
847
auto [type_inst_id, type_id] = MapType (context, loc_id, ret_type);
844
- if (type_id == SemIR::ErrorInst::TypeId ) {
848
+ if (!type_inst_id. has_value () ) {
845
849
context.TODO (loc_id, llvm::formatv (" Unsupported: return type: {0}" ,
846
850
ret_type.getAsString ()));
847
851
return SemIR::ErrorInst::InstId;
@@ -878,8 +882,8 @@ struct FunctionParamsInsts {
878
882
// to create the Call parameters instructions block. Currently the implicit
879
883
// parameter patterns are not taken into account. Returns the parameter patterns
880
884
// block id, the return slot pattern id, and the call parameters block id.
881
- // Returns `std::nullopt` if the function declaration has an unsupported
882
- // parameter type.
885
+ // Produces a diagnostic and returns `std::nullopt` if the function declaration
886
+ // has an unsupported parameter type.
883
887
static auto CreateFunctionParamsInsts (Context& context, SemIR::LocId loc_id,
884
888
const clang::FunctionDecl* clang_decl)
885
889
-> std::optional<FunctionParamsInsts> {
@@ -992,10 +996,15 @@ static auto ImportNameDecl(Context& context, SemIR::LocId loc_id,
992
996
return ImportNamespaceDecl (context, scope_id, name_id,
993
997
clang_namespace_decl);
994
998
}
995
- if (auto * clang_record_decl =
996
- clang::dyn_cast<clang::CXXRecordDecl>(clang_decl)) {
997
- return ImportCXXRecordDecl (context, loc_id, scope_id, name_id,
998
- clang_record_decl);
999
+ if (auto * type_decl = clang::dyn_cast<clang::TypeDecl>(clang_decl)) {
1000
+ auto type = type_decl->getASTContext ().getTypeDeclType (type_decl);
1001
+ auto type_inst_id = MapType (context, loc_id, type).inst_id ;
1002
+ if (!type_inst_id.has_value ()) {
1003
+ context.TODO (loc_id, llvm::formatv (" Unsupported: Type declaration: {0}" ,
1004
+ type.getAsString ()));
1005
+ return SemIR::ErrorInst::InstId;
1006
+ }
1007
+ return type_inst_id;
999
1008
}
1000
1009
1001
1010
context.TODO (loc_id, llvm::formatv (" Unsupported: Declaration type {0}" ,
0 commit comments