tint->dawn: Shuffle source tree in preperation of merging repos

docs/    -> docs/tint/
fuzzers/ -> src/tint/fuzzers/
samples/ -> src/tint/cmd/
src/     -> src/tint/
test/    -> test/tint/

BUG=tint:1418,tint:1433

Change-Id: Id2aa79f989aef3245b80ef4aa37a27ff16cd700b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/80482
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/tint/sem/struct.cc b/src/tint/sem/struct.cc
new file mode 100644
index 0000000..6168a9d
--- /dev/null
+++ b/src/tint/sem/struct.cc
@@ -0,0 +1,177 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/sem/struct.h"
+
+#include <cmath>
+#include <iomanip>
+#include <string>
+#include <utility>
+
+#include "src/tint/ast/struct_member.h"
+#include "src/tint/symbol_table.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::sem::Struct);
+TINT_INSTANTIATE_TYPEINFO(tint::sem::StructMember);
+
+namespace tint {
+namespace sem {
+
+Struct::Struct(const ast::Struct* declaration,
+               Symbol name,
+               StructMemberList members,
+               uint32_t align,
+               uint32_t size,
+               uint32_t size_no_padding)
+    : declaration_(declaration),
+      name_(name),
+      members_(std::move(members)),
+      align_(align),
+      size_(size),
+      size_no_padding_(size_no_padding) {
+  constructible_ = true;
+  for (auto* member : members_) {
+    if (!member->Type()->IsConstructible()) {
+      constructible_ = false;
+      break;
+    }
+  }
+}
+
+Struct::~Struct() = default;
+
+const StructMember* Struct::FindMember(Symbol name) const {
+  for (auto* member : members_) {
+    if (member->Declaration()->symbol == name) {
+      return member;
+    }
+  }
+  return nullptr;
+}
+
+std::string Struct::type_name() const {
+  return "__struct_" + name_.to_str();
+}
+
+uint32_t Struct::Align() const {
+  return align_;
+}
+
+uint32_t Struct::Size() const {
+  return size_;
+}
+
+std::string Struct::FriendlyName(const SymbolTable& symbols) const {
+  return symbols.NameFor(name_);
+}
+
+std::string Struct::Layout(const tint::SymbolTable& symbols) const {
+  std::stringstream ss;
+
+  auto member_name_of = [&](const sem::StructMember* sm) {
+    return symbols.NameFor(sm->Declaration()->symbol);
+  };
+
+  if (Members().empty()) {
+    return {};
+  }
+  const auto* const last_member = Members().back();
+  const uint32_t last_member_struct_padding_offset =
+      last_member->Offset() + last_member->Size();
+
+  // Compute max widths to align output
+  const auto offset_w =
+      static_cast<int>(::log10(last_member_struct_padding_offset)) + 1;
+  const auto size_w = static_cast<int>(::log10(Size())) + 1;
+  const auto align_w = static_cast<int>(::log10(Align())) + 1;
+
+  auto print_struct_begin_line = [&](size_t align, size_t size,
+                                     std::string struct_name) {
+    ss << "/*          " << std::setw(offset_w) << " "
+       << "align(" << std::setw(align_w) << align << ") size("
+       << std::setw(size_w) << size << ") */ struct " << struct_name << " {\n";
+  };
+
+  auto print_struct_end_line = [&]() {
+    ss << "/*                         "
+       << std::setw(offset_w + size_w + align_w) << " "
+       << "*/ };";
+  };
+
+  auto print_member_line = [&](size_t offset, size_t align, size_t size,
+                               std::string s) {
+    ss << "/* offset(" << std::setw(offset_w) << offset << ") align("
+       << std::setw(align_w) << align << ") size(" << std::setw(size_w) << size
+       << ") */   " << s << ";\n";
+  };
+
+  print_struct_begin_line(Align(), Size(), UnwrapRef()->FriendlyName(symbols));
+
+  for (size_t i = 0; i < Members().size(); ++i) {
+    auto* const m = Members()[i];
+
+    // Output field alignment padding, if any
+    auto* const prev_member = (i == 0) ? nullptr : Members()[i - 1];
+    if (prev_member) {
+      uint32_t padding =
+          m->Offset() - (prev_member->Offset() + prev_member->Size());
+      if (padding > 0) {
+        size_t padding_offset = m->Offset() - padding;
+        print_member_line(padding_offset, 1, padding,
+                          "// -- implicit field alignment padding --");
+      }
+    }
+
+    // Output member
+    std::string member_name = member_name_of(m);
+    print_member_line(
+        m->Offset(), m->Align(), m->Size(),
+        member_name + " : " + m->Type()->UnwrapRef()->FriendlyName(symbols));
+  }
+
+  // Output struct size padding, if any
+  uint32_t struct_padding = Size() - last_member_struct_padding_offset;
+  if (struct_padding > 0) {
+    print_member_line(last_member_struct_padding_offset, 1, struct_padding,
+                      "// -- implicit struct size padding --");
+  }
+
+  print_struct_end_line();
+
+  return ss.str();
+}
+
+bool Struct::IsConstructible() const {
+  return constructible_;
+}
+
+StructMember::StructMember(const ast::StructMember* declaration,
+                           Symbol name,
+                           sem::Type* type,
+                           uint32_t index,
+                           uint32_t offset,
+                           uint32_t align,
+                           uint32_t size)
+    : declaration_(declaration),
+      name_(name),
+      type_(type),
+      index_(index),
+      offset_(offset),
+      align_(align),
+      size_(size) {}
+
+StructMember::~StructMember() = default;
+
+}  // namespace sem
+}  // namespace tint