Просмотр исходного кода

Lowering for tuple indexing. (#3059)

Co-authored-by: Farzana Ahmed Siddique <fasiddique@google.com>
Farzana Ahmed Siddique 2 лет назад
Родитель
Сommit
3a093980a6

+ 12 - 4
toolchain/lowering/lowering_handle.cpp

@@ -145,10 +145,18 @@ auto LoweringHandleFunctionDeclaration(LoweringFunctionContext& /*context*/,
       << node;
 }
 
-auto LoweringHandleIndex(LoweringFunctionContext& /*context*/,
-                         SemanticsNodeId /*node_id*/, SemanticsNode node)
-    -> void {
-  CARBON_FATAL() << "TODO: Add support: " << node;
+auto LoweringHandleIndex(LoweringFunctionContext& context,
+                         SemanticsNodeId node_id, SemanticsNode node) -> void {
+  auto [tuple_node_id, index_node_id] = node.GetAsIndex();
+  auto* llvm_type =
+      context.GetType(context.semantics_ir().GetNode(tuple_node_id).type_id());
+  auto index_node = context.semantics_ir().GetNode(index_node_id);
+  const auto index = context.semantics_ir()
+                         .GetIntegerLiteral(index_node.GetAsIntegerLiteral())
+                         .getZExtValue();
+  auto* gep = context.builder().CreateStructGEP(
+      llvm_type, context.GetLocal(tuple_node_id), index, "Index");
+  context.SetLocal(node_id, gep);
 }
 
 auto LoweringHandleIntegerLiteral(LoweringFunctionContext& context,

+ 46 - 0
toolchain/lowering/testdata/index/member_access.carbon

@@ -0,0 +1,46 @@
+// 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
+//
+// AUTOUPDATE
+// CHECK:STDOUT: ; ModuleID = 'member_access.carbon'
+// CHECK:STDOUT: source_filename = "member_access.carbon"
+// CHECK:STDOUT:
+// CHECK:STDOUT: %TupleLiteralType = type { {}, {}, {} }
+// CHECK:STDOUT: %TupleLiteralType.0 = type { i32, i32, i32 }
+// CHECK:STDOUT:
+// CHECK:STDOUT: define i32 @Run() {
+// CHECK:STDOUT:   %TupleLiteralValue = alloca %TupleLiteralType, align 8
+// CHECK:STDOUT:   %1 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 0
+// CHECK:STDOUT:   store {} zeroinitializer, ptr %1, align 1
+// CHECK:STDOUT:   %2 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 1
+// CHECK:STDOUT:   store {} zeroinitializer, ptr %2, align 1
+// CHECK:STDOUT:   %3 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 2
+// CHECK:STDOUT:   store {} zeroinitializer, ptr %3, align 1
+// CHECK:STDOUT:   %var = alloca %TupleLiteralType.0, align 8
+// CHECK:STDOUT:   %TupleLiteralValue1 = alloca %TupleLiteralType.0, align 8
+// CHECK:STDOUT:   %4 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue1, i32 0, i32 0
+// CHECK:STDOUT:   store i32 0, ptr %4, align 4
+// CHECK:STDOUT:   %5 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue1, i32 0, i32 1
+// CHECK:STDOUT:   store i32 1, ptr %5, align 4
+// CHECK:STDOUT:   %6 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue1, i32 0, i32 2
+// CHECK:STDOUT:   store i32 2, ptr %6, align 4
+// CHECK:STDOUT:   %7 = load %TupleLiteralType.0, ptr %TupleLiteralValue1, align 4
+// CHECK:STDOUT:   store %TupleLiteralType.0 %7, ptr %var, align 4
+// CHECK:STDOUT:   %var2 = alloca i32, align 4
+// CHECK:STDOUT:   %Index = getelementptr inbounds %TupleLiteralType.0, ptr %var, i32 0, i32 0
+// CHECK:STDOUT:   %8 = load i32, ptr %Index, align 4
+// CHECK:STDOUT:   store i32 %8, ptr %var2, align 4
+// CHECK:STDOUT:   %var3 = alloca i32, align 4
+// CHECK:STDOUT:   %Index4 = getelementptr inbounds %TupleLiteralType.0, ptr %var, i32 0, i32 2
+// CHECK:STDOUT:   %9 = load i32, ptr %Index4, align 4
+// CHECK:STDOUT:   store i32 %9, ptr %var3, align 4
+// CHECK:STDOUT:   ret i32 0
+// CHECK:STDOUT: }
+
+fn Run() -> i32 {
+  var a: (i32, i32, i32) = (0, 1, 2);
+  var b: i32 = a[0];
+  var c: i32 = a[2];
+  return 0;
+}

+ 2 - 2
toolchain/semantics/semantics_handle_index.cpp

@@ -29,8 +29,8 @@ auto SemanticsHandleIndexExpression(SemanticsContext& context,
 
   if (name_type_node.kind() == SemanticsNodeKind::TupleType &&
       index_node.kind() == SemanticsNodeKind::IntegerLiteral) {
-    const auto& index_val = (context.semantics_ir().GetIntegerLiteral(
-        index_node.GetAsIntegerLiteral()));
+    const auto& index_val = context.semantics_ir().GetIntegerLiteral(
+        index_node.GetAsIntegerLiteral());
     auto type_block =
         context.semantics_ir().GetTypeBlock(name_type_node.GetAsTupleType());