mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:40:12 +01:00
Initial support for interop with class/struct/union fields. (#5849)
Add a new type, `custom_layout_type`, representing a struct type whose
size, alignment, and field offsets can be manually controlled. Use this
as the object representation type for imported C++ class types (which
also includes struct and union types), allowing us to model C++ class
type layouts. In passing, also add support for incomplete C++ class
types, mapping them into incomplete Carbon class types.
Map C++ fields into Carbon field declarations, allowing direct access to
C++ fields from Carbon. So far, no support is added for base classes nor
anonymous struct or union declarations; those will be added in
subsequent PRs. Also, we don't map C++ access control into Carbon yet,
so all C++ fields are accessible regardless of their access control.
For now we still use a `struct_type` as the object representation for
empty C++ classes, in order to continue to support our existing tests
that convert `{}` to empty C++ class types. This is temporary and should
be removed once we support interop with C++ class initialization.
This commit is contained in:
@@ -136,6 +136,7 @@ cc_library(
|
||||
"//toolchain/sem_ir:file",
|
||||
"//toolchain/sem_ir:formatter",
|
||||
"//toolchain/sem_ir:typed_insts",
|
||||
"@llvm-project//clang:ast",
|
||||
"@llvm-project//clang:basic",
|
||||
"@llvm-project//clang:frontend",
|
||||
"@llvm-project//clang:lex",
|
||||
|
||||
@@ -275,6 +275,9 @@ class Context {
|
||||
auto struct_type_fields() -> SemIR::StructTypeFieldsStore& {
|
||||
return sem_ir().struct_type_fields();
|
||||
}
|
||||
auto custom_layouts() -> SemIR::CustomLayoutStore& {
|
||||
return sem_ir().custom_layouts();
|
||||
}
|
||||
auto types() -> SemIR::TypeStore& { return sem_ir().types(); }
|
||||
// Instructions should be added with `AddInst` or `AddInstInNoBlock` from
|
||||
// `inst.h`. This is `const` to prevent accidental misuse.
|
||||
|
||||
@@ -574,6 +574,10 @@ static auto ConvertStructToClass(
|
||||
if (object_repr_id == SemIR::ErrorInst::TypeId) {
|
||||
return SemIR::ErrorInst::InstId;
|
||||
}
|
||||
if (context.types().Is<SemIR::CustomLayoutType>(object_repr_id)) {
|
||||
// Builtin conversion does not apply.
|
||||
return value_id;
|
||||
}
|
||||
auto dest_struct_type =
|
||||
context.types().GetAs<SemIR::StructType>(object_repr_id);
|
||||
|
||||
|
||||
@@ -700,4 +700,44 @@ auto ImportNameFromOtherPackage(
|
||||
return result_id;
|
||||
}
|
||||
|
||||
// Returns whether a parse node associated with an imported instruction of kind
|
||||
// `imported_kind` is usable as the location of a corresponding local
|
||||
// instruction of kind `local_kind`.
|
||||
static auto HasCompatibleImportedNodeKind(SemIR::InstKind imported_kind,
|
||||
SemIR::InstKind local_kind) -> bool {
|
||||
if (imported_kind == local_kind) {
|
||||
return true;
|
||||
}
|
||||
if (imported_kind == SemIR::ImportDecl::Kind &&
|
||||
local_kind == SemIR::Namespace::Kind) {
|
||||
static_assert(
|
||||
std::is_convertible_v<decltype(SemIR::ImportDecl::Kind)::TypedNodeId,
|
||||
decltype(SemIR::Namespace::Kind)::TypedNodeId>);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace Internal {
|
||||
|
||||
auto CheckCompatibleImportedNodeKind(Context& context,
|
||||
SemIR::ImportIRInstId imported_loc_id,
|
||||
SemIR::InstKind kind) -> void {
|
||||
auto& import_ir_inst = context.import_ir_insts().Get(imported_loc_id);
|
||||
if (import_ir_inst.ir_id() == SemIR::ImportIRId::Cpp) {
|
||||
// We don't require a matching node kind if the location is in C++, because
|
||||
// there isn't a node.
|
||||
return;
|
||||
}
|
||||
const auto* import_ir =
|
||||
context.import_irs().Get(import_ir_inst.ir_id()).sem_ir;
|
||||
auto imported_kind = import_ir->insts().Get(import_ir_inst.inst_id()).kind();
|
||||
CARBON_CHECK(
|
||||
HasCompatibleImportedNodeKind(imported_kind, kind),
|
||||
"Node of kind {0} created with location of imported node of kind {1}",
|
||||
kind, imported_kind);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
@@ -93,6 +93,30 @@ auto ImportNameFromOtherPackage(
|
||||
import_ir_scopes,
|
||||
SemIR::NameId name_id) -> SemIR::InstId;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
// Checks that the provided imported location has a node kind that is
|
||||
// compatible with that of the given instruction.
|
||||
auto CheckCompatibleImportedNodeKind(Context& context,
|
||||
SemIR::ImportIRInstId imported_loc_id,
|
||||
SemIR::InstKind kind) -> void;
|
||||
} // namespace Internal
|
||||
|
||||
// Returns a LocIdAndInst for an instruction with an imported location. Checks
|
||||
// that the imported location is compatible with the kind of instruction being
|
||||
// created.
|
||||
template <typename InstT>
|
||||
requires SemIR::Internal::HasNodeId<InstT>
|
||||
auto MakeImportedLocIdAndInst(Context& context,
|
||||
SemIR::ImportIRInstId imported_loc_id, InstT inst)
|
||||
-> SemIR::LocIdAndInst {
|
||||
if constexpr (!SemIR::Internal::HasUntypedNodeId<InstT>) {
|
||||
Internal::CheckCompatibleImportedNodeKind(context, imported_loc_id,
|
||||
InstT::Kind);
|
||||
}
|
||||
return SemIR::LocIdAndInst::UncheckedLoc(imported_loc_id, inst);
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
#endif // CARBON_TOOLCHAIN_CHECK_IMPORT_H_
|
||||
|
||||
+194
-71
@@ -10,6 +10,8 @@
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
@@ -42,6 +44,7 @@
|
||||
#include "toolchain/parse/node_ids.h"
|
||||
#include "toolchain/sem_ir/clang_decl.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst.h"
|
||||
#include "toolchain/sem_ir/name_scope.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
|
||||
@@ -105,9 +108,9 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
|
||||
public:
|
||||
// Creates an instance with the location that triggers calling Clang.
|
||||
// `context` must not be null.
|
||||
explicit CarbonClangDiagnosticConsumer(Context* context,
|
||||
clang::CompilerInvocation* invocation)
|
||||
: context_(context), invocation_(invocation) {}
|
||||
explicit CarbonClangDiagnosticConsumer(
|
||||
Context* context, std::shared_ptr<clang::CompilerInvocation> invocation)
|
||||
: context_(context), invocation_(std::move(invocation)) {}
|
||||
|
||||
// Generates a Carbon warning for each Clang warning and a Carbon error for
|
||||
// each Clang error or fatal.
|
||||
@@ -185,7 +188,7 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
|
||||
Context* context_;
|
||||
|
||||
// The compiler invocation that is producing the diagnostics.
|
||||
clang::CompilerInvocation* invocation_;
|
||||
std::shared_ptr<clang::CompilerInvocation> invocation_;
|
||||
|
||||
// Information on a Clang diagnostic that can be converted to a Carbon
|
||||
// diagnostic.
|
||||
@@ -219,11 +222,11 @@ static auto GenerateAst(Context& context,
|
||||
std::shared_ptr<clang::CompilerInvocation> invocation)
|
||||
-> std::pair<std::unique_ptr<clang::ASTUnit>, bool> {
|
||||
// Build a diagnostics engine.
|
||||
CarbonClangDiagnosticConsumer diagnostics_consumer(&context,
|
||||
invocation.get());
|
||||
auto diagnostics_consumer =
|
||||
std::make_unique<CarbonClangDiagnosticConsumer>(&context, invocation);
|
||||
llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diags(
|
||||
clang::CompilerInstance::createDiagnostics(
|
||||
*fs, invocation->getDiagnosticOpts(), &diagnostics_consumer,
|
||||
*fs, invocation->getDiagnosticOpts(), diagnostics_consumer.get(),
|
||||
/*ShouldOwnClient=*/false));
|
||||
|
||||
// Extract the input from the frontend invocation and make sure it makes
|
||||
@@ -247,9 +250,6 @@ static auto GenerateAst(Context& context,
|
||||
invocation, std::make_shared<clang::PCHContainerOperations>(), nullptr,
|
||||
diags, new clang::FileManager(invocation->getFileSystemOpts(), fs));
|
||||
|
||||
// Remove link to the diagnostics consumer before its destruction.
|
||||
ast->getDiagnostics().setClient(nullptr);
|
||||
|
||||
// Remove remapped file before its underlying storage is destroyed.
|
||||
invocation->getPreprocessorOpts().clearRemappedFiles();
|
||||
|
||||
@@ -259,9 +259,15 @@ static auto GenerateAst(Context& context,
|
||||
context.sem_ir().set_cpp_ast(ast.get());
|
||||
|
||||
// Emit any diagnostics we queued up while building the AST.
|
||||
diagnostics_consumer.EmitDiagnostics();
|
||||
diagnostics_consumer->EmitDiagnostics();
|
||||
bool any_errors = diagnostics_consumer->getNumErrors() > 0;
|
||||
|
||||
return {std::move(ast), !ast || diagnostics_consumer.getNumErrors() > 0};
|
||||
// Transfer ownership of the consumer to the AST unit, in case more
|
||||
// diagnostics are produced by AST queries.
|
||||
ast->getDiagnostics().setClient(diagnostics_consumer.release(),
|
||||
/*ShouldOwnClient=*/true);
|
||||
|
||||
return {std::move(ast), !ast || any_errors};
|
||||
}
|
||||
|
||||
// Adds a namespace for the `Cpp` import and returns its `NameScopeId`.
|
||||
@@ -373,7 +379,10 @@ static auto ClangLookup(Context& context, SemIR::NameScopeId scope_id,
|
||||
// Returns whether `decl` already mapped to an instruction.
|
||||
static auto IsClangDeclImported(const Context& context, clang::Decl* decl)
|
||||
-> bool {
|
||||
return context.sem_ir().clang_decls().Lookup(decl).has_value();
|
||||
return context.sem_ir()
|
||||
.clang_decls()
|
||||
.Lookup(decl->getCanonicalDecl())
|
||||
.has_value();
|
||||
}
|
||||
|
||||
// If `decl` already mapped to an instruction, returns that instruction.
|
||||
@@ -381,7 +390,7 @@ static auto IsClangDeclImported(const Context& context, clang::Decl* decl)
|
||||
static auto LookupClangDeclInstId(const Context& context, clang::Decl* decl)
|
||||
-> SemIR::InstId {
|
||||
const auto& clang_decls = context.sem_ir().clang_decls();
|
||||
if (auto context_clang_decl_id = clang_decls.Lookup(decl);
|
||||
if (auto context_clang_decl_id = clang_decls.Lookup(decl->getCanonicalDecl());
|
||||
context_clang_decl_id.has_value()) {
|
||||
return clang_decls.Get(context_clang_decl_id).inst_id;
|
||||
}
|
||||
@@ -442,22 +451,27 @@ static auto ImportNamespaceDecl(Context& context,
|
||||
context.name_scopes()
|
||||
.Get(result.name_scope_id)
|
||||
.set_clang_decl_context_id(context.sem_ir().clang_decls().Add(
|
||||
{.decl = clang_decl, .inst_id = result.inst_id}));
|
||||
{.decl = clang_decl->getCanonicalDecl(), .inst_id = result.inst_id}));
|
||||
return result.inst_id;
|
||||
}
|
||||
|
||||
static auto MapType(Context& context, SemIR::LocId loc_id, clang::QualType type)
|
||||
-> TypeExpr;
|
||||
|
||||
// Creates a class declaration for the given class name in the given scope.
|
||||
// Returns the `InstId` for the declaration.
|
||||
static auto BuildClassDecl(Context& context, SemIR::NameScopeId parent_scope_id,
|
||||
static auto BuildClassDecl(Context& context,
|
||||
SemIR::ImportIRInstId import_ir_inst_id,
|
||||
SemIR::NameScopeId parent_scope_id,
|
||||
SemIR::NameId name_id)
|
||||
-> std::tuple<SemIR::ClassId, SemIR::InstId> {
|
||||
-> std::tuple<SemIR::ClassId, SemIR::TypeInstId> {
|
||||
// Add the class declaration.
|
||||
auto class_decl = SemIR::ClassDecl{.type_id = SemIR::TypeType::TypeId,
|
||||
.class_id = SemIR::ClassId::None,
|
||||
.decl_block_id = SemIR::InstBlockId::None};
|
||||
// TODO: Consider setting a proper location.
|
||||
auto class_decl_id = AddPlaceholderInstInNoBlock(
|
||||
context, SemIR::LocIdAndInst::NoLoc(class_decl));
|
||||
context,
|
||||
SemIR::LocIdAndInst::UncheckedLoc(import_ir_inst_id, class_decl));
|
||||
context.imports().push_back(class_decl_id);
|
||||
|
||||
SemIR::Class class_info = {
|
||||
@@ -486,76 +500,159 @@ static auto BuildClassDecl(Context& context, SemIR::NameScopeId parent_scope_id,
|
||||
|
||||
SetClassSelfType(context, class_decl.class_id);
|
||||
|
||||
return {class_decl.class_id, class_decl_id};
|
||||
return {class_decl.class_id, context.types().GetAsTypeInstId(class_decl_id)};
|
||||
}
|
||||
|
||||
// Checks that the specified finished class definition is valid and builds and
|
||||
// returns a corresponding complete type witness instruction.
|
||||
// TODO: Remove recursion into mapping field types.
|
||||
// NOLINTNEXTLINE(misc-no-recursion)
|
||||
static auto ImportClassObjectRepr(Context& context,
|
||||
SemIR::ImportIRInstId import_ir_inst_id,
|
||||
SemIR::TypeInstId class_type_inst_id,
|
||||
const clang::CXXRecordDecl* clang_def)
|
||||
-> SemIR::TypeInstId {
|
||||
// For now, if the class is empty, produce an empty struct as the object
|
||||
// representation. This allows our tests to continue to pass while we don't
|
||||
// properly support initializing imported C++ classes.
|
||||
// TODO: Remove this.
|
||||
if (clang_def->isEmpty()) {
|
||||
return context.types().GetAsTypeInstId(AddInst(
|
||||
context,
|
||||
MakeImportedLocIdAndInst(
|
||||
context, import_ir_inst_id,
|
||||
SemIR::StructType{.type_id = SemIR::TypeType::TypeId,
|
||||
.fields_id = SemIR::StructTypeFieldsId::Empty})));
|
||||
}
|
||||
|
||||
const auto& clang_layout =
|
||||
context.ast_context().getASTRecordLayout(clang_def);
|
||||
|
||||
llvm::SmallVector<uint64_t> layout;
|
||||
llvm::SmallVector<SemIR::StructTypeField> fields;
|
||||
|
||||
static_assert(SemIR::CustomLayoutId::SizeIndex == 0);
|
||||
layout.push_back(clang_layout.getSize().getQuantity());
|
||||
|
||||
static_assert(SemIR::CustomLayoutId::AlignIndex == 1);
|
||||
layout.push_back(clang_layout.getAlignment().getQuantity());
|
||||
|
||||
static_assert(SemIR::CustomLayoutId::FirstFieldIndex == 2);
|
||||
|
||||
// TODO: Import vptr(s).
|
||||
// TODO: Import bases.
|
||||
|
||||
// Import fields.
|
||||
for (auto* field : clang_def->fields()) {
|
||||
if (field->isBitField()) {
|
||||
// TODO: Add a representation for named bitfield members.
|
||||
continue;
|
||||
}
|
||||
if (field->isAnonymousStructOrUnion()) {
|
||||
// TODO: Visit IndirectFieldDecls and add them to the layout.
|
||||
continue;
|
||||
}
|
||||
|
||||
auto field_name_id = AddIdentifierName(context, field->getName());
|
||||
auto [field_type_inst_id, field_type_id] =
|
||||
MapType(context, import_ir_inst_id, field->getType());
|
||||
|
||||
// Create a field now, as we know the index to use.
|
||||
// TODO: Consider doing this lazily instead.
|
||||
auto field_decl_id = AddInst(
|
||||
context, MakeImportedLocIdAndInst(
|
||||
context, import_ir_inst_id,
|
||||
SemIR::FieldDecl{
|
||||
.type_id = GetUnboundElementType(
|
||||
context, class_type_inst_id, field_type_inst_id),
|
||||
.name_id = field_name_id,
|
||||
.index = SemIR::ElementIndex(fields.size())}));
|
||||
context.sem_ir().clang_decls().Add(
|
||||
{.decl = field->getCanonicalDecl(), .inst_id = field_decl_id});
|
||||
|
||||
layout.push_back(context.ast_context()
|
||||
.toCharUnitsFromBits(clang_layout.getFieldOffset(
|
||||
field->getFieldIndex()))
|
||||
.getQuantity());
|
||||
fields.push_back(
|
||||
{.name_id = field_name_id, .type_inst_id = field_type_inst_id});
|
||||
}
|
||||
|
||||
// TODO: Add a field to prevent tail padding reuse if necessary.
|
||||
|
||||
return AddTypeInst<SemIR::CustomLayoutType>(
|
||||
context, import_ir_inst_id,
|
||||
{.type_id = SemIR::TypeType::TypeId,
|
||||
.fields_id = context.struct_type_fields().Add(fields),
|
||||
.layout_id = context.custom_layouts().Add(layout)});
|
||||
}
|
||||
|
||||
// Creates a class definition based on the information in the given Clang
|
||||
// declaration, which is assumed to be for a class definition. Returns the new
|
||||
// class id and instruction id.
|
||||
// declaration, which is assumed to be for a class definition.
|
||||
// TODO: Remove recursion into mapping field types.
|
||||
// NOLINTNEXTLINE(misc-no-recursion)
|
||||
static auto BuildClassDefinition(Context& context,
|
||||
clang::CXXRecordDecl* clang_decl)
|
||||
-> std::tuple<SemIR::ClassId, SemIR::InstId> {
|
||||
auto [class_id, class_inst_id] =
|
||||
BuildClassDecl(context, GetParentNameScopeId(context, clang_decl),
|
||||
AddIdentifierName(context, clang_decl->getName()));
|
||||
SemIR::ImportIRInstId import_ir_inst_id,
|
||||
SemIR::ClassId class_id,
|
||||
SemIR::TypeInstId class_inst_id,
|
||||
SemIR::ClangDeclId clang_decl_id,
|
||||
clang::CXXRecordDecl* clang_def) -> void {
|
||||
auto& class_info = context.classes().Get(class_id);
|
||||
StartClassDefinition(context, class_info, class_inst_id);
|
||||
|
||||
// Name lookup into the Carbon class looks in the C++ class definition.
|
||||
context.name_scopes()
|
||||
.Get(class_info.scope_id)
|
||||
.set_clang_decl_context_id(context.sem_ir().clang_decls().Add(
|
||||
{.decl = clang_decl, .inst_id = class_inst_id}));
|
||||
.set_clang_decl_context_id(clang_decl_id);
|
||||
|
||||
return {class_id, class_inst_id};
|
||||
context.inst_block_stack().Push();
|
||||
|
||||
// Compute the class's object representation.
|
||||
auto object_repr_id = ImportClassObjectRepr(context, import_ir_inst_id,
|
||||
class_inst_id, clang_def);
|
||||
class_info.complete_type_witness_id = AddInst<SemIR::CompleteTypeWitness>(
|
||||
context, import_ir_inst_id,
|
||||
{.type_id = GetSingletonType(context, SemIR::WitnessType::TypeInstId),
|
||||
.object_repr_type_inst_id = object_repr_id});
|
||||
|
||||
class_info.body_block_id = context.inst_block_stack().Pop();
|
||||
}
|
||||
|
||||
// Mark the given `Decl` as failed in `clang_decls`.
|
||||
static auto MarkFailedDecl(Context& context, clang::Decl* clang_decl) {
|
||||
context.sem_ir().clang_decls().Add(
|
||||
{.decl = clang_decl, .inst_id = SemIR::ErrorInst::InstId});
|
||||
context.sem_ir().clang_decls().Add({.decl = clang_decl->getCanonicalDecl(),
|
||||
.inst_id = SemIR::ErrorInst::InstId});
|
||||
}
|
||||
|
||||
// Imports a record declaration from Clang to Carbon. If successful, returns
|
||||
// the new Carbon class declaration `InstId`.
|
||||
// TODO: Change `clang_decl` to `const &` when lookup is using `clang::DeclID`
|
||||
// and we don't need to store the decl for lookup context.
|
||||
static auto ImportCXXRecordDecl(Context& context, SemIR::LocId loc_id,
|
||||
// TODO: Remove recursion into mapping field types.
|
||||
// NOLINTNEXTLINE(misc-no-recursion)
|
||||
static auto ImportCXXRecordDecl(Context& context,
|
||||
clang::CXXRecordDecl* clang_decl)
|
||||
-> SemIR::InstId {
|
||||
clang::CXXRecordDecl* clang_def = clang_decl->getDefinition();
|
||||
if (!clang_def) {
|
||||
context.TODO(loc_id,
|
||||
"Unsupported: Record declarations without a definition");
|
||||
MarkFailedDecl(context, clang_decl);
|
||||
return SemIR::ErrorInst::InstId;
|
||||
if (clang_def) {
|
||||
clang_decl = clang_def;
|
||||
}
|
||||
auto import_ir_inst_id = AddImportIRInst(context, clang_decl->getLocation());
|
||||
|
||||
auto [class_id, class_inst_id] = BuildClassDecl(
|
||||
context, import_ir_inst_id, GetParentNameScopeId(context, clang_decl),
|
||||
AddIdentifierName(context, clang_decl->getName()));
|
||||
|
||||
// TODO: The caller does the same lookup. Avoid doing it twice.
|
||||
auto clang_decl_id = context.sem_ir().clang_decls().Add(
|
||||
{.decl = clang_decl->getCanonicalDecl(), .inst_id = class_inst_id});
|
||||
|
||||
if (clang_def) {
|
||||
BuildClassDefinition(context, import_ir_inst_id, class_id, class_inst_id,
|
||||
clang_decl_id, clang_def);
|
||||
}
|
||||
|
||||
if (clang_def->isDynamicClass()) {
|
||||
context.TODO(loc_id, "Unsupported: Dynamic Class");
|
||||
MarkFailedDecl(context, clang_decl);
|
||||
return SemIR::ErrorInst::InstId;
|
||||
}
|
||||
|
||||
if (clang_def->isUnion() && !clang_def->fields().empty()) {
|
||||
context.TODO(loc_id, "Unsupported: Non-empty union");
|
||||
MarkFailedDecl(context, clang_decl);
|
||||
return SemIR::ErrorInst::InstId;
|
||||
}
|
||||
|
||||
auto [class_id, class_def_id] = BuildClassDefinition(context, clang_def);
|
||||
|
||||
// The class type is now fully defined. Compute its object representation.
|
||||
ComputeClassObjectRepr(context,
|
||||
// TODO: Consider having a proper location here.
|
||||
Parse::ClassDefinitionId::None, class_id,
|
||||
// TODO: Set fields.
|
||||
/*field_decls=*/{},
|
||||
// TODO: Set vtable.
|
||||
/*vtable_contents=*/{},
|
||||
// TODO: Set block.
|
||||
/*body=*/{});
|
||||
|
||||
return class_def_id;
|
||||
return class_inst_id;
|
||||
}
|
||||
|
||||
// Creates an integer type of the given size.
|
||||
@@ -587,8 +684,10 @@ static auto MapBuiltinType(Context& context, clang::QualType qual_type,
|
||||
|
||||
// Maps a C++ record type to a Carbon type.
|
||||
// TODO: Support more record types.
|
||||
static auto MapRecordType(Context& context, SemIR::LocId loc_id,
|
||||
const clang::RecordType& type) -> TypeExpr {
|
||||
// TODO: Remove recursion mapping fields of class types.
|
||||
// NOLINTNEXTLINE(misc-no-recursion)
|
||||
static auto MapRecordType(Context& context, const clang::RecordType& type)
|
||||
-> TypeExpr {
|
||||
auto* record_decl = clang::dyn_cast<clang::CXXRecordDecl>(type.getDecl());
|
||||
if (!record_decl) {
|
||||
return {.inst_id = SemIR::TypeInstId::None, .type_id = SemIR::TypeId::None};
|
||||
@@ -597,7 +696,7 @@ static auto MapRecordType(Context& context, SemIR::LocId loc_id,
|
||||
// Check if the declaration is already mapped.
|
||||
SemIR::InstId record_inst_id = LookupClangDeclInstId(context, record_decl);
|
||||
if (!record_inst_id.has_value()) {
|
||||
record_inst_id = ImportCXXRecordDecl(context, loc_id, record_decl);
|
||||
record_inst_id = ImportCXXRecordDecl(context, record_decl);
|
||||
}
|
||||
SemIR::TypeInstId record_type_inst_id =
|
||||
context.types().GetAsTypeInstId(record_inst_id);
|
||||
@@ -609,14 +708,16 @@ static auto MapRecordType(Context& context, SemIR::LocId loc_id,
|
||||
// Maps a C++ type that is not a wrapper type such as a pointer to a Carbon
|
||||
// type.
|
||||
// TODO: Support more types.
|
||||
static auto MapNonWrapperType(Context& context, SemIR::LocId loc_id,
|
||||
clang::QualType type) -> TypeExpr {
|
||||
// TODO: Remove recursion mapping fields of class types.
|
||||
// NOLINTNEXTLINE(misc-no-recursion)
|
||||
static auto MapNonWrapperType(Context& context, clang::QualType type)
|
||||
-> TypeExpr {
|
||||
if (const auto* builtin_type = type->getAs<clang::BuiltinType>()) {
|
||||
return MapBuiltinType(context, type, *builtin_type);
|
||||
}
|
||||
|
||||
if (const auto* record_type = type->getAs<clang::RecordType>()) {
|
||||
return MapRecordType(context, loc_id, *record_type);
|
||||
return MapRecordType(context, *record_type);
|
||||
}
|
||||
|
||||
CARBON_CHECK(!type.hasQualifiers() && !type->isPointerType(),
|
||||
@@ -673,6 +774,8 @@ static auto MapPointerType(Context& context, SemIR::LocId loc_id,
|
||||
// Maps a C++ type to a Carbon type. `type` should not be canonicalized because
|
||||
// we check for pointer nullability and nullability will be lost by
|
||||
// canonicalization.
|
||||
// TODO: Remove recursion mapping fields of class types.
|
||||
// NOLINTNEXTLINE(misc-no-recursion)
|
||||
static auto MapType(Context& context, SemIR::LocId loc_id, clang::QualType type)
|
||||
-> TypeExpr {
|
||||
// Unwrap any type modifiers and wrappers.
|
||||
@@ -689,7 +792,7 @@ static auto MapType(Context& context, SemIR::LocId loc_id, clang::QualType type)
|
||||
wrapper_types.push_back(orig_type);
|
||||
}
|
||||
|
||||
auto mapped = MapNonWrapperType(context, loc_id, type);
|
||||
auto mapped = MapNonWrapperType(context, type);
|
||||
|
||||
for (auto wrapper : llvm::reverse(wrapper_types)) {
|
||||
if (!mapped.inst_id.has_value() ||
|
||||
@@ -961,6 +1064,7 @@ static auto ImportFunctionDecl(Context& context, SemIR::LocId loc_id,
|
||||
MarkFailedDecl(context, clang_decl);
|
||||
return SemIR::ErrorInst::InstId;
|
||||
}
|
||||
|
||||
if (clang_decl->getTemplatedKind() ==
|
||||
clang::FunctionDecl::TK_FunctionTemplate) {
|
||||
context.TODO(loc_id, "Unsupported: Template function");
|
||||
@@ -968,6 +1072,14 @@ static auto ImportFunctionDecl(Context& context, SemIR::LocId loc_id,
|
||||
return SemIR::ErrorInst::InstId;
|
||||
}
|
||||
|
||||
if (auto* method_decl = dyn_cast<clang::CXXMethodDecl>(clang_decl)) {
|
||||
if (method_decl->isVirtual()) {
|
||||
context.TODO(loc_id, "Unsupported: Virtual function");
|
||||
MarkFailedDecl(context, clang_decl);
|
||||
return SemIR::ErrorInst::InstId;
|
||||
}
|
||||
}
|
||||
|
||||
context.scope_stack().PushForDeclName();
|
||||
context.inst_block_stack().Push();
|
||||
context.pattern_block_stack().Push();
|
||||
@@ -1047,6 +1159,7 @@ static auto GetDependentUnimportedTypeDecls(const Context& context,
|
||||
if (!IsClangDeclImported(context, record_decl)) {
|
||||
return {record_decl};
|
||||
}
|
||||
// TODO: Also collect field types.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1115,6 +1228,16 @@ static auto ImportDeclAfterDependencies(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
return type_inst_id;
|
||||
}
|
||||
if (clang::isa<clang::FieldDecl>(clang_decl)) {
|
||||
// Usable fields get imported as a side effect of importing the class.
|
||||
if (SemIR::InstId existing_inst_id =
|
||||
LookupClangDeclInstId(context, clang_decl);
|
||||
existing_inst_id.has_value()) {
|
||||
return existing_inst_id;
|
||||
}
|
||||
context.TODO(loc_id, "Unsupported: Unhandled kind of field declaration");
|
||||
return SemIR::InstId::None;
|
||||
}
|
||||
|
||||
context.TODO(loc_id, llvm::formatv("Unsupported: Declaration type {0}",
|
||||
clang_decl->getDeclKindName())
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/check/eval.h"
|
||||
#include "toolchain/check/generic.h"
|
||||
#include "toolchain/check/import.h"
|
||||
#include "toolchain/check/inst.h"
|
||||
#include "toolchain/check/name_lookup.h"
|
||||
#include "toolchain/check/type.h"
|
||||
@@ -3440,39 +3441,4 @@ auto ImportImpl(Context& context, SemIR::ImportIRId import_ir_id,
|
||||
.first_decl_id());
|
||||
}
|
||||
|
||||
// Returns whether a parse node associated with an imported instruction of kind
|
||||
// `imported_kind` is usable as the location of a corresponding local
|
||||
// instruction of kind `local_kind`.
|
||||
static auto HasCompatibleImportedNodeKind(SemIR::InstKind imported_kind,
|
||||
SemIR::InstKind local_kind) -> bool {
|
||||
if (imported_kind == local_kind) {
|
||||
return true;
|
||||
}
|
||||
if (imported_kind == SemIR::ImportDecl::Kind &&
|
||||
local_kind == SemIR::Namespace::Kind) {
|
||||
static_assert(
|
||||
std::is_convertible_v<decltype(SemIR::ImportDecl::Kind)::TypedNodeId,
|
||||
decltype(SemIR::Namespace::Kind)::TypedNodeId>);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace Internal {
|
||||
|
||||
auto CheckCompatibleImportedNodeKind(Context& context,
|
||||
SemIR::ImportIRInstId imported_loc_id,
|
||||
SemIR::InstKind kind) -> void {
|
||||
auto& import_ir_inst = context.import_ir_insts().Get(imported_loc_id);
|
||||
const auto* import_ir =
|
||||
context.import_irs().Get(import_ir_inst.ir_id()).sem_ir;
|
||||
auto imported_kind = import_ir->insts().Get(import_ir_inst.inst_id()).kind();
|
||||
CARBON_CHECK(
|
||||
HasCompatibleImportedNodeKind(imported_kind, kind),
|
||||
"Node of kind {0} created with location of imported node of kind {1}",
|
||||
kind, imported_kind);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
@@ -52,30 +52,6 @@ auto ImportImplsFromApiFile(Context& context) -> void;
|
||||
auto ImportImpl(Context& context, SemIR::ImportIRId import_ir_id,
|
||||
SemIR::ImplId impl_id) -> void;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
// Checks that the provided imported location has a node kind that is
|
||||
// compatible with that of the given instruction.
|
||||
auto CheckCompatibleImportedNodeKind(Context& context,
|
||||
SemIR::ImportIRInstId imported_loc_id,
|
||||
SemIR::InstKind kind) -> void;
|
||||
} // namespace Internal
|
||||
|
||||
// Returns a LocIdAndInst for an instruction with an imported location. Checks
|
||||
// that the imported location is compatible with the kind of instruction being
|
||||
// created.
|
||||
template <typename InstT>
|
||||
requires SemIR::Internal::HasNodeId<InstT>
|
||||
auto MakeImportedLocIdAndInst(Context& context,
|
||||
SemIR::ImportIRInstId imported_loc_id, InstT inst)
|
||||
-> SemIR::LocIdAndInst {
|
||||
if constexpr (!SemIR::Internal::HasUntypedNodeId<InstT>) {
|
||||
Internal::CheckCompatibleImportedNodeKind(context, imported_loc_id,
|
||||
InstT::Kind);
|
||||
}
|
||||
return SemIR::LocIdAndInst::UncheckedLoc(imported_loc_id, inst);
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
#endif // CARBON_TOOLCHAIN_CHECK_IMPORT_REF_H_
|
||||
|
||||
+66
-74
@@ -18,23 +18,32 @@
|
||||
|
||||
class Bar;
|
||||
|
||||
// --- fail_todo_import_declaration.carbon
|
||||
// --- import_declaration.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "declaration.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_declaration.carbon:[[@LINE+7]]:13: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_declaration.carbon:[[@LINE+4]]:13: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
|
||||
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
fn MyF(bar: Cpp.Bar*);
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- fail_use_declaration_as_definition.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "declaration.h";
|
||||
|
||||
fn MyF() {
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE+6]]:12: error: binding pattern has incomplete type `Bar` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: var bar: Cpp.Bar;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./declaration.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR:
|
||||
var bar: Cpp.Bar;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Definition
|
||||
// ============================================================================
|
||||
@@ -158,28 +167,17 @@ fn MyF() {
|
||||
|
||||
class Bar {
|
||||
public:
|
||||
Bar* foo;
|
||||
Bar* _Nonnull foo;
|
||||
};
|
||||
|
||||
// --- fail_todo_import_public_data_member.carbon
|
||||
// --- import_public_data_member.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "public_static_data_member.h";
|
||||
import Cpp library "public_data_member.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn MyF(bar : Cpp.Bar*) {
|
||||
// CHECK:STDERR: fail_todo_import_public_data_member.carbon:[[@LINE+11]]:27: error: semantics TODO: `Unsupported: Declaration type Var` [SemanticsTodo]
|
||||
// CHECK:STDERR: let foo_bar: Cpp.Bar* = bar->foo;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_public_data_member.carbon:[[@LINE+8]]:27: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: let foo_bar: Cpp.Bar* = bar->foo;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_import_public_data_member.carbon:[[@LINE+4]]:27: error: member name `foo` not found in `Cpp.Bar` [MemberNameNotFoundInInstScope]
|
||||
// CHECK:STDERR: let foo_bar: Cpp.Bar* = bar->foo;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
let foo_bar: Cpp.Bar* = bar->foo;
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
@@ -230,7 +228,7 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "inheritance_pointers.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn MyF1(bar : Cpp.Bar1*);
|
||||
fn MyF1(bar: Cpp.Bar1*);
|
||||
// TODO: Support C++ inheritance.
|
||||
// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE+10]]:33: error: cannot implicitly convert expression of type `Cpp.Bar2*` to `Cpp.Bar1*` [ConversionFailure]
|
||||
// CHECK:STDERR: fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
|
||||
@@ -239,8 +237,8 @@ fn MyF1(bar : Cpp.Bar1*);
|
||||
// CHECK:STDERR: fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE-8]]:9: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR: fn MyF1(bar : Cpp.Bar1*);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fn MyF1(bar: Cpp.Bar1*);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
|
||||
//@dump-sem-ir-end
|
||||
@@ -256,21 +254,14 @@ class Bar {
|
||||
virtual ~Bar();
|
||||
};
|
||||
|
||||
// --- fail_todo_import_dynamic.carbon
|
||||
// --- import_dynamic.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "dynamic.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_dynamic.carbon:[[@LINE+7]]:14: error: semantics TODO: `Unsupported: Dynamic Class` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn MyF(bar : Cpp.Bar*);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_dynamic.carbon:[[@LINE+4]]:14: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
|
||||
// CHECK:STDERR: fn MyF(bar : Cpp.Bar*);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
fn MyF(bar : Cpp.Bar*);
|
||||
fn MyF(bar: Cpp.Bar*);
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// ============================================================================
|
||||
@@ -355,36 +346,40 @@ import Cpp library "template.h";
|
||||
fn MyF(bar: Cpp.Bar*);
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// CHECK:STDOUT: --- fail_todo_import_declaration.carbon
|
||||
// CHECK:STDOUT: --- import_declaration.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Bar: type = class_type @Bar [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [concrete]
|
||||
// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete]
|
||||
// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .Bar = <error>
|
||||
// CHECK:STDOUT: .Bar = %Bar.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Bar.decl: type = class_decl @Bar [concrete = constants.%Bar] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {
|
||||
// CHECK:STDOUT: %bar.patt: <error> = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: <error> = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %bar.patt: %pattern_type = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: %pattern_type = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %bar.param: <error> = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc14: type = splice_block %ptr [concrete = <error>] {
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref: <error> = name_ref Bar, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %bar: <error> = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: %bar: %ptr = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: <error>);
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: %ptr);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_definition.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -412,7 +407,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -448,7 +442,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -479,7 +472,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: fn @MyF() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %foo.ref: %Bar.foo.type = name_ref foo, imports.%Bar.foo.decl [concrete = constants.%Bar.foo]
|
||||
// CHECK:STDOUT: %Bar.foo.call: init %empty_tuple.type = call %foo.ref()
|
||||
@@ -512,7 +504,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc19: type = splice_block %ptr [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc19_12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref.loc19_15: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref.loc19_15 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -520,11 +511,12 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_public_data_member.carbon
|
||||
// CHECK:STDOUT: --- import_public_data_member.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Bar: type = class_type @Bar [concrete]
|
||||
// CHECK:STDOUT: %ptr.f68: type = ptr_type %Bar [concrete]
|
||||
// CHECK:STDOUT: %Bar.elem: type = unbound_element_type %Bar, %ptr.f68 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr.f68 [concrete]
|
||||
// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete]
|
||||
// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete]
|
||||
@@ -546,7 +538,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr.f68 = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr.loc7 [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc7: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref.loc7: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr.loc7: type = ptr_type %Bar.ref.loc7 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -560,14 +551,16 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %foo_bar.patt: %pattern_type = binding_pattern foo_bar [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %bar.ref: %ptr.f68 = name_ref bar, %bar
|
||||
// CHECK:STDOUT: %.loc19_30: ref %Bar = deref %bar.ref
|
||||
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc19_23: type = splice_block %ptr.loc19 [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref.loc19: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr.loc19: type = ptr_type %Bar.ref.loc19 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: %.loc8_30.1: ref %Bar = deref %bar.ref
|
||||
// CHECK:STDOUT: %foo.ref: %Bar.elem = name_ref foo, @Bar.%.1 [concrete = @Bar.%.1]
|
||||
// CHECK:STDOUT: %.loc8_30.2: ref %ptr.f68 = class_element_access %.loc8_30.1, element0
|
||||
// CHECK:STDOUT: %.loc8_23: type = splice_block %ptr.loc8 [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref.loc8: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr.loc8: type = ptr_type %Bar.ref.loc8 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo_bar: %ptr.f68 = bind_name foo_bar, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc8_30.3: %ptr.f68 = bind_value %.loc8_30.2
|
||||
// CHECK:STDOUT: %foo_bar: %ptr.f68 = bind_name foo_bar, %.loc8_30.3
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -598,12 +591,10 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: fn @MyF() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar1.ref: type = name_ref Bar1, imports.%Bar1.decl [concrete = constants.%Bar1]
|
||||
// CHECK:STDOUT: %foo1.ref.loc8: %Bar1.foo1.type = name_ref foo1, imports.%Bar1.foo1.decl [concrete = constants.%Bar1.foo1]
|
||||
// CHECK:STDOUT: %Bar1.foo1.call.loc8: init %empty_tuple.type = call %foo1.ref.loc8()
|
||||
// CHECK:STDOUT: %Cpp.ref.loc9: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar2.ref.loc9: type = name_ref Bar2, imports.%Bar2.decl [concrete = constants.%Bar2]
|
||||
// CHECK:STDOUT: %foo1.ref.loc9: %Bar1.foo1.type = name_ref foo1, imports.%Bar1.foo1.decl [concrete = constants.%Bar1.foo1]
|
||||
// CHECK:STDOUT: %Bar1.foo1.call.loc9: init %empty_tuple.type = call %foo1.ref.loc9()
|
||||
@@ -648,7 +639,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr.f68 = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar1.ref: type = name_ref Bar1, imports.%Bar1.decl [concrete = constants.%Bar1]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar1.ref [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -661,7 +651,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr.eca = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc19_23: type = splice_block %ptr [concrete = constants.%ptr.eca] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar2.ref: type = name_ref Bar2, imports.%Bar2.decl [concrete = constants.%Bar2]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar2.ref [concrete = constants.%ptr.eca]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -680,36 +669,40 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_dynamic.carbon
|
||||
// CHECK:STDOUT: --- import_dynamic.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Bar: type = class_type @Bar [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [concrete]
|
||||
// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete]
|
||||
// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .Bar = <error>
|
||||
// CHECK:STDOUT: .Bar = %Bar.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Bar.decl: type = class_decl @Bar [concrete = constants.%Bar] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {
|
||||
// CHECK:STDOUT: %bar.patt: <error> = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: <error> = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %bar.patt: %pattern_type = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: %pattern_type = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %bar.param: <error> = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc14: type = splice_block %ptr [concrete = <error>] {
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref: <error> = name_ref Bar, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %bar: <error> = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: %bar: %ptr = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: <error>);
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: %ptr);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_to_inherit_public.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -742,12 +735,11 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Derived {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %.loc8: %Derived.elem = base_decl %Bar.ref, element0 [concrete]
|
||||
// CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Bar} [concrete = constants.%struct_type.base.36d]
|
||||
// CHECK:STDOUT: %complete_type.loc9: <witness> = complete_type_witness %struct_type.base [concrete = constants.%complete_type.fff]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type.loc9
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %struct_type.base [concrete = constants.%complete_type.fff]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%Derived
|
||||
|
||||
@@ -0,0 +1,670 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon
|
||||
// EXTRA-ARGS: --dump-sem-ir-ranges=ignore
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/class/field.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/class/field.carbon
|
||||
|
||||
// --- struct.h
|
||||
|
||||
struct Struct {
|
||||
int a;
|
||||
int b;
|
||||
int* _Nonnull p;
|
||||
};
|
||||
|
||||
// --- use_struct_fields.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "struct.h";
|
||||
|
||||
fn F(s: Cpp.Struct) -> (i32, i32, i32) {
|
||||
//@dump-sem-ir-begin
|
||||
return (s.a, s.b, *s.p);
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// --- union.h
|
||||
|
||||
union Union {
|
||||
int a;
|
||||
int b;
|
||||
int* _Nonnull p;
|
||||
};
|
||||
|
||||
// --- use_union_fields.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "union.h";
|
||||
|
||||
fn F(u: Cpp.Union) -> i32 {
|
||||
//@dump-sem-ir-begin
|
||||
return u.a;
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
fn G(u: Cpp.Union) -> i32 {
|
||||
//@dump-sem-ir-begin
|
||||
return u.b;
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
fn H(u: Cpp.Union) -> i32 {
|
||||
//@dump-sem-ir-begin
|
||||
return *u.p;
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// --- with_bitfields.h
|
||||
|
||||
struct Struct {
|
||||
int a;
|
||||
int b : 2;
|
||||
};
|
||||
|
||||
union Union {
|
||||
int c;
|
||||
int d : 3;
|
||||
};
|
||||
|
||||
// --- use_non_bitfields_in_type_with_bitfields.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "with_bitfields.h";
|
||||
|
||||
fn F(s: Cpp.Struct) -> i32 {
|
||||
//@dump-sem-ir-begin
|
||||
return s.a;
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
fn G(s: Cpp.Union) -> i32 {
|
||||
//@dump-sem-ir-begin
|
||||
return s.c;
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// --- fail_todo_use_bitfields.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "with_bitfields.h";
|
||||
|
||||
fn F(s: Cpp.Struct) -> i32 {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+11]]:10: error: semantics TODO: `Unsupported: Unhandled kind of field declaration` [SemanticsTodo]
|
||||
// CHECK:STDERR: return s.b;
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+8]]:10: note: in `Cpp` name lookup for `b` [InCppNameLookup]
|
||||
// CHECK:STDERR: return s.b;
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+4]]:10: error: member name `b` not found in `Cpp.Struct` [MemberNameNotFoundInInstScope]
|
||||
// CHECK:STDERR: return s.b;
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR:
|
||||
return s.b;
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
fn G(s: Cpp.Union) -> i32 {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+11]]:10: error: semantics TODO: `Unsupported: Unhandled kind of field declaration` [SemanticsTodo]
|
||||
// CHECK:STDERR: return s.d;
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+8]]:10: note: in `Cpp` name lookup for `d` [InCppNameLookup]
|
||||
// CHECK:STDERR: return s.d;
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_use_bitfields.carbon:[[@LINE+4]]:10: error: member name `d` not found in `Cpp.Union` [MemberNameNotFoundInInstScope]
|
||||
// CHECK:STDERR: return s.d;
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR:
|
||||
return s.d;
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- use_struct_fields.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Struct: type = class_type @Struct [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Struct.elem.86b: type = unbound_element_type %Struct, %i32 [concrete]
|
||||
// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %Struct.elem.765: type = unbound_element_type %Struct, %ptr.235 [concrete]
|
||||
// CHECK:STDOUT: %.550: type = custom_layout_type {size=16, align=8, .a@0: %i32, .b@4: %i32, .p@8: %ptr.235} [concrete]
|
||||
// CHECK:STDOUT: %complete_type.8cf: <witness> = complete_type_witness %.550 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.60c: type = pattern_type %Struct [concrete]
|
||||
// CHECK:STDOUT: %tuple.type.ff9: type = tuple_type (type, type, type) [concrete]
|
||||
// CHECK:STDOUT: %tuple.type.189: type = tuple_type (%i32, %i32, %i32) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.b5a: type = pattern_type %tuple.type.189 [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .Struct = %Struct.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Struct.decl: type = class_decl @Struct [concrete = constants.%Struct] {} {}
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .Cpp = imports.%Cpp
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %Cpp.import_cpp = import_cpp {
|
||||
// CHECK:STDOUT: import Cpp "struct.h"
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||
// CHECK:STDOUT: %s.patt: %pattern_type.60c = binding_pattern s [concrete]
|
||||
// CHECK:STDOUT: %s.param_patt: %pattern_type.60c = value_param_pattern %s.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.b5a = return_slot_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.b5a = out_param_pattern %return.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %int_32.loc6_25: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.loc6_25: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %int_32.loc6_30: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.loc6_30: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %int_32.loc6_35: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.loc6_35: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc6_38.1: %tuple.type.ff9 = tuple_literal (%i32.loc6_25, %i32.loc6_30, %i32.loc6_35)
|
||||
// CHECK:STDOUT: %.loc6_38.2: type = converted %.loc6_38.1, constants.%tuple.type.189 [concrete = constants.%tuple.type.189]
|
||||
// CHECK:STDOUT: %s.param: %Struct = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc6_12: type = splice_block %Struct.ref [concrete = constants.%Struct] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Struct.ref: type = name_ref Struct, imports.%Struct.decl [concrete = constants.%Struct]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %s: %Struct = bind_name s, %s.param
|
||||
// CHECK:STDOUT: %return.param: ref %tuple.type.189 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %tuple.type.189 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Struct {
|
||||
// CHECK:STDOUT: %int_32.1: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.1: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.1: %Struct.elem.86b = field_decl a, element0 [concrete]
|
||||
// CHECK:STDOUT: %int_32.2: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.2: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.2: %Struct.elem.86b = field_decl b, element1 [concrete]
|
||||
// CHECK:STDOUT: %int_32.3: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.3: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.3: %Struct.elem.765 = field_decl p, element2 [concrete]
|
||||
// CHECK:STDOUT: %.4: type = custom_layout_type {size=16, align=8, .a@0: %i32, .b@4: %i32, .p@8: %ptr.235} [concrete = constants.%.550]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %.4 [concrete = constants.%complete_type.8cf]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%Struct
|
||||
// CHECK:STDOUT: .a = %.1
|
||||
// CHECK:STDOUT: .b = %.2
|
||||
// CHECK:STDOUT: .p = %.3
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%s.param: %Struct) -> %return.param: %tuple.type.189 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %s.ref.loc8_11: %Struct = name_ref s, %s
|
||||
// CHECK:STDOUT: %a.ref: %Struct.elem.86b = name_ref a, @Struct.%.1 [concrete = @Struct.%.1]
|
||||
// CHECK:STDOUT: %.loc8_12.1: ref %i32 = class_element_access %s.ref.loc8_11, element0
|
||||
// CHECK:STDOUT: %.loc8_12.2: %i32 = bind_value %.loc8_12.1
|
||||
// CHECK:STDOUT: %s.ref.loc8_16: %Struct = name_ref s, %s
|
||||
// CHECK:STDOUT: %b.ref: %Struct.elem.86b = name_ref b, @Struct.%.2 [concrete = @Struct.%.2]
|
||||
// CHECK:STDOUT: %.loc8_17.1: ref %i32 = class_element_access %s.ref.loc8_16, element1
|
||||
// CHECK:STDOUT: %.loc8_17.2: %i32 = bind_value %.loc8_17.1
|
||||
// CHECK:STDOUT: %s.ref.loc8_22: %Struct = name_ref s, %s
|
||||
// CHECK:STDOUT: %p.ref: %Struct.elem.765 = name_ref p, @Struct.%.3 [concrete = @Struct.%.3]
|
||||
// CHECK:STDOUT: %.loc8_23.1: ref %ptr.235 = class_element_access %s.ref.loc8_22, element2
|
||||
// CHECK:STDOUT: %.loc8_23.2: %ptr.235 = bind_value %.loc8_23.1
|
||||
// CHECK:STDOUT: %.loc8_21.1: ref %i32 = deref %.loc8_23.2
|
||||
// CHECK:STDOUT: %.loc8_25.1: %tuple.type.189 = tuple_literal (%.loc8_12.2, %.loc8_17.2, %.loc8_21.1)
|
||||
// CHECK:STDOUT: %tuple.elem0: ref %i32 = tuple_access %return, element0
|
||||
// CHECK:STDOUT: %.loc8_25.2: init %i32 = initialize_from %.loc8_12.2 to %tuple.elem0
|
||||
// CHECK:STDOUT: %tuple.elem1: ref %i32 = tuple_access %return, element1
|
||||
// CHECK:STDOUT: %.loc8_25.3: init %i32 = initialize_from %.loc8_17.2 to %tuple.elem1
|
||||
// CHECK:STDOUT: %.loc8_21.2: %i32 = bind_value %.loc8_21.1
|
||||
// CHECK:STDOUT: %tuple.elem2: ref %i32 = tuple_access %return, element2
|
||||
// CHECK:STDOUT: %.loc8_25.4: init %i32 = initialize_from %.loc8_21.2 to %tuple.elem2
|
||||
// CHECK:STDOUT: %.loc8_25.5: init %tuple.type.189 = tuple_init (%.loc8_25.2, %.loc8_25.3, %.loc8_25.4) to %return
|
||||
// CHECK:STDOUT: %.loc8_26: init %tuple.type.189 = converted %.loc8_25.1, %.loc8_25.5
|
||||
// CHECK:STDOUT: return %.loc8_26 to %return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- use_union_fields.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Union: type = class_type @Union [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Union.elem.041: type = unbound_element_type %Union, %i32 [concrete]
|
||||
// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %Union.elem.92a: type = unbound_element_type %Union, %ptr.235 [concrete]
|
||||
// CHECK:STDOUT: %.c84: type = custom_layout_type {size=8, align=8, .a@0: %i32, .b@0: %i32, .p@0: %ptr.235} [concrete]
|
||||
// CHECK:STDOUT: %complete_type.1b0: <witness> = complete_type_witness %.c84 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.a90: type = pattern_type %Union [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %H.type: type = fn_type @H [concrete]
|
||||
// CHECK:STDOUT: %H: %H.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .Union = %Union.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Union.decl: type = class_decl @Union [concrete = constants.%Union] {} {}
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .Cpp = imports.%Cpp
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: .H = %H.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %Cpp.import_cpp = import_cpp {
|
||||
// CHECK:STDOUT: import Cpp "union.h"
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||
// CHECK:STDOUT: %u.patt: %pattern_type.a90 = binding_pattern u [concrete]
|
||||
// CHECK:STDOUT: %u.param_patt: %pattern_type.a90 = value_param_pattern %u.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %u.param: %Union = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc6: type = splice_block %Union.ref [concrete = constants.%Union] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Union.ref: type = name_ref Union, imports.%Union.decl [concrete = constants.%Union]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %u: %Union = bind_name u, %u.param
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {
|
||||
// CHECK:STDOUT: %u.patt: %pattern_type.a90 = binding_pattern u [concrete]
|
||||
// CHECK:STDOUT: %u.param_patt: %pattern_type.a90 = value_param_pattern %u.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %u.param: %Union = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc12: type = splice_block %Union.ref [concrete = constants.%Union] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Union.ref: type = name_ref Union, imports.%Union.decl [concrete = constants.%Union]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %u: %Union = bind_name u, %u.param
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %H.decl: %H.type = fn_decl @H [concrete = constants.%H] {
|
||||
// CHECK:STDOUT: %u.patt: %pattern_type.a90 = binding_pattern u [concrete]
|
||||
// CHECK:STDOUT: %u.param_patt: %pattern_type.a90 = value_param_pattern %u.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %u.param: %Union = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc18: type = splice_block %Union.ref [concrete = constants.%Union] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Union.ref: type = name_ref Union, imports.%Union.decl [concrete = constants.%Union]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %u: %Union = bind_name u, %u.param
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Union {
|
||||
// CHECK:STDOUT: %int_32.1: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.1: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.1: %Union.elem.041 = field_decl a, element0 [concrete]
|
||||
// CHECK:STDOUT: %int_32.2: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.2: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.2: %Union.elem.041 = field_decl b, element1 [concrete]
|
||||
// CHECK:STDOUT: %int_32.3: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32.3: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.3: %Union.elem.92a = field_decl p, element2 [concrete]
|
||||
// CHECK:STDOUT: %.4: type = custom_layout_type {size=8, align=8, .a@0: %i32, .b@0: %i32, .p@0: %ptr.235} [concrete = constants.%.c84]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %.4 [concrete = constants.%complete_type.1b0]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%Union
|
||||
// CHECK:STDOUT: .a = %.1
|
||||
// CHECK:STDOUT: .b = %.2
|
||||
// CHECK:STDOUT: .p = %.3
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%u.param: %Union) -> %i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %u.ref: %Union = name_ref u, %u
|
||||
// CHECK:STDOUT: %a.ref: %Union.elem.041 = name_ref a, @Union.%.1 [concrete = @Union.%.1]
|
||||
// CHECK:STDOUT: %.loc8_11.1: ref %i32 = class_element_access %u.ref, element0
|
||||
// CHECK:STDOUT: %.loc8_11.2: %i32 = bind_value %.loc8_11.1
|
||||
// CHECK:STDOUT: return %.loc8_11.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%u.param: %Union) -> %i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %u.ref: %Union = name_ref u, %u
|
||||
// CHECK:STDOUT: %b.ref: %Union.elem.041 = name_ref b, @Union.%.2 [concrete = @Union.%.2]
|
||||
// CHECK:STDOUT: %.loc14_11.1: ref %i32 = class_element_access %u.ref, element1
|
||||
// CHECK:STDOUT: %.loc14_11.2: %i32 = bind_value %.loc14_11.1
|
||||
// CHECK:STDOUT: return %.loc14_11.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @H(%u.param: %Union) -> %i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %u.ref: %Union = name_ref u, %u
|
||||
// CHECK:STDOUT: %p.ref: %Union.elem.92a = name_ref p, @Union.%.3 [concrete = @Union.%.3]
|
||||
// CHECK:STDOUT: %.loc20_12.1: ref %ptr.235 = class_element_access %u.ref, element2
|
||||
// CHECK:STDOUT: %.loc20_12.2: %ptr.235 = bind_value %.loc20_12.1
|
||||
// CHECK:STDOUT: %.loc20_10.1: ref %i32 = deref %.loc20_12.2
|
||||
// CHECK:STDOUT: %.loc20_10.2: %i32 = bind_value %.loc20_10.1
|
||||
// CHECK:STDOUT: return %.loc20_10.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- use_non_bitfields_in_type_with_bitfields.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Struct: type = class_type @Struct [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Struct.elem: type = unbound_element_type %Struct, %i32 [concrete]
|
||||
// CHECK:STDOUT: %.f9e: type = custom_layout_type {size=8, align=4, .a@0: %i32} [concrete]
|
||||
// CHECK:STDOUT: %complete_type.d3c: <witness> = complete_type_witness %.f9e [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.60c: type = pattern_type %Struct [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Union: type = class_type @Union [concrete]
|
||||
// CHECK:STDOUT: %Union.elem: type = unbound_element_type %Union, %i32 [concrete]
|
||||
// CHECK:STDOUT: %.891: type = custom_layout_type {size=4, align=4, .c@0: %i32} [concrete]
|
||||
// CHECK:STDOUT: %complete_type.591: <witness> = complete_type_witness %.891 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.a90: type = pattern_type %Union [concrete]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .Struct = %Struct.decl
|
||||
// CHECK:STDOUT: .Union = %Union.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Struct.decl: type = class_decl @Struct [concrete = constants.%Struct] {} {}
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: %Union.decl: type = class_decl @Union [concrete = constants.%Union] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .Cpp = imports.%Cpp
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %Cpp.import_cpp = import_cpp {
|
||||
// CHECK:STDOUT: import Cpp "with_bitfields.h"
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||
// CHECK:STDOUT: %s.patt: %pattern_type.60c = binding_pattern s [concrete]
|
||||
// CHECK:STDOUT: %s.param_patt: %pattern_type.60c = value_param_pattern %s.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %s.param: %Struct = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc6: type = splice_block %Struct.ref [concrete = constants.%Struct] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Struct.ref: type = name_ref Struct, imports.%Struct.decl [concrete = constants.%Struct]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %s: %Struct = bind_name s, %s.param
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {
|
||||
// CHECK:STDOUT: %s.patt: %pattern_type.a90 = binding_pattern s [concrete]
|
||||
// CHECK:STDOUT: %s.param_patt: %pattern_type.a90 = value_param_pattern %s.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %s.param: %Union = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc12: type = splice_block %Union.ref [concrete = constants.%Union] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Union.ref: type = name_ref Union, imports.%Union.decl [concrete = constants.%Union]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %s: %Union = bind_name s, %s.param
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Struct {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.1: %Struct.elem = field_decl a, element0 [concrete]
|
||||
// CHECK:STDOUT: %.2: type = custom_layout_type {size=8, align=4, .a@0: %i32} [concrete = constants.%.f9e]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %.2 [concrete = constants.%complete_type.d3c]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%Struct
|
||||
// CHECK:STDOUT: .a = %.1
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Union {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.1: %Union.elem = field_decl c, element0 [concrete]
|
||||
// CHECK:STDOUT: %.2: type = custom_layout_type {size=4, align=4, .c@0: %i32} [concrete = constants.%.891]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %.2 [concrete = constants.%complete_type.591]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%Union
|
||||
// CHECK:STDOUT: .c = %.1
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%s.param: %Struct) -> %i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %s.ref: %Struct = name_ref s, %s
|
||||
// CHECK:STDOUT: %a.ref: %Struct.elem = name_ref a, @Struct.%.1 [concrete = @Struct.%.1]
|
||||
// CHECK:STDOUT: %.loc8_11.1: ref %i32 = class_element_access %s.ref, element0
|
||||
// CHECK:STDOUT: %.loc8_11.2: %i32 = bind_value %.loc8_11.1
|
||||
// CHECK:STDOUT: return %.loc8_11.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%s.param: %Union) -> %i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %s.ref: %Union = name_ref s, %s
|
||||
// CHECK:STDOUT: %c.ref: %Union.elem = name_ref c, @Union.%.1 [concrete = @Union.%.1]
|
||||
// CHECK:STDOUT: %.loc14_11.1: ref %i32 = class_element_access %s.ref, element0
|
||||
// CHECK:STDOUT: %.loc14_11.2: %i32 = bind_value %.loc14_11.1
|
||||
// CHECK:STDOUT: return %.loc14_11.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_use_bitfields.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Struct: type = class_type @Struct [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Struct.elem: type = unbound_element_type %Struct, %i32 [concrete]
|
||||
// CHECK:STDOUT: %.f9e: type = custom_layout_type {size=8, align=4, .a@0: %i32} [concrete]
|
||||
// CHECK:STDOUT: %complete_type.d3c: <witness> = complete_type_witness %.f9e [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.60c: type = pattern_type %Struct [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Union: type = class_type @Union [concrete]
|
||||
// CHECK:STDOUT: %Union.elem: type = unbound_element_type %Union, %i32 [concrete]
|
||||
// CHECK:STDOUT: %.891: type = custom_layout_type {size=4, align=4, .c@0: %i32} [concrete]
|
||||
// CHECK:STDOUT: %complete_type.591: <witness> = complete_type_witness %.891 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.a90: type = pattern_type %Union [concrete]
|
||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .Struct = %Struct.decl
|
||||
// CHECK:STDOUT: .Union = %Union.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Struct.decl: type = class_decl @Struct [concrete = constants.%Struct] {} {}
|
||||
// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic]
|
||||
// CHECK:STDOUT: %Union.decl: type = class_decl @Union [concrete = constants.%Union] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .Core = imports.%Core
|
||||
// CHECK:STDOUT: .Cpp = imports.%Cpp
|
||||
// CHECK:STDOUT: .F = %F.decl
|
||||
// CHECK:STDOUT: .G = %G.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %Cpp.import_cpp = import_cpp {
|
||||
// CHECK:STDOUT: import Cpp "with_bitfields.h"
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||
// CHECK:STDOUT: %s.patt: %pattern_type.60c = binding_pattern s [concrete]
|
||||
// CHECK:STDOUT: %s.param_patt: %pattern_type.60c = value_param_pattern %s.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %s.param: %Struct = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc6: type = splice_block %Struct.ref [concrete = constants.%Struct] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Struct.ref: type = name_ref Struct, imports.%Struct.decl [concrete = constants.%Struct]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %s: %Struct = bind_name s, %s.param
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {
|
||||
// CHECK:STDOUT: %s.patt: %pattern_type.a90 = binding_pattern s [concrete]
|
||||
// CHECK:STDOUT: %s.param_patt: %pattern_type.a90 = value_param_pattern %s.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %s.param: %Union = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc23: type = splice_block %Union.ref [concrete = constants.%Union] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Union.ref: type = name_ref Union, imports.%Union.decl [concrete = constants.%Union]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %s: %Union = bind_name s, %s.param
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Struct {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.1: %Struct.elem = field_decl a, element0 [concrete]
|
||||
// CHECK:STDOUT: %.2: type = custom_layout_type {size=8, align=4, .a@0: %i32} [concrete = constants.%.f9e]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %.2 [concrete = constants.%complete_type.d3c]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%Struct
|
||||
// CHECK:STDOUT: .b = <poisoned>
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Union {
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.1: %Union.elem = field_decl c, element0 [concrete]
|
||||
// CHECK:STDOUT: %.2: type = custom_layout_type {size=4, align=4, .c@0: %i32} [concrete = constants.%.891]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %.2 [concrete = constants.%complete_type.591]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%Union
|
||||
// CHECK:STDOUT: .d = <poisoned>
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%s.param: %Struct) -> %i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %s.ref: %Struct = name_ref s, %s
|
||||
// CHECK:STDOUT: %b.ref: <error> = name_ref b, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: return <error>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G(%s.param: %Union) -> %i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %s.ref: %Union = name_ref s, %s
|
||||
// CHECK:STDOUT: %d.ref: <error> = name_ref d, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: return <error>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
+12
-12
@@ -226,8 +226,6 @@ fn Ref(p: Cpp.HasQualifiers*) {
|
||||
// CHECK:STDOUT: %v.param: %HasQualifiers = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc6_12: type = splice_block %HasQualifiers.ref.loc6_12 [concrete = constants.%HasQualifiers] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc6_9: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type]
|
||||
// CHECK:STDOUT: %HasQualifiers.ref.loc6_12: type = name_ref HasQualifiers, imports.%HasQualifiers.decl [concrete = constants.%HasQualifiers]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %v: %HasQualifiers = bind_name v, %v.param
|
||||
@@ -242,7 +240,9 @@ fn Ref(p: Cpp.HasQualifiers*) {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @HasQualifiers {
|
||||
// CHECK:STDOUT: complete_type_witness = @F.%complete_type
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%HasQualifiers
|
||||
@@ -378,8 +378,6 @@ fn Ref(p: Cpp.HasQualifiers*) {
|
||||
// CHECK:STDOUT: %v.param: %HasQualifiers = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc6: type = splice_block %HasQualifiers.ref [concrete = constants.%HasQualifiers] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: %HasQualifiers.ref: type = name_ref HasQualifiers, imports.%HasQualifiers.decl [concrete = constants.%HasQualifiers]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %v: %HasQualifiers = bind_name v, %v.param
|
||||
@@ -387,7 +385,9 @@ fn Ref(p: Cpp.HasQualifiers*) {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @HasQualifiers {
|
||||
// CHECK:STDOUT: complete_type_witness = @Value.%complete_type
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%HasQualifiers
|
||||
@@ -500,8 +500,6 @@ fn Ref(p: Cpp.HasQualifiers*) {
|
||||
// CHECK:STDOUT: %p.param: %ptr.ec3 = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc6: type = splice_block %ptr [concrete = constants.%ptr.ec3] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type]
|
||||
// CHECK:STDOUT: %HasQualifiers.ref: type = name_ref HasQualifiers, imports.%HasQualifiers.decl [concrete = constants.%HasQualifiers]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %HasQualifiers.ref [concrete = constants.%ptr.ec3]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -510,7 +508,9 @@ fn Ref(p: Cpp.HasQualifiers*) {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @HasQualifiers {
|
||||
// CHECK:STDOUT: complete_type_witness = @Ref.%complete_type
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%HasQualifiers
|
||||
@@ -572,8 +572,6 @@ fn Ref(p: Cpp.HasQualifiers*) {
|
||||
// CHECK:STDOUT: %p.param: %ptr.ec3 = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc6: type = splice_block %ptr [concrete = constants.%ptr.ec3] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type]
|
||||
// CHECK:STDOUT: %HasQualifiers.ref: type = name_ref HasQualifiers, imports.%HasQualifiers.decl [concrete = constants.%HasQualifiers]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %HasQualifiers.ref [concrete = constants.%ptr.ec3]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -582,7 +580,9 @@ fn Ref(p: Cpp.HasQualifiers*) {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @HasQualifiers {
|
||||
// CHECK:STDOUT: complete_type_witness = @Ref.%complete_type
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type]
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete = constants.%complete_type]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%HasQualifiers
|
||||
|
||||
+129
-75
@@ -18,23 +18,32 @@
|
||||
|
||||
struct Bar;
|
||||
|
||||
// --- fail_todo_import_declaration.carbon
|
||||
// --- import_declaration.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "declaration.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_declaration.carbon:[[@LINE+7]]:13: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_declaration.carbon:[[@LINE+4]]:13: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
|
||||
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
fn MyF(bar: Cpp.Bar*);
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- fail_use_declaration_as_definition.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "declaration.h";
|
||||
|
||||
fn MyF() {
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE+6]]:12: error: binding pattern has incomplete type `Bar` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: var bar: Cpp.Bar;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./declaration.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR:
|
||||
var bar: Cpp.Bar;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Definition
|
||||
// ============================================================================
|
||||
@@ -112,6 +121,7 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "private_static_member_function.h";
|
||||
|
||||
fn MyF() {
|
||||
// TODO: Should fail because `foo` is inaccessible.
|
||||
Cpp.Bar.foo();
|
||||
}
|
||||
|
||||
@@ -122,7 +132,7 @@ fn MyF() {
|
||||
// --- public_static_data_member.h
|
||||
|
||||
struct Bar {
|
||||
static Bar* foo;
|
||||
static Bar* _Nonnull foo;
|
||||
};
|
||||
|
||||
// --- fail_todo_import_public_static_data_member.carbon
|
||||
@@ -155,10 +165,10 @@ fn MyF() {
|
||||
// --- public_data_member.h
|
||||
|
||||
struct Bar {
|
||||
Bar* foo;
|
||||
Bar* _Nonnull foo;
|
||||
};
|
||||
|
||||
// --- fail_todo_import_public_data_member.carbon
|
||||
// --- import_public_data_member.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -166,17 +176,6 @@ import Cpp library "public_data_member.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn MyF(bar : Cpp.Bar*) {
|
||||
// CHECK:STDERR: fail_todo_import_public_data_member.carbon:[[@LINE+11]]:27: error: semantics TODO: `Unsupported: Declaration type Field` [SemanticsTodo]
|
||||
// CHECK:STDERR: let foo_bar: Cpp.Bar* = bar->foo;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_public_data_member.carbon:[[@LINE+8]]:27: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: let foo_bar: Cpp.Bar* = bar->foo;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_import_public_data_member.carbon:[[@LINE+4]]:27: error: member name `foo` not found in `Cpp.Bar` [MemberNameNotFoundInInstScope]
|
||||
// CHECK:STDERR: let foo_bar: Cpp.Bar* = bar->foo;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
let foo_bar: Cpp.Bar* = bar->foo;
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
@@ -225,7 +224,7 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "inheritance_pointers.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn MyF1(bar : Cpp.Bar1*);
|
||||
fn MyF1(bar: Cpp.Bar1*);
|
||||
// TODO: Support C++ inheritance.
|
||||
// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE+10]]:33: error: cannot implicitly convert expression of type `Cpp.Bar2*` to `Cpp.Bar1*` [ConversionFailure]
|
||||
// CHECK:STDERR: fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
|
||||
@@ -234,8 +233,8 @@ fn MyF1(bar : Cpp.Bar1*);
|
||||
// CHECK:STDERR: fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE-8]]:9: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR: fn MyF1(bar : Cpp.Bar1*);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fn MyF1(bar: Cpp.Bar1*);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
|
||||
//@dump-sem-ir-end
|
||||
@@ -247,24 +246,36 @@ fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
|
||||
// --- dynamic.h
|
||||
|
||||
struct Bar {
|
||||
virtual ~Bar();
|
||||
virtual void f();
|
||||
};
|
||||
|
||||
// --- fail_todo_import_dynamic.carbon
|
||||
// --- import_dynamic.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "dynamic.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_dynamic.carbon:[[@LINE+7]]:14: error: semantics TODO: `Unsupported: Dynamic Class` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn MyF(bar : Cpp.Bar*);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_dynamic.carbon:[[@LINE+4]]:14: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
|
||||
// CHECK:STDERR: fn MyF(bar : Cpp.Bar*);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
fn MyF(bar : Cpp.Bar*);
|
||||
fn MyF(bar: Cpp.Bar*);
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- fail_todo_call_dynamic.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "dynamic.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn MyF(bar: Cpp.Bar*) {
|
||||
// CHECK:STDERR: fail_todo_call_dynamic.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Virtual function` [SemanticsTodo]
|
||||
// CHECK:STDERR: bar->f();
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: fail_todo_call_dynamic.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `f` [InCppNameLookup]
|
||||
// CHECK:STDERR: bar->f();
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
bar->f();
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// ============================================================================
|
||||
@@ -313,6 +324,7 @@ class Derived {
|
||||
}
|
||||
|
||||
fn MyF() {
|
||||
// TODO: Should fail because `foo` is inaccessible.
|
||||
Derived.foo();
|
||||
}
|
||||
|
||||
@@ -346,36 +358,40 @@ import Cpp library "template.h";
|
||||
fn MyF(bar: Cpp.Bar*);
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// CHECK:STDOUT: --- fail_todo_import_declaration.carbon
|
||||
// CHECK:STDOUT: --- import_declaration.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Bar: type = class_type @Bar [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [concrete]
|
||||
// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete]
|
||||
// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .Bar = <error>
|
||||
// CHECK:STDOUT: .Bar = %Bar.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Bar.decl: type = class_decl @Bar [concrete = constants.%Bar] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {
|
||||
// CHECK:STDOUT: %bar.patt: <error> = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: <error> = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %bar.patt: %pattern_type = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: %pattern_type = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %bar.param: <error> = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc14: type = splice_block %ptr [concrete = <error>] {
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref: <error> = name_ref Bar, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %bar: <error> = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: %bar: %ptr = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: <error>);
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: %ptr);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_definition.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -403,7 +419,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -439,7 +454,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -470,7 +484,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: fn @MyF() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %foo.ref: %Bar.foo.type = name_ref foo, imports.%Bar.foo.decl [concrete = constants.%Bar.foo]
|
||||
// CHECK:STDOUT: %Bar.foo.call: init %empty_tuple.type = call %foo.ref()
|
||||
@@ -503,7 +516,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc19: type = splice_block %ptr [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc19_12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref.loc19_15: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref.loc19_15 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -511,11 +523,12 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_public_data_member.carbon
|
||||
// CHECK:STDOUT: --- import_public_data_member.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Bar: type = class_type @Bar [concrete]
|
||||
// CHECK:STDOUT: %ptr.f68: type = ptr_type %Bar [concrete]
|
||||
// CHECK:STDOUT: %Bar.elem: type = unbound_element_type %Bar, %ptr.f68 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr.f68 [concrete]
|
||||
// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete]
|
||||
// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete]
|
||||
@@ -537,7 +550,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr.f68 = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr.loc7 [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc7: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref.loc7: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr.loc7: type = ptr_type %Bar.ref.loc7 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -551,14 +563,16 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %foo_bar.patt: %pattern_type = binding_pattern foo_bar [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %bar.ref: %ptr.f68 = name_ref bar, %bar
|
||||
// CHECK:STDOUT: %.loc19_30: ref %Bar = deref %bar.ref
|
||||
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc19_23: type = splice_block %ptr.loc19 [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref.loc19: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr.loc19: type = ptr_type %Bar.ref.loc19 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: %.loc8_30.1: ref %Bar = deref %bar.ref
|
||||
// CHECK:STDOUT: %foo.ref: %Bar.elem = name_ref foo, @Bar.%.1 [concrete = @Bar.%.1]
|
||||
// CHECK:STDOUT: %.loc8_30.2: ref %ptr.f68 = class_element_access %.loc8_30.1, element0
|
||||
// CHECK:STDOUT: %.loc8_23: type = splice_block %ptr.loc8 [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref.loc8: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr.loc8: type = ptr_type %Bar.ref.loc8 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo_bar: %ptr.f68 = bind_name foo_bar, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc8_30.3: %ptr.f68 = bind_value %.loc8_30.2
|
||||
// CHECK:STDOUT: %foo_bar: %ptr.f68 = bind_name foo_bar, %.loc8_30.3
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -589,12 +603,10 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: fn @MyF() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar1.ref: type = name_ref Bar1, imports.%Bar1.decl [concrete = constants.%Bar1]
|
||||
// CHECK:STDOUT: %foo1.ref.loc8: %Bar1.foo1.type = name_ref foo1, imports.%Bar1.foo1.decl [concrete = constants.%Bar1.foo1]
|
||||
// CHECK:STDOUT: %Bar1.foo1.call.loc8: init %empty_tuple.type = call %foo1.ref.loc8()
|
||||
// CHECK:STDOUT: %Cpp.ref.loc9: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar2.ref.loc9: type = name_ref Bar2, imports.%Bar2.decl [concrete = constants.%Bar2]
|
||||
// CHECK:STDOUT: %foo1.ref.loc9: %Bar1.foo1.type = name_ref foo1, imports.%Bar1.foo1.decl [concrete = constants.%Bar1.foo1]
|
||||
// CHECK:STDOUT: %Bar1.foo1.call.loc9: init %empty_tuple.type = call %foo1.ref.loc9()
|
||||
@@ -639,7 +651,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr.f68 = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar1.ref: type = name_ref Bar1, imports.%Bar1.decl [concrete = constants.%Bar1]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar1.ref [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -652,7 +663,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr.eca = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc19_23: type = splice_block %ptr [concrete = constants.%ptr.eca] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar2.ref: type = name_ref Bar2, imports.%Bar2.decl [concrete = constants.%Bar2]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar2.ref [concrete = constants.%ptr.eca]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -671,36 +681,81 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_dynamic.carbon
|
||||
// CHECK:STDOUT: --- import_dynamic.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Bar: type = class_type @Bar [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [concrete]
|
||||
// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete]
|
||||
// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .Bar = <error>
|
||||
// CHECK:STDOUT: .Bar = %Bar.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Bar.decl: type = class_decl @Bar [concrete = constants.%Bar] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {
|
||||
// CHECK:STDOUT: %bar.patt: <error> = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: <error> = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %bar.patt: %pattern_type = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: %pattern_type = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %bar.param: <error> = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc14: type = splice_block %ptr [concrete = <error>] {
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref: <error> = name_ref Bar, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %bar: <error> = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: %bar: %ptr = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: <error>);
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: %ptr);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_call_dynamic.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Bar: type = class_type @Bar [concrete]
|
||||
// CHECK:STDOUT: %ptr.f68: type = ptr_type %Bar [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr.f68 [concrete]
|
||||
// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete]
|
||||
// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .Bar = %Bar.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Bar.decl: type = class_decl @Bar [concrete = constants.%Bar] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {
|
||||
// CHECK:STDOUT: %bar.patt: %pattern_type = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: %pattern_type = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %bar.param: %ptr.f68 = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %bar: %ptr.f68 = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: %ptr.f68) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %bar.ref: %ptr.f68 = name_ref bar, %bar
|
||||
// CHECK:STDOUT: %.loc15: ref %Bar = deref %bar.ref
|
||||
// CHECK:STDOUT: %f.ref: <error> = name_ref f, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_to_inherit_public.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -733,12 +788,11 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class @Derived {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %.loc8: %Derived.elem = base_decl %Bar.ref, element0 [concrete]
|
||||
// CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Bar} [concrete = constants.%struct_type.base.36d]
|
||||
// CHECK:STDOUT: %complete_type.loc9: <witness> = complete_type_witness %struct_type.base [concrete = constants.%complete_type.fff]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type.loc9
|
||||
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %struct_type.base [concrete = constants.%complete_type.fff]
|
||||
// CHECK:STDOUT: complete_type_witness = %complete_type
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = constants.%Derived
|
||||
|
||||
+49
-47
@@ -2,7 +2,7 @@
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
@@ -18,23 +18,32 @@
|
||||
|
||||
union Bar;
|
||||
|
||||
// --- fail_todo_import_declaration.carbon
|
||||
// --- import_declaration.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "declaration.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_declaration.carbon:[[@LINE+7]]:13: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_declaration.carbon:[[@LINE+4]]:13: note: in `Cpp` name lookup for `Bar` [InCppNameLookup]
|
||||
// CHECK:STDERR: fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
fn MyF(bar: Cpp.Bar*);
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- fail_use_declaration_as_definition.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "declaration.h";
|
||||
|
||||
fn MyF() {
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE+6]]:12: error: binding pattern has incomplete type `Bar` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: var bar: Cpp.Bar;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./declaration.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR:
|
||||
var bar: Cpp.Bar;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Definition
|
||||
// ============================================================================
|
||||
@@ -113,6 +122,7 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "private_static_member_function.h";
|
||||
|
||||
fn MyF() {
|
||||
// TODO: Should fail because `foo` is inaccessible.
|
||||
Cpp.Bar.foo();
|
||||
}
|
||||
|
||||
@@ -124,7 +134,7 @@ fn MyF() {
|
||||
|
||||
union Bar {
|
||||
public:
|
||||
static Bar* foo;
|
||||
static Bar* _Nonnull foo;
|
||||
};
|
||||
|
||||
// --- fail_todo_import_public_static_data_member.carbon
|
||||
@@ -158,28 +168,17 @@ fn MyF() {
|
||||
|
||||
union Bar {
|
||||
public:
|
||||
Bar* foo;
|
||||
Bar* _Nonnull foo;
|
||||
};
|
||||
|
||||
// --- fail_todo_import_public_data_member.carbon
|
||||
// --- import_public_data_member.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "public_static_data_member.h";
|
||||
import Cpp library "public_data_member.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn MyF(bar : Cpp.Bar*) {
|
||||
// CHECK:STDERR: fail_todo_import_public_data_member.carbon:[[@LINE+11]]:27: error: semantics TODO: `Unsupported: Declaration type Var` [SemanticsTodo]
|
||||
// CHECK:STDERR: let foo_bar: Cpp.Bar* = bar->foo;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_public_data_member.carbon:[[@LINE+8]]:27: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: let foo_bar: Cpp.Bar* = bar->foo;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_import_public_data_member.carbon:[[@LINE+4]]:27: error: member name `foo` not found in `Cpp.Bar` [MemberNameNotFoundInInstScope]
|
||||
// CHECK:STDERR: let foo_bar: Cpp.Bar* = bar->foo;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
let foo_bar: Cpp.Bar* = bar->foo;
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
@@ -202,6 +201,7 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "to_inherit_public.h";
|
||||
|
||||
class Derived {
|
||||
// TODO: Presumably we should disallow deriving from a union.
|
||||
extend base: Cpp.Bar;
|
||||
}
|
||||
|
||||
@@ -239,36 +239,40 @@ import Cpp library "template.h";
|
||||
fn MyF(bar: Cpp.Bar*);
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// CHECK:STDOUT: --- fail_todo_import_declaration.carbon
|
||||
// CHECK:STDOUT: --- import_declaration.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Bar: type = class_type @Bar [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [concrete]
|
||||
// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete]
|
||||
// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .Bar = <error>
|
||||
// CHECK:STDOUT: .Bar = %Bar.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Bar.decl: type = class_decl @Bar [concrete = constants.%Bar] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {
|
||||
// CHECK:STDOUT: %bar.patt: <error> = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: <error> = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %bar.patt: %pattern_type = binding_pattern bar [concrete]
|
||||
// CHECK:STDOUT: %bar.param_patt: %pattern_type = value_param_pattern %bar.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %bar.param: <error> = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc14: type = splice_block %ptr [concrete = <error>] {
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref: <error> = name_ref Bar, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %bar: <error> = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: %bar: %ptr = bind_name bar, %bar.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: <error>);
|
||||
// CHECK:STDOUT: fn @MyF(%bar.param: %ptr);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_definition.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -296,7 +300,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -332,7 +335,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr [concrete = constants.%ptr] {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref [concrete = constants.%ptr]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -363,7 +365,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: fn @MyF() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %foo.ref: %Bar.foo.type = name_ref foo, imports.%Bar.foo.decl [concrete = constants.%Bar.foo]
|
||||
// CHECK:STDOUT: %Bar.foo.call: init %empty_tuple.type = call %foo.ref()
|
||||
@@ -396,7 +397,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc19: type = splice_block %ptr [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc19_12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref.loc19_15: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Bar.ref.loc19_15 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -404,11 +404,12 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_public_data_member.carbon
|
||||
// CHECK:STDOUT: --- import_public_data_member.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %Bar: type = class_type @Bar [concrete]
|
||||
// CHECK:STDOUT: %ptr.f68: type = ptr_type %Bar [concrete]
|
||||
// CHECK:STDOUT: %Bar.elem: type = unbound_element_type %Bar, %ptr.f68 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr.f68 [concrete]
|
||||
// CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete]
|
||||
// CHECK:STDOUT: %MyF: %MyF.type = struct_value () [concrete]
|
||||
@@ -430,7 +431,6 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %bar.param: %ptr.f68 = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc7: type = splice_block %ptr.loc7 [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc7: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Bar.ref.loc7: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr.loc7: type = ptr_type %Bar.ref.loc7 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -444,14 +444,16 @@ fn MyF(bar: Cpp.Bar*);
|
||||
// CHECK:STDOUT: %foo_bar.patt: %pattern_type = binding_pattern foo_bar [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %bar.ref: %ptr.f68 = name_ref bar, %bar
|
||||
// CHECK:STDOUT: %.loc19_30: ref %Bar = deref %bar.ref
|
||||
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc19_23: type = splice_block %ptr.loc19 [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref.loc19: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr.loc19: type = ptr_type %Bar.ref.loc19 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: %.loc8_30.1: ref %Bar = deref %bar.ref
|
||||
// CHECK:STDOUT: %foo.ref: %Bar.elem = name_ref foo, @Bar.%.1 [concrete = @Bar.%.1]
|
||||
// CHECK:STDOUT: %.loc8_30.2: ref %ptr.f68 = class_element_access %.loc8_30.1, element0
|
||||
// CHECK:STDOUT: %.loc8_23: type = splice_block %ptr.loc8 [concrete = constants.%ptr.f68] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Bar.ref.loc8: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar]
|
||||
// CHECK:STDOUT: %ptr.loc8: type = ptr_type %Bar.ref.loc8 [concrete = constants.%ptr.f68]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo_bar: %ptr.f68 = bind_name foo_bar, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc8_30.3: %ptr.f68 = bind_value %.loc8_30.2
|
||||
// CHECK:STDOUT: %foo_bar: %ptr.f68 = bind_name foo_bar, %.loc8_30.3
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+67
-90
@@ -2,7 +2,7 @@
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/destroy.carbon
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
@@ -27,12 +27,12 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "decl_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+7]]:11: error: forming value of incomplete type `Cpp.C` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo({});
|
||||
}
|
||||
@@ -44,12 +44,11 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "decl_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+11]]:10: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: let c: Cpp.C;
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+8]]:10: note: in `Cpp` name lookup for `C` [InCppNameLookup]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+10]]:10: error: binding pattern has incomplete type `C` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: let c: Cpp.C;
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+4]]:15: error: expected `=`; `let` declaration must have an initializer [ExpectedInitializerAfterLet]
|
||||
// CHECK:STDERR: let c: Cpp.C;
|
||||
@@ -77,14 +76,21 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "double_decl_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+7]]:12: error: forming value of incomplete type `Cpp.C` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo1({});
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo1` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo1({});
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./double_decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo1({});
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+7]]:12: error: forming value of incomplete type `Cpp.C` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo2({});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE-14]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./double_decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo2({});
|
||||
}
|
||||
|
||||
@@ -124,7 +130,7 @@ class C {
|
||||
|
||||
auto foo(C) -> void;
|
||||
|
||||
// --- import_definition_single_data_member_value_param_type.carbon
|
||||
// --- fail_todo_import_definition_single_data_member_value_param_type.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -132,6 +138,14 @@ import Cpp library "definition_single_data_member_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_definition_single_data_member_value_param_type.carbon:[[@LINE+8]]:11: error: cannot implicitly convert expression of type `{}` to `Cpp.C` [ConversionFailure]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_definition_single_data_member_value_param_type.carbon:[[@LINE+5]]:11: note: type `{}` does not implement interface `Core.ImplicitAs(Cpp.C)` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_definition_single_data_member_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo({});
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
@@ -152,7 +166,7 @@ class C {
|
||||
|
||||
auto foo(C) -> void;
|
||||
|
||||
// --- import_definition_multiple_data_members_value_param_type.carbon
|
||||
// --- fail_todo_import_definition_multiple_data_members_value_param_type.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -160,6 +174,14 @@ import Cpp library "definition_multiple_data_members_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_definition_multiple_data_members_value_param_type.carbon:[[@LINE+8]]:11: error: cannot implicitly convert expression of type `{}` to `Cpp.C` [ConversionFailure]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_definition_multiple_data_members_value_param_type.carbon:[[@LINE+5]]:11: note: type `{}` does not implement interface `Core.ImplicitAs(Cpp.C)` [MissingImplInMemberAccessNote]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_definition_multiple_data_members_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo({});
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
@@ -285,19 +307,12 @@ class C;
|
||||
|
||||
auto foo(C* _Nonnull) -> void;
|
||||
|
||||
// --- fail_todo_import_decl_pointer_param_type.carbon
|
||||
// --- import_decl_pointer_param_type.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "decl_pointer_param_type.h";
|
||||
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_param_type.carbon:[[@LINE+7]]:9: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn F(c: Cpp.C*) {
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_param_type.carbon:[[@LINE+4]]:9: note: in `Cpp` name lookup for `C` [InCppNameLookup]
|
||||
// CHECK:STDERR: fn F(c: Cpp.C*) {
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR:
|
||||
fn F(c: Cpp.C*) {
|
||||
//@dump-sem-ir-begin
|
||||
Cpp.foo(c);
|
||||
@@ -343,12 +358,12 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "decl_value_return_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+7]]:3: error: function returns incomplete type `Cpp.C` [IncompleteTypeInFunctionReturnType]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon: note: return type declared here [IncompleteReturnTypeHere]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo();
|
||||
}
|
||||
@@ -385,7 +400,7 @@ class C;
|
||||
|
||||
auto foo() -> C* _Nonnull;
|
||||
|
||||
// --- fail_todo_import_decl_pointer_return_type.carbon
|
||||
// --- import_decl_pointer_return_type.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -393,13 +408,6 @@ import Cpp library "decl_pointer_return_type.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_return_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_return_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo();
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
@@ -455,7 +463,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %C = temporary_storage
|
||||
@@ -472,7 +479,7 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_definition_single_data_member_value_param_type.carbon
|
||||
// CHECK:STDOUT: --- fail_todo_import_definition_single_data_member_value_param_type.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
@@ -480,10 +487,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %C.val: %C = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.1b3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.21b: %T.as.Destroy.impl.Op.type.1b3 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -501,24 +504,14 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %C = temporary_storage
|
||||
// CHECK:STDOUT: %.loc8_12.3: init %C = class_init (), %.loc8_12.2 [concrete = constants.%C.val]
|
||||
// CHECK:STDOUT: %.loc8_12.4: ref %C = temporary %.loc8_12.2, %.loc8_12.3
|
||||
// CHECK:STDOUT: %.loc8_12.5: ref %C = converted %.loc8_12.1, %.loc8_12.4
|
||||
// CHECK:STDOUT: %.loc8_12.6: %C = bind_value %.loc8_12.5
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_12.6)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_12.2, constants.%T.as.Destroy.impl.Op.21b
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_12.2, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc8_12.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
|
||||
// CHECK:STDOUT: %.loc16_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc16_12.2: %C = converted %.loc16_12.1, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_definition_multiple_data_members_value_param_type.carbon
|
||||
// CHECK:STDOUT: --- fail_todo_import_definition_multiple_data_members_value_param_type.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
@@ -526,10 +519,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %C.val: %C = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.1b3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.21b: %T.as.Destroy.impl.Op.type.1b3 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -547,20 +536,10 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %C = temporary_storage
|
||||
// CHECK:STDOUT: %.loc8_12.3: init %C = class_init (), %.loc8_12.2 [concrete = constants.%C.val]
|
||||
// CHECK:STDOUT: %.loc8_12.4: ref %C = temporary %.loc8_12.2, %.loc8_12.3
|
||||
// CHECK:STDOUT: %.loc8_12.5: ref %C = converted %.loc8_12.1, %.loc8_12.4
|
||||
// CHECK:STDOUT: %.loc8_12.6: %C = bind_value %.loc8_12.5
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_12.6)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_12.2, constants.%T.as.Destroy.impl.Op.21b
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_12.2, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc8_12.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
|
||||
// CHECK:STDOUT: %.loc16_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc16_12.2: %C = converted %.loc16_12.1, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -600,7 +579,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %C = temporary_storage
|
||||
@@ -667,7 +645,6 @@ fn F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %N1.ref: <namespace> = name_ref N1, imports.%N1 [concrete = imports.%N1]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_15.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_15.2: ref %C = temporary_storage
|
||||
@@ -720,7 +697,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %C = temporary_storage
|
||||
@@ -786,7 +762,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %bar.ref: %C.bar.type = name_ref bar, imports.%C.bar.decl [concrete = constants.%C.bar]
|
||||
// CHECK:STDOUT: %C.bar.call: init %empty_tuple.type = call %bar.ref()
|
||||
@@ -841,7 +816,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %C = temporary_storage
|
||||
@@ -862,9 +836,11 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_decl_pointer_param_type.carbon
|
||||
// CHECK:STDOUT: --- import_decl_pointer_param_type.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
@@ -872,10 +848,11 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .C = <error>
|
||||
// CHECK:STDOUT: .C = %C.decl
|
||||
// CHECK:STDOUT: .foo = %foo.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
@@ -883,12 +860,12 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%c.param: <error>) {
|
||||
// CHECK:STDOUT: fn @F(%c.param: %ptr) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc15: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %c.ref: <error> = name_ref c, %c
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
|
||||
// CHECK:STDOUT: %c.ref: %ptr = name_ref c, %c
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%c.ref)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -952,7 +929,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_11.1: ref %C = temporary_storage
|
||||
// CHECK:STDOUT: %foo.call: init %C = call %foo.ref() to %.loc8_11.1
|
||||
@@ -965,9 +941,11 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_decl_pointer_return_type.carbon
|
||||
// CHECK:STDOUT: --- import_decl_pointer_return_type.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -988,7 +966,7 @@ fn F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %foo.call: init <error> = call %foo.ref()
|
||||
// CHECK:STDOUT: %foo.call: init %ptr = call %foo.ref()
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -1016,7 +994,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %foo.call: init %ptr = call %foo.ref()
|
||||
// CHECK:STDOUT: <elided>
|
||||
|
||||
@@ -77,7 +77,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %Y.ref: type = name_ref Y, imports.%X.decl [concrete = constants.%X]
|
||||
// CHECK:STDOUT: %f.ref: %X.f.type = name_ref f, imports.%X.f.decl [concrete = constants.%X.f]
|
||||
// CHECK:STDOUT: %int_42: Core.IntLiteral = int_value 42 [concrete = constants.%int_42.20e]
|
||||
|
||||
@@ -229,7 +229,6 @@ fn F() {
|
||||
// CHECK:STDOUT: assign %s.var, %.loc8_3
|
||||
// CHECK:STDOUT: %.loc8_13: type = splice_block %S.ref [concrete = constants.%S] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %s: ref %S = bind_name s, %s.var
|
||||
@@ -292,7 +291,6 @@ fn F() {
|
||||
// CHECK:STDOUT: assign %s.var, %.loc8_3
|
||||
// CHECK:STDOUT: %.loc8_13: type = splice_block %S.ref.loc8 [concrete = constants.%S] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %S.ref.loc8: type = name_ref S, imports.%S.decl [concrete = constants.%S]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %s: ref %S = bind_name s, %s.var
|
||||
@@ -560,7 +558,6 @@ fn F() {
|
||||
// CHECK:STDOUT: assign %s.var, %.loc8_3
|
||||
// CHECK:STDOUT: %.loc8_13: type = splice_block %S.ref [concrete = constants.%S] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %s: ref %S = bind_name s, %s.var
|
||||
|
||||
+60
-89
@@ -27,12 +27,12 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "decl_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+7]]:11: error: forming value of incomplete type `Cpp.S` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo({});
|
||||
}
|
||||
@@ -44,12 +44,11 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "decl_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+11]]:10: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: let s: Cpp.S;
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+8]]:10: note: in `Cpp` name lookup for `S` [InCppNameLookup]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+10]]:10: error: binding pattern has incomplete type `S` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: let s: Cpp.S;
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+4]]:15: error: expected `=`; `let` declaration must have an initializer [ExpectedInitializerAfterLet]
|
||||
// CHECK:STDERR: let s: Cpp.S;
|
||||
@@ -77,14 +76,21 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "double_decl_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+7]]:12: error: forming value of incomplete type `Cpp.S` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo1({});
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo1` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo1({});
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./double_decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo1({});
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+7]]:12: error: forming value of incomplete type `Cpp.S` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo2({});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE-14]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./double_decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo2({});
|
||||
}
|
||||
|
||||
@@ -124,7 +130,7 @@ struct S {
|
||||
|
||||
auto foo(S) -> void;
|
||||
|
||||
// --- import_definition_single_data_member_value_param_type.carbon
|
||||
// --- fail_todo_import_definition_single_data_member_value_param_type.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -132,6 +138,11 @@ import Cpp library "definition_single_data_member_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_definition_single_data_member_value_param_type.carbon:[[@LINE+5]]:11: error: name `Core.ImplicitAs` implicitly referenced here, but not found [CoreNameNotFound]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_definition_single_data_member_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo({});
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
@@ -152,7 +163,7 @@ struct S {
|
||||
|
||||
auto foo(S) -> void;
|
||||
|
||||
// --- import_definition_multiple_data_members_value_param_type.carbon
|
||||
// --- fail_todo_import_definition_multiple_data_members_value_param_type.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -160,6 +171,11 @@ import Cpp library "definition_multiple_data_members_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_definition_multiple_data_members_value_param_type.carbon:[[@LINE+5]]:11: error: name `Core.ImplicitAs` implicitly referenced here, but not found [CoreNameNotFound]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_definition_multiple_data_members_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo({});
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
@@ -284,19 +300,12 @@ struct S;
|
||||
|
||||
auto foo(S* _Nonnull) -> void;
|
||||
|
||||
// --- fail_todo_import_decl_pointer_param_type.carbon
|
||||
// --- import_decl_pointer_param_type.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "decl_pointer_param_type.h";
|
||||
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_param_type.carbon:[[@LINE+7]]:9: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn F(s: Cpp.S*) {
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_param_type.carbon:[[@LINE+4]]:9: note: in `Cpp` name lookup for `S` [InCppNameLookup]
|
||||
// CHECK:STDERR: fn F(s: Cpp.S*) {
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR:
|
||||
fn F(s: Cpp.S*) {
|
||||
//@dump-sem-ir-begin
|
||||
Cpp.foo(s);
|
||||
@@ -342,12 +351,12 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "decl_value_return_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+7]]:3: error: function returns incomplete type `Cpp.S` [IncompleteTypeInFunctionReturnType]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon: note: return type declared here [IncompleteReturnTypeHere]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo();
|
||||
}
|
||||
@@ -384,7 +393,7 @@ struct S;
|
||||
|
||||
auto foo() -> S* _Nonnull;
|
||||
|
||||
// --- fail_todo_import_decl_pointer_return_type.carbon
|
||||
// --- import_decl_pointer_return_type.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -392,13 +401,6 @@ import Cpp library "decl_pointer_return_type.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_return_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_return_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo();
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
@@ -454,7 +456,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
|
||||
@@ -471,7 +472,7 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_definition_single_data_member_value_param_type.carbon
|
||||
// CHECK:STDOUT: --- fail_todo_import_definition_single_data_member_value_param_type.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
@@ -479,10 +480,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.642: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%S) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.ab5: %T.as.Destroy.impl.Op.type.642 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -500,24 +497,14 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
|
||||
// CHECK:STDOUT: %.loc8_12.3: init %S = class_init (), %.loc8_12.2 [concrete = constants.%S.val]
|
||||
// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3
|
||||
// CHECK:STDOUT: %.loc8_12.5: ref %S = converted %.loc8_12.1, %.loc8_12.4
|
||||
// CHECK:STDOUT: %.loc8_12.6: %S = bind_value %.loc8_12.5
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_12.6)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_12.2, constants.%T.as.Destroy.impl.Op.ab5
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_12.2, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_12.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
|
||||
// CHECK:STDOUT: %.loc13_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc13_12.2: %S = converted %.loc13_12.1, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_definition_multiple_data_members_value_param_type.carbon
|
||||
// CHECK:STDOUT: --- fail_todo_import_definition_multiple_data_members_value_param_type.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
@@ -525,10 +512,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.642: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%S) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.ab5: %T.as.Destroy.impl.Op.type.642 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -546,20 +529,10 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
|
||||
// CHECK:STDOUT: %.loc8_12.3: init %S = class_init (), %.loc8_12.2 [concrete = constants.%S.val]
|
||||
// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3
|
||||
// CHECK:STDOUT: %.loc8_12.5: ref %S = converted %.loc8_12.1, %.loc8_12.4
|
||||
// CHECK:STDOUT: %.loc8_12.6: %S = bind_value %.loc8_12.5
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_12.6)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_12.2, constants.%T.as.Destroy.impl.Op.ab5
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_12.2, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_12.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
|
||||
// CHECK:STDOUT: %.loc13_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc13_12.2: %S = converted %.loc13_12.1, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -599,7 +572,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
|
||||
@@ -666,7 +638,6 @@ fn F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %N1.ref: <namespace> = name_ref N1, imports.%N1 [concrete = imports.%N1]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_15.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_15.2: ref %S = temporary_storage
|
||||
@@ -719,7 +690,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
|
||||
@@ -785,7 +755,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
|
||||
// CHECK:STDOUT: %bar.ref: %S.bar.type = name_ref bar, imports.%S.bar.decl [concrete = constants.%S.bar]
|
||||
// CHECK:STDOUT: %S.bar.call: init %empty_tuple.type = call %bar.ref()
|
||||
@@ -840,7 +809,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
|
||||
@@ -861,9 +829,11 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_decl_pointer_param_type.carbon
|
||||
// CHECK:STDOUT: --- import_decl_pointer_param_type.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %S: type = class_type @S [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %S [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
@@ -871,10 +841,11 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .S = <error>
|
||||
// CHECK:STDOUT: .S = %S.decl
|
||||
// CHECK:STDOUT: .foo = %foo.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {}
|
||||
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
@@ -882,12 +853,12 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%s.param: <error>) {
|
||||
// CHECK:STDOUT: fn @F(%s.param: %ptr) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc15: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %s.ref: <error> = name_ref s, %s
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
|
||||
// CHECK:STDOUT: %s.ref: %ptr = name_ref s, %s
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%s.ref)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -951,7 +922,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_11.1: ref %S = temporary_storage
|
||||
// CHECK:STDOUT: %foo.call: init %S = call %foo.ref() to %.loc8_11.1
|
||||
@@ -964,9 +934,11 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_decl_pointer_return_type.carbon
|
||||
// CHECK:STDOUT: --- import_decl_pointer_return_type.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %S: type = class_type @S [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %S [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -987,7 +959,7 @@ fn F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %foo.call: init <error> = call %foo.ref()
|
||||
// CHECK:STDOUT: %foo.call: init %ptr = call %foo.ref()
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -1015,7 +987,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %foo.call: init %ptr = call %foo.ref()
|
||||
// CHECK:STDOUT: <elided>
|
||||
|
||||
+50
-56
@@ -28,12 +28,12 @@ import Cpp library "decl_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+7]]:11: error: forming value of incomplete type `Cpp.U` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE-7]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo({});
|
||||
//@dump-sem-ir-end
|
||||
@@ -46,12 +46,11 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "decl_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+11]]:10: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: let u: Cpp.U;
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+8]]:10: note: in `Cpp` name lookup for `U` [InCppNameLookup]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+10]]:10: error: binding pattern has incomplete type `U` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: let u: Cpp.U;
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+4]]:15: error: expected `=`; `let` declaration must have an initializer [ExpectedInitializerAfterLet]
|
||||
// CHECK:STDERR: let u: Cpp.U;
|
||||
@@ -79,14 +78,21 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "double_decl_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+7]]:12: error: forming value of incomplete type `Cpp.U` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo1({});
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo1` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo1({});
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./double_decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo1({});
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+7]]:12: error: forming value of incomplete type `Cpp.U` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo2({});
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE-14]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./double_decl_value_param_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo2({});
|
||||
}
|
||||
|
||||
@@ -134,12 +140,10 @@ import Cpp library "definition_single_data_member_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_import_definition_single_data_member_value_param_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Non-empty union` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_import_definition_single_data_member_value_param_type.carbon:[[@LINE+5]]:11: error: name `Core.ImplicitAs` implicitly referenced here, but not found [CoreNameNotFound]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_import_definition_single_data_member_value_param_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_import_definition_single_data_member_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo({});
|
||||
//@dump-sem-ir-end
|
||||
@@ -169,12 +173,10 @@ import Cpp library "definition_multiple_data_members_value_param_type.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_import_definition_multiple_data_members_value_param_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Non-empty union` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_import_definition_multiple_data_members_value_param_type.carbon:[[@LINE+5]]:11: error: name `Core.ImplicitAs` implicitly referenced here, but not found [CoreNameNotFound]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_import_definition_multiple_data_members_value_param_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo({});
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_import_definition_multiple_data_members_value_param_type.carbon: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo({});
|
||||
//@dump-sem-ir-end
|
||||
@@ -301,19 +303,12 @@ union U;
|
||||
|
||||
auto foo(U* _Nonnull) -> void;
|
||||
|
||||
// --- fail_todo_import_decl_pointer_param_type.carbon
|
||||
// --- import_decl_pointer_param_type.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "decl_pointer_param_type.h";
|
||||
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_param_type.carbon:[[@LINE+7]]:9: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn F(u: Cpp.U*) {
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_param_type.carbon:[[@LINE+4]]:9: note: in `Cpp` name lookup for `U` [InCppNameLookup]
|
||||
// CHECK:STDERR: fn F(u: Cpp.U*) {
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR:
|
||||
fn F(u: Cpp.U*) {
|
||||
//@dump-sem-ir-begin
|
||||
Cpp.foo(u);
|
||||
@@ -359,12 +354,12 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "decl_value_return_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+7]]:3: error: function returns incomplete type `Cpp.U` [IncompleteTypeInFunctionReturnType]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon: note: return type declared here [IncompleteReturnTypeHere]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo();
|
||||
}
|
||||
@@ -409,7 +404,7 @@ import Cpp library "decl_pointer_return_type.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_return_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_return_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: nullable pointer: U *` [SemanticsTodo]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_decl_pointer_return_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
@@ -501,7 +496,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %U = temporary_storage
|
||||
@@ -522,9 +516,10 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %U: type = class_type @U [concrete]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -543,7 +538,8 @@ fn F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc15: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc13_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc13_12.2: %U = converted %.loc13_12.1, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
@@ -552,9 +548,10 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %U: type = class_type @U [concrete]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -573,7 +570,8 @@ fn F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc15: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc13_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc13_12.2: %U = converted %.loc13_12.1, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
@@ -614,7 +612,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %U = temporary_storage
|
||||
@@ -681,7 +678,6 @@ fn F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %N1.ref: <namespace> = name_ref N1, imports.%N1 [concrete = imports.%N1]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_15.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_15.2: ref %U = temporary_storage
|
||||
@@ -734,7 +730,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %U = temporary_storage
|
||||
@@ -800,7 +795,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %U.ref: type = name_ref U, imports.%U.decl [concrete = constants.%U]
|
||||
// CHECK:STDOUT: %bar.ref: %U.bar.type = name_ref bar, imports.%U.bar.decl [concrete = constants.%U.bar]
|
||||
// CHECK:STDOUT: %U.bar.call: init %empty_tuple.type = call %bar.ref()
|
||||
@@ -855,7 +849,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
|
||||
// CHECK:STDOUT: %.loc8_12.2: ref %U = temporary_storage
|
||||
@@ -876,9 +869,11 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_decl_pointer_param_type.carbon
|
||||
// CHECK:STDOUT: --- import_decl_pointer_param_type.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %U: type = class_type @U [concrete]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %U [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
@@ -886,10 +881,11 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .U = <error>
|
||||
// CHECK:STDOUT: .U = %U.decl
|
||||
// CHECK:STDOUT: .foo = %foo.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %U.decl: type = class_decl @U [concrete = constants.%U] {} {}
|
||||
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
@@ -897,12 +893,12 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%u.param: <error>) {
|
||||
// CHECK:STDOUT: fn @F(%u.param: %ptr) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc15: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %u.ref: <error> = name_ref u, %u
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
|
||||
// CHECK:STDOUT: %u.ref: %ptr = name_ref u, %u
|
||||
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%u.ref)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -966,7 +962,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_11.1: ref %U = temporary_storage
|
||||
// CHECK:STDOUT: %foo.call: init %U = call %foo.ref() to %.loc8_11.1
|
||||
@@ -1030,7 +1025,6 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %foo.call: init %ptr = call %foo.ref()
|
||||
// CHECK:STDOUT: <elided>
|
||||
|
||||
@@ -331,7 +331,6 @@ fn MyF() {
|
||||
// CHECK:STDOUT: fn @MyF() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_11.1: ref %X = temporary_storage
|
||||
// CHECK:STDOUT: %foo.call: init %X = call %foo.ref() to %.loc8_11.1
|
||||
|
||||
@@ -140,6 +140,10 @@ class TypeCompleter {
|
||||
auto BuildInfoForInst(SemIR::TypeId /*type_id*/, SemIR::ConstType inst) const
|
||||
-> SemIR::CompleteTypeInfo;
|
||||
|
||||
auto BuildInfoForInst(SemIR::TypeId type_id,
|
||||
SemIR::CustomLayoutType inst) const
|
||||
-> SemIR::CompleteTypeInfo;
|
||||
|
||||
auto BuildInfoForInst(SemIR::TypeId /*type_id*/,
|
||||
SemIR::PartialType inst) const
|
||||
-> SemIR::CompleteTypeInfo;
|
||||
@@ -294,6 +298,12 @@ auto TypeCompleter::AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool {
|
||||
Push(context_->types().GetTypeIdForTypeInstId(inst.inner_id));
|
||||
break;
|
||||
}
|
||||
case CARBON_KIND(SemIR::CustomLayoutType inst): {
|
||||
for (auto field : context_->struct_type_fields().Get(inst.fields_id)) {
|
||||
Push(context_->types().GetTypeIdForTypeInstId(field.type_inst_id));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CARBON_KIND(SemIR::PartialType inst): {
|
||||
Push(context_->types().GetTypeIdForTypeInstId(inst.inner_id));
|
||||
break;
|
||||
@@ -520,6 +530,14 @@ auto TypeCompleter::BuildInfoForInst(SemIR::TypeId /*type_id*/,
|
||||
return GetNestedInfo(context_->types().GetTypeIdForTypeInstId(inst.inner_id));
|
||||
}
|
||||
|
||||
auto TypeCompleter::BuildInfoForInst(SemIR::TypeId type_id,
|
||||
SemIR::CustomLayoutType /*inst*/) const
|
||||
-> SemIR::CompleteTypeInfo {
|
||||
// TODO: Should we support other value representations for custom layout
|
||||
// types?
|
||||
return {.value_repr = MakePointerValueRepr(type_id)};
|
||||
}
|
||||
|
||||
auto TypeCompleter::BuildInfoForInst(SemIR::TypeId /*type_id*/,
|
||||
SemIR::PartialType inst) const
|
||||
-> SemIR::CompleteTypeInfo {
|
||||
|
||||
@@ -768,6 +768,13 @@ static auto BuildTypeForInst(FileContext& context, SemIR::ConstType inst)
|
||||
context.sem_ir().types().GetTypeIdForTypeInstId(inst.inner_id));
|
||||
}
|
||||
|
||||
static auto BuildTypeForInst(FileContext& context, SemIR::CustomLayoutType inst)
|
||||
-> llvm::Type* {
|
||||
auto layout = context.sem_ir().custom_layouts().Get(inst.layout_id);
|
||||
return llvm::ArrayType::get(llvm::Type::getInt8Ty(context.llvm_context()),
|
||||
layout[SemIR::CustomLayoutId::SizeIndex]);
|
||||
}
|
||||
|
||||
static auto BuildTypeForInst(FileContext& context, SemIR::PartialType inst)
|
||||
-> llvm::Type* {
|
||||
return context.GetType(
|
||||
|
||||
@@ -218,6 +218,8 @@ auto FunctionContext::CreateAlloca(llvm::Type* type, const llvm::Twine& name)
|
||||
builder().SetCurrentDebugLocation(debug_loc);
|
||||
|
||||
// Create an alloca for this variable in the entry block.
|
||||
// TODO: Compute alignment of the type, which may be greater than the
|
||||
// alignment computed by LLVM.
|
||||
alloca = builder().CreateAlloca(type, /*ArraySize=*/nullptr, name);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "toolchain/lower/function_context.h"
|
||||
#include "toolchain/sem_ir/expr_info.h"
|
||||
#include "toolchain/sem_ir/file.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
|
||||
@@ -26,6 +27,30 @@ static auto GetPointeeType(FunctionContext::TypeInFile type)
|
||||
.type_id = type.file->GetPointeeType(type.type_id)};
|
||||
}
|
||||
|
||||
// Given an index within a SemIR aggregate type, returns the corresponding index
|
||||
// of the element within the LLVM type suitable for use with the getelementptr
|
||||
// instruction.
|
||||
static auto GetElementIndex(FunctionContext::TypeInFile type,
|
||||
SemIR::ElementIndex idx) -> unsigned int {
|
||||
auto type_inst = type.file->types().GetAsInst(type.type_id);
|
||||
|
||||
if (auto custom_layout_type = type_inst.TryAs<SemIR::CustomLayoutType>()) {
|
||||
// For custom layout types, we form an array of i8 as the LLVM type, so the
|
||||
// offset in the type is the getelementptr index.
|
||||
// TODO: This offset might not fit into an `unsigned int`.
|
||||
return type.file->custom_layouts().Get(
|
||||
custom_layout_type
|
||||
->layout_id)[SemIR::CustomLayoutId::FirstFieldIndex + idx.index];
|
||||
}
|
||||
|
||||
// For now, struct and tuple types map directly into LLVM struct types with
|
||||
// identical field numbering.
|
||||
CARBON_CHECK(
|
||||
type_inst.Is<SemIR::StructType>() || type_inst.Is<SemIR::TupleType>(),
|
||||
"Indexing unexpected aggregate type {0}", type_inst);
|
||||
return idx.index;
|
||||
}
|
||||
|
||||
// Extracts an element of an aggregate, such as a struct, tuple, or class, by
|
||||
// index. Depending on the expression category and value representation of the
|
||||
// aggregate input, this will either produce a value or a reference.
|
||||
@@ -58,14 +83,16 @@ static auto GetAggregateElement(FunctionContext& context,
|
||||
return aggr_value;
|
||||
case SemIR::ValueRepr::Copy:
|
||||
// We are holding the values of the aggregate directly, elementwise.
|
||||
return context.builder().CreateExtractValue(aggr_value, idx.index,
|
||||
name);
|
||||
return context.builder().CreateExtractValue(
|
||||
aggr_value, GetElementIndex(value_repr.type(), idx), name);
|
||||
case SemIR::ValueRepr::Pointer: {
|
||||
// The value representation is a pointer to an aggregate that we want
|
||||
// to index into.
|
||||
auto* value_type = context.GetType(GetPointeeType(value_repr.type()));
|
||||
auto value_rep_type = GetPointeeType(value_repr.type());
|
||||
auto* value_type = context.GetType(value_rep_type);
|
||||
auto* elem_ptr = context.builder().CreateStructGEP(
|
||||
value_type, aggr_value, idx.index, name);
|
||||
value_type, aggr_value, GetElementIndex(value_rep_type, idx),
|
||||
name);
|
||||
|
||||
if (!value_repr.repr.elements_are_values()) {
|
||||
// `elem_ptr` points to an object representation, which is our
|
||||
@@ -88,17 +115,21 @@ static auto GetAggregateElement(FunctionContext& context,
|
||||
case SemIR::ExprCategory::DurableRef:
|
||||
case SemIR::ExprCategory::EphemeralRef: {
|
||||
// Just locate the aggregate element.
|
||||
auto* aggr_type = context.GetTypeOfInst(aggr_inst_id);
|
||||
return context.builder().CreateStructGEP(aggr_type, aggr_value, idx.index,
|
||||
name);
|
||||
auto aggr_type = context.GetTypeIdOfInst(aggr_inst_id);
|
||||
auto object_repr = FunctionContext::TypeInFile{
|
||||
.file = aggr_type.file,
|
||||
.type_id = aggr_type.file->types().GetObjectRepr(aggr_type.type_id)};
|
||||
return context.builder().CreateStructGEP(
|
||||
context.GetType(object_repr), aggr_value,
|
||||
GetElementIndex(object_repr, idx), name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static auto GetStructFieldName(FunctionContext::TypeInFile struct_type,
|
||||
SemIR::ElementIndex index) -> llvm::StringRef {
|
||||
auto struct_type_inst =
|
||||
struct_type.file->types().GetAs<SemIR::StructType>(struct_type.type_id);
|
||||
auto struct_type_inst = struct_type.file->types().GetAs<SemIR::AnyStructType>(
|
||||
struct_type.type_id);
|
||||
auto fields =
|
||||
struct_type.file->struct_type_fields().Get(struct_type_inst.fields_id);
|
||||
// We intentionally don't add this to the fingerprint because it's only used
|
||||
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/interop/cpp/field.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/interop/cpp/field.carbon
|
||||
|
||||
// --- struct.h
|
||||
|
||||
struct A {
|
||||
int n;
|
||||
alignas(16) int m;
|
||||
};
|
||||
|
||||
// --- access_struct.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "struct.h";
|
||||
|
||||
// TODO: We generate 4-byte-aligned loads here, and should generate
|
||||
// 16-byte-aligned loads as Clang does.
|
||||
fn AccessN(a: Cpp.A) -> i32 {
|
||||
return a.n;
|
||||
}
|
||||
|
||||
fn AccessM(a: Cpp.A) -> i32 {
|
||||
return a.m;
|
||||
}
|
||||
|
||||
// --- assign_struct.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "struct.h";
|
||||
|
||||
// TODO: We generate 4-byte-aligned stores here, and should generate
|
||||
// 16-byte-aligned stores as Clang does.
|
||||
fn AssignN(p: Cpp.A*) {
|
||||
p->n = 1;
|
||||
}
|
||||
|
||||
fn AssignM(p: Cpp.A*) {
|
||||
p->m = 1;
|
||||
}
|
||||
|
||||
// --- union.h
|
||||
|
||||
union A {
|
||||
int n;
|
||||
int m;
|
||||
};
|
||||
|
||||
// --- access_union.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "union.h";
|
||||
|
||||
fn AccessN(a: Cpp.A) -> i32 {
|
||||
return a.n;
|
||||
}
|
||||
|
||||
fn AccessM(a: Cpp.A) -> i32 {
|
||||
return a.m;
|
||||
}
|
||||
|
||||
// --- assign_union.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp library "union.h";
|
||||
|
||||
fn AssignN(p: Cpp.A*) {
|
||||
p->n = 1;
|
||||
}
|
||||
|
||||
fn AssignM(p: Cpp.A*) {
|
||||
p->m = 1;
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: ; ModuleID = 'access_struct.carbon'
|
||||
// CHECK:STDOUT: source_filename = "access_struct.carbon"
|
||||
// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
||||
// CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: define i32 @_CAccessN.Main(ptr %a) !dbg !7 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc9_11.1.n = getelementptr inbounds nuw [32 x i8], ptr %a, i32 0, i32 0, !dbg !10
|
||||
// CHECK:STDOUT: %.loc9_11.2 = load i32, ptr %.loc9_11.1.n, align 4, !dbg !10
|
||||
// CHECK:STDOUT: ret i32 %.loc9_11.2, !dbg !11
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: define i32 @_CAccessM.Main(ptr %a) !dbg !12 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc13_11.1.m = getelementptr inbounds nuw [32 x i8], ptr %a, i32 0, i32 16, !dbg !13
|
||||
// CHECK:STDOUT: %.loc13_11.2 = load i32, ptr %.loc13_11.1.m, align 4, !dbg !13
|
||||
// CHECK:STDOUT: ret i32 %.loc13_11.2, !dbg !14
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4}
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!5}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
// CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
|
||||
// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
|
||||
// CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
|
||||
// CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C, file: !6, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !6 = !DIFile(filename: "access_struct.carbon", directory: "")
|
||||
// CHECK:STDOUT: !7 = distinct !DISubprogram(name: "AccessN", linkageName: "_CAccessN.Main", scope: null, file: !6, line: 8, type: !8, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !8 = !DISubroutineType(types: !9)
|
||||
// CHECK:STDOUT: !9 = !{}
|
||||
// CHECK:STDOUT: !10 = !DILocation(line: 9, column: 10, scope: !7)
|
||||
// CHECK:STDOUT: !11 = !DILocation(line: 9, column: 3, scope: !7)
|
||||
// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "AccessM", linkageName: "_CAccessM.Main", scope: null, file: !6, line: 12, type: !8, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !13 = !DILocation(line: 13, column: 10, scope: !12)
|
||||
// CHECK:STDOUT: !14 = !DILocation(line: 13, column: 3, scope: !12)
|
||||
// CHECK:STDOUT: ; ModuleID = 'assign_struct.carbon'
|
||||
// CHECK:STDOUT: source_filename = "assign_struct.carbon"
|
||||
// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
||||
// CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: define void @_CAssignN.Main(ptr %p) !dbg !7 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc9_4.2.n = getelementptr inbounds nuw [32 x i8], ptr %p, i32 0, i32 0, !dbg !10
|
||||
// CHECK:STDOUT: store i32 1, ptr %.loc9_4.2.n, align 4, !dbg !10
|
||||
// CHECK:STDOUT: ret void, !dbg !11
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: define void @_CAssignM.Main(ptr %p) !dbg !12 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc13_4.2.m = getelementptr inbounds nuw [32 x i8], ptr %p, i32 0, i32 16, !dbg !13
|
||||
// CHECK:STDOUT: store i32 1, ptr %.loc13_4.2.m, align 4, !dbg !13
|
||||
// CHECK:STDOUT: ret void, !dbg !14
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4}
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!5}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
// CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
|
||||
// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
|
||||
// CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
|
||||
// CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C, file: !6, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !6 = !DIFile(filename: "assign_struct.carbon", directory: "")
|
||||
// CHECK:STDOUT: !7 = distinct !DISubprogram(name: "AssignN", linkageName: "_CAssignN.Main", scope: null, file: !6, line: 8, type: !8, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !8 = !DISubroutineType(types: !9)
|
||||
// CHECK:STDOUT: !9 = !{}
|
||||
// CHECK:STDOUT: !10 = !DILocation(line: 9, column: 3, scope: !7)
|
||||
// CHECK:STDOUT: !11 = !DILocation(line: 8, column: 1, scope: !7)
|
||||
// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "AssignM", linkageName: "_CAssignM.Main", scope: null, file: !6, line: 12, type: !8, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !13 = !DILocation(line: 13, column: 3, scope: !12)
|
||||
// CHECK:STDOUT: !14 = !DILocation(line: 12, column: 1, scope: !12)
|
||||
// CHECK:STDOUT: ; ModuleID = 'access_union.carbon'
|
||||
// CHECK:STDOUT: source_filename = "access_union.carbon"
|
||||
// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
||||
// CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: define i32 @_CAccessN.Main(ptr %a) !dbg !7 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc7_11.1.n = getelementptr inbounds nuw [4 x i8], ptr %a, i32 0, i32 0, !dbg !10
|
||||
// CHECK:STDOUT: %.loc7_11.2 = load i32, ptr %.loc7_11.1.n, align 4, !dbg !10
|
||||
// CHECK:STDOUT: ret i32 %.loc7_11.2, !dbg !11
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: define i32 @_CAccessM.Main(ptr %a) !dbg !12 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc11_11.1.m = getelementptr inbounds nuw [4 x i8], ptr %a, i32 0, i32 0, !dbg !13
|
||||
// CHECK:STDOUT: %.loc11_11.2 = load i32, ptr %.loc11_11.1.m, align 4, !dbg !13
|
||||
// CHECK:STDOUT: ret i32 %.loc11_11.2, !dbg !14
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4}
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!5}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
// CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
|
||||
// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
|
||||
// CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
|
||||
// CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C, file: !6, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !6 = !DIFile(filename: "access_union.carbon", directory: "")
|
||||
// CHECK:STDOUT: !7 = distinct !DISubprogram(name: "AccessN", linkageName: "_CAccessN.Main", scope: null, file: !6, line: 6, type: !8, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !8 = !DISubroutineType(types: !9)
|
||||
// CHECK:STDOUT: !9 = !{}
|
||||
// CHECK:STDOUT: !10 = !DILocation(line: 7, column: 10, scope: !7)
|
||||
// CHECK:STDOUT: !11 = !DILocation(line: 7, column: 3, scope: !7)
|
||||
// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "AccessM", linkageName: "_CAccessM.Main", scope: null, file: !6, line: 10, type: !8, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !13 = !DILocation(line: 11, column: 10, scope: !12)
|
||||
// CHECK:STDOUT: !14 = !DILocation(line: 11, column: 3, scope: !12)
|
||||
// CHECK:STDOUT: ; ModuleID = 'assign_union.carbon'
|
||||
// CHECK:STDOUT: source_filename = "assign_union.carbon"
|
||||
// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
||||
// CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: define void @_CAssignN.Main(ptr %p) !dbg !7 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc7_4.2.n = getelementptr inbounds nuw [4 x i8], ptr %p, i32 0, i32 0, !dbg !10
|
||||
// CHECK:STDOUT: store i32 1, ptr %.loc7_4.2.n, align 4, !dbg !10
|
||||
// CHECK:STDOUT: ret void, !dbg !11
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: define void @_CAssignM.Main(ptr %p) !dbg !12 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc11_4.2.m = getelementptr inbounds nuw [4 x i8], ptr %p, i32 0, i32 0, !dbg !13
|
||||
// CHECK:STDOUT: store i32 1, ptr %.loc11_4.2.m, align 4, !dbg !13
|
||||
// CHECK:STDOUT: ret void, !dbg !14
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4}
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!5}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
// CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4}
|
||||
// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 0}
|
||||
// CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2}
|
||||
// CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C, file: !6, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !6 = !DIFile(filename: "assign_union.carbon", directory: "")
|
||||
// CHECK:STDOUT: !7 = distinct !DISubprogram(name: "AssignN", linkageName: "_CAssignN.Main", scope: null, file: !6, line: 6, type: !8, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !8 = !DISubroutineType(types: !9)
|
||||
// CHECK:STDOUT: !9 = !{}
|
||||
// CHECK:STDOUT: !10 = !DILocation(line: 7, column: 3, scope: !7)
|
||||
// CHECK:STDOUT: !11 = !DILocation(line: 6, column: 1, scope: !7)
|
||||
// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "AssignM", linkageName: "_CAssignM.Main", scope: null, file: !6, line: 10, type: !8, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !13 = !DILocation(line: 11, column: 3, scope: !12)
|
||||
// CHECK:STDOUT: !14 = !DILocation(line: 10, column: 1, scope: !12)
|
||||
@@ -109,6 +109,7 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory {
|
||||
case CompleteTypeWitness::Kind:
|
||||
case ConstType::Kind:
|
||||
case ConvertToValueAction::Kind:
|
||||
case CustomLayoutType::Kind:
|
||||
case FacetAccessType::Kind:
|
||||
case FacetType::Kind:
|
||||
case FacetValue::Kind:
|
||||
|
||||
@@ -61,6 +61,8 @@ struct ExprRegion {
|
||||
|
||||
using ExprRegionStore = ValueStore<ExprRegionId, ExprRegion>;
|
||||
|
||||
using CustomLayoutStore = BlockValueStore<CustomLayoutId, uint64_t>;
|
||||
|
||||
// Provides semantic analysis on a Parse::Tree.
|
||||
class File : public Printable<File> {
|
||||
public:
|
||||
@@ -210,6 +212,10 @@ class File : public Printable<File> {
|
||||
auto struct_type_fields() const -> const StructTypeFieldsStore& {
|
||||
return struct_type_fields_;
|
||||
}
|
||||
auto custom_layouts() -> CustomLayoutStore& { return custom_layouts_; }
|
||||
auto custom_layouts() const -> const CustomLayoutStore& {
|
||||
return custom_layouts_;
|
||||
}
|
||||
auto types() -> TypeStore& { return types_; }
|
||||
auto types() const -> const TypeStore& { return types_; }
|
||||
auto insts() -> InstStore& { return insts_; }
|
||||
@@ -361,6 +367,9 @@ class File : public Printable<File> {
|
||||
// Storage for StructTypeField lists.
|
||||
StructTypeFieldsStore struct_type_fields_ = StructTypeFieldsStore(allocator_);
|
||||
|
||||
// Storage for custom layouts.
|
||||
CustomLayoutStore custom_layouts_ = CustomLayoutStore(allocator_);
|
||||
|
||||
// Descriptions of types used in this file.
|
||||
TypeStore types_ = TypeStore(this);
|
||||
|
||||
|
||||
@@ -1006,6 +1006,23 @@ auto Formatter::FormatInstRhs(Inst inst) -> void {
|
||||
return;
|
||||
}
|
||||
|
||||
case CARBON_KIND(CustomLayoutType type): {
|
||||
out_ << " {";
|
||||
auto layout = sem_ir_->custom_layouts().Get(type.layout_id);
|
||||
out_ << "size=" << layout[CustomLayoutId::SizeIndex]
|
||||
<< ", align=" << layout[CustomLayoutId::AlignIndex];
|
||||
for (auto [field, offset] :
|
||||
llvm::zip(sem_ir_->struct_type_fields().Get(type.fields_id),
|
||||
layout.drop_front(CustomLayoutId::FirstFieldIndex))) {
|
||||
out_ << ", .";
|
||||
FormatName(field.name_id);
|
||||
out_ << "@" << offset << ": ";
|
||||
FormatInstAsType(field.type_inst_id);
|
||||
}
|
||||
out_ << "}";
|
||||
return;
|
||||
}
|
||||
|
||||
case CARBON_KIND(FloatLiteral value): {
|
||||
llvm::SmallVector<char, 16> buffer;
|
||||
sem_ir_->floats().Get(value.float_id).toString(buffer);
|
||||
|
||||
@@ -401,8 +401,10 @@ auto Formatter::FormatEntityStart(llvm::StringRef entity_kind,
|
||||
if (import_ir_inst_id.has_value()) {
|
||||
auto import_ir_id =
|
||||
sem_ir_->import_ir_insts().Get(import_ir_inst_id).ir_id();
|
||||
const auto* import_file = sem_ir_->import_irs().Get(import_ir_id).sem_ir;
|
||||
pending_imported_from_ = import_file->filename();
|
||||
if (const auto* import_file =
|
||||
sem_ir_->import_irs().Get(import_ir_id).sem_ir) {
|
||||
pending_imported_from_ = import_file->filename();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ using IdKind = TypeEnum<
|
||||
ClassId,
|
||||
CompileTimeBindIndex,
|
||||
ConstantId,
|
||||
CustomLayoutId,
|
||||
DeclInstBlockId,
|
||||
DestInstId,
|
||||
ElementIndex,
|
||||
|
||||
@@ -728,6 +728,26 @@ struct StructTypeFieldsId : public IdBase<StructTypeFieldsId> {
|
||||
|
||||
constexpr StructTypeFieldsId StructTypeFieldsId::Empty = StructTypeFieldsId(0);
|
||||
|
||||
// The ID of a `CustomLayout` block.
|
||||
struct CustomLayoutId : public IdBase<CustomLayoutId> {
|
||||
static constexpr llvm::StringLiteral Label = "custom_layout";
|
||||
|
||||
// The canonical empty block. This is never used, but needed by
|
||||
// BlockValueStore.
|
||||
static const CustomLayoutId Empty;
|
||||
|
||||
// The index in a custom layout of the overall size field.
|
||||
static constexpr int SizeIndex = 0;
|
||||
// The index in a custom layout of the overall alignment field.
|
||||
static constexpr int AlignIndex = 1;
|
||||
// The index in a custom layout of the offset of the first struct field.
|
||||
static constexpr int FirstFieldIndex = 2;
|
||||
|
||||
using IdBase::IdBase;
|
||||
};
|
||||
|
||||
constexpr CustomLayoutId CustomLayoutId::Empty = CustomLayoutId(0);
|
||||
|
||||
// The ID of a type.
|
||||
struct TypeId : public IdBase<TypeId> {
|
||||
static constexpr llvm::StringLiteral Label = "type";
|
||||
|
||||
@@ -33,9 +33,13 @@ auto GetCanonicalFileAndInstId(const File* sem_ir, SemIR::InstId inst_id)
|
||||
if (auto import_ir_inst_id = sem_ir->insts().GetImportSource(inst_id);
|
||||
import_ir_inst_id.has_value()) {
|
||||
auto import_ir_inst = sem_ir->import_ir_insts().Get(import_ir_inst_id);
|
||||
sem_ir = sem_ir->import_irs().Get(import_ir_inst.ir_id()).sem_ir;
|
||||
inst_id = import_ir_inst.inst_id();
|
||||
continue;
|
||||
// TODO: For imports from C++, we return the importing instruction, which
|
||||
// isn't necessarily canonical.
|
||||
if (import_ir_inst.ir_id() != ImportIRId::Cpp) {
|
||||
sem_ir = sem_ir->import_irs().Get(import_ir_inst.ir_id()).sem_ir;
|
||||
inst_id = import_ir_inst.inst_id();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Step through export declarations to their exported value.
|
||||
|
||||
@@ -167,6 +167,17 @@ struct AnyParamPattern {
|
||||
CallParamIndex index;
|
||||
};
|
||||
|
||||
// A struct-like type with a list of named fields.
|
||||
struct AnyStructType {
|
||||
using CategoryInfo = CategoryOf<StructType, CustomLayoutType>;
|
||||
|
||||
InstKind kind;
|
||||
|
||||
TypeId type_id;
|
||||
StructTypeFieldsId fields_id;
|
||||
AnyRawId arg1;
|
||||
};
|
||||
|
||||
} // namespace Carbon::SemIR
|
||||
|
||||
#endif // CARBON_TOOLCHAIN_SEM_IR_INST_CATEGORIES_H_
|
||||
|
||||
@@ -150,6 +150,16 @@ struct Worklist {
|
||||
AddBlock(sem_ir->struct_type_fields().Get(struct_type_fields_id));
|
||||
}
|
||||
|
||||
auto Add(CustomLayoutId custom_layout_id) -> void {
|
||||
if (!custom_layout_id.has_value()) {
|
||||
AddInvalid();
|
||||
return;
|
||||
}
|
||||
auto block = sem_ir->custom_layouts().Get(custom_layout_id);
|
||||
contents.push_back(block.size());
|
||||
contents.insert(contents.end(), block.begin(), block.end());
|
||||
}
|
||||
|
||||
auto Add(NameScopeId name_scope_id) -> void {
|
||||
if (!name_scope_id.has_value()) {
|
||||
AddInvalid();
|
||||
|
||||
@@ -55,6 +55,7 @@ CARBON_SEM_IR_INST_KIND(CompleteTypeWitness)
|
||||
CARBON_SEM_IR_INST_KIND(ConstType)
|
||||
CARBON_SEM_IR_INST_KIND(ConvertToValueAction)
|
||||
CARBON_SEM_IR_INST_KIND(Converted)
|
||||
CARBON_SEM_IR_INST_KIND(CustomLayoutType)
|
||||
CARBON_SEM_IR_INST_KIND(Deref)
|
||||
CARBON_SEM_IR_INST_KIND(ErrorInst)
|
||||
CARBON_SEM_IR_INST_KIND(ExportDecl)
|
||||
|
||||
@@ -299,6 +299,12 @@ class Stringifier {
|
||||
step_stack_->PushInstId(inst.inner_id);
|
||||
}
|
||||
|
||||
auto StringifyInst(InstId /*inst_id*/, CustomLayoutType inst) -> void {
|
||||
auto layout = sem_ir_->custom_layouts().Get(inst.layout_id);
|
||||
*out_ << "<size " << layout[CustomLayoutId::SizeIndex] << ", align "
|
||||
<< layout[CustomLayoutId::AlignIndex] << ">";
|
||||
}
|
||||
|
||||
auto StringifyInst(InstId /*inst_id*/, FacetAccessType inst) -> void {
|
||||
// Given `T:! I`, print `T as type` as simply `T`.
|
||||
step_stack_->PushInstId(inst.facet_value_inst_id);
|
||||
|
||||
@@ -552,6 +552,20 @@ struct ConvertToValueAction {
|
||||
TypeInstId target_type_inst_id;
|
||||
};
|
||||
|
||||
// A type whose layout is determined externally. This is used as the object
|
||||
// representation of class types imported from C++.
|
||||
struct CustomLayoutType {
|
||||
static constexpr auto Kind = InstKind::CustomLayoutType.Define<Parse::NodeId>(
|
||||
{.ir_name = "custom_layout_type",
|
||||
.is_type = InstIsType::Always,
|
||||
.constant_kind = InstConstantKind::WheneverPossible,
|
||||
.deduce_through = true});
|
||||
|
||||
TypeId type_id;
|
||||
StructTypeFieldsId fields_id;
|
||||
CustomLayoutId layout_id;
|
||||
};
|
||||
|
||||
// The `*` dereference operator, as in `*pointer`.
|
||||
struct Deref {
|
||||
static constexpr auto Kind =
|
||||
|
||||
Reference in New Issue
Block a user