blob: 0a77654e4275a662fa13e974d35b2dcd7901fac8 [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>
Sarah Mashayekhid8ea65b2020-11-18 22:34:30 +000020#include <vector>
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000021
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000022#include "src/ast/assignment_statement.h"
Sarah Mashayekhi8db00df2020-08-20 17:00:09 +000023#include "src/ast/call_expression.h"
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000024#include "src/ast/expression.h"
Sarah Mashayekhi65f88d62020-08-06 21:24:14 +000025#include "src/ast/identifier_expression.h"
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000026#include "src/ast/module.h"
Sarah Mashayekhib08e2532020-08-17 15:46:07 +000027#include "src/ast/return_statement.h"
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000028#include "src/ast/statement.h"
Ben Clayton1d8098a2020-11-30 23:30:58 +000029#include "src/ast/switch_statement.h"
Sarah Mashayekhib77399c2020-08-05 15:23:47 +000030#include "src/ast/variable.h"
Ben Clayton1d8098a2020-11-30 23:30:58 +000031#include "src/ast/variable_decl_statement.h"
Ben Claytonba06db62020-11-26 16:50:02 +000032#include "src/diagnostic/diagnostic.h"
33#include "src/diagnostic/formatter.h"
Sarah Mashayekhib77399c2020-08-05 15:23:47 +000034#include "src/scope_stack.h"
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000035
36namespace tint {
37
38/// Determines if the module is complete and valid
39class ValidatorImpl {
40 public:
41 /// Constructor
dan sinclair795b6b52021-01-11 15:10:19 +000042 /// @param module the module to validate
43 explicit ValidatorImpl(const ast::Module* module);
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000044 ~ValidatorImpl();
45
46 /// Runs the validator
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000047 /// @returns true if the validation was successful
dan sinclair795b6b52021-01-11 15:10:19 +000048 bool Validate();
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000049
Ben Claytonba06db62020-11-26 16:50:02 +000050 /// @returns the diagnostic messages
51 const diag::List& diagnostics() const { return diags_; }
52 /// @returns the diagnostic messages
53 diag::List& diagnostics() { return diags_; }
54
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000055 /// @returns error messages from the validator
Ben Claytonba06db62020-11-26 16:50:02 +000056 std::string error() {
Ben Claytond2217382021-01-11 21:09:22 +000057 diag::Formatter formatter{{false, false, false, false}};
Ben Claytonba06db62020-11-26 16:50:02 +000058 return formatter.format(diags_);
59 }
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000060 /// @returns true if an error was encountered
Ben Claytonba06db62020-11-26 16:50:02 +000061 bool has_error() const { return diags_.contains_errors(); }
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000062
Ben Claytonf8971ae2020-12-02 15:31:08 +000063 /// Appends an error at `src` with the code `code` and message `msg`
Ben Claytonf32a3c12020-11-26 17:49:22 +000064 /// @param src the source causing the error
65 /// @param code the validation error code
66 /// @param msg the error message
67 void add_error(const Source& src, const char* code, const std::string& msg);
68
Ben Claytonf8971ae2020-12-02 15:31:08 +000069 /// Appends an error at `src` with the message `msg`
Sarah Mashayekhi462dd672020-03-04 20:51:29 +000070 /// @param src the source causing the error
71 /// @param msg the error message
Ben Claytonba06db62020-11-26 16:50:02 +000072 void add_error(const Source& src, const std::string& msg);
73
Sarah Mashayekhi4fb431c2020-08-25 15:04:53 +000074 /// Validate global variables
75 /// @param global_vars list of global variables to check
76 /// @returns true if the validation was successful
77 bool ValidateGlobalVariables(const ast::VariableList& global_vars);
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000078 /// Validates Functions
79 /// @param funcs the functions to check
80 /// @returns true if the validation was successful
dan sinclair5f812622020-09-22 14:53:03 +000081 bool ValidateFunctions(const ast::FunctionList& funcs);
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000082 /// Validates a function
83 /// @param func the function to check
84 /// @returns true if the validation was successful
Sarah Mashayekhia3f97782020-07-30 02:27:03 +000085 bool ValidateFunction(const ast::Function* func);
Ben Claytonca2c1ed2021-01-05 18:20:40 +000086 /// Validates a function parameter
87 /// @param param the function parameter to check
88 /// @returns true if the validation was successful
89 bool ValidateParameter(const ast::Variable* param);
dan sinclair4069f332020-07-27 15:25:00 +000090 /// Validates a block of statements
91 /// @param block the statements to check
92 /// @returns true if the validation was successful
Sarah Mashayekhia3f97782020-07-30 02:27:03 +000093 bool ValidateStatements(const ast::BlockStatement* block);
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000094 /// Validates a statement
95 /// @param stmt the statement to check
96 /// @returns true if the validation was successful
Sarah Mashayekhia3f97782020-07-30 02:27:03 +000097 bool ValidateStatement(const ast::Statement* stmt);
Sarah Mashayekhi591fe912020-07-23 23:49:52 +000098 /// Validates an assignment
Sarah Mashayekhie88f1c32020-08-07 14:34:34 +000099 /// @param assign the assignment to check
Sarah Mashayekhi591fe912020-07-23 23:49:52 +0000100 /// @returns true if the validation was successful
Sarah Mashayekhie88f1c32020-08-07 14:34:34 +0000101 bool ValidateAssign(const ast::AssignmentStatement* assign);
Sarah Mashayekhi65f88d62020-08-06 21:24:14 +0000102 /// Validates an expression
103 /// @param expr the expression to check
Sarah Mashayekhi8db00df2020-08-20 17:00:09 +0000104 /// @return true if the expression is valid
Sarah Mashayekhi65f88d62020-08-06 21:24:14 +0000105 bool ValidateExpression(const ast::Expression* expr);
106 /// Validates v-0006:Variables must be defined before use
107 /// @param ident the identifer to check if its in the scope
108 /// @return true if idnet was defined
109 bool ValidateIdentifier(const ast::IdentifierExpression* ident);
110 /// Validates if the input follows type checking rules
Sarah Mashayekhie88f1c32020-08-07 14:34:34 +0000111 /// @param assign the assignment to check
Sarah Mashayekhi65f88d62020-08-06 21:24:14 +0000112 /// @returns ture if successful
Sarah Mashayekhie88f1c32020-08-07 14:34:34 +0000113 bool ValidateResultTypes(const ast::AssignmentStatement* assign);
114 /// Validate v-0021: Cannot re-assign a constant
115 /// @param assign is the assigment to check if its lhs is a const
116 /// @returns false if lhs of assign is a constant identifier
117 bool ValidateConstant(const ast::AssignmentStatement* assign);
Ben Claytonf8971ae2020-12-02 15:31:08 +0000118 /// Validates declaration name uniqueness
119 /// @param decl is the new declaration to be added
120 /// @returns true if no previous declaration with the `decl` 's name
Sarah Mashayekhid3107bd2020-08-11 20:44:06 +0000121 /// exist in the variable stack
122 bool ValidateDeclStatement(const ast::VariableDeclStatement* decl);
Sarah Mashayekhib08e2532020-08-17 15:46:07 +0000123 /// Validates return statement
124 /// @param ret the return statement to check
125 /// @returns true if function return type matches the return statement type
126 bool ValidateReturnStatement(const ast::ReturnStatement* ret);
Sarah Mashayekhi8db00df2020-08-20 17:00:09 +0000127 /// Validates function calls
128 /// @param expr the call to validate
129 /// @returns true if successful
130 bool ValidateCallExpr(const ast::CallExpression* expr);
Sarah Mashayekhi2e9f1f52020-09-10 14:37:17 +0000131 /// Validates switch statements
132 /// @param s the switch statement to check
133 /// @returns true if the valdiation was successful
134 bool ValidateSwitch(const ast::SwitchStatement* s);
135 /// Validates case statements
136 /// @param c the case statement to check
137 /// @returns true if the valdiation was successful
138 bool ValidateCase(const ast::CaseStatement* c);
Sarah Mashayekhi3b040582020-11-11 14:21:05 +0000139 /// Validates entry points
140 /// @param funcs the functions to check
141 /// @returns true if the valdiation was successful
142 bool ValidateEntryPoint(const ast::FunctionList& funcs);
Sarah Mashayekhi462dd672020-03-04 20:51:29 +0000143
Sarah Mashayekhid8ea65b2020-11-18 22:34:30 +0000144 /// Validates constructed types
145 /// @param constructed_types the types to check
146 /// @returns true if the valdiation was successful
147 bool ValidateConstructedTypes(
148 const std::vector<ast::type::Type*>& constructed_types);
149
Sarah Mashayekhi462dd672020-03-04 20:51:29 +0000150 private:
dan sinclair795b6b52021-01-11 15:10:19 +0000151 const ast::Module& module_;
Ben Claytonba06db62020-11-26 16:50:02 +0000152 diag::List diags_;
Sarah Mashayekhib77399c2020-08-05 15:23:47 +0000153 ScopeStack<ast::Variable*> variable_stack_;
Sarah Mashayekhieec1a6e2020-08-17 15:32:38 +0000154 ScopeStack<ast::Function*> function_stack_;
Sarah Mashayekhib08e2532020-08-17 15:46:07 +0000155 ast::Function* current_function_ = nullptr;
Sarah Mashayekhi462dd672020-03-04 20:51:29 +0000156};
157
158} // namespace tint
159
Sarah Mashayekhi34f90a02020-11-06 17:31:15 +0000160#endif // SRC_VALIDATOR_VALIDATOR_IMPL_H_