mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:20:13 +01:00
Export Carbon global variables and static vars to C++ (#7298)
Add `ExportVarToCpp`. This checks the `clang_decls` mapping and returns an existing decl if found. Otherwise, it creates a new `VarDecl` and adds it to the `clang_decls` mapping. When lowering, in `FileContext::BuildGlobalVariableDecl`, the `clang_decls` mapping is used to lookup an existing `llvm::GlobalVariable` for the instruction. If found, use that rather than creating a new one to avoid an unwanted second definition in the llvm IR.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "toolchain/check/type.h"
|
||||
#include "toolchain/sem_ir/generic.h"
|
||||
#include "toolchain/sem_ir/mangler.h"
|
||||
#include "toolchain/sem_ir/pattern.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
#include "toolchain/sem_ir/vtable.h"
|
||||
|
||||
@@ -937,4 +938,66 @@ auto ExportDestructorToCpp(Context& context, const SemIR::Class& class_info,
|
||||
return cpp_destructor_decl;
|
||||
}
|
||||
|
||||
auto ExportVarToCpp(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::VarStorage var_storage) -> clang::VarDecl* {
|
||||
// Check if the variable was already exported and return the existing
|
||||
// `VarDecl` if so. Note that the `pattern_id` is used as the key
|
||||
// rather than the `InstId` for the `VarStorage`. This just makes
|
||||
// lookup more convenient in places where the `VarStorage` `InstId` is
|
||||
// not readily accessible.
|
||||
auto clang_decl_id = context.clang_decls().Lookup(var_storage.pattern_id);
|
||||
if (clang_decl_id.has_value()) {
|
||||
return cast<clang::VarDecl>(
|
||||
context.clang_decls().Get(clang_decl_id).key.decl);
|
||||
}
|
||||
|
||||
// Look up the entity name and check the scope.
|
||||
auto entity_name_id = GetFirstBindingNameFromPatternId(
|
||||
context.sem_ir(), var_storage.pattern_id);
|
||||
const auto& entity_name = context.entity_names().Get(entity_name_id);
|
||||
auto scope_inst = context.insts().Get(
|
||||
context.name_scopes().Get(entity_name.parent_scope_id).inst_id());
|
||||
CARBON_CHECK(scope_inst.Is<SemIR::Namespace>() ||
|
||||
scope_inst.Is<SemIR::ClassDecl>());
|
||||
|
||||
// Map the parent scope into the C++ AST.
|
||||
auto* decl_context =
|
||||
ExportNameScopeToCpp(context, loc_id, entity_name.parent_scope_id);
|
||||
if (!decl_context) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Map the type.
|
||||
auto cpp_type = MapToCppType(context, var_storage.type_id);
|
||||
if (cpp_type.isNull()) {
|
||||
context.TODO(loc_id, "failed to map Carbon type to C++");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create the `clang::VarDecl` and add it to `clang_decls()`.
|
||||
auto clang_loc = GetCppLocation(context, loc_id);
|
||||
auto* identifier_info = GetClangIdentifierInfo(context, entity_name.name_id);
|
||||
auto* var_decl = clang::VarDecl::Create(
|
||||
context.ast_context(), decl_context,
|
||||
/*StartLoc=*/clang_loc, /*IdLoc=*/clang_loc, identifier_info, cpp_type,
|
||||
/*TInfo=*/nullptr, clang::SC_Extern);
|
||||
context.clang_decls().Add(
|
||||
{.key = SemIR::ClangDeclKey::ForNonFunctionDecl(var_decl),
|
||||
.inst_id = var_storage.pattern_id});
|
||||
|
||||
if (scope_inst.Is<SemIR::ClassDecl>()) {
|
||||
// TODO: Map Carbon access to C++ access.
|
||||
var_decl->setAccess(clang::AS_public);
|
||||
}
|
||||
|
||||
// Set the Carbon mangled variable name.
|
||||
SemIR::Mangler m(context.sem_ir(), context.total_ir_count(),
|
||||
context.mangle_string_fingerprint());
|
||||
std::string mangled_name = m.MangleGlobalVariable(var_storage.pattern_id);
|
||||
var_decl->addAttr(
|
||||
clang::AsmLabelAttr::Create(context.ast_context(), mangled_name));
|
||||
|
||||
return var_decl;
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
@@ -64,6 +64,13 @@ auto ExportDestructorToCpp(Context& context, const SemIR::Class& class_info,
|
||||
clang::CXXRecordDecl* record_decl)
|
||||
-> clang::CXXDestructorDecl*;
|
||||
|
||||
// Export a Carbon variable into C++.
|
||||
//
|
||||
// Returns nullptr if the variable could not be exported an an error was
|
||||
// diagnosed.
|
||||
auto ExportVarToCpp(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::VarStorage var_storage) -> clang::VarDecl*;
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
#endif // CARBON_TOOLCHAIN_CHECK_CPP_EXPORT_H_
|
||||
|
||||
@@ -435,6 +435,10 @@ auto CarbonExternalASTSource::MapInstIdToClangDeclOrType(LookupResult lookup)
|
||||
case CARBON_KIND(SemIR::FieldDecl field_decl): {
|
||||
return ExportFieldToCpp(*context_, target_inst_id, field_decl);
|
||||
}
|
||||
case CARBON_KIND(SemIR::VarStorage var_storage): {
|
||||
return ExportVarToCpp(*context_, SemIR::LocId(target_inst_id),
|
||||
var_storage);
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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/check/testdata/interop/cpp/class/export/static.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/class/export/static.carbon
|
||||
|
||||
// --- static.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
import Cpp;
|
||||
|
||||
class C {
|
||||
static var x: i32 = 123;
|
||||
}
|
||||
|
||||
inline Cpp '''
|
||||
int F() {
|
||||
return Carbon::C::x;
|
||||
}
|
||||
''';
|
||||
@@ -30,7 +30,7 @@ fn G(x: Cpp.X, n: i32) -> i32 {
|
||||
return x.arr[n];
|
||||
}
|
||||
|
||||
// --- fail_todo_export_variable.carbon
|
||||
// --- export_variable.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp;
|
||||
@@ -39,10 +39,6 @@ var arr: array(i32, 5);
|
||||
|
||||
inline Cpp '''
|
||||
int F(int n) {
|
||||
// CHECK:STDERR: fail_todo_export_variable.carbon:[[@LINE+4]]:18: error: no member named 'arr' in namespace 'Carbon' [CppInteropParseError]
|
||||
// CHECK:STDERR: 13 | return Carbon::arr[n];
|
||||
// CHECK:STDERR: | ^~~
|
||||
// CHECK:STDERR:
|
||||
return Carbon::arr[n];
|
||||
}
|
||||
''';
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// 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/check/testdata/interop/cpp/var/export/var.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/var/export/var.carbon
|
||||
|
||||
// --- var.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp;
|
||||
|
||||
var x: i32 = 123;
|
||||
|
||||
inline Cpp '''
|
||||
int Get() {
|
||||
return Carbon::x;
|
||||
}
|
||||
''';
|
||||
|
||||
// --- fail_var_unsupported_type.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp;
|
||||
|
||||
// CHECK:STDERR: fail_var_unsupported_type.carbon:[[@LINE+4]]:5: error: semantics TODO: `failed to map Carbon type to C++` [SemanticsTodo]
|
||||
// CHECK:STDERR: var x: () = ();
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR:
|
||||
var x: () = ();
|
||||
|
||||
inline Cpp '''
|
||||
void F() {
|
||||
// CHECK:STDERR: fail_var_unsupported_type.carbon:[[@LINE+4]]:11: error: no member named 'x' in namespace 'Carbon' [CppInteropParseError]
|
||||
// CHECK:STDERR: 17 | Carbon::x;
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR:
|
||||
Carbon::x;
|
||||
}
|
||||
''';
|
||||
+2
-2
@@ -7,9 +7,9 @@
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/var/constexpr.carbon
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/var/import/constexpr.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/var/constexpr.carbon
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/var/import/constexpr.carbon
|
||||
|
||||
// --- bool.carbon
|
||||
|
||||
+2
-2
@@ -7,9 +7,9 @@
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/var/global.carbon
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/var/import/global.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/var/global.carbon
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/var/import/global.carbon
|
||||
|
||||
// ============================================================================
|
||||
// Global scope
|
||||
+2
-2
@@ -6,9 +6,9 @@
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/var/namespace.carbon
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/var/import/namespace.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/var/namespace.carbon
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/var/import/namespace.carbon
|
||||
|
||||
// --- namespace.h
|
||||
|
||||
@@ -672,6 +672,21 @@ auto FileContext::BuildDISubprogram(const SemIR::Function& function,
|
||||
|
||||
auto FileContext::BuildGlobalVariableDecl(SemIR::VarStorage var_storage)
|
||||
-> llvm::Constant* {
|
||||
// When a Carbon variable is exported and used from C++, code
|
||||
// generation for the C++ code may have already created an
|
||||
// llvm::GlobalVariable. If so, return that global rather than
|
||||
// creating a new one.
|
||||
auto clang_decl_id = sem_ir().clang_decls().Lookup(var_storage.pattern_id);
|
||||
if (clang_decl_id.has_value()) {
|
||||
auto* decl = sem_ir().clang_decls().Get(clang_decl_id).key.decl;
|
||||
auto* constant = cpp_code_generator_->GetAddrOfGlobal(
|
||||
CreateGlobalDecl(cast<clang::NamedDecl>(decl)),
|
||||
/*isForDefinition=*/false);
|
||||
if (constant) {
|
||||
return constant;
|
||||
}
|
||||
}
|
||||
|
||||
auto var_name_id =
|
||||
SemIR::GetFirstBindingNameFromPatternId(sem_ir(), var_storage.pattern_id);
|
||||
if (auto cpp_global_var_id =
|
||||
|
||||
+101
@@ -23,6 +23,24 @@ fn F() {
|
||||
C.static_field_with_init = 789;
|
||||
}
|
||||
|
||||
// --- static_export.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
import Cpp;
|
||||
|
||||
class C {
|
||||
static var x: i32 = 123;
|
||||
}
|
||||
|
||||
inline Cpp '''
|
||||
int F() {
|
||||
return Carbon::C::x;
|
||||
}
|
||||
''';
|
||||
|
||||
fn Run() -> i32 {
|
||||
return Cpp.F();
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: ; ModuleID = 'static.carbon'
|
||||
// CHECK:STDOUT: source_filename = "static.carbon"
|
||||
// CHECK:STDOUT:
|
||||
@@ -65,3 +83,86 @@ fn F() {
|
||||
// CHECK:STDOUT: !11 = !DILocation(line: 4, column: 10, scope: !10)
|
||||
// CHECK:STDOUT: !12 = !DILocation(line: 5, column: 10, scope: !10)
|
||||
// CHECK:STDOUT: !13 = !DILocation(line: 0, scope: !10)
|
||||
// CHECK:STDOUT: ; ModuleID = 'static_export.carbon'
|
||||
// CHECK:STDOUT: source_filename = "static_export.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: @_Cx.C.Main = global i32 0, align 4
|
||||
// CHECK:STDOUT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @_C__global_init.Main, ptr null }]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
|
||||
// CHECK:STDOUT: define dso_local noundef i32 @_Z1Fv() #0 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %0 = load i32, ptr @_Cx.C.Main, align 4, !tbaa !7
|
||||
// CHECK:STDOUT: ret i32 %0
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
|
||||
// CHECK:STDOUT: define void @"_C__destroy_thunk:thunk.C.Main"(ptr %self) #1 !dbg !11 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: call void @"_COp.907c496eccf2294c:core.Destroy.Core"(ptr %self), !dbg !17
|
||||
// CHECK:STDOUT: ret void, !dbg !17
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define weak_odr void @"_COp.907c496eccf2294c:core.Destroy.Core"(ptr %self) #2 !dbg !18 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret void, !dbg !21
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @main() #2 !dbg !22 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %F.call = call i32 @_Z1Fv(), !dbg !26
|
||||
// CHECK:STDOUT: ret i32 %F.call, !dbg !27
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define internal void @_C__global_init.Main() #2 !dbg !28 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: store i32 123, ptr @_Cx.C.Main, align 4, !dbg !31
|
||||
// CHECK:STDOUT: ret void, !dbg !32
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: attributes #0 = { mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
||||
// CHECK:STDOUT: attributes #1 = { alwaysinline nounwind }
|
||||
// CHECK:STDOUT: attributes #2 = { nounwind }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4}
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!5}
|
||||
// CHECK:STDOUT: !llvm.errno.tbaa = !{!7}
|
||||
// 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 8, !"PIC Level", i32 2}
|
||||
// CHECK:STDOUT: !3 = !{i32 7, !"PIE Level", i32 2}
|
||||
// CHECK:STDOUT: !4 = !{i32 7, !"uwtable", i32 2}
|
||||
// CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !6, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !6 = !DIFile(filename: "static_export.carbon", directory: "")
|
||||
// CHECK:STDOUT: !7 = !{!8, !8, i64 0}
|
||||
// CHECK:STDOUT: !8 = !{!"int", !9, i64 0}
|
||||
// CHECK:STDOUT: !9 = !{!"omnipotent char", !10, i64 0}
|
||||
// CHECK:STDOUT: !10 = !{!"Simple C++ TBAA"}
|
||||
// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "__destroy_thunk", linkageName: "_C__destroy_thunk:thunk.C.Main", scope: null, file: !6, line: 4, type: !12, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !15)
|
||||
// CHECK:STDOUT: !12 = !DISubroutineType(types: !13)
|
||||
// CHECK:STDOUT: !13 = !{null, !14}
|
||||
// CHECK:STDOUT: !14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
|
||||
// CHECK:STDOUT: !15 = !{!16}
|
||||
// CHECK:STDOUT: !16 = !DILocalVariable(arg: 1, scope: !11, type: !14)
|
||||
// CHECK:STDOUT: !17 = !DILocation(line: 4, column: 1, scope: !11)
|
||||
// CHECK:STDOUT: !18 = distinct !DISubprogram(name: "Op", linkageName: "_COp.907c496eccf2294c:core.Destroy.Core", scope: null, file: !6, line: 4, type: !12, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !19)
|
||||
// CHECK:STDOUT: !19 = !{!20}
|
||||
// CHECK:STDOUT: !20 = !DILocalVariable(arg: 1, scope: !18, type: !14)
|
||||
// CHECK:STDOUT: !21 = !DILocation(line: 4, column: 1, scope: !18)
|
||||
// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "Run", linkageName: "main", scope: null, file: !6, line: 14, type: !23, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !23 = !DISubroutineType(types: !24)
|
||||
// CHECK:STDOUT: !24 = !{!25}
|
||||
// CHECK:STDOUT: !25 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
// CHECK:STDOUT: !26 = !DILocation(line: 15, column: 10, scope: !22)
|
||||
// CHECK:STDOUT: !27 = !DILocation(line: 15, column: 3, scope: !22)
|
||||
// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "__global_init", linkageName: "_C__global_init.Main", scope: null, file: !6, type: !29, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !29 = !DISubroutineType(types: !30)
|
||||
// CHECK:STDOUT: !30 = !{null}
|
||||
// CHECK:STDOUT: !31 = !DILocation(line: 5, column: 10, scope: !28)
|
||||
// CHECK:STDOUT: !32 = !DILocation(line: 0, scope: !28)
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
// 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/var/export.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/var/export.carbon
|
||||
|
||||
// --- var_export.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import Cpp;
|
||||
|
||||
var x: i32;
|
||||
|
||||
inline Cpp '''
|
||||
int Get() {
|
||||
return Carbon::x;
|
||||
}
|
||||
''';
|
||||
|
||||
fn Run() -> i32 {
|
||||
return Cpp.Get();
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: ; ModuleID = 'var_export.carbon'
|
||||
// CHECK:STDOUT: source_filename = "var_export.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: @_Cx.Main = global i32 0, align 4
|
||||
// CHECK:STDOUT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @_C__global_init.Main, ptr null }]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
|
||||
// CHECK:STDOUT: define dso_local noundef i32 @_Z3Getv() #0 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %0 = load i32, ptr @_Cx.Main, align 4, !tbaa !7
|
||||
// CHECK:STDOUT: ret i32 %0
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @main() #1 !dbg !11 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %Get.call = call i32 @_Z3Getv(), !dbg !15
|
||||
// CHECK:STDOUT: ret i32 %Get.call, !dbg !16
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define internal void @_C__global_init.Main() #1 !dbg !17 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: store i32 poison, ptr @_Cx.Main, align 4, !dbg !20
|
||||
// CHECK:STDOUT: ret void, !dbg !21
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: attributes #0 = { mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
||||
// CHECK:STDOUT: attributes #1 = { nounwind }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4}
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!5}
|
||||
// CHECK:STDOUT: !llvm.errno.tbaa = !{!7}
|
||||
// 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 8, !"PIC Level", i32 2}
|
||||
// CHECK:STDOUT: !3 = !{i32 7, !"PIE Level", i32 2}
|
||||
// CHECK:STDOUT: !4 = !{i32 7, !"uwtable", i32 2}
|
||||
// CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !6, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !6 = !DIFile(filename: "var_export.carbon", directory: "")
|
||||
// CHECK:STDOUT: !7 = !{!8, !8, i64 0}
|
||||
// CHECK:STDOUT: !8 = !{!"int", !9, i64 0}
|
||||
// CHECK:STDOUT: !9 = !{!"omnipotent char", !10, i64 0}
|
||||
// CHECK:STDOUT: !10 = !{!"Simple C++ TBAA"}
|
||||
// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "Run", linkageName: "main", scope: null, file: !6, line: 13, type: !12, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !12 = !DISubroutineType(types: !13)
|
||||
// CHECK:STDOUT: !13 = !{!14}
|
||||
// CHECK:STDOUT: !14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
// CHECK:STDOUT: !15 = !DILocation(line: 14, column: 10, scope: !11)
|
||||
// CHECK:STDOUT: !16 = !DILocation(line: 14, column: 3, scope: !11)
|
||||
// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "__global_init", linkageName: "_C__global_init.Main", scope: null, file: !6, type: !18, spFlags: DISPFlagDefinition, unit: !5)
|
||||
// CHECK:STDOUT: !18 = !DISubroutineType(types: !19)
|
||||
// CHECK:STDOUT: !19 = !{null}
|
||||
// CHECK:STDOUT: !20 = !DILocation(line: 5, column: 1, scope: !17)
|
||||
// CHECK:STDOUT: !21 = !DILocation(line: 0, scope: !17)
|
||||
Reference in New Issue
Block a user