import.cpp 101 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/check/cpp/import.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <optional>
  8. #include <string>
  9. #include <tuple>
  10. #include <utility>
  11. #include "clang/AST/ASTContext.h"
  12. #include "clang/AST/RecordLayout.h"
  13. #include "clang/AST/UnresolvedSet.h"
  14. #include "clang/AST/VTableBuilder.h"
  15. #include "clang/Frontend/CompilerInvocation.h"
  16. #include "clang/Sema/Lookup.h"
  17. #include "clang/Sema/Overload.h"
  18. #include "common/check.h"
  19. #include "common/ostream.h"
  20. #include "common/raw_string_ostream.h"
  21. #include "llvm/ADT/IntrusiveRefCntPtr.h"
  22. #include "llvm/ADT/ScopeExit.h"
  23. #include "llvm/ADT/StringRef.h"
  24. #include "llvm/Support/raw_ostream.h"
  25. #include "toolchain/base/int.h"
  26. #include "toolchain/base/kind_switch.h"
  27. #include "toolchain/base/value_ids.h"
  28. #include "toolchain/check/call.h"
  29. #include "toolchain/check/class.h"
  30. #include "toolchain/check/context.h"
  31. #include "toolchain/check/control_flow.h"
  32. #include "toolchain/check/convert.h"
  33. #include "toolchain/check/core_identifier.h"
  34. #include "toolchain/check/cpp/access.h"
  35. #include "toolchain/check/cpp/custom_type_mapping.h"
  36. #include "toolchain/check/cpp/generate_ast.h"
  37. #include "toolchain/check/cpp/location.h"
  38. #include "toolchain/check/cpp/macros.h"
  39. #include "toolchain/check/cpp/thunk.h"
  40. #include "toolchain/check/cpp/type_mapping.h"
  41. #include "toolchain/check/diagnostic_helpers.h"
  42. #include "toolchain/check/eval.h"
  43. #include "toolchain/check/function.h"
  44. #include "toolchain/check/import.h"
  45. #include "toolchain/check/inst.h"
  46. #include "toolchain/check/literal.h"
  47. #include "toolchain/check/member_access.h"
  48. #include "toolchain/check/name_lookup.h"
  49. #include "toolchain/check/operator.h"
  50. #include "toolchain/check/pattern.h"
  51. #include "toolchain/check/pattern_match.h"
  52. #include "toolchain/check/type.h"
  53. #include "toolchain/check/type_completion.h"
  54. #include "toolchain/check/unused.h"
  55. #include "toolchain/parse/node_ids.h"
  56. #include "toolchain/sem_ir/clang_decl.h"
  57. #include "toolchain/sem_ir/class.h"
  58. #include "toolchain/sem_ir/cpp_file.h"
  59. #include "toolchain/sem_ir/cpp_overload_set.h"
  60. #include "toolchain/sem_ir/function.h"
  61. #include "toolchain/sem_ir/ids.h"
  62. #include "toolchain/sem_ir/inst.h"
  63. #include "toolchain/sem_ir/name_scope.h"
  64. #include "toolchain/sem_ir/pattern.h"
  65. #include "toolchain/sem_ir/type_info.h"
  66. #include "toolchain/sem_ir/typed_insts.h"
  67. namespace Carbon::Check {
  68. // Adds the name to the scope with the given `access_kind` and `inst_id`.
  69. // `inst_id` must have a value.
  70. static auto AddNameToScope(Context& context, SemIR::NameScopeId scope_id,
  71. SemIR::NameId name_id, SemIR::AccessKind access_kind,
  72. SemIR::InstId inst_id) -> void {
  73. CARBON_CHECK(inst_id.has_value());
  74. context.name_scopes().Get(scope_id).AddRequired(
  75. {.name_id = name_id,
  76. .result = SemIR::ScopeLookupResult::MakeFound(inst_id, access_kind)});
  77. }
  78. // Maps a Clang name to a Carbon `NameId`.
  79. auto AddIdentifierName(Context& context, llvm::StringRef name)
  80. -> SemIR::NameId {
  81. return SemIR::NameId::ForIdentifier(context.identifiers().Add(name));
  82. }
  83. // Adds the given source location and an `ImportIRInst` referring to it in
  84. // `ImportIRId::Cpp`.
  85. static auto AddImportIRInst(SemIR::File& file,
  86. clang::SourceLocation clang_source_loc)
  87. -> SemIR::ImportIRInstId {
  88. SemIR::ClangSourceLocId clang_source_loc_id =
  89. file.clang_source_locs().Add(clang_source_loc);
  90. return file.import_ir_insts().Add(SemIR::ImportIRInst(clang_source_loc_id));
  91. }
  92. // Adds a namespace for the `Cpp` import and returns its `NameScopeId`.
  93. static auto AddNamespace(Context& context, PackageNameId cpp_package_id,
  94. llvm::ArrayRef<Parse::Tree::PackagingNames> imports)
  95. -> SemIR::NameScopeId {
  96. return AddImportNamespaceToScope(
  97. context,
  98. GetSingletonType(context, SemIR::NamespaceType::TypeInstId),
  99. SemIR::NameId::ForPackageName(cpp_package_id),
  100. SemIR::NameScopeId::Package,
  101. /*diagnose_duplicate_namespace=*/false,
  102. [&]() {
  103. return AddInst<SemIR::ImportCppDecl>(
  104. context,
  105. context.parse_tree().As<Parse::ImportDeclId>(
  106. imports.front().node_id),
  107. {});
  108. })
  109. .add_result.name_scope_id;
  110. }
  111. auto ImportCpp(Context& context,
  112. llvm::ArrayRef<Parse::Tree::PackagingNames> imports,
  113. llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs,
  114. llvm::LLVMContext* llvm_context,
  115. std::shared_ptr<clang::CompilerInvocation> invocation) -> void {
  116. if (imports.empty()) {
  117. // TODO: Consider always having a (non-null) AST even if there are no Cpp
  118. // imports.
  119. return;
  120. }
  121. PackageNameId package_id = imports.front().package_id;
  122. CARBON_CHECK(
  123. llvm::all_of(imports, [&](const Parse::Tree::PackagingNames& import) {
  124. return import.package_id == package_id;
  125. }));
  126. auto name_scope_id = AddNamespace(context, package_id, imports);
  127. SemIR::NameScope& name_scope = context.name_scopes().Get(name_scope_id);
  128. name_scope.set_is_closed_import(true);
  129. if (GenerateAst(context, imports, fs, llvm_context, std::move(invocation))) {
  130. name_scope.set_clang_decl_context_id(
  131. context.clang_decls().Add(
  132. {.key = SemIR::ClangDeclKey(
  133. context.ast_context().getTranslationUnitDecl()),
  134. .inst_id = name_scope.inst_id()}),
  135. /*is_cpp_scope=*/true);
  136. } else {
  137. name_scope.set_has_error();
  138. }
  139. }
  140. // NOLINTNEXTLINE(misc-no-recursion)
  141. static auto FindCorrespondingType(Context& context, SemIR::LocId loc_id,
  142. clang::QualType type) -> clang::QualType;
  143. // Given a class template specialization in some C++ AST which is *not* expected
  144. // to be `context`, find the corresponding declaration in `context`, if there is
  145. // one.
  146. // NOLINTNEXTLINE(misc-no-recursion)
  147. static auto FindCorrespondingTemplateSpecialization(
  148. Context& context, SemIR::LocId loc_id,
  149. const clang::ClassTemplateSpecializationDecl* source_spec,
  150. clang::ClassTemplateDecl* target_template) -> clang::Decl* {
  151. const auto& args = source_spec->getTemplateArgs();
  152. auto loc = GetCppLocation(context, loc_id);
  153. clang::TemplateArgumentListInfo arg_list(loc, loc);
  154. for (unsigned i = 0; i < args.size(); ++i) {
  155. const auto& arg = args[i];
  156. if (arg.getKind() == clang::TemplateArgument::Type) {
  157. auto type = FindCorrespondingType(context, loc_id, arg.getAsType());
  158. if (type.isNull()) {
  159. return nullptr;
  160. }
  161. arg_list.addArgument(clang::TemplateArgumentLoc(
  162. clang::TemplateArgument(type),
  163. context.ast_context().getTrivialTypeSourceInfo(type, loc)));
  164. } else {
  165. return nullptr;
  166. }
  167. }
  168. clang::TemplateName template_name(target_template);
  169. auto clang_type = context.clang_sema().CheckTemplateIdType(
  170. clang::ElaboratedTypeKeyword::None, template_name, loc, arg_list,
  171. /*Scope=*/nullptr, /*ForNestedNameSpecifier=*/false);
  172. if (!clang_type.isNull()) {
  173. return clang_type->getAsCXXRecordDecl();
  174. }
  175. return nullptr;
  176. }
  177. // Given a declaration in some C++ AST which is *not* expected to be `context`,
  178. // find the corresponding declaration in `context`, if there is one.
  179. // TODO: Make this non-recursive, or remove it once we support importing C++
  180. // ASTs for cross file imports.
  181. // NOLINTNEXTLINE(misc-no-recursion)
  182. static auto FindCorrespondingDecl(Context& context, SemIR::LocId loc_id,
  183. const clang::Decl* decl) -> clang::Decl* {
  184. if (const auto* named_decl = dyn_cast<clang::NamedDecl>(decl)) {
  185. auto* parent = dyn_cast_or_null<clang::DeclContext>(FindCorrespondingDecl(
  186. context, loc_id, cast<clang::Decl>(named_decl->getDeclContext())));
  187. if (!parent) {
  188. return nullptr;
  189. }
  190. clang::DeclarationName name;
  191. if (auto* identifier = named_decl->getDeclName().getAsIdentifierInfo()) {
  192. name = &context.ast_context().Idents.get(identifier->getName());
  193. } else {
  194. // TODO: Handle more name kinds.
  195. return nullptr;
  196. }
  197. auto decls = parent->lookup(name);
  198. // TODO: If there are multiple results, try to pick the right one.
  199. if (!decls.isSingleResult() ||
  200. decls.front()->getKind() != named_decl->getKind()) {
  201. if (const auto* source_spec =
  202. dyn_cast<clang::ClassTemplateSpecializationDecl>(named_decl)) {
  203. if (auto* target_template =
  204. dyn_cast<clang::ClassTemplateDecl>(decls.front())) {
  205. if (auto* result = FindCorrespondingTemplateSpecialization(
  206. context, loc_id, source_spec, target_template)) {
  207. return result;
  208. }
  209. }
  210. }
  211. return nullptr;
  212. }
  213. return decls.front();
  214. }
  215. if (isa<clang::TranslationUnitDecl>(decl)) {
  216. return context.ast_context().getTranslationUnitDecl();
  217. }
  218. return nullptr;
  219. }
  220. // Given a type in some C++ AST which is *not* expected to be `context`,
  221. // find the corresponding type in `context`, if there is one.
  222. // NOLINTNEXTLINE(misc-no-recursion)
  223. static auto FindCorrespondingType(Context& context, SemIR::LocId loc_id,
  224. clang::QualType type) -> clang::QualType {
  225. if (type.isNull()) {
  226. return clang::QualType();
  227. }
  228. if (const auto* builtin = type->getAs<clang::BuiltinType>()) {
  229. switch (builtin->getKind()) {
  230. #define BUILTIN_TYPE(Id, SingletonId) \
  231. case clang::BuiltinType::Id: \
  232. return context.ast_context().SingletonId;
  233. #include "clang/AST/BuiltinTypes.def"
  234. #undef BUILTIN_TYPE
  235. default:
  236. return clang::QualType();
  237. }
  238. }
  239. if (const auto* record = type->getAs<clang::RecordType>()) {
  240. const auto* decl = record->getDecl();
  241. auto* corresponding_decl = FindCorrespondingDecl(context, loc_id, decl);
  242. if (!corresponding_decl) {
  243. return clang::QualType();
  244. }
  245. if (const auto* tag_decl = dyn_cast<clang::TagDecl>(corresponding_decl)) {
  246. return context.ast_context().getTypeDeclType(
  247. cast<clang::TypeDecl>(tag_decl));
  248. }
  249. return clang::QualType();
  250. }
  251. return clang::QualType();
  252. }
  253. auto ImportCppDeclFromFile(Context& context, SemIR::LocId loc_id,
  254. const SemIR::File& file,
  255. SemIR::ClangDeclId clang_decl_id)
  256. -> SemIR::ConstantId {
  257. CARBON_CHECK(clang_decl_id.has_value());
  258. auto key = file.clang_decls().Get(clang_decl_id).key;
  259. const auto* decl = key.decl;
  260. auto* corresponding = FindCorrespondingDecl(context, loc_id, decl);
  261. if (!corresponding) {
  262. // TODO: This needs a proper diagnostic.
  263. context.TODO(
  264. loc_id,
  265. "use of imported C++ declaration with no corresponding local import");
  266. return SemIR::ErrorInst::ConstantId;
  267. }
  268. key.decl = corresponding;
  269. auto imported_inst_id = ImportCppDecl(context, loc_id, key);
  270. auto imported_const_id = context.constant_values().Get(imported_inst_id);
  271. if (!imported_const_id.is_constant()) {
  272. context.TODO(loc_id, "imported C++ declant is not constant");
  273. return SemIR::ErrorInst::ConstantId;
  274. }
  275. return imported_const_id;
  276. }
  277. auto ImportCppConstantFromFile(Context& context, SemIR::LocId loc_id,
  278. const SemIR::File& file, SemIR::InstId inst_id)
  279. -> SemIR::ConstantId {
  280. // TODO: We should perform cross-file imports by importing the C++ AST. For
  281. // now we require the C++ declaration to already be imported into the
  282. // destination file, and find the corresponding declaration there and import
  283. // that.
  284. if (!context.cpp_context()) {
  285. context.TODO(
  286. loc_id, "indirect import of C++ declaration with no direct Cpp import");
  287. return SemIR::ErrorInst::ConstantId;
  288. }
  289. auto const_inst_id = file.constant_values().GetConstantInstId(inst_id);
  290. CARBON_KIND_SWITCH(file.insts().Get(const_inst_id)) {
  291. case CARBON_KIND(SemIR::ClassType class_type): {
  292. const auto& class_info = file.classes().Get(class_type.class_id);
  293. CARBON_CHECK(class_info.scope_id.has_value());
  294. return ImportCppDeclFromFile(
  295. context, loc_id, file,
  296. file.name_scopes().Get(class_info.scope_id).clang_decl_context_id());
  297. }
  298. case CARBON_KIND(SemIR::Namespace namespace_decl): {
  299. return ImportCppDeclFromFile(context, loc_id, file,
  300. file.name_scopes()
  301. .Get(namespace_decl.name_scope_id)
  302. .clang_decl_context_id());
  303. }
  304. default: {
  305. context.TODO(loc_id, "indirect import of unsupported C++ declaration");
  306. return SemIR::ErrorInst::ConstantId;
  307. }
  308. }
  309. }
  310. // Returns the Clang `DeclContext` for the given name scope. Return the
  311. // translation unit decl if no scope is provided.
  312. static auto GetDeclContext(Context& context, SemIR::NameScopeId scope_id)
  313. -> clang::DeclContext* {
  314. if (!scope_id.has_value()) {
  315. return context.ast_context().getTranslationUnitDecl();
  316. }
  317. auto scope_clang_decl_context_id =
  318. context.name_scopes().Get(scope_id).clang_decl_context_id();
  319. return dyn_cast<clang::DeclContext>(
  320. context.clang_decls().Get(scope_clang_decl_context_id).key.decl);
  321. }
  322. // Returns true if the given Clang declaration is the implicit injected class
  323. // name within the class.
  324. static auto IsDeclInjectedClassName(Context& context,
  325. SemIR::NameScopeId scope_id,
  326. SemIR::NameId name_id,
  327. const clang::NamedDecl* named_decl)
  328. -> bool {
  329. if (!named_decl->isImplicit()) {
  330. return false;
  331. }
  332. const auto* record_decl = dyn_cast<clang::CXXRecordDecl>(named_decl);
  333. if (!record_decl) {
  334. return false;
  335. }
  336. const SemIR::ClangDecl& clang_decl = context.clang_decls().Get(
  337. context.name_scopes().Get(scope_id).clang_decl_context_id());
  338. const auto* scope_record_decl =
  339. cast<clang::CXXRecordDecl>(clang_decl.key.decl);
  340. const clang::ASTContext& ast_context = context.ast_context();
  341. CARBON_CHECK(ast_context.getCanonicalTagType(scope_record_decl) ==
  342. ast_context.getCanonicalTagType(record_decl));
  343. auto class_decl = context.insts().GetAs<SemIR::ClassDecl>(clang_decl.inst_id);
  344. CARBON_CHECK(name_id == context.classes().Get(class_decl.class_id).name_id);
  345. return true;
  346. }
  347. // Performs a qualified name lookup of the identifier in the given scope.
  348. // Returns the lookup result if lookup was successful.
  349. static auto ClangLookupName(Context& context, SemIR::NameScopeId scope_id,
  350. clang::IdentifierInfo* identifier_name)
  351. -> std::optional<clang::LookupResult> {
  352. CARBON_CHECK(identifier_name, "Identifier name is empty");
  353. clang::Sema& sema = context.clang_sema();
  354. // TODO: Map the LocId of the lookup to a clang SourceLocation and provide it
  355. // here so that clang's diagnostics can point into the carbon code that uses
  356. // the name.
  357. clang::LookupResult lookup(
  358. sema,
  359. clang::DeclarationNameInfo(clang::DeclarationName(identifier_name),
  360. clang::SourceLocation()),
  361. clang::Sema::LookupNameKind::LookupOrdinaryName);
  362. bool found =
  363. sema.LookupQualifiedName(lookup, GetDeclContext(context, scope_id));
  364. if (!found) {
  365. return std::nullopt;
  366. }
  367. return lookup;
  368. }
  369. // Returns whether `decl` already mapped to an instruction.
  370. static auto IsClangDeclImported(Context& context, SemIR::ClangDeclKey key)
  371. -> bool {
  372. return context.clang_decls().Lookup(key).has_value();
  373. }
  374. // If `decl` already mapped to an instruction, returns that instruction.
  375. // Otherwise returns `None`.
  376. static auto LookupClangDeclInstId(Context& context, SemIR::ClangDeclKey key)
  377. -> SemIR::InstId {
  378. const auto& clang_decls = context.clang_decls();
  379. if (auto context_clang_decl_id = clang_decls.Lookup(key);
  380. context_clang_decl_id.has_value()) {
  381. return clang_decls.Get(context_clang_decl_id).inst_id;
  382. }
  383. return SemIR::InstId::None;
  384. }
  385. // Returns the parent of the given declaration. Skips declaration types we
  386. // ignore.
  387. static auto GetParentDecl(clang::Decl* clang_decl) -> clang::Decl* {
  388. auto* parent_dc = clang_decl->getDeclContext();
  389. while (!parent_dc->isLookupContext()) {
  390. parent_dc = parent_dc->getParent();
  391. }
  392. return cast<clang::Decl>(parent_dc);
  393. }
  394. // Returns the given declaration's parent scope. Assumes the parent declaration
  395. // was already imported.
  396. static auto GetParentNameScopeId(Context& context, clang::Decl* clang_decl)
  397. -> SemIR::NameScopeId {
  398. auto* parent_decl = GetParentDecl(clang_decl);
  399. if (auto* tag_decl = dyn_cast<clang::TagDecl>(parent_decl)) {
  400. auto class_inst_id =
  401. LookupClangDeclInstId(context, SemIR::ClangDeclKey(tag_decl));
  402. CARBON_CHECK(class_inst_id.has_value());
  403. auto class_inst = context.insts().Get(class_inst_id);
  404. auto class_id = SemIR::ClassId::None;
  405. if (auto class_decl = class_inst.TryAs<SemIR::ClassDecl>()) {
  406. // Common case: the tag was imported as a new Carbon class.
  407. class_id = class_decl->class_id;
  408. } else {
  409. // Rare case: the tag was imported as an existing Carbon class. This
  410. // happens for C++ classes that get mapped to Carbon prelude types, such
  411. // as `std::string_view`.
  412. // TODO: In this case, should we import the C++ class declaration and use
  413. // it as the parent, rather than using the existing Carbon class?
  414. class_id = class_inst.As<SemIR::ClassType>().class_id;
  415. }
  416. return context.classes().Get(class_id).scope_id;
  417. }
  418. if (isa<clang::NamespaceDecl, clang::TranslationUnitDecl>(parent_decl)) {
  419. auto namespace_inst_id = LookupClangDeclInstId(
  420. context, SemIR::ClangDeclKey::ForNonFunctionDecl(parent_decl));
  421. CARBON_CHECK(namespace_inst_id.has_value());
  422. return context.insts()
  423. .GetAs<SemIR::Namespace>(namespace_inst_id)
  424. .name_scope_id;
  425. }
  426. CARBON_FATAL("Unexpected kind of parent {0}", parent_decl->getDeclKindName());
  427. }
  428. // Imports a namespace declaration from Clang to Carbon. If successful, returns
  429. // the new Carbon namespace declaration `InstId`. If the declaration was already
  430. // imported, returns the mapped instruction.
  431. static auto ImportNamespaceDecl(Context& context,
  432. clang::NamespaceDecl* clang_decl)
  433. -> SemIR::InstId {
  434. auto key = SemIR::ClangDeclKey(clang_decl);
  435. // Check if the declaration is already mapped.
  436. if (SemIR::InstId existing_inst_id = LookupClangDeclInstId(context, key);
  437. existing_inst_id.has_value()) {
  438. return existing_inst_id;
  439. }
  440. auto result = AddImportNamespace(
  441. context, GetSingletonType(context, SemIR::NamespaceType::TypeInstId),
  442. AddIdentifierName(context, clang_decl->getName()),
  443. GetParentNameScopeId(context, clang_decl),
  444. /*import_id=*/SemIR::InstId::None);
  445. context.name_scopes()
  446. .Get(result.name_scope_id)
  447. .set_clang_decl_context_id(
  448. context.clang_decls().Add({.key = key, .inst_id = result.inst_id}),
  449. /*is_cpp_scope=*/true);
  450. return result.inst_id;
  451. }
  452. // Creates a class declaration for the given class name in the given scope.
  453. // Returns the `InstId` for the declaration.
  454. static auto BuildClassDecl(Context& context,
  455. SemIR::ImportIRInstId import_ir_inst_id,
  456. SemIR::NameScopeId parent_scope_id,
  457. SemIR::NameId name_id)
  458. -> std::tuple<SemIR::ClassId, SemIR::TypeInstId> {
  459. // Add the class declaration.
  460. auto class_decl = SemIR::ClassDecl{.type_id = SemIR::TypeType::TypeId,
  461. .class_id = SemIR::ClassId::None,
  462. .decl_block_id = SemIR::InstBlockId::None};
  463. auto class_decl_id = AddPlaceholderImportedInstInNoBlock(
  464. context, SemIR::LocIdAndInst::RuntimeVerified(
  465. context.sem_ir(), import_ir_inst_id, class_decl));
  466. SemIR::Class class_info = {
  467. {.name_id = name_id,
  468. .parent_scope_id = parent_scope_id,
  469. .generic_id = SemIR::GenericId::None,
  470. .first_param_node_id = Parse::NodeId::None,
  471. .last_param_node_id = Parse::NodeId::None,
  472. .pattern_block_id = SemIR::InstBlockId::None,
  473. .implicit_param_patterns_id = SemIR::InstBlockId::None,
  474. .param_patterns_id = SemIR::InstBlockId::None,
  475. .is_extern = false,
  476. .extern_library_id = SemIR::LibraryNameId::None,
  477. .non_owning_decl_id = SemIR::InstId::None,
  478. .first_owning_decl_id = class_decl_id},
  479. {// `.self_type_id` depends on the ClassType, so is set below.
  480. .self_type_id = SemIR::TypeId::None,
  481. // TODO: Support Dynamic classes.
  482. // TODO: Support Final classes.
  483. .inheritance_kind = SemIR::Class::Base}};
  484. class_decl.class_id = context.classes().Add(class_info);
  485. // Write the class ID into the ClassDecl.
  486. ReplaceInstBeforeConstantUse(context, class_decl_id, class_decl);
  487. SetClassSelfType(context, class_decl.class_id);
  488. return {class_decl.class_id, context.types().GetAsTypeInstId(class_decl_id)};
  489. }
  490. // Imports a tag declaration from Clang to Carbon. This covers classes (which
  491. // includes structs and unions) as well as enums. If successful, returns the new
  492. // Carbon class declaration `InstId`.
  493. static auto ImportTagDecl(Context& context, clang::TagDecl* clang_decl)
  494. -> SemIR::InstId {
  495. auto import_ir_inst_id =
  496. AddImportIRInst(context.sem_ir(), clang_decl->getLocation());
  497. auto [class_id, class_inst_id] = BuildClassDecl(
  498. context, import_ir_inst_id, GetParentNameScopeId(context, clang_decl),
  499. AddIdentifierName(context, clang_decl->getName()));
  500. // TODO: The caller does the same lookup. Avoid doing it twice.
  501. auto key = SemIR::ClangDeclKey(clang_decl);
  502. auto clang_decl_id =
  503. context.clang_decls().Add({.key = key, .inst_id = class_inst_id});
  504. // Name lookup into the Carbon class looks in the C++ class definition.
  505. auto& class_info = context.classes().Get(class_id);
  506. class_info.scope_id = context.name_scopes().Add(
  507. class_inst_id, SemIR::NameId::None, class_info.parent_scope_id);
  508. context.name_scopes()
  509. .Get(class_info.scope_id)
  510. .set_clang_decl_context_id(clang_decl_id, /*is_cpp_scope=*/true);
  511. return class_inst_id;
  512. }
  513. // Determines the Carbon inheritance kind to use for a C++ class definition.
  514. static auto GetInheritanceKind(clang::CXXRecordDecl* class_def)
  515. -> SemIR::Class::InheritanceKind {
  516. if (class_def->isUnion()) {
  517. // Treat all unions as final classes to match their C++ semantics. While we
  518. // could support this, the author of a C++ union has no way to mark their
  519. // type as `final` to prevent it, and so we assume the intent was to
  520. // disallow inheritance.
  521. return SemIR::Class::Final;
  522. }
  523. if (class_def->hasAttr<clang::FinalAttr>()) {
  524. // The class is final in C++; don't allow Carbon types to derive from it.
  525. // Note that such a type might also be abstract in C++; we treat final as
  526. // taking precedence.
  527. //
  528. // We could also treat classes with a final destructor as being final, as
  529. // Clang does when determining whether a class is "effectively final", but
  530. // to keep our rules simpler we do not.
  531. return SemIR::Class::Final;
  532. }
  533. if (class_def->getNumVBases()) {
  534. // TODO: We treat classes with virtual bases as final for now. We use the
  535. // layout of the class including its virtual bases as its Carbon type
  536. // layout, so we wouldn't behave correctly if we derived from it.
  537. return SemIR::Class::Final;
  538. }
  539. if (class_def->isAbstract()) {
  540. // If the class has any abstract members, it's abstract.
  541. return SemIR::Class::Abstract;
  542. }
  543. // Allow inheritance from any other C++ class type.
  544. return SemIR::Class::Base;
  545. }
  546. // Checks that the specified finished class definition is valid and builds and
  547. // returns a corresponding complete type witness instruction.
  548. static auto ImportClassObjectRepr(Context& context, SemIR::ClassId class_id,
  549. SemIR::ImportIRInstId import_ir_inst_id,
  550. SemIR::TypeInstId class_type_inst_id,
  551. const clang::CXXRecordDecl* clang_def)
  552. -> SemIR::TypeInstId {
  553. if (clang_def->isInvalidDecl()) {
  554. // Clang already diagnosed this error.
  555. return SemIR::ErrorInst::TypeInstId;
  556. }
  557. // For now, if the class is empty and an aggregate, produce an empty struct as
  558. // the object representation. This allows our tests to continue to pass while
  559. // we don't properly support initializing imported C++ classes. We only do
  560. // this for aggregates so that non-aggregate classes are not incorrectly
  561. // initializable from `{}`.
  562. // TODO: Remove this.
  563. if (clang_def->isEmpty() && !clang_def->getNumBases() &&
  564. clang_def->isAggregate()) {
  565. return context.types().GetAsTypeInstId(AddInst(
  566. context,
  567. SemIR::LocIdAndInst::RuntimeVerified(
  568. context.sem_ir(), import_ir_inst_id,
  569. SemIR::StructType{.type_id = SemIR::TypeType::TypeId,
  570. .fields_id = SemIR::StructTypeFieldsId::Empty})));
  571. }
  572. const auto& clang_layout =
  573. context.ast_context().getASTRecordLayout(clang_def);
  574. llvm::SmallVector<SemIR::ObjectSize> layout;
  575. llvm::SmallVector<SemIR::StructTypeField> fields;
  576. static_assert(SemIR::CustomLayoutId::SizeIndex == 0);
  577. layout.push_back(
  578. SemIR::ObjectSize::Bytes(clang_layout.getSize().getQuantity()));
  579. static_assert(SemIR::CustomLayoutId::AlignIndex == 1);
  580. layout.push_back(
  581. SemIR::ObjectSize::Bytes(clang_layout.getAlignment().getQuantity()));
  582. static_assert(SemIR::CustomLayoutId::FirstFieldIndex == 2);
  583. // TODO: Import vptr(s).
  584. // The kind of base class we've picked so far. These are ordered in increasing
  585. // preference order.
  586. enum class BaseKind {
  587. None,
  588. Empty,
  589. NonEmpty,
  590. Polymorphic,
  591. };
  592. BaseKind base_kind = BaseKind::None;
  593. // Import bases.
  594. for (const auto& base : clang_def->bases()) {
  595. if (base.isVirtual()) {
  596. // If the base is virtual, skip it from the layout. We don't know where it
  597. // will actually appear within the complete object layout, as a pointer to
  598. // this class might point to a derived type that puts the vbase in a
  599. // different place.
  600. // TODO: Track that the virtual base existed. Support derived-to-vbase
  601. // conversions by generating a clang AST fragment.
  602. continue;
  603. }
  604. auto [base_type_inst_id, base_type_id] =
  605. ImportCppType(context, import_ir_inst_id, base.getType());
  606. if (!base_type_id.has_value()) {
  607. // TODO: If the base class's type can't be mapped, skip it.
  608. continue;
  609. }
  610. auto base_decl_id = AddInst(
  611. context,
  612. SemIR::LocIdAndInst::RuntimeVerified(
  613. context.sem_ir(), import_ir_inst_id,
  614. SemIR::BaseDecl{.type_id = GetUnboundElementType(
  615. context, class_type_inst_id, base_type_inst_id),
  616. .base_type_inst_id = base_type_inst_id,
  617. .index = SemIR::ElementIndex(fields.size())}));
  618. auto* base_class = base.getType()->getAsCXXRecordDecl();
  619. CARBON_CHECK(base_class, "Base class {0} is not a class",
  620. base.getType().getAsString());
  621. // If there's a unique "best" base class, treat it as a Carbon base class
  622. // too.
  623. // TODO: Improve handling for the case where the class has multiple base
  624. // classes.
  625. BaseKind kind = base_class->isPolymorphic() ? BaseKind::Polymorphic
  626. : base_class->isEmpty() ? BaseKind::Empty
  627. : BaseKind::NonEmpty;
  628. auto& class_info = context.classes().Get(class_id);
  629. if (kind > base_kind) {
  630. // This base is better than the previous best.
  631. class_info.base_id = base_decl_id;
  632. base_kind = kind;
  633. } else if (kind == base_kind) {
  634. // Multiple base classes of this kind: no unique best.
  635. class_info.base_id = SemIR::InstId::None;
  636. }
  637. // TODO: If the base class has virtual bases, the size of the type that we
  638. // add to the layout here will be the full size of the class (including
  639. // virtual bases), whereas the size actually occupied by this base class is
  640. // only the nvsize (excluding virtual bases).
  641. auto base_offset = base.isVirtual()
  642. ? clang_layout.getVBaseClassOffset(base_class)
  643. : clang_layout.getBaseClassOffset(base_class);
  644. layout.push_back(SemIR::ObjectSize::Bytes(base_offset.getQuantity()));
  645. fields.push_back(
  646. {.name_id = SemIR::NameId::Base, .type_inst_id = base_type_inst_id});
  647. }
  648. // Import fields.
  649. for (auto* decl : clang_def->decls()) {
  650. auto* field = dyn_cast<clang::FieldDecl>(decl);
  651. // Track the chain of fields from the class to this field. This chain is
  652. // only one element long unless the field is a member of an anonymous struct
  653. // or union.
  654. clang::NamedDecl* single_field_chain[1] = {field};
  655. llvm::ArrayRef<clang::NamedDecl*> chain = single_field_chain;
  656. // If this isn't a field, it might be an indirect field in an anonymous
  657. // struct or union.
  658. if (!field) {
  659. auto* indirect_field = dyn_cast<clang::IndirectFieldDecl>(decl);
  660. if (!indirect_field) {
  661. continue;
  662. }
  663. chain = indirect_field->chain();
  664. field = indirect_field->getAnonField();
  665. }
  666. if (field->isBitField()) {
  667. // TODO: Add a representation for named bitfield members.
  668. continue;
  669. }
  670. if (field->isAnonymousStructOrUnion()) {
  671. // Fields within an anonymous structure or union will be added via their
  672. // IndirectFieldDecls.
  673. continue;
  674. }
  675. auto field_name_id = AddIdentifierName(context, field->getName());
  676. auto [field_type_inst_id, field_type_id] =
  677. ImportCppType(context, import_ir_inst_id, field->getType());
  678. if (!field_type_inst_id.has_value()) {
  679. // TODO: For now, just skip over fields whose types we can't map.
  680. continue;
  681. }
  682. // Create a field now, as we know the index to use.
  683. // TODO: Consider doing this lazily instead.
  684. auto field_decl_id = AddInst(
  685. context, SemIR::LocIdAndInst::RuntimeVerified(
  686. context.sem_ir(), import_ir_inst_id,
  687. SemIR::FieldDecl{
  688. .type_id = GetUnboundElementType(
  689. context, class_type_inst_id, field_type_inst_id),
  690. .name_id = field_name_id,
  691. .index = SemIR::ElementIndex(fields.size())}));
  692. // The imported SemIR::FieldDecl represents the original declaration `decl`,
  693. // which is either the field or the indirect field declaration.
  694. auto key = SemIR::ClangDeclKey::ForNonFunctionDecl(decl);
  695. context.clang_decls().Add({.key = key, .inst_id = field_decl_id});
  696. // Compute the offset to the field that appears directly in the class.
  697. uint64_t offset = clang_layout.getFieldOffset(
  698. cast<clang::FieldDecl>(chain.front())->getFieldIndex());
  699. // If this is an indirect field, walk the path and accumulate the offset to
  700. // the named field.
  701. for (auto* inner_decl : chain.drop_front()) {
  702. auto* inner_field = cast<clang::FieldDecl>(inner_decl);
  703. const auto& inner_layout =
  704. context.ast_context().getASTRecordLayout(inner_field->getParent());
  705. offset += inner_layout.getFieldOffset(inner_field->getFieldIndex());
  706. }
  707. layout.push_back(SemIR::ObjectSize::Bits(offset));
  708. fields.push_back(
  709. {.name_id = field_name_id, .type_inst_id = field_type_inst_id});
  710. }
  711. // TODO: Add a field to prevent tail padding reuse if necessary.
  712. return AddTypeInst(
  713. context, SemIR::LocIdAndInst::RuntimeVerified(
  714. context.sem_ir(), import_ir_inst_id,
  715. SemIR::CustomLayoutType{
  716. .type_id = SemIR::TypeType::TypeId,
  717. .fields_id = context.struct_type_fields().Add(fields),
  718. .layout_id = context.custom_layouts().Add(layout)}));
  719. }
  720. // Creates a Carbon class definition based on the information in the given Clang
  721. // class declaration, which is assumed to be for a class definition.
  722. static auto BuildClassDefinition(Context& context,
  723. SemIR::ImportIRInstId import_ir_inst_id,
  724. SemIR::ClassId class_id,
  725. SemIR::TypeInstId class_inst_id,
  726. clang::CXXRecordDecl* clang_def) -> void {
  727. auto& class_info = context.classes().Get(class_id);
  728. CARBON_CHECK(!class_info.has_definition_started());
  729. class_info.definition_id = class_inst_id;
  730. context.inst_block_stack().Push();
  731. class_info.inheritance_kind = GetInheritanceKind(clang_def);
  732. // Compute the class's object representation.
  733. auto object_repr_id = ImportClassObjectRepr(
  734. context, class_id, import_ir_inst_id, class_inst_id, clang_def);
  735. class_info.complete_type_witness_id =
  736. AddInst(context, SemIR::LocIdAndInst::RuntimeVerified(
  737. context.sem_ir(), import_ir_inst_id,
  738. SemIR::CompleteTypeWitness{
  739. .type_id = GetSingletonType(
  740. context, SemIR::WitnessType::TypeInstId),
  741. .object_repr_type_inst_id = object_repr_id}));
  742. class_info.body_block_id = context.inst_block_stack().Pop();
  743. }
  744. // Computes and returns the Carbon type to use as the object representation of
  745. // the given C++ enum type. This is a builtin int type matching the enum's
  746. // representation.
  747. static auto ImportEnumObjectRepresentation(
  748. Context& context, SemIR::ImportIRInstId import_ir_inst_id,
  749. clang::EnumDecl* enum_decl) -> SemIR::TypeInstId {
  750. auto int_type = enum_decl->getIntegerType();
  751. CARBON_CHECK(!int_type.isNull(), "incomplete enum type {0}",
  752. enum_decl->getNameAsString());
  753. auto int_kind = int_type->isSignedIntegerType() ? SemIR::IntKind::Signed
  754. : SemIR::IntKind::Unsigned;
  755. auto bit_width_id = GetOrAddInst(
  756. context, SemIR::LocIdAndInst::RuntimeVerified(
  757. context.sem_ir(), import_ir_inst_id,
  758. SemIR::IntValue{
  759. .type_id = GetSingletonType(
  760. context, SemIR::IntLiteralType::TypeInstId),
  761. .int_id = context.ints().AddUnsigned(llvm::APInt(
  762. 64, context.ast_context().getIntWidth(int_type)))}));
  763. return context.types().GetAsTypeInstId(
  764. GetOrAddInst(context, SemIR::LocIdAndInst::NoLoc(SemIR::IntType{
  765. .type_id = SemIR::TypeType::TypeId,
  766. .int_kind = int_kind,
  767. .bit_width_id = bit_width_id})));
  768. }
  769. // Creates a Carbon class definition based on the information in the given Clang
  770. // enum declaration.
  771. static auto BuildEnumDefinition(Context& context,
  772. SemIR::ImportIRInstId import_ir_inst_id,
  773. SemIR::ClassId class_id,
  774. SemIR::TypeInstId class_inst_id,
  775. clang::EnumDecl* enum_decl) -> void {
  776. auto& class_info = context.classes().Get(class_id);
  777. CARBON_CHECK(!class_info.has_definition_started());
  778. class_info.definition_id = class_inst_id;
  779. context.inst_block_stack().Push();
  780. // Don't allow inheritance from C++ enums, to match the behavior in C++.
  781. class_info.inheritance_kind = SemIR::Class::Final;
  782. // Compute the enum type's object representation. An enum is an adapter for
  783. // the corresponding builtin integer type.
  784. auto object_repr_id =
  785. ImportEnumObjectRepresentation(context, import_ir_inst_id, enum_decl);
  786. class_info.adapt_id = AddInst(
  787. context, SemIR::LocIdAndInst::RuntimeVerified(
  788. context.sem_ir(), import_ir_inst_id,
  789. SemIR::AdaptDecl{.adapted_type_inst_id = object_repr_id}));
  790. class_info.complete_type_witness_id =
  791. AddInst(context, SemIR::LocIdAndInst::RuntimeVerified(
  792. context.sem_ir(), import_ir_inst_id,
  793. SemIR::CompleteTypeWitness{
  794. .type_id = GetSingletonType(
  795. context, SemIR::WitnessType::TypeInstId),
  796. .object_repr_type_inst_id = object_repr_id}));
  797. class_info.body_block_id = context.inst_block_stack().Pop();
  798. }
  799. // Imports an enumerator declaration from Clang to Carbon.
  800. static auto ImportEnumConstantDecl(Context& context,
  801. clang::EnumConstantDecl* enumerator_decl)
  802. -> SemIR::InstId {
  803. auto key = SemIR::ClangDeclKey(enumerator_decl);
  804. CARBON_CHECK(!IsClangDeclImported(context, key));
  805. // Find the enclosing enum type.
  806. auto enum_key = SemIR::ClangDeclKey(
  807. cast<clang::EnumDecl>(enumerator_decl->getDeclContext()));
  808. auto type_inst_id = LookupClangDeclInstId(context, enum_key);
  809. auto type_id = context.types().GetTypeIdForTypeInstId(type_inst_id);
  810. // Build a corresponding IntValue.
  811. auto int_id = context.ints().Add(enumerator_decl->getInitVal());
  812. auto import_ir_inst_id =
  813. AddImportIRInst(context.sem_ir(), enumerator_decl->getLocation());
  814. auto inst_id = AddInstInNoBlock(
  815. context, SemIR::LocIdAndInst::RuntimeVerified(
  816. context.sem_ir(), import_ir_inst_id,
  817. SemIR::IntValue{.type_id = type_id, .int_id = int_id}));
  818. context.imports().push_back(inst_id);
  819. context.clang_decls().Add({.key = key, .inst_id = inst_id});
  820. return inst_id;
  821. }
  822. // Mark the given `key` as failed in `clang_decls`.
  823. static auto MarkFailedDecl(Context& context, SemIR::ClangDeclKey key) {
  824. context.clang_decls().Add({.key = key, .inst_id = SemIR::ErrorInst::InstId});
  825. }
  826. // Creates an integer type of the given size.
  827. static auto MakeIntType(Context& context, IntId size_id, bool is_signed)
  828. -> TypeExpr {
  829. auto type_inst_id = MakeIntTypeLiteral(
  830. context, Parse::NodeId::None,
  831. is_signed ? SemIR::IntKind::Signed : SemIR::IntKind::Unsigned, size_id);
  832. return ExprAsType(context, Parse::NodeId::None, type_inst_id);
  833. }
  834. static auto MakeCppCompatType(Context& context, SemIR::LocId loc_id,
  835. CoreIdentifier name) -> TypeExpr {
  836. return ExprAsType(
  837. context, loc_id,
  838. LookupNameInCore(context, loc_id, {CoreIdentifier::CppCompat, name}));
  839. }
  840. // Maps a C++ builtin integer type to a Carbon `Core.CppCompat` type.
  841. static auto MapBuiltinCppCompatIntegerType(Context& context,
  842. unsigned int cpp_width,
  843. unsigned int carbon_width,
  844. CoreIdentifier cpp_compat_name)
  845. -> TypeExpr {
  846. if (cpp_width != carbon_width) {
  847. return TypeExpr::None;
  848. }
  849. return MakeCppCompatType(context, Parse::NodeId::None, cpp_compat_name);
  850. }
  851. // Maps a C++ builtin integer type to a Carbon type.
  852. // TODO: Handle integer types that map to named aliases.
  853. static auto MapBuiltinIntegerType(Context& context, SemIR::LocId loc_id,
  854. clang::QualType qual_type,
  855. const clang::BuiltinType& type) -> TypeExpr {
  856. clang::ASTContext& ast_context = context.ast_context();
  857. unsigned width = ast_context.getIntWidth(qual_type);
  858. bool is_signed = type.isSignedInteger();
  859. auto int_n_type = ast_context.getIntTypeForBitwidth(width, is_signed);
  860. if (clang::ASTContext::hasSameType(qual_type, int_n_type)) {
  861. TypeExpr type_expr =
  862. MakeIntType(context, context.ints().Add(width), is_signed);
  863. // Try to make sure integer types of 32 or 64 bits are complete so we can
  864. // check against them when deciding whether we need to generate a thunk.
  865. if (width == 32 || width == 64) {
  866. SemIR::TypeId type_id = type_expr.type_id;
  867. if (!context.types().IsComplete(type_id)) {
  868. TryToCompleteType(context, type_id, loc_id);
  869. }
  870. }
  871. return type_expr;
  872. }
  873. if (clang::ASTContext::hasSameType(qual_type, ast_context.CharTy)) {
  874. return ExprAsType(context, Parse::NodeId::None,
  875. MakeCharTypeLiteral(context, Parse::NodeId::None));
  876. }
  877. if (clang::ASTContext::hasSameType(qual_type, ast_context.LongTy)) {
  878. return MapBuiltinCppCompatIntegerType(context, width, 32,
  879. CoreIdentifier::Long32);
  880. }
  881. if (clang::ASTContext::hasSameType(qual_type, ast_context.UnsignedLongTy)) {
  882. return MapBuiltinCppCompatIntegerType(context, width, 32,
  883. CoreIdentifier::ULong32);
  884. }
  885. if (clang::ASTContext::hasSameType(qual_type, ast_context.LongLongTy)) {
  886. return MapBuiltinCppCompatIntegerType(context, width, 64,
  887. CoreIdentifier::LongLong64);
  888. }
  889. if (clang::ASTContext::hasSameType(qual_type,
  890. ast_context.UnsignedLongLongTy)) {
  891. return MapBuiltinCppCompatIntegerType(context, width, 64,
  892. CoreIdentifier::ULongLong64);
  893. }
  894. return TypeExpr::None;
  895. }
  896. static auto MapNullptrType(Context& context, SemIR::LocId loc_id) -> TypeExpr {
  897. return MakeCppCompatType(context, loc_id, CoreIdentifier::NullptrT);
  898. }
  899. // Maps a C++ builtin type to a Carbon type.
  900. // TODO: Support more builtin types.
  901. static auto MapBuiltinType(Context& context, SemIR::LocId loc_id,
  902. clang::QualType qual_type,
  903. const clang::BuiltinType& type) -> TypeExpr {
  904. clang::ASTContext& ast_context = context.ast_context();
  905. if (type.isBooleanType()) {
  906. CARBON_CHECK(ast_context.hasSameType(qual_type, ast_context.BoolTy));
  907. return ExprAsType(context, Parse::NodeId::None,
  908. context.types().GetTypeInstId(GetSingletonType(
  909. context, SemIR::BoolType::TypeInstId)));
  910. }
  911. if (type.isInteger()) {
  912. return MapBuiltinIntegerType(context, loc_id, qual_type, type);
  913. }
  914. if (type.isFloatingPoint()) {
  915. if (type.isFloat16Type() || type.isFloat32Type() || type.isDoubleType() ||
  916. type.isFloat128Type()) {
  917. return ExprAsType(
  918. context, Parse::NodeId::None,
  919. MakeFloatTypeLiteral(
  920. context, Parse::NodeId::None,
  921. context.ints().Add(ast_context.getTypeSize(qual_type))));
  922. }
  923. // TODO: Handle floating-point types that map to named aliases.
  924. } else if (type.isVoidType()) {
  925. return MakeCppCompatType(context, loc_id, CoreIdentifier::VoidBase);
  926. } else if (type.isNullPtrType()) {
  927. return MapNullptrType(context, loc_id);
  928. }
  929. return TypeExpr::None;
  930. }
  931. // Determines whether record_decl is a C++ class that has a custom mapping into
  932. // Carbon, and if so, returns the corresponding Carbon type. Otherwise returns
  933. // None.
  934. static auto LookupCustomRecordType(Context& context,
  935. const clang::CXXRecordDecl* record_decl)
  936. -> TypeExpr {
  937. switch (GetCustomCppTypeMapping(record_decl)) {
  938. case CustomCppTypeMapping::None:
  939. return TypeExpr::None;
  940. case CustomCppTypeMapping::Str:
  941. return MakeStringType(
  942. context,
  943. AddImportIRInst(context.sem_ir(), record_decl->getLocation()));
  944. }
  945. }
  946. // Maps a C++ tag type (class, struct, union, enum) to a Carbon type.
  947. static auto MapTagType(Context& context, const clang::TagType& type)
  948. -> TypeExpr {
  949. auto* tag_decl = type.getDecl();
  950. CARBON_CHECK(tag_decl);
  951. // Check if the declaration is already mapped.
  952. auto key = SemIR::ClangDeclKey(tag_decl);
  953. SemIR::InstId tag_inst_id = LookupClangDeclInstId(context, key);
  954. if (!tag_inst_id.has_value()) {
  955. if (auto* record_decl = dyn_cast<clang::CXXRecordDecl>(tag_decl)) {
  956. auto custom_type = LookupCustomRecordType(context, record_decl);
  957. if (custom_type.inst_id.has_value()) {
  958. context.clang_decls().Add({.key = key, .inst_id = custom_type.inst_id});
  959. return custom_type;
  960. }
  961. }
  962. tag_inst_id = ImportTagDecl(context, tag_decl);
  963. }
  964. SemIR::TypeInstId record_type_inst_id =
  965. context.types().GetAsTypeInstId(tag_inst_id);
  966. return {
  967. // TODO: inst_id's location should be the location of the usage, not
  968. // the location of the type definition. Possibly we should synthesize a
  969. // NameRef inst, to match how this would work in Carbon code.
  970. .inst_id = record_type_inst_id,
  971. .type_id = context.types().GetTypeIdForTypeInstId(record_type_inst_id)};
  972. }
  973. // Maps a C++ type that is not a wrapper type such as a pointer to a Carbon
  974. // type.
  975. // TODO: Support more types.
  976. static auto MapNonWrapperType(Context& context, SemIR::LocId loc_id,
  977. clang::QualType type) -> TypeExpr {
  978. if (const auto* builtin_type = type->getAs<clang::BuiltinType>()) {
  979. return MapBuiltinType(context, loc_id, type, *builtin_type);
  980. }
  981. if (const auto* tag_type = type->getAs<clang::TagType>()) {
  982. return MapTagType(context, *tag_type);
  983. }
  984. CARBON_CHECK(!type.hasQualifiers() && !type->isPointerType(),
  985. "Should not see wrapper types here");
  986. return TypeExpr::None;
  987. }
  988. // Maps a qualified C++ type to a Carbon type.
  989. static auto MapQualifiedType(Context& context, clang::QualType type,
  990. TypeExpr type_expr) -> TypeExpr {
  991. auto quals = type.getQualifiers();
  992. if (quals.hasConst()) {
  993. auto type_id = GetConstType(context, type_expr.inst_id);
  994. type_expr = TypeExpr::ForUnsugared(context, type_id);
  995. quals.removeConst();
  996. }
  997. // TODO: Support other qualifiers.
  998. if (!quals.empty()) {
  999. return TypeExpr::None;
  1000. }
  1001. return type_expr;
  1002. }
  1003. // Returns true if the type has the `_Nonnull` attribute.
  1004. static auto IsClangTypeNonNull(clang::QualType type) -> bool {
  1005. auto nullability = type->getNullability();
  1006. return nullability.has_value() &&
  1007. *nullability == clang::NullabilityKind::NonNull;
  1008. }
  1009. // Like `clang::QualType::getUnqualifiedType()`, retrieves the unqualified
  1010. // variant of the given type, but preserves `_Nonnull`.
  1011. static auto ClangGetUnqualifiedTypePreserveNonNull(
  1012. Context& context, clang::QualType original_type) -> clang::QualType {
  1013. clang::QualType type = original_type.getUnqualifiedType();
  1014. // Preserve non-nullability.
  1015. if (IsClangTypeNonNull(original_type) && !IsClangTypeNonNull(type)) {
  1016. type = context.ast_context().getAttributedType(
  1017. clang::NullabilityKind::NonNull, type, type);
  1018. }
  1019. return type;
  1020. }
  1021. // Returns the type `Core.Optional(T)`, where `T` is described by
  1022. // `inner_type_inst_id`.
  1023. static auto MakeOptionalType(Context& context, SemIR::LocId loc_id,
  1024. SemIR::InstId inner_type_inst_id) -> TypeExpr {
  1025. auto fn_inst_id = LookupNameInCore(context, loc_id, CoreIdentifier::Optional);
  1026. auto call_id = PerformCall(context, loc_id, fn_inst_id, {inner_type_inst_id});
  1027. return ExprAsType(context, loc_id, call_id);
  1028. }
  1029. // Maps a C++ pointer type to a Carbon pointer type.
  1030. static auto MapPointerType(Context& context, SemIR::LocId loc_id,
  1031. clang::QualType type, TypeExpr pointee_type_expr)
  1032. -> TypeExpr {
  1033. CARBON_CHECK(type->isPointerType());
  1034. bool optional =
  1035. !IsClangTypeNonNull(type) &&
  1036. // If the type was produced by C++ template substitution, then we assume
  1037. // it was deduced from a Carbon pointer type, so it's non-null.
  1038. !type->getAs<clang::SubstTemplateTypeParmType>();
  1039. TypeExpr pointer_type_expr = TypeExpr::ForUnsugared(
  1040. context, GetPointerType(context, pointee_type_expr.inst_id));
  1041. if (optional) {
  1042. pointer_type_expr =
  1043. MakeOptionalType(context, loc_id, pointer_type_expr.inst_id);
  1044. }
  1045. return pointer_type_expr;
  1046. }
  1047. // Maps a C++ reference type to a Carbon type. We map all references to
  1048. // pointers for now. Note that when mapping function parameters and return
  1049. // types, a different rule is used; see MapParameterType for details.
  1050. // TODO: Revisit this and decide what we really want to do here.
  1051. static auto MapReferenceType(Context& context, clang::QualType type,
  1052. TypeExpr referenced_type_expr) -> TypeExpr {
  1053. CARBON_CHECK(type->isReferenceType());
  1054. SemIR::TypeId pointer_type_id =
  1055. GetPointerType(context, referenced_type_expr.inst_id);
  1056. pointer_type_id =
  1057. GetConstType(context, context.types().GetTypeInstId(pointer_type_id));
  1058. return TypeExpr::ForUnsugared(context, pointer_type_id);
  1059. }
  1060. // Maps a C++ type to a Carbon type. `type` should not be canonicalized because
  1061. // we check for pointer nullability and nullability will be lost by
  1062. // canonicalization.
  1063. static auto MapType(Context& context, SemIR::LocId loc_id, clang::QualType type)
  1064. -> TypeExpr {
  1065. // Unwrap any type modifiers and wrappers.
  1066. llvm::SmallVector<clang::QualType> wrapper_types;
  1067. while (true) {
  1068. clang::QualType orig_type = type;
  1069. if (type.hasQualifiers()) {
  1070. type = ClangGetUnqualifiedTypePreserveNonNull(context, type);
  1071. } else if (type->isPointerType()) {
  1072. type = type->getPointeeType();
  1073. } else if (type->isReferenceType()) {
  1074. type = type.getNonReferenceType();
  1075. } else {
  1076. break;
  1077. }
  1078. wrapper_types.push_back(orig_type);
  1079. }
  1080. auto mapped = MapNonWrapperType(context, loc_id, type);
  1081. for (auto wrapper : llvm::reverse(wrapper_types)) {
  1082. if (!mapped.inst_id.has_value() ||
  1083. mapped.type_id == SemIR::ErrorInst::TypeId) {
  1084. break;
  1085. }
  1086. if (wrapper.hasQualifiers()) {
  1087. mapped = MapQualifiedType(context, wrapper, mapped);
  1088. } else if (wrapper->isPointerType()) {
  1089. mapped = MapPointerType(context, loc_id, wrapper, mapped);
  1090. } else if (wrapper->isReferenceType()) {
  1091. mapped = MapReferenceType(context, wrapper, mapped);
  1092. } else {
  1093. CARBON_FATAL("Unexpected wrapper type {0}", wrapper.getAsString());
  1094. }
  1095. }
  1096. return mapped;
  1097. }
  1098. namespace {
  1099. // Information about how to map a C++ parameter type into Carbon.
  1100. struct ParameterTypeInfo {
  1101. // The type to use for the Carbon parameter.
  1102. TypeExpr type;
  1103. // Whether to build a `ref` pattern.
  1104. bool want_ref_pattern;
  1105. };
  1106. } // namespace
  1107. // Given the type of a C++ function parameter, returns information about the
  1108. // type to use for the corresponding Carbon parameter.
  1109. //
  1110. // Note that if the parameter has a type for which `IsSimpleAbiType` returns
  1111. // true, we must produce a parameter type that has the same calling convention
  1112. // as the C++ type.
  1113. static auto MapParameterType(Context& context, SemIR::LocId loc_id,
  1114. clang::QualType param_type) -> ParameterTypeInfo {
  1115. ParameterTypeInfo info = {.type = TypeExpr::None, .want_ref_pattern = false};
  1116. // Perform some custom mapping for parameters of reference type:
  1117. //
  1118. // * `T& x` -> `ref x: T`.
  1119. // * `const T& x` -> `x: T`.
  1120. // * `T&& x` -> `x: T`.
  1121. //
  1122. // TODO: For the `&&` mapping, we allow an rvalue reference to bind to a
  1123. // durable reference expression. This should not be allowed.
  1124. if (param_type->isReferenceType()) {
  1125. clang::QualType pointee_type = param_type->getPointeeType();
  1126. if (param_type->isLValueReferenceType()) {
  1127. if (pointee_type.isConstQualified()) {
  1128. // TODO: Consider only doing this if `const` is the only qualifier. For
  1129. // now, any other qualifier will fail when mapping the type.
  1130. auto split_type = pointee_type.getSplitUnqualifiedType();
  1131. split_type.Quals.removeConst();
  1132. pointee_type = context.ast_context().getQualifiedType(split_type);
  1133. } else {
  1134. // The reference will map to a `ref` pattern.
  1135. info.want_ref_pattern = true;
  1136. }
  1137. }
  1138. param_type = pointee_type;
  1139. }
  1140. info.type = MapType(context, loc_id, param_type);
  1141. return info;
  1142. }
  1143. // Returns a block for the implicit parameters of the given function
  1144. // declaration. Because function templates are not yet supported, this currently
  1145. // only contains the `self` parameter. On error, produces a diagnostic and
  1146. // returns None.
  1147. static auto MakeImplicitParamPatternsBlockId(
  1148. Context& context, SemIR::LocId loc_id,
  1149. const clang::FunctionDecl& clang_decl) -> SemIR::InstBlockId {
  1150. const auto* method_decl = dyn_cast<clang::CXXMethodDecl>(&clang_decl);
  1151. if (!method_decl || method_decl->isStatic() ||
  1152. isa<clang::CXXConstructorDecl>(clang_decl)) {
  1153. return SemIR::InstBlockId::Empty;
  1154. }
  1155. // Build a `self` parameter from the object parameter.
  1156. BeginSubpattern(context);
  1157. clang::QualType param_type =
  1158. method_decl->getFunctionObjectParameterReferenceType();
  1159. auto param_info = MapParameterType(context, loc_id, param_type);
  1160. auto [type_inst_id, type_id] = param_info.type;
  1161. SemIR::ExprRegionId type_expr_region_id =
  1162. ConsumeSubpatternExpr(context, type_inst_id);
  1163. EndEmptySubpattern(context);
  1164. if (!type_id.has_value()) {
  1165. context.TODO(loc_id,
  1166. llvm::formatv("Unsupported: object parameter type: {0}",
  1167. param_type.getAsString()));
  1168. return SemIR::InstBlockId::None;
  1169. }
  1170. // TODO: Fill in a location once available.
  1171. auto pattern_id = AddParamPattern(context, loc_id, SemIR::NameId::SelfValue,
  1172. type_expr_region_id, type_id,
  1173. param_info.want_ref_pattern);
  1174. return context.inst_blocks().Add({pattern_id});
  1175. }
  1176. // Returns a block id for the explicit parameters of the given function
  1177. // declaration. If the function declaration has no parameters, it returns
  1178. // `SemIR::InstBlockId::Empty`. In the case of an unsupported parameter type, it
  1179. // produces an error and returns `SemIR::InstBlockId::None`. `signature`
  1180. // specifies how to convert the C++ signature to the Carbon signature.
  1181. // TODO: Consider refactoring to extract and reuse more logic from
  1182. // `HandleAnyBindingPattern()`.
  1183. static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id,
  1184. const clang::FunctionDecl& clang_decl,
  1185. SemIR::ClangDeclKey::Signature signature)
  1186. -> SemIR::InstBlockId {
  1187. llvm::SmallVector<SemIR::InstId> param_ids;
  1188. llvm::SmallVector<SemIR::InstId> param_type_ids;
  1189. param_ids.reserve(signature.num_params);
  1190. param_type_ids.reserve(signature.num_params);
  1191. CARBON_CHECK(static_cast<int>(clang_decl.getNumNonObjectParams()) >=
  1192. signature.num_params,
  1193. "Function has fewer parameters than requested: {0} < {1}",
  1194. clang_decl.getNumNonObjectParams(), signature.num_params);
  1195. const auto* function_type =
  1196. clang_decl.getType()->castAs<clang::FunctionProtoType>();
  1197. for (int i : llvm::seq(signature.num_params)) {
  1198. const auto* param = clang_decl.getNonObjectParameter(i);
  1199. clang::QualType orig_param_type = function_type->getParamType(
  1200. clang_decl.hasCXXExplicitFunctionObjectParameter() + i);
  1201. // The parameter type is decayed but hasn't necessarily had its qualifiers
  1202. // removed.
  1203. // TODO: The presence of qualifiers here is probably a Clang bug.
  1204. clang::QualType param_type =
  1205. ClangGetUnqualifiedTypePreserveNonNull(context, orig_param_type);
  1206. // Mark the start of a region of insts, needed for the type expression
  1207. // created later with the call of `ConsumeSubpatternExpr()`.
  1208. BeginSubpattern(context);
  1209. auto param_info = MapParameterType(context, loc_id, param_type);
  1210. auto [type_inst_id, type_id] = param_info.type;
  1211. // Type expression of the binding pattern - a single-entry/single-exit
  1212. // region that allows control flow in the type expression e.g. fn F(x: if C
  1213. // then i32 else i64).
  1214. SemIR::ExprRegionId type_expr_region_id =
  1215. ConsumeSubpatternExpr(context, type_inst_id);
  1216. EndEmptySubpattern(context);
  1217. if (!type_id.has_value()) {
  1218. context.TODO(loc_id, llvm::formatv("Unsupported: parameter type: {0}",
  1219. orig_param_type.getAsString()));
  1220. return SemIR::InstBlockId::None;
  1221. }
  1222. llvm::StringRef param_name = param->getName();
  1223. SemIR::NameId name_id =
  1224. param_name.empty()
  1225. // Translate an unnamed parameter to an underscore to
  1226. // match Carbon's naming of unnamed/unused function params.
  1227. ? SemIR::NameId::Underscore
  1228. : AddIdentifierName(context, param_name);
  1229. SemIR::LocId param_loc_id =
  1230. AddImportIRInst(context.sem_ir(), param->getLocation());
  1231. // TODO: Add template support.
  1232. SemIR::InstId pattern_id =
  1233. AddParamPattern(context, param_loc_id, name_id, type_expr_region_id,
  1234. type_id, param_info.want_ref_pattern);
  1235. param_ids.push_back(pattern_id);
  1236. param_type_ids.push_back(type_inst_id);
  1237. }
  1238. switch (signature.kind) {
  1239. case SemIR::ClangDeclKey::Signature::Normal: {
  1240. // Use the converted parameter list as-is.
  1241. break;
  1242. }
  1243. case SemIR::ClangDeclKey::Signature::TuplePattern: {
  1244. // Replace the parameters with a single tuple pattern containing the
  1245. // converted parameter list.
  1246. auto param_block_id = context.inst_blocks().Add(param_ids);
  1247. auto tuple_pattern_type_id =
  1248. GetPatternType(context, GetTupleType(context, param_type_ids));
  1249. SemIR::InstId pattern_id = AddInst(
  1250. context, SemIR::LocIdAndInst::RuntimeVerified(
  1251. context.sem_ir(), loc_id,
  1252. SemIR::TuplePattern{.type_id = tuple_pattern_type_id,
  1253. .elements_id = param_block_id}));
  1254. param_ids = {pattern_id};
  1255. break;
  1256. }
  1257. }
  1258. return context.inst_blocks().Add(param_ids);
  1259. }
  1260. // Returns the return `TypeExpr` of the given function declaration. In case of
  1261. // an unsupported return type, returns `SemIR::ErrorInst::InstId`. Constructors
  1262. // are treated as returning a class instance.
  1263. // TODO: Support more return types.
  1264. static auto GetReturnTypeExpr(Context& context, SemIR::LocId loc_id,
  1265. clang::FunctionDecl* clang_decl)
  1266. -> Context::FormExpr {
  1267. auto make_init_form = [&](SemIR::TypeInstId type_component_inst_id) {
  1268. SemIR::InitForm inst = {.type_id = SemIR::FormType::TypeId,
  1269. .type_component_inst_id = type_component_inst_id};
  1270. return context.constant_values().GetInstId(TryEvalInst(context, inst));
  1271. };
  1272. auto make_ref_form = [&](SemIR::TypeInstId type_component_inst_id) {
  1273. SemIR::RefForm inst = {.type_id = SemIR::FormType::TypeId,
  1274. .type_component_inst_id = type_component_inst_id};
  1275. return context.constant_values().GetInstId(TryEvalInst(context, inst));
  1276. };
  1277. clang::QualType orig_ret_type = clang_decl->getReturnType();
  1278. if (!orig_ret_type->isVoidType()) {
  1279. bool is_reference = orig_ret_type->isReferenceType();
  1280. if (is_reference) {
  1281. orig_ret_type = orig_ret_type->getPointeeType();
  1282. }
  1283. // TODO: We should eventually map reference returns to non-pointer types
  1284. // here. We should return by `ref` for `T&` return types once `ref` return
  1285. // is implemented.
  1286. auto [orig_type_inst_id, type_id] = MapType(context, loc_id, orig_ret_type);
  1287. if (!orig_type_inst_id.has_value()) {
  1288. context.TODO(loc_id, llvm::formatv("Unsupported: return type: {0}",
  1289. orig_ret_type.getAsString()));
  1290. return Context::FormExpr::Error;
  1291. }
  1292. Context::FormExpr result = {
  1293. .form_inst_id = is_reference ? make_ref_form(orig_type_inst_id)
  1294. : make_init_form(orig_type_inst_id),
  1295. .type_component_inst_id = orig_type_inst_id,
  1296. .type_component_id = type_id};
  1297. return result;
  1298. }
  1299. auto* ctor = dyn_cast<clang::CXXConstructorDecl>(clang_decl);
  1300. if (!ctor) {
  1301. // void.
  1302. return {.form_inst_id = SemIR::InstId::None,
  1303. .type_component_inst_id = SemIR::TypeInstId::None,
  1304. .type_component_id = SemIR::TypeId::None};
  1305. }
  1306. // TODO: Make this a `PartialType`.
  1307. SemIR::TypeInstId record_type_inst_id = context.types().GetAsTypeInstId(
  1308. LookupClangDeclInstId(context, SemIR::ClangDeclKey(ctor->getParent())));
  1309. return {.form_inst_id = make_init_form(record_type_inst_id),
  1310. .type_component_inst_id = record_type_inst_id,
  1311. .type_component_id =
  1312. context.types().GetTypeIdForTypeInstId(record_type_inst_id)};
  1313. }
  1314. // Information about a function's declared return type, corresponding to the
  1315. // fields of SemIR::Function with the same names.
  1316. struct ReturnInfo {
  1317. SemIR::TypeInstId return_type_inst_id;
  1318. SemIR::InstId return_form_inst_id;
  1319. SemIR::InstId return_pattern_id;
  1320. };
  1321. // Returns information about the declared return type of the given function
  1322. // declaration. In case of an unsupported return type, it produces a diagnostic,
  1323. // and the returned return_type_inst_id will be `SemIR::ErrorInst::InstId`.
  1324. // Constructors are treated as returning a class instance.
  1325. static auto GetReturnInfo(Context& context, SemIR::LocId loc_id,
  1326. clang::FunctionDecl* clang_decl) -> ReturnInfo {
  1327. auto [form_inst_id, type_inst_id, type_id] =
  1328. GetReturnTypeExpr(context, loc_id, clang_decl);
  1329. if (!form_inst_id.has_value()) {
  1330. // void.
  1331. return {.return_type_inst_id = SemIR::TypeInstId::None,
  1332. .return_form_inst_id = SemIR::InstId::None,
  1333. .return_pattern_id = SemIR::InstId::None};
  1334. }
  1335. if (form_inst_id == SemIR::ErrorInst::InstId) {
  1336. return {.return_type_inst_id = SemIR::ErrorInst::TypeInstId,
  1337. .return_form_inst_id = SemIR::ErrorInst::InstId,
  1338. .return_pattern_id = SemIR::InstId::None};
  1339. }
  1340. auto pattern_type_id = GetPatternType(context, type_id);
  1341. clang::SourceLocation return_type_loc =
  1342. clang_decl->getReturnTypeSourceRange().getBegin();
  1343. if (return_type_loc.isInvalid()) {
  1344. // TODO: While `getReturnTypeSourceRange()` should work, it seems broken for
  1345. // trailing return type. See
  1346. // https://github.com/llvm/llvm-project/issues/162649. Until this is fixed,
  1347. // we fallback to `getTypeSpecStartLoc()`.
  1348. return_type_loc = clang_decl->getTypeSpecStartLoc();
  1349. }
  1350. SemIR::ImportIRInstId return_type_import_ir_inst_id =
  1351. AddImportIRInst(context.sem_ir(), return_type_loc);
  1352. auto return_pattern_id = SemIR::InstId::None;
  1353. if (auto init_form =
  1354. context.insts().TryGetAs<SemIR::InitForm>(form_inst_id)) {
  1355. auto param_pattern_id = AddInst(
  1356. context, SemIR::LocIdAndInst::RuntimeVerified(
  1357. context.sem_ir(), return_type_import_ir_inst_id,
  1358. SemIR::OutParamPattern(
  1359. {.type_id = pattern_type_id,
  1360. .pretty_name_id = SemIR::NameId::ReturnSlot})));
  1361. return_pattern_id =
  1362. AddInst(context,
  1363. SemIR::LocIdAndInst::RuntimeVerified(
  1364. context.sem_ir(), return_type_import_ir_inst_id,
  1365. SemIR::ReturnSlotPattern({.type_id = pattern_type_id,
  1366. .subpattern_id = param_pattern_id,
  1367. .type_inst_id = type_inst_id})));
  1368. }
  1369. return {.return_type_inst_id = type_inst_id,
  1370. .return_form_inst_id = form_inst_id,
  1371. .return_pattern_id = return_pattern_id};
  1372. }
  1373. namespace {
  1374. // Represents the insts and inst blocks associated with the parameters and
  1375. // returns of a function declaration, corresponding to the fields of
  1376. // SemIR::Function with the same names.
  1377. struct FunctionSignatureInsts {
  1378. SemIR::InstBlockId implicit_param_patterns_id;
  1379. SemIR::InstBlockId param_patterns_id;
  1380. SemIR::TypeInstId return_type_inst_id;
  1381. SemIR::InstId return_form_inst_id;
  1382. SemIR::InstId return_pattern_id;
  1383. SemIR::InstBlockId call_param_patterns_id;
  1384. SemIR::InstBlockId call_params_id;
  1385. SemIR::Function::CallParamIndexRanges param_ranges;
  1386. };
  1387. } // namespace
  1388. // Creates the insts and inst blocks that represent the parameters and returns
  1389. // of the given C++ function's Carbon counterpart, including emitting a callee
  1390. // pattern match to create the `Call` parameters, and returns a
  1391. // FunctionSignatureInsts containing the results. Produces a diagnostic and
  1392. // returns `std::nullopt` if the function declaration has an unsupported
  1393. // parameter type. `signature` specifies how to convert the C++ function
  1394. // signature to the Carbon function signature.
  1395. static auto CreateFunctionSignatureInsts(
  1396. Context& context, SemIR::LocId loc_id, clang::FunctionDecl* clang_decl,
  1397. SemIR::ClangDeclKey::Signature signature)
  1398. -> std::optional<FunctionSignatureInsts> {
  1399. context.full_pattern_stack().StartImplicitParamList();
  1400. auto implicit_param_patterns_id =
  1401. MakeImplicitParamPatternsBlockId(context, loc_id, *clang_decl);
  1402. if (!implicit_param_patterns_id.has_value()) {
  1403. return std::nullopt;
  1404. }
  1405. context.full_pattern_stack().EndImplicitParamList();
  1406. context.full_pattern_stack().StartExplicitParamList();
  1407. auto param_patterns_id =
  1408. MakeParamPatternsBlockId(context, loc_id, *clang_decl, signature);
  1409. if (!param_patterns_id.has_value()) {
  1410. return std::nullopt;
  1411. }
  1412. context.full_pattern_stack().EndExplicitParamList();
  1413. auto [return_type_inst_id, return_form_inst_id, return_pattern_id] =
  1414. GetReturnInfo(context, loc_id, clang_decl);
  1415. if (return_type_inst_id == SemIR::ErrorInst::TypeInstId) {
  1416. return std::nullopt;
  1417. }
  1418. auto match_results = CalleePatternMatch(context, implicit_param_patterns_id,
  1419. param_patterns_id, return_pattern_id);
  1420. return {{.implicit_param_patterns_id = implicit_param_patterns_id,
  1421. .param_patterns_id = param_patterns_id,
  1422. .return_type_inst_id = return_type_inst_id,
  1423. .return_form_inst_id = return_form_inst_id,
  1424. .return_pattern_id = return_pattern_id,
  1425. .call_param_patterns_id = match_results.call_param_patterns_id,
  1426. .call_params_id = match_results.call_params_id,
  1427. .param_ranges = match_results.param_ranges}};
  1428. }
  1429. // Returns the Carbon function name for the given function.
  1430. static auto GetFunctionName(Context& context, clang::FunctionDecl* clang_decl)
  1431. -> SemIR::NameId {
  1432. switch (clang_decl->getDeclName().getNameKind()) {
  1433. case clang::DeclarationName::CXXConstructorName: {
  1434. auto key = SemIR::ClangDeclKey(
  1435. cast<clang::CXXConstructorDecl>(clang_decl)->getParent());
  1436. return context.classes()
  1437. .Get(context.insts()
  1438. .GetAs<SemIR::ClassDecl>(LookupClangDeclInstId(context, key))
  1439. .class_id)
  1440. .name_id;
  1441. }
  1442. case clang::DeclarationName::CXXDestructorName: {
  1443. return SemIR::NameId::CppDestructor;
  1444. }
  1445. case clang::DeclarationName::CXXOperatorName:
  1446. case clang::DeclarationName::CXXConversionFunctionName: {
  1447. return SemIR::NameId::CppOperator;
  1448. }
  1449. default: {
  1450. return AddIdentifierName(context, clang_decl->getName());
  1451. }
  1452. }
  1453. }
  1454. // Creates a `FunctionDecl` and a `Function` without C++ thunk information.
  1455. // Returns std::nullopt on failure.
  1456. //
  1457. // The given Clang declaration is assumed to:
  1458. // * Have not been imported before.
  1459. // * Be of supported type (ignoring parameters).
  1460. //
  1461. // `signature` specifies how to convert the C++ function signature to the Carbon
  1462. // function signature.
  1463. static auto ImportFunction(Context& context, SemIR::LocId loc_id,
  1464. SemIR::ImportIRInstId import_ir_inst_id,
  1465. clang::FunctionDecl* clang_decl,
  1466. SemIR::ClangDeclKey::Signature signature)
  1467. -> std::optional<SemIR::FunctionId> {
  1468. StartFunctionSignature(context);
  1469. auto function_params_insts =
  1470. CreateFunctionSignatureInsts(context, loc_id, clang_decl, signature);
  1471. auto [pattern_block_id, decl_block_id] =
  1472. FinishFunctionSignature(context, /*check_unused=*/false);
  1473. if (!function_params_insts.has_value()) {
  1474. return std::nullopt;
  1475. }
  1476. auto virtual_modifier = SemIR::Function::VirtualModifier::None;
  1477. int32_t virtual_index = -1;
  1478. if (auto* method_decl = dyn_cast<clang::CXXMethodDecl>(clang_decl)) {
  1479. if (method_decl->size_overridden_methods()) {
  1480. virtual_modifier = SemIR::Function::VirtualModifier::Override;
  1481. } else if (method_decl->isVirtual()) {
  1482. virtual_modifier = SemIR::Function::VirtualModifier::Virtual;
  1483. }
  1484. if (virtual_modifier != SemIR::Function::VirtualModifier::None) {
  1485. // TODO: Add support for Microsoft/non-Itanium vtables.
  1486. virtual_index = dyn_cast<clang::ItaniumVTableContext>(
  1487. context.ast_context().getVTableContext())
  1488. ->getMethodVTableIndex(method_decl);
  1489. }
  1490. }
  1491. SemIR::FunctionFields::EvaluationMode evaluation_mode =
  1492. SemIR::FunctionFields::EvaluationMode::None;
  1493. if (clang_decl->isConsteval()) {
  1494. evaluation_mode = SemIR::FunctionFields::EvaluationMode::MustEval;
  1495. } else if (clang_decl->isConstexpr()) {
  1496. evaluation_mode = SemIR::FunctionFields::EvaluationMode::Eval;
  1497. }
  1498. auto [decl_id, function_id] = MakeFunctionDecl(
  1499. context, import_ir_inst_id, decl_block_id, /*build_generic=*/false,
  1500. /*is_definition=*/false,
  1501. SemIR::Function{
  1502. {
  1503. .name_id = GetFunctionName(context, clang_decl),
  1504. .parent_scope_id = GetParentNameScopeId(context, clang_decl),
  1505. .generic_id = SemIR::GenericId::None,
  1506. .first_param_node_id = Parse::NodeId::None,
  1507. .last_param_node_id = Parse::NodeId::None,
  1508. .pattern_block_id = pattern_block_id,
  1509. .implicit_param_patterns_id =
  1510. function_params_insts->implicit_param_patterns_id,
  1511. .param_patterns_id = function_params_insts->param_patterns_id,
  1512. .is_extern = false,
  1513. .extern_library_id = SemIR::LibraryNameId::None,
  1514. .non_owning_decl_id = SemIR::InstId::None,
  1515. // Set by `MakeFunctionDecl`.
  1516. .first_owning_decl_id = SemIR::InstId::None,
  1517. },
  1518. {
  1519. .call_param_patterns_id =
  1520. function_params_insts->call_param_patterns_id,
  1521. .call_params_id = function_params_insts->call_params_id,
  1522. .call_param_ranges = function_params_insts->param_ranges,
  1523. .return_type_inst_id = function_params_insts->return_type_inst_id,
  1524. .return_form_inst_id = function_params_insts->return_form_inst_id,
  1525. .return_pattern_id = function_params_insts->return_pattern_id,
  1526. .virtual_modifier = virtual_modifier,
  1527. .virtual_index = virtual_index,
  1528. .evaluation_mode = evaluation_mode,
  1529. .self_param_id = FindSelfPattern(
  1530. context, function_params_insts->implicit_param_patterns_id),
  1531. }});
  1532. context.imports().push_back(decl_id);
  1533. context.functions().Get(function_id).clang_decl_id =
  1534. context.clang_decls().Add(
  1535. {.key = SemIR::ClangDeclKey::ForFunctionDecl(clang_decl, signature),
  1536. .inst_id = decl_id});
  1537. return function_id;
  1538. }
  1539. // Imports a C++ function, returning a corresponding Carbon function.
  1540. // `signature` specifies how to convert the C++ function signature to the Carbon
  1541. // function signature. `signature.num_params` may be less than the number of
  1542. // parameters that the C++ function has if default arguments are available for
  1543. // the trailing parameters.
  1544. static auto ImportFunctionDecl(Context& context, SemIR::LocId loc_id,
  1545. clang::FunctionDecl* clang_decl,
  1546. SemIR::ClangDeclKey::Signature signature)
  1547. -> SemIR::InstId {
  1548. auto key = SemIR::ClangDeclKey::ForFunctionDecl(clang_decl, signature);
  1549. // Check if the declaration is already mapped.
  1550. if (SemIR::InstId existing_inst_id = LookupClangDeclInstId(context, key);
  1551. existing_inst_id.has_value()) {
  1552. return existing_inst_id;
  1553. }
  1554. if (clang_decl->isVariadic()) {
  1555. context.TODO(loc_id, "Unsupported: Variadic function");
  1556. MarkFailedDecl(context, key);
  1557. return SemIR::ErrorInst::InstId;
  1558. }
  1559. if (clang_decl->getTemplatedKind() ==
  1560. clang::FunctionDecl::TK_FunctionTemplate) {
  1561. context.TODO(loc_id, "Unsupported: Template function");
  1562. MarkFailedDecl(context, key);
  1563. return SemIR::ErrorInst::InstId;
  1564. }
  1565. auto import_ir_inst_id =
  1566. AddImportIRInst(context.sem_ir(), clang_decl->getLocation());
  1567. CARBON_CHECK(clang_decl->getFunctionType()->isFunctionProtoType(),
  1568. "Not Prototype function (non-C++ code)");
  1569. auto function_id =
  1570. ImportFunction(context, loc_id, import_ir_inst_id, clang_decl, signature);
  1571. if (!function_id) {
  1572. MarkFailedDecl(context, key);
  1573. return SemIR::ErrorInst::InstId;
  1574. }
  1575. SemIR::Function& function_info = context.functions().Get(*function_id);
  1576. if (IsCppThunkRequired(context, function_info)) {
  1577. Diagnostics::AnnotationScope annotate_diagnostics(
  1578. &context.emitter(), [&](auto& builder) {
  1579. CARBON_DIAGNOSTIC(InCppThunk, Note,
  1580. "in thunk for C++ function used here");
  1581. builder.Note(loc_id, InCppThunk);
  1582. });
  1583. if (clang::FunctionDecl* thunk_clang_decl =
  1584. BuildCppThunk(context, function_info)) {
  1585. if (auto thunk_function_id = ImportFunction(
  1586. context, loc_id, import_ir_inst_id, thunk_clang_decl,
  1587. {.num_params =
  1588. static_cast<int32_t>(thunk_clang_decl->getNumParams())})) {
  1589. auto& thunk_function = context.functions().Get(*thunk_function_id);
  1590. thunk_function.SetCppThunk(function_info.first_owning_decl_id);
  1591. SemIR::InstId thunk_function_decl_id =
  1592. thunk_function.first_owning_decl_id;
  1593. function_info.SetHasCppThunk(thunk_function_decl_id);
  1594. }
  1595. }
  1596. } else {
  1597. // Inform Clang that the function has been referenced. This will trigger
  1598. // instantiation if needed.
  1599. context.clang_sema().MarkFunctionReferenced(GetCppLocation(context, loc_id),
  1600. clang_decl);
  1601. // If the function is trivial, mark it as being a builtin if possible.
  1602. if (clang_decl->isTrivial()) {
  1603. // Trivial destructors map to a "no_op" builtin.
  1604. if (isa<clang::CXXDestructorDecl>(clang_decl)) {
  1605. function_info.SetBuiltinFunction(SemIR::BuiltinFunctionKind::NoOp);
  1606. }
  1607. // TODO: Should we model a trivial default constructor as performing
  1608. // value-initialization (zero-initializing all fields) or
  1609. // default-initialization (leaving fields uniniitalized)? Either way we
  1610. // could model that effect as a builtin.
  1611. // TODO: Add a builtin to model trivial copies.
  1612. }
  1613. }
  1614. return function_info.first_owning_decl_id;
  1615. }
  1616. namespace {
  1617. // An item to be imported in an import worklist.
  1618. // TODO: If worklists ever become particularly large, consider changing this
  1619. // to use a `PointerIntPair`.
  1620. struct ImportItem {
  1621. // A declaration that we want to import.
  1622. SemIR::ClangDeclKey decl_key;
  1623. // Whether we have added `decl`'s dependencies to the worklist.
  1624. bool added_dependencies;
  1625. };
  1626. // A worklist of declarations to import.
  1627. using ImportWorklist = llvm::SmallVector<ImportItem>;
  1628. } // namespace
  1629. // Adds the given declaration to our list of declarations to import.
  1630. static auto AddDependentDecl(Context& context, SemIR::ClangDeclKey decl,
  1631. ImportWorklist& worklist) -> void {
  1632. if (!IsClangDeclImported(context, decl)) {
  1633. worklist.push_back({.decl_key = decl, .added_dependencies = false});
  1634. }
  1635. }
  1636. // Finds all decls that need to be imported before importing the given type and
  1637. // adds them to the given set.
  1638. static auto AddDependentUnimportedTypeDecls(Context& context,
  1639. clang::QualType type,
  1640. ImportWorklist& worklist) -> void {
  1641. while (true) {
  1642. if (type->isPointerType() || type->isReferenceType()) {
  1643. type = type->getPointeeType();
  1644. } else if (const clang::ArrayType* array_type =
  1645. type->getAsArrayTypeUnsafe()) {
  1646. type = array_type->getElementType();
  1647. } else {
  1648. break;
  1649. }
  1650. }
  1651. if (const auto* tag_type = type->getAs<clang::TagType>()) {
  1652. AddDependentDecl(context, SemIR::ClangDeclKey(tag_type->getDecl()),
  1653. worklist);
  1654. }
  1655. }
  1656. // Finds all decls that need to be imported before importing the given function
  1657. // and adds them to the given set.
  1658. static auto AddDependentUnimportedFunctionDecls(
  1659. Context& context, const clang::FunctionDecl& clang_decl,
  1660. SemIR::ClangDeclKey::Signature signature, ImportWorklist& worklist)
  1661. -> void {
  1662. const auto* function_type =
  1663. clang_decl.getType()->castAs<clang::FunctionProtoType>();
  1664. for (int i : llvm::seq(clang_decl.hasCXXExplicitFunctionObjectParameter() +
  1665. signature.num_params)) {
  1666. AddDependentUnimportedTypeDecls(context, function_type->getParamType(i),
  1667. worklist);
  1668. }
  1669. AddDependentUnimportedTypeDecls(context, clang_decl.getReturnType(),
  1670. worklist);
  1671. }
  1672. // Finds all decls that need to be imported before importing the given
  1673. // declaration and adds them to the given set.
  1674. static auto AddDependentUnimportedDecls(Context& context,
  1675. SemIR::ClangDeclKey key,
  1676. ImportWorklist& worklist) -> void {
  1677. clang::Decl* clang_decl = key.decl;
  1678. if (auto* clang_function_decl = clang_decl->getAsFunction()) {
  1679. AddDependentUnimportedFunctionDecls(context, *clang_function_decl,
  1680. key.signature, worklist);
  1681. } else if (auto* type_decl = dyn_cast<clang::TypeDecl>(clang_decl)) {
  1682. if (!isa<clang::TagDecl>(clang_decl)) {
  1683. AddDependentUnimportedTypeDecls(
  1684. context, type_decl->getASTContext().getTypeDeclType(type_decl),
  1685. worklist);
  1686. }
  1687. } else if (auto* var_decl = dyn_cast<clang::VarDecl>(clang_decl)) {
  1688. AddDependentUnimportedTypeDecls(context, var_decl->getType(), worklist);
  1689. }
  1690. auto* parent = GetParentDecl(clang_decl);
  1691. if (llvm::isa_and_nonnull<clang::TagDecl, clang::NamespaceDecl,
  1692. clang::TranslationUnitDecl>(parent)) {
  1693. AddDependentDecl(context, SemIR::ClangDeclKey::ForNonFunctionDecl(parent),
  1694. worklist);
  1695. }
  1696. }
  1697. static auto ImportVarDecl(Context& context, SemIR::LocId loc_id,
  1698. clang::VarDecl* var_decl) -> SemIR::InstId {
  1699. if (SemIR::InstId existing_inst_id =
  1700. LookupClangDeclInstId(context, SemIR::ClangDeclKey(var_decl));
  1701. existing_inst_id.has_value()) {
  1702. return existing_inst_id;
  1703. }
  1704. // Extract type and name.
  1705. clang::QualType var_type = var_decl->getType();
  1706. SemIR::TypeId var_type_id = MapType(context, loc_id, var_type).type_id;
  1707. if (!var_type_id.has_value()) {
  1708. context.TODO(loc_id, llvm::formatv("Unsupported: var type: {0}",
  1709. var_type.getAsString()));
  1710. return SemIR::ErrorInst::InstId;
  1711. }
  1712. SemIR::NameId var_name_id = AddIdentifierName(context, var_decl->getName());
  1713. // Create an entity name to identify this variable.
  1714. SemIR::EntityNameId entity_name_id = context.entity_names().Add(
  1715. {.name_id = var_name_id,
  1716. .parent_scope_id = GetParentNameScopeId(context, var_decl),
  1717. .is_unused = false});
  1718. // Create `RefBindingPattern` and `VarPattern`. Mirror the behavior of
  1719. // import_ref and don't create a `NameBindingDecl` here; we'd never use it for
  1720. // anything.
  1721. SemIR::TypeId pattern_type_id = GetPatternType(context, var_type_id);
  1722. SemIR::InstId binding_pattern_inst_id =
  1723. AddInstInNoBlock<SemIR::RefBindingPattern>(
  1724. context, loc_id,
  1725. {.type_id = pattern_type_id, .entity_name_id = entity_name_id});
  1726. context.imports().push_back(binding_pattern_inst_id);
  1727. auto pattern_id = AddInstInNoBlock<SemIR::VarPattern>(
  1728. context, Parse::VariablePatternId::None,
  1729. {.type_id = pattern_type_id, .subpattern_id = binding_pattern_inst_id});
  1730. context.imports().push_back(pattern_id);
  1731. // Create the imported storage for the global. We intentionally use the
  1732. // untyped form of `AddInstInNoBlock` to bypass the check on adding an
  1733. // instruction that requires a cleanup, because we don't want a cleanup here!
  1734. SemIR::InstId var_storage_inst_id = AddInstInNoBlock(
  1735. context, {loc_id, SemIR::VarStorage{.type_id = var_type_id,
  1736. .pattern_id = pattern_id}});
  1737. context.imports().push_back(var_storage_inst_id);
  1738. // Register the variable so we don't create it again, and track the
  1739. // corresponding declaration to use for mangling.
  1740. auto clang_decl_id = context.clang_decls().Add(
  1741. {.key = SemIR::ClangDeclKey(var_decl), .inst_id = var_storage_inst_id});
  1742. context.cpp_global_names().Add({.key = {.entity_name_id = entity_name_id},
  1743. .clang_decl_id = clang_decl_id});
  1744. // Inform Clang that the variable has been referenced.
  1745. context.clang_sema().MarkVariableReferenced(GetCppLocation(context, loc_id),
  1746. var_decl);
  1747. return var_storage_inst_id;
  1748. }
  1749. static auto ImportTemplateDecl(Context& context,
  1750. clang::TemplateDecl* template_decl)
  1751. -> SemIR::InstId {
  1752. auto key = SemIR::ClangDeclKey(template_decl);
  1753. // TODO: Avoid doing this lookup both here and in the insertion below.
  1754. if (SemIR::InstId existing_inst_id = LookupClangDeclInstId(context, key);
  1755. existing_inst_id.has_value()) {
  1756. return existing_inst_id;
  1757. }
  1758. // Add a placeholder instruction to resolve cycle between the clang
  1759. // declaration and the type.
  1760. auto import_loc_id =
  1761. AddImportIRInst(context.sem_ir(), template_decl->getLocation());
  1762. SemIR::StructValue value = {.type_id = SemIR::TypeId::None,
  1763. .elements_id = SemIR::InstBlockId::Empty};
  1764. auto inst_id = AddPlaceholderImportedInstInNoBlock(
  1765. context, SemIR::LocIdAndInst::RuntimeVerified(context.sem_ir(),
  1766. import_loc_id, value));
  1767. // Create a type for the constant value.
  1768. auto name_id = context.entity_names().Add(
  1769. {.name_id = AddIdentifierName(context, template_decl->getName()),
  1770. .parent_scope_id = GetParentNameScopeId(context, template_decl)});
  1771. auto decl_id = context.clang_decls().Add({.key = key, .inst_id = inst_id});
  1772. value.type_id = GetCppTemplateNameType(context, name_id, decl_id);
  1773. // Update the value with its type.
  1774. ReplaceInstBeforeConstantUse(context, inst_id, value);
  1775. return inst_id;
  1776. }
  1777. // Imports a declaration from Clang to Carbon. Returns the instruction for the
  1778. // new Carbon declaration, which will be an ErrorInst on failure. Assumes all
  1779. // dependencies have already been imported.
  1780. static auto ImportDeclAfterDependencies(Context& context, SemIR::LocId loc_id,
  1781. SemIR::ClangDeclKey key)
  1782. -> SemIR::InstId {
  1783. clang::Decl* clang_decl = key.decl;
  1784. if (auto* clang_function_decl = clang_decl->getAsFunction()) {
  1785. return ImportFunctionDecl(context, loc_id, clang_function_decl,
  1786. key.signature);
  1787. }
  1788. if (auto* clang_namespace_decl = dyn_cast<clang::NamespaceDecl>(clang_decl)) {
  1789. return ImportNamespaceDecl(context, clang_namespace_decl);
  1790. }
  1791. if (auto* type_decl = dyn_cast<clang::TypeDecl>(clang_decl)) {
  1792. auto type = clang_decl->getASTContext().getTypeDeclType(type_decl);
  1793. auto type_inst_id = MapType(context, loc_id, type).inst_id;
  1794. if (!type_inst_id.has_value()) {
  1795. context.TODO(AddImportIRInst(context.sem_ir(), type_decl->getLocation()),
  1796. llvm::formatv("Unsupported: Type declaration: {0}",
  1797. type.getAsString()));
  1798. return SemIR::ErrorInst::InstId;
  1799. }
  1800. context.clang_decls().Add({.key = key, .inst_id = type_inst_id});
  1801. return type_inst_id;
  1802. }
  1803. if (isa<clang::FieldDecl, clang::IndirectFieldDecl>(clang_decl)) {
  1804. // Usable fields get imported as a side effect of importing the class.
  1805. if (SemIR::InstId existing_inst_id = LookupClangDeclInstId(context, key);
  1806. existing_inst_id.has_value()) {
  1807. return existing_inst_id;
  1808. }
  1809. context.TODO(AddImportIRInst(context.sem_ir(), clang_decl->getLocation()),
  1810. "Unsupported: field declaration has unhandled type or kind");
  1811. return SemIR::ErrorInst::InstId;
  1812. }
  1813. if (auto* enum_const_decl = dyn_cast<clang::EnumConstantDecl>(clang_decl)) {
  1814. return ImportEnumConstantDecl(context, enum_const_decl);
  1815. }
  1816. if (auto* var_decl = dyn_cast<clang::VarDecl>(clang_decl)) {
  1817. return ImportVarDecl(context, loc_id, var_decl);
  1818. }
  1819. if (auto* template_decl = dyn_cast<clang::TemplateDecl>(clang_decl)) {
  1820. return ImportTemplateDecl(context, template_decl);
  1821. }
  1822. context.TODO(AddImportIRInst(context.sem_ir(), clang_decl->getLocation()),
  1823. llvm::formatv("Unsupported: Declaration type {0}",
  1824. clang_decl->getDeclKindName()));
  1825. return SemIR::ErrorInst::InstId;
  1826. }
  1827. // Attempts to import a set of declarations. Returns `false` if an error was
  1828. // produced, `true` otherwise.
  1829. static auto ImportDeclSet(Context& context, SemIR::LocId loc_id,
  1830. ImportWorklist& worklist) -> bool {
  1831. // Walk the dependency graph in depth-first order, and import declarations
  1832. // once we've imported all of their dependencies.
  1833. while (!worklist.empty()) {
  1834. auto& item = worklist.back();
  1835. if (!item.added_dependencies) {
  1836. // Skip items we've already imported. We checked this when initially
  1837. // adding the item to the worklist, but it might have been added to the
  1838. // worklist twice before the first time we visited it. For example, this
  1839. // happens for `fn F(a: Cpp.T, b: Cpp.T)`.
  1840. if (IsClangDeclImported(context, item.decl_key)) {
  1841. worklist.pop_back();
  1842. continue;
  1843. }
  1844. // First time visiting this declaration (preorder): add its dependencies
  1845. // to the work list.
  1846. item.added_dependencies = true;
  1847. AddDependentUnimportedDecls(context, item.decl_key, worklist);
  1848. } else {
  1849. // Second time visiting this declaration (postorder): its dependencies are
  1850. // already imported, so we can import it now.
  1851. auto decl_key = worklist.pop_back_val().decl_key;
  1852. auto inst_id = ImportDeclAfterDependencies(context, loc_id, decl_key);
  1853. CARBON_CHECK(inst_id.has_value());
  1854. if (inst_id == SemIR::ErrorInst::InstId) {
  1855. return false;
  1856. }
  1857. CARBON_CHECK(IsClangDeclImported(context, decl_key));
  1858. }
  1859. }
  1860. return true;
  1861. }
  1862. auto ImportCppDecl(Context& context, SemIR::LocId loc_id,
  1863. SemIR::ClangDeclKey key) -> SemIR::InstId {
  1864. // Collect dependencies by walking the dependency graph in depth-first order.
  1865. ImportWorklist worklist;
  1866. AddDependentDecl(context, key, worklist);
  1867. if (!ImportDeclSet(context, loc_id, worklist)) {
  1868. return SemIR::ErrorInst::InstId;
  1869. }
  1870. return LookupClangDeclInstId(context, key);
  1871. }
  1872. auto ImportCppType(Context& context, SemIR::LocId loc_id, clang::QualType type)
  1873. -> TypeExpr {
  1874. // Collect dependencies by walking the dependency graph in depth-first order.
  1875. ImportWorklist worklist;
  1876. AddDependentUnimportedTypeDecls(context, type, worklist);
  1877. if (!ImportDeclSet(context, loc_id, worklist)) {
  1878. return {.inst_id = SemIR::ErrorInst::TypeInstId,
  1879. .type_id = SemIR::ErrorInst::TypeId};
  1880. }
  1881. return MapType(context, loc_id, type);
  1882. }
  1883. // Imports a Clang declaration into Carbon and adds that name into the
  1884. // `NameScope`.
  1885. static auto ImportNameDeclIntoScope(Context& context, SemIR::LocId loc_id,
  1886. SemIR::NameScopeId scope_id,
  1887. SemIR::NameId name_id,
  1888. SemIR::ClangDeclKey key,
  1889. SemIR::AccessKind access_kind)
  1890. -> SemIR::ScopeLookupResult {
  1891. SemIR::InstId inst_id = ImportCppDecl(context, loc_id, key);
  1892. if (!inst_id.has_value()) {
  1893. return SemIR::ScopeLookupResult::MakeNotFound();
  1894. }
  1895. AddNameToScope(context, scope_id, name_id, access_kind, inst_id);
  1896. return SemIR::ScopeLookupResult::MakeWrappedLookupResult(inst_id,
  1897. access_kind);
  1898. }
  1899. // Returns true if the scope is the top `Cpp` scope.
  1900. static auto IsTopCppScope(Context& context, SemIR::NameScopeId scope_id)
  1901. -> bool {
  1902. const SemIR::NameScope& name_scope = context.name_scopes().Get(scope_id);
  1903. CARBON_CHECK(name_scope.is_cpp_scope());
  1904. return name_scope.parent_scope_id() == SemIR::NameScopeId::Package;
  1905. }
  1906. // For a builtin name like `Cpp.long`, returns the associated type.
  1907. static auto LookupBuiltinName(Context& context, SemIR::LocId loc_id,
  1908. SemIR::NameScopeId scope_id,
  1909. SemIR::NameId name_id) -> SemIR::InstId {
  1910. if (!IsTopCppScope(context, scope_id)) {
  1911. return SemIR::InstId::None;
  1912. }
  1913. auto name = context.names().GetAsStringIfIdentifier(name_id);
  1914. if (!name) {
  1915. return SemIR::InstId::None;
  1916. }
  1917. const clang::ASTContext& ast_context = context.ast_context();
  1918. // List of types based on
  1919. // https://github.com/carbon-language/carbon-lang/blob/trunk/proposals/p5448.md#details
  1920. auto builtin_type =
  1921. llvm::StringSwitch<clang::QualType>(*name)
  1922. .Case("signed_char", ast_context.SignedCharTy)
  1923. .Case("short", ast_context.ShortTy)
  1924. .Case("int", ast_context.IntTy)
  1925. .Case("long", ast_context.LongTy)
  1926. .Case("long_long", ast_context.LongLongTy)
  1927. .Case("unsigned_char", ast_context.UnsignedCharTy)
  1928. .Case("unsigned_short", ast_context.UnsignedShortTy)
  1929. .Case("unsigned_int", ast_context.UnsignedIntTy)
  1930. .Case("unsigned_long", ast_context.UnsignedLongTy)
  1931. .Case("unsigned_long_long", ast_context.UnsignedLongLongTy)
  1932. .Case("float", ast_context.FloatTy)
  1933. .Case("double", ast_context.DoubleTy)
  1934. .Case("long_double", ast_context.LongDoubleTy)
  1935. .Case("void", ast_context.VoidTy)
  1936. .Default(clang::QualType());
  1937. if (builtin_type.isNull()) {
  1938. if (*name == "nullptr") {
  1939. // Map `Cpp.nullptr` to an uninitialized value of type `Core.CppNullptrT`.
  1940. auto type_id = MapNullptrType(context, loc_id).type_id;
  1941. return GetOrAddInst<SemIR::UninitializedValue>(
  1942. context, SemIR::LocId::None, {.type_id = type_id});
  1943. }
  1944. return SemIR::InstId::None;
  1945. }
  1946. SemIR::InstId inst_id =
  1947. MapNonWrapperType(context, loc_id, builtin_type).inst_id;
  1948. if (!inst_id.has_value()) {
  1949. context.TODO(loc_id, llvm::formatv("Unsupported: builtin type: {0}",
  1950. builtin_type.getAsString()));
  1951. return SemIR::ErrorInst::InstId;
  1952. }
  1953. return inst_id;
  1954. }
  1955. auto ImportCppOverloadSet(
  1956. Context& context, SemIR::LocId loc_id, SemIR::NameScopeId scope_id,
  1957. SemIR::NameId name_id, clang::CXXRecordDecl* naming_class,
  1958. clang::UnresolvedSet<4>&& overload_set,
  1959. clang::OverloadCandidateSet::OperatorRewriteInfo operator_rewrite_info)
  1960. -> SemIR::InstId {
  1961. SemIR::CppOverloadSetId overload_set_id = context.cpp_overload_sets().Add(
  1962. SemIR::CppOverloadSet{.name_id = name_id,
  1963. .parent_scope_id = scope_id,
  1964. .naming_class = naming_class,
  1965. .candidate_functions = std::move(overload_set),
  1966. .operator_rewrite_info = operator_rewrite_info});
  1967. auto overload_set_inst_id = AddInstInNoBlock<SemIR::CppOverloadSetValue>(
  1968. context, loc_id,
  1969. {.type_id = GetCppOverloadSetType(context, overload_set_id,
  1970. SemIR::SpecificId::None),
  1971. .overload_set_id = overload_set_id});
  1972. context.imports().push_back(overload_set_inst_id);
  1973. return overload_set_inst_id;
  1974. }
  1975. // Gets the best access for an overloaded function set. This is the access that
  1976. // we use for the overload set as a whole. More fine-grained checking is done
  1977. // after overload resolution.
  1978. static auto GetOverloadSetAccess(const clang::UnresolvedSet<4>& overload_set)
  1979. -> SemIR::AccessKind {
  1980. SemIR::AccessKind access_kind = SemIR::AccessKind::Private;
  1981. for (clang::DeclAccessPair overload : overload_set.pairs()) {
  1982. access_kind = std::min(access_kind, MapCppAccess(overload));
  1983. if (access_kind == SemIR::AccessKind::Public) {
  1984. break;
  1985. }
  1986. }
  1987. return access_kind;
  1988. }
  1989. // Imports an overload set from Clang to Carbon and adds the name into the
  1990. // `NameScope`.
  1991. static auto ImportOverloadSetIntoScope(Context& context, SemIR::LocId loc_id,
  1992. SemIR::NameScopeId scope_id,
  1993. SemIR::NameId name_id,
  1994. clang::CXXRecordDecl* naming_class,
  1995. clang::UnresolvedSet<4>&& overload_set)
  1996. -> SemIR::ScopeLookupResult {
  1997. SemIR::AccessKind access_kind = GetOverloadSetAccess(overload_set);
  1998. SemIR::InstId inst_id = ImportCppOverloadSet(
  1999. context, loc_id, scope_id, name_id, naming_class, std::move(overload_set),
  2000. /*operator_rewrite_info=*/{});
  2001. AddNameToScope(context, scope_id, name_id, access_kind, inst_id);
  2002. return SemIR::ScopeLookupResult::MakeWrappedLookupResult(inst_id,
  2003. access_kind);
  2004. }
  2005. // Imports the constructors for a given class name. The found constructors are
  2006. // imported as part of an overload set into the scope. Currently copy/move
  2007. // constructors are not imported.
  2008. static auto ImportConstructorsIntoScope(Context& context, SemIR::LocId loc_id,
  2009. SemIR::NameScopeId scope_id,
  2010. SemIR::NameId name_id)
  2011. -> SemIR::ScopeLookupResult {
  2012. auto* naming_class =
  2013. cast<clang::CXXRecordDecl>(GetDeclContext(context, scope_id));
  2014. clang::DeclContextLookupResult constructors_lookup =
  2015. context.clang_sema().LookupConstructors(naming_class);
  2016. clang::UnresolvedSet<4> overload_set;
  2017. for (auto* decl : constructors_lookup) {
  2018. auto info = clang::getConstructorInfo(decl);
  2019. if (!info.Constructor || info.Constructor->isCopyOrMoveConstructor()) {
  2020. continue;
  2021. }
  2022. overload_set.addDecl(info.FoundDecl, info.FoundDecl.getAccess());
  2023. }
  2024. if (overload_set.empty()) {
  2025. return SemIR::ScopeLookupResult::MakeNotFound();
  2026. }
  2027. return ImportOverloadSetIntoScope(context, loc_id, scope_id, name_id,
  2028. naming_class, std::move(overload_set));
  2029. }
  2030. // Attempts to import a builtin name from Clang to Carbon and adds the name into
  2031. // the scope.
  2032. static auto ImportBuiltinNameIntoScope(Context& context, SemIR::LocId loc_id,
  2033. SemIR::NameScopeId scope_id,
  2034. SemIR::NameId name_id)
  2035. -> SemIR::ScopeLookupResult {
  2036. SemIR::InstId builtin_inst_id =
  2037. LookupBuiltinName(context, loc_id, scope_id, name_id);
  2038. if (builtin_inst_id.has_value()) {
  2039. AddNameToScope(context, scope_id, name_id, SemIR::AccessKind::Public,
  2040. builtin_inst_id);
  2041. return SemIR::ScopeLookupResult::MakeWrappedLookupResult(
  2042. builtin_inst_id, SemIR::AccessKind::Public);
  2043. }
  2044. return SemIR::ScopeLookupResult::MakeNotFound();
  2045. }
  2046. // Checks if the name scope is a class that is not complete.
  2047. static auto IsIncompleteClass(Context& context, SemIR::NameScopeId scope_id)
  2048. -> bool {
  2049. auto class_decl = context.insts().TryGetAs<SemIR::ClassDecl>(
  2050. context.name_scopes().Get(scope_id).inst_id());
  2051. return class_decl.has_value() &&
  2052. !context.types().IsComplete(
  2053. context.classes().Get(class_decl->class_id).self_type_id);
  2054. }
  2055. // Imports a macro definition into the scope. Currently supports only simple
  2056. // object-like macros that expand to a constant integer value.
  2057. // TODO: Add support for other macro types and non-integer literal values.
  2058. static auto ImportMacro(Context& context, SemIR::LocId loc_id,
  2059. SemIR::NameScopeId scope_id, SemIR::NameId name_id,
  2060. clang::MacroInfo* macro_info)
  2061. -> SemIR::ScopeLookupResult {
  2062. auto inst_id = TryEvaluateMacro(context, loc_id, name_id, macro_info);
  2063. if (inst_id == SemIR::ErrorInst::InstId) {
  2064. return SemIR::ScopeLookupResult::MakeNotFound();
  2065. }
  2066. AddNameToScope(context, scope_id, name_id, SemIR::AccessKind::Public,
  2067. inst_id);
  2068. return SemIR::ScopeLookupResult::MakeWrappedLookupResult(
  2069. inst_id, SemIR::AccessKind::Public);
  2070. }
  2071. // Looks up a macro definition in the top-level `Cpp` scope. Returns nullptr if
  2072. // the macro is not found or if it is a builtin macro, function-like macro or a
  2073. // macro used for header guards.
  2074. // TODO: Function-like and builtin macros are currently not supported and their
  2075. // support still needs to be clarified.
  2076. static auto LookupMacro(Context& context, SemIR::NameScopeId scope_id,
  2077. clang::IdentifierInfo* identifier_info)
  2078. -> clang::MacroInfo* {
  2079. if (!IsTopCppScope(context, scope_id)) {
  2080. return nullptr;
  2081. }
  2082. CARBON_CHECK(identifier_info, "Identifier info is empty");
  2083. clang::MacroInfo* macro_info =
  2084. context.clang_sema().getPreprocessor().getMacroInfo(identifier_info);
  2085. if (macro_info && !macro_info->isUsedForHeaderGuard() &&
  2086. !macro_info->isFunctionLike() && !macro_info->isBuiltinMacro()) {
  2087. return macro_info;
  2088. }
  2089. return nullptr;
  2090. }
  2091. auto GetClangIdentifierInfo(Context& context, SemIR::NameId name_id)
  2092. -> clang::IdentifierInfo* {
  2093. std::optional<llvm::StringRef> string_name =
  2094. context.names().GetAsStringIfIdentifier(name_id);
  2095. if (!string_name) {
  2096. return nullptr;
  2097. }
  2098. clang::IdentifierInfo* identifier_info =
  2099. context.clang_sema().getPreprocessor().getIdentifierInfo(*string_name);
  2100. return identifier_info;
  2101. }
  2102. auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
  2103. SemIR::NameScopeId scope_id, SemIR::NameId name_id)
  2104. -> SemIR::ScopeLookupResult {
  2105. Diagnostics::AnnotationScope annotate_diagnostics(
  2106. &context.emitter(), [&](auto& builder) {
  2107. CARBON_DIAGNOSTIC(InCppNameLookup, Note,
  2108. "in `Cpp` name lookup for `{0}`", SemIR::NameId);
  2109. builder.Note(loc_id, InCppNameLookup, name_id);
  2110. });
  2111. if (IsIncompleteClass(context, scope_id)) {
  2112. return SemIR::ScopeLookupResult::MakeError();
  2113. }
  2114. clang::IdentifierInfo* identifier_info =
  2115. GetClangIdentifierInfo(context, name_id);
  2116. if (!identifier_info) {
  2117. return SemIR::ScopeLookupResult::MakeNotFound();
  2118. }
  2119. if (clang::MacroInfo* macro_info =
  2120. LookupMacro(context, scope_id, identifier_info)) {
  2121. return ImportMacro(context, loc_id, scope_id, name_id, macro_info);
  2122. }
  2123. auto lookup = ClangLookupName(context, scope_id, identifier_info);
  2124. if (!lookup) {
  2125. return ImportBuiltinNameIntoScope(context, loc_id, scope_id, name_id);
  2126. }
  2127. // Access checks are performed separately by the Carbon name lookup logic.
  2128. lookup->suppressAccessDiagnostics();
  2129. if (lookup->isOverloadedResult() ||
  2130. (lookup->isSingleResult() &&
  2131. lookup->getFoundDecl()->isFunctionOrFunctionTemplate())) {
  2132. clang::UnresolvedSet<4> overload_set;
  2133. overload_set.append(lookup->begin(), lookup->end());
  2134. return ImportOverloadSetIntoScope(context, loc_id, scope_id, name_id,
  2135. lookup->getNamingClass(),
  2136. std::move(overload_set));
  2137. }
  2138. if (!lookup->isSingleResult()) {
  2139. // Clang will diagnose ambiguous lookup results for us.
  2140. if (!lookup->isAmbiguous()) {
  2141. context.TODO(loc_id,
  2142. llvm::formatv("Unsupported: Lookup succeeded but couldn't "
  2143. "find a single result; LookupResultKind: {0}",
  2144. static_cast<int>(lookup->getResultKind())));
  2145. }
  2146. context.name_scopes().AddRequiredName(scope_id, name_id,
  2147. SemIR::ErrorInst::InstId);
  2148. return SemIR::ScopeLookupResult::MakeError();
  2149. }
  2150. if (IsDeclInjectedClassName(context, scope_id, name_id,
  2151. lookup->getFoundDecl())) {
  2152. return ImportConstructorsIntoScope(context, loc_id, scope_id, name_id);
  2153. }
  2154. auto key = SemIR::ClangDeclKey::ForNonFunctionDecl(lookup->getFoundDecl());
  2155. return ImportNameDeclIntoScope(context, loc_id, scope_id, name_id, key,
  2156. MapCppAccess(lookup->begin().getPair()));
  2157. }
  2158. auto ImportClassDefinitionForClangDecl(Context& context,
  2159. SemIR::ClassId class_id,
  2160. SemIR::ClangDeclId clang_decl_id)
  2161. -> bool {
  2162. SemIR::CppFile* cpp_file = context.sem_ir().cpp_file();
  2163. CARBON_CHECK(cpp_file);
  2164. auto* clang_decl =
  2165. cast<clang::TagDecl>(context.clang_decls().Get(clang_decl_id).key.decl);
  2166. auto class_inst_id = context.types().GetAsTypeInstId(
  2167. context.classes().Get(class_id).first_owning_decl_id);
  2168. clang::SourceLocation loc = clang_decl->getLocation();
  2169. // Ask Clang whether the type is complete. This triggers template
  2170. // instantiation if necessary.
  2171. clang::DiagnosticErrorTrap trap(cpp_file->diagnostics());
  2172. if (!context.cpp_context()->sema().isCompleteType(
  2173. loc, context.ast_context().getCanonicalTagType(clang_decl))) {
  2174. // Type is incomplete. Nothing more to do, but tell the caller if we
  2175. // produced an error.
  2176. return !trap.hasErrorOccurred();
  2177. }
  2178. auto import_ir_inst_id =
  2179. context.insts().GetCanonicalLocId(class_inst_id).import_ir_inst_id();
  2180. if (auto* class_decl = dyn_cast<clang::CXXRecordDecl>(clang_decl)) {
  2181. auto* class_def = class_decl->getDefinition();
  2182. CARBON_CHECK(class_def, "Complete type has no definition");
  2183. BuildClassDefinition(context, import_ir_inst_id, class_id, class_inst_id,
  2184. class_def);
  2185. } else if (auto* enum_decl = dyn_cast<clang::EnumDecl>(clang_decl)) {
  2186. BuildEnumDefinition(context, import_ir_inst_id, class_id, class_inst_id,
  2187. enum_decl);
  2188. }
  2189. return true;
  2190. }
  2191. auto GetAsClangVarDecl(Context& context, SemIR::InstId inst_id)
  2192. -> clang::VarDecl* {
  2193. if (const auto& var_storage =
  2194. context.insts().TryGetAs<SemIR::VarStorage>(inst_id)) {
  2195. auto var_name_id = SemIR::GetFirstBindingNameFromPatternId(
  2196. context.sem_ir(), var_storage->pattern_id);
  2197. if (auto cpp_global_var_id = context.sem_ir().cpp_global_vars().Lookup(
  2198. {.entity_name_id = var_name_id});
  2199. cpp_global_var_id.has_value()) {
  2200. SemIR::ClangDeclId clang_decl_id = context.sem_ir()
  2201. .cpp_global_vars()
  2202. .Get(cpp_global_var_id)
  2203. .clang_decl_id;
  2204. return cast<clang::VarDecl>(
  2205. context.clang_decls().Get(clang_decl_id).key.decl);
  2206. }
  2207. }
  2208. return nullptr;
  2209. }
  2210. } // namespace Carbon::Check