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/program.cc b/src/tint/program.cc
new file mode 100644
index 0000000..a6a6ab7
--- /dev/null
+++ b/src/tint/program.cc
@@ -0,0 +1,131 @@
+// 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/program.h"
+
+#include <utility>
+
+#include "src/tint/demangler.h"
+#include "src/tint/resolver/resolver.h"
+#include "src/tint/sem/expression.h"
+
+namespace tint {
+namespace {
+
+std::string DefaultPrinter(const Program*) {
+ return "<no program printer assigned>";
+}
+
+} // namespace
+
+Program::Printer Program::printer = DefaultPrinter;
+
+Program::Program() = default;
+
+Program::Program(Program&& program)
+ : id_(std::move(program.id_)),
+ types_(std::move(program.types_)),
+ ast_nodes_(std::move(program.ast_nodes_)),
+ sem_nodes_(std::move(program.sem_nodes_)),
+ ast_(std::move(program.ast_)),
+ sem_(std::move(program.sem_)),
+ symbols_(std::move(program.symbols_)),
+ diagnostics_(std::move(program.diagnostics_)),
+ is_valid_(program.is_valid_) {
+ program.AssertNotMoved();
+ program.moved_ = true;
+}
+
+Program::Program(ProgramBuilder&& builder) {
+ id_ = builder.ID();
+
+ is_valid_ = builder.IsValid();
+ if (builder.ResolveOnBuild() && builder.IsValid()) {
+ resolver::Resolver resolver(&builder);
+ if (!resolver.Resolve()) {
+ is_valid_ = false;
+ }
+ }
+
+ // The above must be called *before* the calls to std::move() below
+ types_ = std::move(builder.Types());
+ ast_nodes_ = std::move(builder.ASTNodes());
+ sem_nodes_ = std::move(builder.SemNodes());
+ ast_ = &builder.AST(); // ast::Module is actually a heap allocation.
+ sem_ = std::move(builder.Sem());
+ symbols_ = std::move(builder.Symbols());
+ diagnostics_.add(std::move(builder.Diagnostics()));
+ builder.MarkAsMoved();
+
+ if (!is_valid_ && !diagnostics_.contains_errors()) {
+ // If the builder claims to be invalid, then we really should have an error
+ // message generated. If we find a situation where the program is not valid
+ // and there are no errors reported, add one here.
+ diagnostics_.add_error(diag::System::Program, "invalid program generated");
+ }
+}
+
+Program::~Program() = default;
+
+Program& Program::operator=(Program&& program) {
+ program.AssertNotMoved();
+ program.moved_ = true;
+ moved_ = false;
+ id_ = std::move(program.id_);
+ types_ = std::move(program.types_);
+ ast_nodes_ = std::move(program.ast_nodes_);
+ sem_nodes_ = std::move(program.sem_nodes_);
+ ast_ = std::move(program.ast_);
+ sem_ = std::move(program.sem_);
+ symbols_ = std::move(program.symbols_);
+ diagnostics_ = std::move(program.diagnostics_);
+ is_valid_ = program.is_valid_;
+ return *this;
+}
+
+Program Program::Clone() const {
+ AssertNotMoved();
+ return Program(CloneAsBuilder());
+}
+
+ProgramBuilder Program::CloneAsBuilder() const {
+ AssertNotMoved();
+ ProgramBuilder out;
+ CloneContext(&out, this).Clone();
+ return out;
+}
+
+bool Program::IsValid() const {
+ AssertNotMoved();
+ return is_valid_;
+}
+
+const sem::Type* Program::TypeOf(const ast::Expression* expr) const {
+ auto* sem = Sem().Get(expr);
+ return sem ? sem->Type() : nullptr;
+}
+
+const sem::Type* Program::TypeOf(const ast::Type* type) const {
+ return Sem().Get(type);
+}
+
+const sem::Type* Program::TypeOf(const ast::TypeDecl* type_decl) const {
+ return Sem().Get(type_decl);
+}
+
+void Program::AssertNotMoved() const {
+ TINT_ASSERT(Program, !moved_);
+}
+
+} // namespace tint