blob: d619b82212ee99fdea1d0f66bff099293cb1e9b9 [file] [log] [blame]
Sarah Mashayekhi462dd672020-03-04 20:51:29 +00001// Copyright 2020 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Sarah Mashayekhi34f90a02020-11-06 17:31:15 +000015#ifndef SRC_VALIDATOR_VALIDATOR_IMPL_H_
16#define SRC_VALIDATOR_VALIDATOR_IMPL_H_
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000017
18#include <string>
Sarah Mashayekhieec1a6e2020-08-17 15:32:38 +000019#include <unordered_map>
David Neto20f4d1d2021-01-18 19:45:24 +000020#include <unordered_set>
Sarah Mashayekhid8ea65b2020-11-18 22:34:30 +000021#include <vector>
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000022
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000023#include "src/ast/assignment_statement.h"
Sarah Mashayekhi8db00df2020-08-20 17:00:09 +000024#include "src/ast/call_expression.h"
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000025#include "src/ast/expression.h"
Sarah Mashayekhi65f88d62020-08-06 21:24:14 +000026#include "src/ast/identifier_expression.h"
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000027#include "src/ast/module.h"
Sarah Mashayekhib08e2532020-08-17 15:46:07 +000028#include "src/ast/return_statement.h"
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000029#include "src/ast/statement.h"
Ben Clayton1d8098a2020-11-30 23:30:58 +000030#include "src/ast/switch_statement.h"
Sarah Mashayekhib77399c2020-08-05 15:23:47 +000031#include "src/ast/variable.h"
Ben Clayton1d8098a2020-11-30 23:30:58 +000032#include "src/ast/variable_decl_statement.h"
Ben Claytonba06db62020-11-26 16:50:02 +000033#include "src/diagnostic/diagnostic.h"
34#include "src/diagnostic/formatter.h"
Sarah Mashayekhib77399c2020-08-05 15:23:47 +000035#include "src/scope_stack.h"
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000036
37namespace tint {
38
39/// Determines if the module is complete and valid
40class ValidatorImpl {
41 public:
42 /// Constructor
dan sinclair795b6b52021-01-11 15:10:19 +000043 /// @param module the module to validate
44 explicit ValidatorImpl(const ast::Module* module);
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000045 ~ValidatorImpl();
46
47 /// Runs the validator
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000048 /// @returns true if the validation was successful
dan sinclair795b6b52021-01-11 15:10:19 +000049 bool Validate();
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000050
Ben Claytonba06db62020-11-26 16:50:02 +000051 /// @returns the diagnostic messages
52 const diag::List& diagnostics() const { return diags_; }
53 /// @returns the diagnostic messages
54 diag::List& diagnostics() { return diags_; }
55
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000056 /// @returns error messages from the validator
Ben Claytonba06db62020-11-26 16:50:02 +000057 std::string error() {
Ben Claytond2217382021-01-11 21:09:22 +000058 diag::Formatter formatter{{false, false, false, false}};
Ben Claytonba06db62020-11-26 16:50:02 +000059 return formatter.format(diags_);
60 }
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000061 /// @returns true if an error was encountered
Ben Claytonba06db62020-11-26 16:50:02 +000062 bool has_error() const { return diags_.contains_errors(); }
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000063
Ben Claytonf8971ae2020-12-02 15:31:08 +000064 /// Appends an error at `src` with the code `code` and message `msg`
Ben Claytonf32a3c12020-11-26 17:49:22 +000065 /// @param src the source causing the error
66 /// @param code the validation error code
67 /// @param msg the error message
68 void add_error(const Source& src, const char* code, const std::string& msg);
69
Ben Claytonf8971ae2020-12-02 15:31:08 +000070 /// Appends an error at `src` with the message `msg`
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000071 /// @param src the source causing the error
72 /// @param msg the error message
Ben Claytonba06db62020-11-26 16:50:02 +000073 void add_error(const Source& src, const std::string& msg);
74
Sarah Mashayekhi4fb431c2020-08-25 15:04:53 +000075 /// Validate global variables
76 /// @param global_vars list of global variables to check
77 /// @returns true if the validation was successful
78 bool ValidateGlobalVariables(const ast::VariableList& global_vars);
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000079 /// Validates Functions
80 /// @param funcs the functions to check
81 /// @returns true if the validation was successful
dan sinclair5f812622020-09-22 14:53:03 +000082 bool ValidateFunctions(const ast::FunctionList& funcs);
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000083 /// Validates a function
84 /// @param func the function to check
85 /// @returns true if the validation was successful
Sarah Mashayekhia3f97782020-07-30 02:27:03 +000086 bool ValidateFunction(const ast::Function* func);
Ben Claytonca2c1ed2021-01-05 18:20:40 +000087 /// Validates a function parameter
88 /// @param param the function parameter to check
89 /// @returns true if the validation was successful
90 bool ValidateParameter(const ast::Variable* param);
dan sinclair4069f332020-07-27 15:25:00 +000091 /// Validates a block of statements
92 /// @param block the statements to check
93 /// @returns true if the validation was successful
Sarah Mashayekhia3f97782020-07-30 02:27:03 +000094 bool ValidateStatements(const ast::BlockStatement* block);
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000095 /// Validates a statement
96 /// @param stmt the statement to check
97 /// @returns true if the validation was successful
Sarah Mashayekhia3f97782020-07-30 02:27:03 +000098 bool ValidateStatement(const ast::Statement* stmt);
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000099 /// Validates an assignment
Sarah Mashayekhie88f1c32020-08-07 14:34:34 +0000100 /// @param assign the assignment to check
Sarah Mashayekhi591fe912020-07-23 23:49:52 +0000101 /// @returns true if the validation was successful
Sarah Mashayekhie88f1c32020-08-07 14:34:34 +0000102 bool ValidateAssign(const ast::AssignmentStatement* assign);
Sarah Mashayekhi65f88d62020-08-06 21:24:14 +0000103 /// Validates an expression
104 /// @param expr the expression to check
Sarah Mashayekhi8db00df2020-08-20 17:00:09 +0000105 /// @return true if the expression is valid
Sarah Mashayekhi65f88d62020-08-06 21:24:14 +0000106 bool ValidateExpression(const ast::Expression* expr);
107 /// Validates v-0006:Variables must be defined before use
108 /// @param ident the identifer to check if its in the scope
109 /// @return true if idnet was defined
110 bool ValidateIdentifier(const ast::IdentifierExpression* ident);
111 /// Validates if the input follows type checking rules
Sarah Mashayekhie88f1c32020-08-07 14:34:34 +0000112 /// @param assign the assignment to check
Sarah Mashayekhi65f88d62020-08-06 21:24:14 +0000113 /// @returns ture if successful
Sarah Mashayekhie88f1c32020-08-07 14:34:34 +0000114 bool ValidateResultTypes(const ast::AssignmentStatement* assign);
115 /// Validate v-0021: Cannot re-assign a constant
116 /// @param assign is the assigment to check if its lhs is a const
117 /// @returns false if lhs of assign is a constant identifier
118 bool ValidateConstant(const ast::AssignmentStatement* assign);
Ben Claytonf8971ae2020-12-02 15:31:08 +0000119 /// Validates declaration name uniqueness
120 /// @param decl is the new declaration to be added
121 /// @returns true if no previous declaration with the `decl` 's name
Sarah Mashayekhid3107bd2020-08-11 20:44:06 +0000122 /// exist in the variable stack
123 bool ValidateDeclStatement(const ast::VariableDeclStatement* decl);
Sarah Mashayekhib08e2532020-08-17 15:46:07 +0000124 /// Validates return statement
125 /// @param ret the return statement to check
126 /// @returns true if function return type matches the return statement type
127 bool ValidateReturnStatement(const ast::ReturnStatement* ret);
Sarah Mashayekhi8db00df2020-08-20 17:00:09 +0000128 /// Validates function calls
129 /// @param expr the call to validate
130 /// @returns true if successful
131 bool ValidateCallExpr(const ast::CallExpression* expr);
Sarah Mashayekhi2e9f1f52020-09-10 14:37:17 +0000132 /// Validates switch statements
133 /// @param s the switch statement to check
134 /// @returns true if the valdiation was successful
135 bool ValidateSwitch(const ast::SwitchStatement* s);
136 /// Validates case statements
137 /// @param c the case statement to check
138 /// @returns true if the valdiation was successful
139 bool ValidateCase(const ast::CaseStatement* c);
Sarah Mashayekhi3b040582020-11-11 14:21:05 +0000140 /// Validates entry points
141 /// @param funcs the functions to check
142 /// @returns true if the valdiation was successful
143 bool ValidateEntryPoint(const ast::FunctionList& funcs);
Sarah Mashayekhi462dd672020-03-04 20:51:29 +0000144
Sarah Mashayekhid8ea65b2020-11-18 22:34:30 +0000145 /// Validates constructed types
146 /// @param constructed_types the types to check
147 /// @returns true if the valdiation was successful
148 bool ValidateConstructedTypes(
149 const std::vector<ast::type::Type*>& constructed_types);
150
David Neto20f4d1d2021-01-18 19:45:24 +0000151 /// Returns true if the given type is storable. This uses and
152 /// updates `storable_` and `not_storable_`.
153 /// @param type the given type
154 /// @returns true if the given type is storable.
155 bool IsStorable(ast::type::Type* type);
156
Sarah Mashayekhi462dd672020-03-04 20:51:29 +0000157 private:
dan sinclair795b6b52021-01-11 15:10:19 +0000158 const ast::Module& module_;
Ben Claytonba06db62020-11-26 16:50:02 +0000159 diag::List diags_;
Sarah Mashayekhib77399c2020-08-05 15:23:47 +0000160 ScopeStack<ast::Variable*> variable_stack_;
Sarah Mashayekhieec1a6e2020-08-17 15:32:38 +0000161 ScopeStack<ast::Function*> function_stack_;
Sarah Mashayekhib08e2532020-08-17 15:46:07 +0000162 ast::Function* current_function_ = nullptr;
Sarah Mashayekhi462dd672020-03-04 20:51:29 +0000163};
164
165} // namespace tint
166
Sarah Mashayekhi34f90a02020-11-06 17:31:15 +0000167#endif // SRC_VALIDATOR_VALIDATOR_IMPL_H_