910e62b5创建于 1月15日历史提交
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <array>
#include <tuple>

// Expected rewrite:
// struct GlobalBuffer {
//   int val;
// };
// std::array<GlobalBuffer, 4> globalBuffer;
struct GlobalBuffer {
  int val;
};
std::array<GlobalBuffer, 4> globalBuffer;

// Expected rewrite:
// struct GlobalHasName {
//   int val;
// };
// std::array<GlobalHasName, 4> globalNamedBuffer;
struct GlobalHasName {
  int val;
};
std::array<GlobalHasName, 4> globalNamedBuffer;

// Expected rewrite:
// std::array<GlobalHasName, 4> globalNamedBufferButNotInline;
std::array<GlobalHasName, 4> globalNamedBufferButNotInline;

int UnsafeIndex();  // This function might return an out-of-bound index.

void fct() {
  // Expected rewrite:
  // struct FuncBuffer {
  //   int val;
  // };
  // std::array<FuncBuffer, 4> func_buffer;
  struct FuncBuffer {
    int val;
  };
  std::array<FuncBuffer, 4> func_buffer;

  // Expected rewrite:
  // struct TestCases {
  //   int val;
  // };
  // const std::array<TestCases, 4> kTestCases = {{{1}, {2}, {3}, {4}}};
  struct TestCases {
    int val;
  };
  const std::array<TestCases, 4> kTestCases = {{{1}, {2}, {3}, {4}}};
  std::ignore = kTestCases[UnsafeIndex()].val;  // Trigger spanification.

  // Expected rewrite:
  // struct GTestCases {
  //   int val;
  // };
  // const std::array<GTestCases, 4> gTestCases = {{{1}, {2}, {3}, {4}}};
  struct GTestCases {
    int val;
  };
  const std::array<GTestCases, 4> gTestCases = {{{1}, {2}, {3}, {4}}};
  std::ignore = gTestCases[UnsafeIndex()].val;  // Trigger spanification.

  // Expected rewrite:
  // struct Knights {
  //   int val;
  // };
  // const std::array<Knights, 4> knights = {{{1}, {2}, {3}, {4}}};
  struct Knights {
    int val;
  };
  const std::array<Knights, 4> knights = {{{1}, {2}, {3}, {4}}};
  std::ignore = knights[UnsafeIndex()].val;  // Trigger spanification.

  // Expected rewrite:
  // struct funcHasName {
  //   int val;
  // };
  // std::array<funcHasName, 4> funcNamedBuffer;
  struct funcHasName {
    int val;
  };
  std::array<funcHasName, 4> funcNamedBuffer;

  // Expected rewrite:
  // std::array<funcHasName, 4> funcNamedBufferButNotInline;
  std::array<funcHasName, 4> funcNamedBufferButNotInline;

  // Expected rewrite:
  // struct FuncBuffer2 {
  //   int val;
  // };
  // static const auto func_buffer2 =
  //     std::to_array<FuncBuffer2>({{1}, {2}, {3}, {4}});
  struct FuncBuffer2 {
    int val;
  };
  static const auto func_buffer2 =
      std::to_array<FuncBuffer2>({{1}, {2}, {3}, {4}});

  // Expected rewrite:
  // struct FuncBufferWithComment {
  //   int val; // Comment
  // };
  // std::array<FuncBuffer, 4> funcBufferWithComment;
  struct FuncBufferWithComment {
    int val;  // Comment
  };
  std::array<FuncBufferWithComment, 4> funcBufferWithComment;

  // Classes can also be used in a similar way.
  // Expected rewrite:
  // class UnnamedClassBuffer {
  //  public:
  //   int val;
  // };
  // std::array<UnnamedClassBuffer, 4> unnamedClassBuffer;
  class UnnamedClassBuffer {
   public:
    int val;
  };
  std::array<UnnamedClassBuffer, 4> unnamedClassBuffer;

  // Unions can also be used in a similar way.
  // Expected rewrite:
  // union UnnamedUnionBuffer {
  //   int val;
  //   float fval;
  // };
  // std::array<UnnamedUnionBuffer, 4> unnamedUnionBuffer;
  union UnnamedUnionBuffer {
    int val;
    float fval;
  };
  std::array<UnnamedUnionBuffer, 4> unnamedUnionBuffer;

  // Expected rewrite:
  // struct NestedStructBuffer {
  //   struct {
  //     int val;
  //   } inner;
  // };
  // std::array<NestedStructBuffer, 3> nestedStructBuffer;
  struct NestedStructBuffer {
    struct {
      int val;
    } inner;
  };
  std::array<NestedStructBuffer, 4> nestedStructBuffer;

  // Buffer accesses to trigger spanification.
  func_buffer[UnsafeIndex()].val = 3;
  globalBuffer[UnsafeIndex()].val = 3;
  funcNamedBuffer[UnsafeIndex()].val = 3;
  globalNamedBuffer[UnsafeIndex()].val = 3;
  globalNamedBufferButNotInline[UnsafeIndex()].val = 3;
  funcNamedBufferButNotInline[UnsafeIndex()].val = 3;
  (void)func_buffer2[UnsafeIndex()].val;
  funcBufferWithComment[UnsafeIndex()].val = 3;
  unnamedClassBuffer[UnsafeIndex()].val = 3;
  unnamedUnionBuffer[UnsafeIndex()].val = 3;
  nestedStructBuffer[UnsafeIndex()].inner.val = 3;
}

// `const` makes the decl have internal linkage, so this should be rewritten
// regardless of crbug.com/364338808.
// Expected rewrite:
// struct MyGlobalStruct1 {
//   int val;
// };
// const std::array<MyGlobalStruct1, 1 + 2> my_global_struct1 = {{
//     {1},
//     {2},
//     {3},
// }};
struct MyGlobalStruct1 {
  int val;
};
const std::array<MyGlobalStruct1, 1 + 2> my_global_struct1 = {{
    {1},
    {2},
    {3},
}};

namespace {

// Anonymous namespace makes the decl have internal linkage, so this should be
// rewritten regardless of crbug.com/364338808.
// Expected rewrite:
// struct MyGlobalStruct2 {
//   int val;
// };
// auto my_global_struct2 = std::to_array<MyGlobalStruct2>({
//     {1},
//     {2},
//     {3},
// });
struct MyGlobalStruct2 {
  int val;
};
auto my_global_struct2 = std::to_array<MyGlobalStruct2>({
    {1},
    {2},
    {3},
});

}  // namespace

void named_global_struct_with_var_decl() {
  // Buffer accesses to trigger spanification for the global structs above.
  std::ignore = my_global_struct1[UnsafeIndex()].val;
  std::ignore = my_global_struct2[UnsafeIndex()].val;
}