Rename semantic to sem

* Rename namespace semantic to sem
* Rename directory src/semantic/ to src/sem/

Bug: tint:724
Change-Id: I76383b821fbca7f1037a803c497b595a706dcb06
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48120
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
Antonio Maiorano
2021-04-16 19:07:51 +00:00
committed by Commit Bot service account
parent 26cd48603d
commit 5cd71b8c0a
174 changed files with 847 additions and 866 deletions

69
src/sem/array.h Normal file
View File

@@ -0,0 +1,69 @@
// 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.
#ifndef SRC_SEM_ARRAY_H_
#define SRC_SEM_ARRAY_H_
#include <stdint.h>
#include "src/sem/node.h"
namespace tint {
// Forward declarations
namespace type {
class Array;
} // namespace type
namespace sem {
/// Array holds the semantic information for Array nodes.
class Array : public Castable<Array, Node> {
public:
/// Constructor
/// @param type the Array type
/// @param align the byte alignment of the structure
/// @param size the byte size of the structure
/// @param stride the number of bytes from the start of one element of the
/// array to the start of the next element
Array(type::Array* type, uint32_t align, uint32_t size, uint32_t stride);
/// @return the resolved type of the Array
type::Array* Type() const { return type_; }
/// @returns the byte alignment of the array
/// @note this may differ from the alignment of a structure member of this
/// array type, if the member is annotated with the `[[align(n)]]` decoration.
uint32_t Align() const { return align_; }
/// @returns the byte size of the array
/// @note this may differ from the size of a structure member of this array
/// type, if the member is annotated with the `[[size(n)]]` decoration.
uint32_t Size() const { return size_; }
/// @returns the number of bytes from the start of one element of the
/// array to the start of the next element
uint32_t Stride() const { return stride_; }
private:
type::Array* const type_;
uint32_t const align_;
uint32_t const size_;
uint32_t const stride_;
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_ARRAY_H_

49
src/sem/call.h Normal file
View File

@@ -0,0 +1,49 @@
// 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.
#ifndef SRC_SEM_CALL_H_
#define SRC_SEM_CALL_H_
#include "src/sem/expression.h"
#include "src/sem/intrinsic.h"
namespace tint {
namespace sem {
/// Call is the base class for semantic nodes that hold semantic information for
/// ast::CallExpression nodes.
class Call : public Castable<Call, Expression> {
public:
/// Constructor
/// @param declaration the AST node
/// @param target the call target
/// @param statement the statement that owns this expression
Call(ast::Expression* declaration,
const CallTarget* target,
Statement* statement);
/// Destructor
~Call() override;
/// @return the target of the call
const CallTarget* Target() const { return target_; }
private:
CallTarget const* const target_;
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_CALL_H_

102
src/sem/call_target.h Normal file
View File

@@ -0,0 +1,102 @@
// 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.
#ifndef SRC_SEM_CALL_TARGET_H_
#define SRC_SEM_CALL_TARGET_H_
#include <vector>
#include "src/sem/node.h"
#include "src/type/sampler_type.h"
namespace tint {
// Forward declarations
namespace type {
class Type;
} // namespace type
namespace sem {
/// Parameter describes a single parameter of a call target
struct Parameter {
/// Usage is extra metadata for identifying a parameter based on its overload
/// position
enum class Usage {
kNone,
kArrayIndex,
kBias,
kCoords,
kDepthRef,
kDdx,
kDdy,
kLevel,
kOffset,
kSampler,
kSampleIndex,
kTexture,
kValue,
};
/// Parameter type
type::Type* const type;
/// Parameter usage
Usage const usage = Usage::kNone;
};
std::ostream& operator<<(std::ostream& out, Parameter parameter);
/// Comparison operator for Parameters
static inline bool operator==(const Parameter& a, const Parameter& b) {
return a.type == b.type && a.usage == b.usage;
}
/// @returns a string representation of the given parameter usage.
const char* str(Parameter::Usage usage);
/// ParameterList is a list of Parameter
using ParameterList = std::vector<Parameter>;
/// @param parameters the list of parameters
/// @param usage the parameter usage to find
/// @returns the index of the parameter with the given usage, or -1 if no
/// parameter with the given usage exists.
int IndexOf(const ParameterList& parameters, Parameter::Usage usage);
/// CallTarget is the base for callable functions
class CallTarget : public Castable<CallTarget, Node> {
public:
/// Constructor
/// @param return_type the return type of the call target
/// @param parameters the parameters for the call target
CallTarget(type::Type* return_type, const ParameterList& parameters);
/// @return the return type of the call target
type::Type* ReturnType() const { return return_type_; }
/// Destructor
~CallTarget() override;
/// @return the parameters of the call target
const ParameterList& Parameters() const { return parameters_; }
private:
type::Type* const return_type_;
ParameterList const parameters_;
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_CALL_TARGET_H_

62
src/sem/expression.h Normal file
View File

@@ -0,0 +1,62 @@
// 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.
#ifndef SRC_SEM_EXPRESSION_H_
#define SRC_SEM_EXPRESSION_H_
#include "src/ast/expression.h"
#include "src/sem/node.h"
namespace tint {
// Forward declarations
namespace sem {
class Statement;
} // namespace sem
namespace type {
class Type;
} // namespace type
namespace sem {
/// Expression holds the semantic information for expression nodes.
class Expression : public Castable<Expression, Node> {
public:
/// Constructor
/// @param declaration the AST node
/// @param type the resolved type of the expression
/// @param statement the statement that owns this expression
Expression(ast::Expression* declaration,
type::Type* type,
Statement* statement);
/// @return the resolved type of the expression
type::Type* Type() const { return type_; }
/// @return the statement that owns this expression
Statement* Stmt() const { return statement_; }
/// @returns the AST node
ast::Expression* Declaration() const { return declaration_; }
private:
ast::Expression* declaration_;
type::Type* const type_;
Statement* const statement_;
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_EXPRESSION_H_

160
src/sem/function.h Normal file
View File

@@ -0,0 +1,160 @@
// 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.
#ifndef SRC_SEM_FUNCTION_H_
#define SRC_SEM_FUNCTION_H_
#include <utility>
#include <vector>
#include "src/ast/variable.h"
#include "src/sem/call_target.h"
namespace tint {
// Forward declarations
namespace ast {
class BindingDecoration;
class BuiltinDecoration;
class Function;
class GroupDecoration;
class LocationDecoration;
class ReturnStatement;
} // namespace ast
namespace sem {
class Variable;
/// Function holds the semantic information for function nodes.
class Function : public Castable<Function, CallTarget> {
public:
/// A vector of [Variable*, ast::Variable::BindingPoint] pairs
using VariableBindings =
std::vector<std::pair<const Variable*, ast::Variable::BindingPoint>>;
/// Constructor
/// @param declaration the ast::Function
/// @param parameters the parameters to the function
/// @param referenced_module_vars the referenced module variables
/// @param local_referenced_module_vars the locally referenced module
/// @param return_statements the function return statements
/// variables
/// @param ancestor_entry_points the ancestor entry points
Function(ast::Function* declaration,
std::vector<const Variable*> parameters,
std::vector<const Variable*> referenced_module_vars,
std::vector<const Variable*> local_referenced_module_vars,
std::vector<const ast::ReturnStatement*> return_statements,
std::vector<Symbol> ancestor_entry_points);
/// Destructor
~Function() override;
/// @returns the ast::Function declaration
ast::Function* Declaration() const { return declaration_; }
/// @return the parameters to the function
const std::vector<const Variable*> Parameters() const { return parameters_; }
/// Note: If this function calls other functions, the return will also include
/// all of the referenced variables from the callees.
/// @returns the referenced module variables
const std::vector<const Variable*>& ReferencedModuleVariables() const {
return referenced_module_vars_;
}
/// @returns the locally referenced module variables
const std::vector<const Variable*>& LocalReferencedModuleVariables() const {
return local_referenced_module_vars_;
}
/// @returns the return statements
const std::vector<const ast::ReturnStatement*> ReturnStatements() const {
return return_statements_;
}
/// @returns the ancestor entry points
const std::vector<Symbol>& AncestorEntryPoints() const {
return ancestor_entry_points_;
}
/// Retrieves any referenced location variables
/// @returns the <variable, decoration> pair.
std::vector<std::pair<const Variable*, ast::LocationDecoration*>>
ReferencedLocationVariables() const;
/// Retrieves any referenced builtin variables
/// @returns the <variable, decoration> pair.
std::vector<std::pair<const Variable*, ast::BuiltinDecoration*>>
ReferencedBuiltinVariables() const;
/// Retrieves any referenced uniform variables. Note, the variables must be
/// decorated with both binding and group decorations.
/// @returns the referenced uniforms
VariableBindings ReferencedUniformVariables() const;
/// Retrieves any referenced storagebuffer variables. Note, the variables
/// must be decorated with both binding and group decorations.
/// @returns the referenced storagebuffers
VariableBindings ReferencedStorageBufferVariables() const;
/// Retrieves any referenced regular Sampler variables. Note, the
/// variables must be decorated with both binding and group decorations.
/// @returns the referenced storagebuffers
VariableBindings ReferencedSamplerVariables() const;
/// Retrieves any referenced comparison Sampler variables. Note, the
/// variables must be decorated with both binding and group decorations.
/// @returns the referenced storagebuffers
VariableBindings ReferencedComparisonSamplerVariables() const;
/// Retrieves any referenced sampled textures variables. Note, the
/// variables must be decorated with both binding and group decorations.
/// @returns the referenced sampled textures
VariableBindings ReferencedSampledTextureVariables() const;
/// Retrieves any referenced multisampled textures variables. Note, the
/// variables must be decorated with both binding and group decorations.
/// @returns the referenced sampled textures
VariableBindings ReferencedMultisampledTextureVariables() const;
/// Retrieves any referenced storage texture variables. Note, the variables
/// must be decorated with both binding and group decorations.
/// @returns the referenced storage textures
VariableBindings ReferencedStorageTextureVariables() const;
/// Retrieves any referenced depth texture variables. Note, the variables
/// must be decorated with both binding and group decorations.
/// @returns the referenced storage textures
VariableBindings ReferencedDepthTextureVariables() const;
/// Checks if the given entry point is an ancestor
/// @param sym the entry point symbol
/// @returns true if `sym` is an ancestor entry point of this function
bool HasAncestorEntryPoint(Symbol sym) const;
private:
VariableBindings ReferencedSamplerVariablesImpl(type::SamplerKind kind) const;
VariableBindings ReferencedSampledTextureVariablesImpl(
bool multisampled) const;
ast::Function* const declaration_;
std::vector<const Variable*> const parameters_;
std::vector<const Variable*> const referenced_module_vars_;
std::vector<const Variable*> const local_referenced_module_vars_;
std::vector<const ast::ReturnStatement*> const return_statements_;
std::vector<Symbol> const ancestor_entry_points_;
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_FUNCTION_H_

89
src/sem/info.h Normal file
View File

@@ -0,0 +1,89 @@
// 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.
#ifndef SRC_SEM_INFO_H_
#define SRC_SEM_INFO_H_
#include <unordered_map>
#include "src/debug.h"
#include "src/sem/node.h"
#include "src/sem/type_mappings.h"
namespace tint {
namespace sem {
/// Info holds all the resolved semantic information for a Program.
class Info {
public:
/// Constructor
Info();
/// Move constructor
Info(Info&&);
/// Destructor
~Info();
/// Move assignment operator
/// @param rhs the Program to move
/// @return this Program
Info& operator=(Info&& rhs);
/// Get looks up the semantic information for the AST or type node `node`.
/// @param node the AST or type node
/// @returns a pointer to the semantic node if found, otherwise nullptr
template <typename AST_OR_TYPE,
typename SEM = SemanticNodeTypeFor<AST_OR_TYPE>>
const SEM* Get(const AST_OR_TYPE* node) const {
auto it = map.find(node);
if (it == map.end()) {
return nullptr;
}
return it->second->template As<SEM>();
}
/// Add registers the semantic node `sem_node` for the AST or type node
/// `node`.
/// @param node the AST or type node
/// @param sem_node the semantic node
template <typename AST_OR_TYPE>
void Add(const AST_OR_TYPE* node,
const SemanticNodeTypeFor<AST_OR_TYPE>* sem_node) {
// Check there's no semantic info already existing for the node
TINT_ASSERT(Get(node) == nullptr);
map.emplace(node, sem_node);
}
/// Wrap returns a new Info created with the contents of `inner`.
/// The Info returned by Wrap is intended to temporarily extend the contents
/// of an existing immutable Info.
/// As the copied contents are owned by `inner`, `inner` must not be
/// destructed or assigned while using the returned Info.
/// @param inner the immutable Info to extend
/// @return the Info that wraps `inner`
static Info Wrap(const Info& inner) {
Info out;
out.map = inner.map;
return out;
}
private:
std::unordered_map<const CastableBase*, const sem::Node*> map;
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_INFO_H_

228
src/sem/intrinsic.h Normal file
View File

@@ -0,0 +1,228 @@
// Copyright 2020 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.
#ifndef SRC_SEM_INTRINSIC_H_
#define SRC_SEM_INTRINSIC_H_
#include <string>
#include "src/sem/call_target.h"
namespace tint {
namespace sem {
enum class IntrinsicType {
kNone = -1,
kAbs,
kAcos,
kAll,
kAny,
kArrayLength,
kAsin,
kAtan,
kAtan2,
kCeil,
kClamp,
kCos,
kCosh,
kCountOneBits,
kCross,
kDeterminant,
kDistance,
kDot,
kDpdx,
kDpdxCoarse,
kDpdxFine,
kDpdy,
kDpdyCoarse,
kDpdyFine,
kExp,
kExp2,
kFaceForward,
kFloor,
kFma,
kFract,
kFrexp,
kFwidth,
kFwidthCoarse,
kFwidthFine,
kInverseSqrt,
kIsFinite,
kIsInf,
kIsNan,
kIsNormal,
kLdexp,
kLength,
kLog,
kLog2,
kMax,
kMin,
kMix,
kModf,
kNormalize,
kPack2x16Float,
kPack2x16Snorm,
kPack2x16Unorm,
kPack4x8Snorm,
kPack4x8Unorm,
kPow,
kReflect,
kReverseBits,
kRound,
kSelect,
kSign,
kSin,
kSinh,
kSmoothStep,
kSqrt,
kStep,
kStorageBarrier,
kTan,
kTanh,
kTextureDimensions,
kTextureLoad,
kTextureNumLayers,
kTextureNumLevels,
kTextureNumSamples,
kTextureSample,
kTextureSampleBias,
kTextureSampleCompare,
kTextureSampleGrad,
kTextureSampleLevel,
kTextureStore,
kTrunc,
kUnpack2x16Float,
kUnpack2x16Snorm,
kUnpack2x16Unorm,
kUnpack4x8Snorm,
kUnpack4x8Unorm,
kWorkgroupBarrier,
};
/// Matches the IntrisicType by name
/// @param name the intrinsic name to parse
/// @returns the parsed IntrinsicType, or IntrinsicType::kNone if `name` did not
/// match any intrinsic.
IntrinsicType ParseIntrinsicType(const std::string& name);
/// @returns the name of the intrinsic function type. The spelling, including
/// case, matches the name in the WGSL spec.
const char* str(IntrinsicType i);
/// Determines if the given `i` is a coarse derivative
/// @param i the intrinsic type
/// @returns true if the given derivative is coarse.
bool IsCoarseDerivativeIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a fine derivative
/// @param i the intrinsic type
/// @returns true if the given derivative is fine.
bool IsFineDerivativeIntrinsic(IntrinsicType i);
/// Determine if the given `i` is a derivative intrinsic
/// @param i the intrinsic type
/// @returns true if the given `i` is a derivative intrinsic
bool IsDerivativeIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a float classification intrinsic
/// @param i the intrinsic type
/// @returns true if the given `i` is a float intrinsic
bool IsFloatClassificationIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a texture operation intrinsic
/// @param i the intrinsic type
/// @returns true if the given `i` is a texture operation intrinsic
bool IsTextureIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a image query intrinsic
/// @param i the intrinsic type
/// @returns true if the given `i` is a image query intrinsic
bool IsImageQueryIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a data packing intrinsic
/// @param i the intrinsic
/// @returns true if the given `i` is a data packing intrinsic
bool IsDataPackingIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a data unpacking intrinsic
/// @param i the intrinsic
/// @returns true if the given `i` is a data unpacking intrinsic
bool IsDataUnpackingIntrinsic(IntrinsicType i);
/// Determines if the given `i` is a barrier intrinsic
/// @param i the intrinsic
/// @returns true if the given `i` is a barrier intrinsic
bool IsBarrierIntrinsic(IntrinsicType i);
/// Intrinsic holds the semantic information for an intrinsic function.
class Intrinsic : public Castable<Intrinsic, CallTarget> {
public:
/// Constructor
/// @param type the intrinsic type
/// @param return_type the return type for the intrinsic call
/// @param parameters the parameters for the intrinsic overload
Intrinsic(IntrinsicType type,
type::Type* return_type,
const ParameterList& parameters);
/// Destructor
~Intrinsic() override;
/// @return the type of the intrinsic
IntrinsicType Type() const { return type_; }
/// @returns the name of the intrinsic function type. The spelling, including
/// case, matches the name in the WGSL spec.
const char* str() const;
/// @returns true if intrinsic is a coarse derivative intrinsic
bool IsCoarseDerivative() const;
/// @returns true if intrinsic is a fine a derivative intrinsic
bool IsFineDerivative() const;
/// @returns true if intrinsic is a derivative intrinsic
bool IsDerivative() const;
/// @returns true if intrinsic is a float intrinsic
bool IsFloatClassification() const;
/// @returns true if intrinsic is a texture operation intrinsic
bool IsTexture() const;
/// @returns true if intrinsic is a image query intrinsic
bool IsImageQuery() const;
/// @returns true if intrinsic is a data packing intrinsic
bool IsDataPacking() const;
/// @returns true if intrinsic is a data unpacking intrinsic
bool IsDataUnpacking() const;
/// @returns true if intrinsic is a barrier intrinsic
bool IsBarrier() const;
private:
IntrinsicType const type_;
};
/// Emits the name of the intrinsic function type. The spelling, including case,
/// matches the name in the WGSL spec.
std::ostream& operator<<(std::ostream& out, IntrinsicType i);
} // namespace sem
} // namespace tint
#endif // SRC_SEM_INTRINSIC_H_

View File

@@ -0,0 +1,105 @@
// 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.
#ifndef SRC_SEM_MEMBER_ACCESSOR_EXPRESSION_H_
#define SRC_SEM_MEMBER_ACCESSOR_EXPRESSION_H_
#include <vector>
#include "src/sem/expression.h"
namespace tint {
/// Forward declarations
namespace ast {
class MemberAccessorExpression;
} // namespace ast
namespace sem {
/// Forward declarations
class Struct;
class StructMember;
/// MemberAccessorExpression holds the semantic information for a
/// ast::MemberAccessorExpression node.
class MemberAccessorExpression
: public Castable<MemberAccessorExpression, Expression> {
public:
/// Constructor
/// @param declaration the AST node
/// @param type the resolved type of the expression
/// @param statement the statement that owns this expression
MemberAccessorExpression(ast::MemberAccessorExpression* declaration,
type::Type* type,
Statement* statement);
/// Destructor
~MemberAccessorExpression() override;
};
/// StructMemberAccess holds the semantic information for a
/// ast::MemberAccessorExpression node that represents an access to a structure
/// member.
class StructMemberAccess
: public Castable<StructMemberAccess, MemberAccessorExpression> {
public:
/// Constructor
/// @param declaration the AST node
/// @param type the resolved type of the expression
/// @param statement the statement that owns this expression
/// @param member the structure member
StructMemberAccess(ast::MemberAccessorExpression* declaration,
type::Type* type,
Statement* statement,
const StructMember* member);
/// Destructor
~StructMemberAccess() override;
/// @returns the structure member
StructMember const* Member() const { return member_; }
private:
StructMember const* const member_;
};
/// Swizzle holds the semantic information for a ast::MemberAccessorExpression
/// node that represents a vector swizzle.
class Swizzle : public Castable<Swizzle, MemberAccessorExpression> {
public:
/// Constructor
/// @param declaration the AST node
/// @param type the resolved type of the expression
/// @param statement the statement that
/// @param indices the swizzle indices
Swizzle(ast::MemberAccessorExpression* declaration,
type::Type* type,
Statement* statement,
std::vector<uint32_t> indices);
/// Destructor
~Swizzle() override;
/// @return the swizzle indices, if this is a vector swizzle
const std::vector<uint32_t>& Indices() const { return indices_; }
private:
std::vector<uint32_t> const indices_;
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_MEMBER_ACCESSOR_EXPRESSION_H_

33
src/sem/node.h Normal file
View File

@@ -0,0 +1,33 @@
// 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.
#ifndef SRC_SEM_NODE_H_
#define SRC_SEM_NODE_H_
#include "src/castable.h"
namespace tint {
namespace sem {
/// Node is the base class for all semantic nodes
class Node : public Castable<Node> {
public:
/// Destructor
~Node() override;
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_NODE_H_

26
src/sem/sem_array.cc Normal file
View File

@@ -0,0 +1,26 @@
// 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/sem/array.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Array);
namespace tint {
namespace sem {
Array::Array(type::Array* type, uint32_t align, uint32_t size, uint32_t stride)
: type_(type), align_(align), size_(size), stride_(stride) {}
} // namespace sem
} // namespace tint

30
src/sem/sem_call.cc Normal file
View File

@@ -0,0 +1,30 @@
// 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/sem/call.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Call);
namespace tint {
namespace sem {
Call::Call(ast::Expression* declaration,
const CallTarget* target,
Statement* statement)
: Base(declaration, target->ReturnType(), statement), target_(target) {}
Call::~Call() = default;
} // namespace sem
} // namespace tint

View File

@@ -0,0 +1,76 @@
// 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/sem/call_target.h"
#include "src/symbol_table.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::CallTarget);
namespace tint {
namespace sem {
CallTarget::CallTarget(type::Type* return_type, const ParameterList& parameters)
: return_type_(return_type), parameters_(parameters) {}
CallTarget::~CallTarget() = default;
int IndexOf(const ParameterList& parameters, Parameter::Usage usage) {
for (size_t i = 0; i < parameters.size(); i++) {
if (parameters[i].usage == usage) {
return static_cast<int>(i);
}
}
return -1;
}
const char* str(Parameter::Usage usage) {
switch (usage) {
case Parameter::Usage::kArrayIndex:
return "array_index";
case Parameter::Usage::kBias:
return "bias";
case Parameter::Usage::kCoords:
return "coords";
case Parameter::Usage::kDepthRef:
return "depth_ref";
case Parameter::Usage::kDdx:
return "ddx";
case Parameter::Usage::kDdy:
return "ddy";
case Parameter::Usage::kLevel:
return "level";
case Parameter::Usage::kOffset:
return "offset";
case Parameter::Usage::kSampler:
return "sampler";
case Parameter::Usage::kSampleIndex:
return "sample_index";
case Parameter::Usage::kTexture:
return "texture";
case Parameter::Usage::kValue:
return "value";
default:
return "<unknown>";
}
}
std::ostream& operator<<(std::ostream& out, Parameter parameter) {
out << "[type: " << parameter.type->FriendlyName(SymbolTable{ProgramID{}})
<< ", usage: " << str(parameter.usage) << "]";
return out;
}
} // namespace sem
} // namespace tint

30
src/sem/sem_expression.cc Normal file
View File

@@ -0,0 +1,30 @@
// 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/sem/expression.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Expression);
namespace tint {
namespace sem {
Expression::Expression(ast::Expression* declaration,
type::Type* type,
Statement* statement)
: declaration_(declaration),
type_(type->UnwrapIfNeeded()),
statement_(statement) {}
} // namespace sem
} // namespace tint

229
src/sem/sem_function.cc Normal file
View File

@@ -0,0 +1,229 @@
// 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/sem/function.h"
#include "src/ast/function.h"
#include "src/sem/variable.h"
#include "src/type/depth_texture_type.h"
#include "src/type/multisampled_texture_type.h"
#include "src/type/sampled_texture_type.h"
#include "src/type/storage_texture_type.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Function);
namespace tint {
namespace sem {
namespace {
ParameterList GetParameters(ast::Function* ast) {
ParameterList parameters;
parameters.reserve(ast->params().size());
for (auto* param : ast->params()) {
parameters.emplace_back(
Parameter{param->declared_type(), Parameter::Usage::kNone});
}
return parameters;
}
} // namespace
Function::Function(ast::Function* declaration,
std::vector<const Variable*> parameters,
std::vector<const Variable*> referenced_module_vars,
std::vector<const Variable*> local_referenced_module_vars,
std::vector<const ast::ReturnStatement*> return_statements,
std::vector<Symbol> ancestor_entry_points)
: Base(declaration->return_type(), GetParameters(declaration)),
declaration_(declaration),
parameters_(std::move(parameters)),
referenced_module_vars_(std::move(referenced_module_vars)),
local_referenced_module_vars_(std::move(local_referenced_module_vars)),
return_statements_(std::move(return_statements)),
ancestor_entry_points_(std::move(ancestor_entry_points)) {}
Function::~Function() = default;
std::vector<std::pair<const Variable*, ast::LocationDecoration*>>
Function::ReferencedLocationVariables() const {
std::vector<std::pair<const Variable*, ast::LocationDecoration*>> ret;
for (auto* var : ReferencedModuleVariables()) {
for (auto* deco : var->Declaration()->decorations()) {
if (auto* location = deco->As<ast::LocationDecoration>()) {
ret.push_back({var, location});
break;
}
}
}
return ret;
}
Function::VariableBindings Function::ReferencedUniformVariables() const {
VariableBindings ret;
for (auto* var : ReferencedModuleVariables()) {
if (var->StorageClass() != ast::StorageClass::kUniform) {
continue;
}
if (auto binding_point = var->Declaration()->binding_point()) {
ret.push_back({var, binding_point});
}
}
return ret;
}
Function::VariableBindings Function::ReferencedStorageBufferVariables() const {
VariableBindings ret;
for (auto* var : ReferencedModuleVariables()) {
if (var->StorageClass() != ast::StorageClass::kStorage) {
continue;
}
if (auto binding_point = var->Declaration()->binding_point()) {
ret.push_back({var, binding_point});
}
}
return ret;
}
std::vector<std::pair<const Variable*, ast::BuiltinDecoration*>>
Function::ReferencedBuiltinVariables() const {
std::vector<std::pair<const Variable*, ast::BuiltinDecoration*>> ret;
for (auto* var : ReferencedModuleVariables()) {
for (auto* deco : var->Declaration()->decorations()) {
if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
ret.push_back({var, builtin});
break;
}
}
}
return ret;
}
Function::VariableBindings Function::ReferencedSamplerVariables() const {
return ReferencedSamplerVariablesImpl(type::SamplerKind::kSampler);
}
Function::VariableBindings Function::ReferencedComparisonSamplerVariables()
const {
return ReferencedSamplerVariablesImpl(type::SamplerKind::kComparisonSampler);
}
Function::VariableBindings Function::ReferencedSampledTextureVariables() const {
return ReferencedSampledTextureVariablesImpl(false);
}
Function::VariableBindings Function::ReferencedMultisampledTextureVariables()
const {
return ReferencedSampledTextureVariablesImpl(true);
}
Function::VariableBindings Function::ReferencedStorageTextureVariables() const {
VariableBindings ret;
for (auto* var : ReferencedModuleVariables()) {
auto* unwrapped_type =
var->Declaration()->declared_type()->UnwrapIfNeeded();
auto* storage_texture = unwrapped_type->As<type::StorageTexture>();
if (storage_texture == nullptr) {
continue;
}
if (auto binding_point = var->Declaration()->binding_point()) {
ret.push_back({var, binding_point});
}
}
return ret;
}
Function::VariableBindings Function::ReferencedDepthTextureVariables() const {
VariableBindings ret;
for (auto* var : ReferencedModuleVariables()) {
auto* unwrapped_type =
var->Declaration()->declared_type()->UnwrapIfNeeded();
auto* storage_texture = unwrapped_type->As<type::DepthTexture>();
if (storage_texture == nullptr) {
continue;
}
if (auto binding_point = var->Declaration()->binding_point()) {
ret.push_back({var, binding_point});
}
}
return ret;
}
bool Function::HasAncestorEntryPoint(Symbol symbol) const {
for (const auto& point : ancestor_entry_points_) {
if (point == symbol) {
return true;
}
}
return false;
}
Function::VariableBindings Function::ReferencedSamplerVariablesImpl(
type::SamplerKind kind) const {
VariableBindings ret;
for (auto* var : ReferencedModuleVariables()) {
auto* unwrapped_type =
var->Declaration()->declared_type()->UnwrapIfNeeded();
auto* sampler = unwrapped_type->As<type::Sampler>();
if (sampler == nullptr || sampler->kind() != kind) {
continue;
}
if (auto binding_point = var->Declaration()->binding_point()) {
ret.push_back({var, binding_point});
}
}
return ret;
}
Function::VariableBindings Function::ReferencedSampledTextureVariablesImpl(
bool multisampled) const {
VariableBindings ret;
for (auto* var : ReferencedModuleVariables()) {
auto* unwrapped_type =
var->Declaration()->declared_type()->UnwrapIfNeeded();
auto* texture = unwrapped_type->As<type::Texture>();
if (texture == nullptr) {
continue;
}
auto is_multisampled = texture->Is<type::MultisampledTexture>();
auto is_sampled = texture->Is<type::SampledTexture>();
if ((multisampled && !is_multisampled) || (!multisampled && !is_sampled)) {
continue;
}
if (auto binding_point = var->Declaration()->binding_point()) {
ret.push_back({var, binding_point});
}
}
return ret;
}
} // namespace sem
} // namespace tint

29
src/sem/sem_info.cc Normal file
View File

@@ -0,0 +1,29 @@
// 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/sem/info.h"
namespace tint {
namespace sem {
Info::Info() = default;
Info::Info(Info&&) = default;
Info::~Info() = default;
Info& Info::operator=(Info&&) = default;
} // namespace sem
} // namespace tint

241
src/sem/sem_intrinsic.cc Normal file
View File

@@ -0,0 +1,241 @@
// Copyright 2020 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/sem/intrinsic.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Intrinsic);
namespace tint {
namespace sem {
std::ostream& operator<<(std::ostream& out, IntrinsicType i) {
out << str(i);
return out;
}
const char* Intrinsic::str() const {
return sem::str(type_);
}
/// Name matches the spelling in the WGSL spec including case.
#define INTRINSIC_LIST() \
INTRINSIC(IntrinsicType::kNone, "<not-an-intrinsic>") \
INTRINSIC(IntrinsicType::kAbs, "abs") \
INTRINSIC(IntrinsicType::kAcos, "acos") \
INTRINSIC(IntrinsicType::kAll, "all") \
INTRINSIC(IntrinsicType::kAny, "any") \
INTRINSIC(IntrinsicType::kArrayLength, "arrayLength") \
INTRINSIC(IntrinsicType::kAsin, "asin") \
INTRINSIC(IntrinsicType::kAtan, "atan") \
INTRINSIC(IntrinsicType::kAtan2, "atan2") \
INTRINSIC(IntrinsicType::kCeil, "ceil") \
INTRINSIC(IntrinsicType::kClamp, "clamp") \
INTRINSIC(IntrinsicType::kCos, "cos") \
INTRINSIC(IntrinsicType::kCosh, "cosh") \
INTRINSIC(IntrinsicType::kCountOneBits, "countOneBits") \
INTRINSIC(IntrinsicType::kCross, "cross") \
INTRINSIC(IntrinsicType::kDeterminant, "determinant") \
INTRINSIC(IntrinsicType::kDistance, "distance") \
INTRINSIC(IntrinsicType::kDot, "dot") \
INTRINSIC(IntrinsicType::kDpdx, "dpdx") \
INTRINSIC(IntrinsicType::kDpdxCoarse, "dpdxCoarse") \
INTRINSIC(IntrinsicType::kDpdxFine, "dpdxFine") \
INTRINSIC(IntrinsicType::kDpdy, "dpdy") \
INTRINSIC(IntrinsicType::kDpdyCoarse, "dpdyCoarse") \
INTRINSIC(IntrinsicType::kDpdyFine, "dpdyFine") \
INTRINSIC(IntrinsicType::kExp, "exp") \
INTRINSIC(IntrinsicType::kExp2, "exp2") \
INTRINSIC(IntrinsicType::kFaceForward, "faceForward") \
INTRINSIC(IntrinsicType::kFloor, "floor") \
INTRINSIC(IntrinsicType::kFma, "fma") \
INTRINSIC(IntrinsicType::kFract, "fract") \
INTRINSIC(IntrinsicType::kFrexp, "frexp") \
INTRINSIC(IntrinsicType::kFwidth, "fwidth") \
INTRINSIC(IntrinsicType::kFwidthCoarse, "fwidthCoarse") \
INTRINSIC(IntrinsicType::kFwidthFine, "fwidthFine") \
INTRINSIC(IntrinsicType::kInverseSqrt, "inverseSqrt") \
INTRINSIC(IntrinsicType::kIsFinite, "isFinite") \
INTRINSIC(IntrinsicType::kIsInf, "isInf") \
INTRINSIC(IntrinsicType::kIsNan, "isNan") \
INTRINSIC(IntrinsicType::kIsNormal, "isNormal") \
INTRINSIC(IntrinsicType::kLdexp, "ldexp") \
INTRINSIC(IntrinsicType::kLength, "length") \
INTRINSIC(IntrinsicType::kLog, "log") \
INTRINSIC(IntrinsicType::kLog2, "log2") \
INTRINSIC(IntrinsicType::kMax, "max") \
INTRINSIC(IntrinsicType::kMin, "min") \
INTRINSIC(IntrinsicType::kMix, "mix") \
INTRINSIC(IntrinsicType::kModf, "modf") \
INTRINSIC(IntrinsicType::kNormalize, "normalize") \
INTRINSIC(IntrinsicType::kPack4x8Snorm, "pack4x8snorm") \
INTRINSIC(IntrinsicType::kPack4x8Unorm, "pack4x8unorm") \
INTRINSIC(IntrinsicType::kPack2x16Snorm, "pack2x16snorm") \
INTRINSIC(IntrinsicType::kPack2x16Unorm, "pack2x16unorm") \
INTRINSIC(IntrinsicType::kPack2x16Float, "pack2x16float") \
INTRINSIC(IntrinsicType::kPow, "pow") \
INTRINSIC(IntrinsicType::kReflect, "reflect") \
INTRINSIC(IntrinsicType::kReverseBits, "reverseBits") \
INTRINSIC(IntrinsicType::kRound, "round") \
INTRINSIC(IntrinsicType::kSelect, "select") \
INTRINSIC(IntrinsicType::kSign, "sign") \
INTRINSIC(IntrinsicType::kSin, "sin") \
INTRINSIC(IntrinsicType::kSinh, "sinh") \
INTRINSIC(IntrinsicType::kSmoothStep, "smoothStep") \
INTRINSIC(IntrinsicType::kSqrt, "sqrt") \
INTRINSIC(IntrinsicType::kStep, "step") \
INTRINSIC(IntrinsicType::kStorageBarrier, "storageBarrier") \
INTRINSIC(IntrinsicType::kTan, "tan") \
INTRINSIC(IntrinsicType::kTanh, "tanh") \
INTRINSIC(IntrinsicType::kTextureDimensions, "textureDimensions") \
INTRINSIC(IntrinsicType::kTextureLoad, "textureLoad") \
INTRINSIC(IntrinsicType::kTextureNumLayers, "textureNumLayers") \
INTRINSIC(IntrinsicType::kTextureNumLevels, "textureNumLevels") \
INTRINSIC(IntrinsicType::kTextureNumSamples, "textureNumSamples") \
INTRINSIC(IntrinsicType::kTextureSample, "textureSample") \
INTRINSIC(IntrinsicType::kTextureSampleBias, "textureSampleBias") \
INTRINSIC(IntrinsicType::kTextureSampleCompare, "textureSampleCompare") \
INTRINSIC(IntrinsicType::kTextureSampleGrad, "textureSampleGrad") \
INTRINSIC(IntrinsicType::kTextureSampleLevel, "textureSampleLevel") \
INTRINSIC(IntrinsicType::kTextureStore, "textureStore") \
INTRINSIC(IntrinsicType::kTrunc, "trunc") \
INTRINSIC(IntrinsicType::kUnpack2x16Float, "unpack2x16float") \
INTRINSIC(IntrinsicType::kUnpack2x16Snorm, "unpack2x16snorm") \
INTRINSIC(IntrinsicType::kUnpack2x16Unorm, "unpack2x16unorm") \
INTRINSIC(IntrinsicType::kUnpack4x8Snorm, "unpack4x8snorm") \
INTRINSIC(IntrinsicType::kUnpack4x8Unorm, "unpack4x8unorm") \
INTRINSIC(IntrinsicType::kWorkgroupBarrier, "workgroupBarrier")
IntrinsicType ParseIntrinsicType(const std::string& name) {
#define INTRINSIC(ENUM, NAME) \
if (name == NAME) { \
return ENUM; \
}
INTRINSIC_LIST()
#undef INTRINSIC
return IntrinsicType::kNone;
}
const char* str(IntrinsicType i) {
#define INTRINSIC(ENUM, NAME) \
case ENUM: \
return NAME;
switch (i) { INTRINSIC_LIST() }
#undef INTRINSIC
return "<unknown>";
}
bool IsCoarseDerivativeIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kDpdxCoarse || i == IntrinsicType::kDpdyCoarse ||
i == IntrinsicType::kFwidthCoarse;
}
bool IsFineDerivativeIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kDpdxFine || i == IntrinsicType::kDpdyFine ||
i == IntrinsicType::kFwidthFine;
}
bool IsDerivativeIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kDpdx || i == IntrinsicType::kDpdy ||
i == IntrinsicType::kFwidth || IsCoarseDerivativeIntrinsic(i) ||
IsFineDerivativeIntrinsic(i);
}
bool IsFloatClassificationIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kIsFinite || i == IntrinsicType::kIsInf ||
i == IntrinsicType::kIsNan || i == IntrinsicType::kIsNormal;
}
bool IsTextureIntrinsic(IntrinsicType i) {
return IsImageQueryIntrinsic(i) || i == IntrinsicType::kTextureLoad ||
i == IntrinsicType::kTextureSample ||
i == IntrinsicType::kTextureSampleLevel ||
i == IntrinsicType::kTextureSampleBias ||
i == IntrinsicType::kTextureSampleCompare ||
i == IntrinsicType::kTextureSampleGrad ||
i == IntrinsicType::kTextureStore;
}
bool IsImageQueryIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kTextureDimensions ||
i == IntrinsicType::kTextureNumLayers ||
i == IntrinsicType::kTextureNumLevels ||
i == IntrinsicType::kTextureNumSamples;
}
bool IsDataPackingIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kPack4x8Snorm ||
i == IntrinsicType::kPack4x8Unorm ||
i == IntrinsicType::kPack2x16Snorm ||
i == IntrinsicType::kPack2x16Unorm ||
i == IntrinsicType::kPack2x16Float;
}
bool IsDataUnpackingIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kUnpack4x8Snorm ||
i == IntrinsicType::kUnpack4x8Unorm ||
i == IntrinsicType::kUnpack2x16Snorm ||
i == IntrinsicType::kUnpack2x16Unorm ||
i == IntrinsicType::kUnpack2x16Float;
}
bool IsBarrierIntrinsic(IntrinsicType i) {
return i == IntrinsicType::kWorkgroupBarrier ||
i == IntrinsicType::kStorageBarrier;
}
Intrinsic::Intrinsic(IntrinsicType type,
type::Type* return_type,
const ParameterList& parameters)
: Base(return_type, parameters), type_(type) {}
Intrinsic::~Intrinsic() = default;
bool Intrinsic::IsCoarseDerivative() const {
return IsCoarseDerivativeIntrinsic(type_);
}
bool Intrinsic::IsFineDerivative() const {
return IsFineDerivativeIntrinsic(type_);
}
bool Intrinsic::IsDerivative() const {
return IsDerivativeIntrinsic(type_);
}
bool Intrinsic::IsFloatClassification() const {
return IsFloatClassificationIntrinsic(type_);
}
bool Intrinsic::IsTexture() const {
return IsTextureIntrinsic(type_);
}
bool Intrinsic::IsImageQuery() const {
return IsImageQueryIntrinsic(type_);
}
bool Intrinsic::IsDataPacking() const {
return IsDataPackingIntrinsic(type_);
}
bool Intrinsic::IsDataUnpacking() const {
return IsDataUnpackingIntrinsic(type_);
}
bool Intrinsic::IsBarrier() const {
return IsBarrierIntrinsic(type_);
}
} // namespace sem
} // namespace tint

View File

@@ -0,0 +1,130 @@
// 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/sem/intrinsic.h"
#include "gtest/gtest.h"
namespace tint {
namespace sem {
namespace {
struct IntrinsicData {
const char* name;
IntrinsicType intrinsic;
};
inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
out << data.name;
return out;
}
using IntrinsicTypeTest = testing::TestWithParam<IntrinsicData>;
TEST_P(IntrinsicTypeTest, Parse) {
auto param = GetParam();
EXPECT_EQ(ParseIntrinsicType(param.name), param.intrinsic);
}
INSTANTIATE_TEST_SUITE_P(
IntrinsicTypeTest,
IntrinsicTypeTest,
testing::Values(
IntrinsicData{"abs", IntrinsicType::kAbs},
IntrinsicData{"acos", IntrinsicType::kAcos},
IntrinsicData{"all", IntrinsicType::kAll},
IntrinsicData{"any", IntrinsicType::kAny},
IntrinsicData{"arrayLength", IntrinsicType::kArrayLength},
IntrinsicData{"asin", IntrinsicType::kAsin},
IntrinsicData{"atan", IntrinsicType::kAtan},
IntrinsicData{"atan2", IntrinsicType::kAtan2},
IntrinsicData{"ceil", IntrinsicType::kCeil},
IntrinsicData{"clamp", IntrinsicType::kClamp},
IntrinsicData{"cos", IntrinsicType::kCos},
IntrinsicData{"cosh", IntrinsicType::kCosh},
IntrinsicData{"countOneBits", IntrinsicType::kCountOneBits},
IntrinsicData{"cross", IntrinsicType::kCross},
IntrinsicData{"determinant", IntrinsicType::kDeterminant},
IntrinsicData{"distance", IntrinsicType::kDistance},
IntrinsicData{"dot", IntrinsicType::kDot},
IntrinsicData{"dpdx", IntrinsicType::kDpdx},
IntrinsicData{"dpdxCoarse", IntrinsicType::kDpdxCoarse},
IntrinsicData{"dpdxFine", IntrinsicType::kDpdxFine},
IntrinsicData{"dpdy", IntrinsicType::kDpdy},
IntrinsicData{"dpdyCoarse", IntrinsicType::kDpdyCoarse},
IntrinsicData{"dpdyFine", IntrinsicType::kDpdyFine},
IntrinsicData{"exp", IntrinsicType::kExp},
IntrinsicData{"exp2", IntrinsicType::kExp2},
IntrinsicData{"faceForward", IntrinsicType::kFaceForward},
IntrinsicData{"floor", IntrinsicType::kFloor},
IntrinsicData{"fma", IntrinsicType::kFma},
IntrinsicData{"fract", IntrinsicType::kFract},
IntrinsicData{"frexp", IntrinsicType::kFrexp},
IntrinsicData{"fwidth", IntrinsicType::kFwidth},
IntrinsicData{"fwidthCoarse", IntrinsicType::kFwidthCoarse},
IntrinsicData{"fwidthFine", IntrinsicType::kFwidthFine},
IntrinsicData{"inverseSqrt", IntrinsicType::kInverseSqrt},
IntrinsicData{"isFinite", IntrinsicType::kIsFinite},
IntrinsicData{"isInf", IntrinsicType::kIsInf},
IntrinsicData{"isNan", IntrinsicType::kIsNan},
IntrinsicData{"isNormal", IntrinsicType::kIsNormal},
IntrinsicData{"ldexp", IntrinsicType::kLdexp},
IntrinsicData{"length", IntrinsicType::kLength},
IntrinsicData{"log", IntrinsicType::kLog},
IntrinsicData{"log2", IntrinsicType::kLog2},
IntrinsicData{"max", IntrinsicType::kMax},
IntrinsicData{"min", IntrinsicType::kMin},
IntrinsicData{"mix", IntrinsicType::kMix},
IntrinsicData{"modf", IntrinsicType::kModf},
IntrinsicData{"normalize", IntrinsicType::kNormalize},
IntrinsicData{"pow", IntrinsicType::kPow},
IntrinsicData{"reflect", IntrinsicType::kReflect},
IntrinsicData{"reverseBits", IntrinsicType::kReverseBits},
IntrinsicData{"round", IntrinsicType::kRound},
IntrinsicData{"select", IntrinsicType::kSelect},
IntrinsicData{"sign", IntrinsicType::kSign},
IntrinsicData{"sin", IntrinsicType::kSin},
IntrinsicData{"sinh", IntrinsicType::kSinh},
IntrinsicData{"smoothStep", IntrinsicType::kSmoothStep},
IntrinsicData{"sqrt", IntrinsicType::kSqrt},
IntrinsicData{"step", IntrinsicType::kStep},
IntrinsicData{"storageBarrier", IntrinsicType::kStorageBarrier},
IntrinsicData{"tan", IntrinsicType::kTan},
IntrinsicData{"tanh", IntrinsicType::kTanh},
IntrinsicData{"textureDimensions", IntrinsicType::kTextureDimensions},
IntrinsicData{"textureLoad", IntrinsicType::kTextureLoad},
IntrinsicData{"textureNumLayers", IntrinsicType::kTextureNumLayers},
IntrinsicData{"textureNumLevels", IntrinsicType::kTextureNumLevels},
IntrinsicData{"textureNumSamples", IntrinsicType::kTextureNumSamples},
IntrinsicData{"textureSample", IntrinsicType::kTextureSample},
IntrinsicData{"textureSampleBias", IntrinsicType::kTextureSampleBias},
IntrinsicData{"textureSampleCompare",
IntrinsicType::kTextureSampleCompare},
IntrinsicData{"textureSampleGrad", IntrinsicType::kTextureSampleGrad},
IntrinsicData{"textureSampleLevel", IntrinsicType::kTextureSampleLevel},
IntrinsicData{"trunc", IntrinsicType::kTrunc},
IntrinsicData{"unpack2x16float", IntrinsicType::kUnpack2x16Float},
IntrinsicData{"unpack2x16snorm", IntrinsicType::kUnpack2x16Snorm},
IntrinsicData{"unpack2x16unorm", IntrinsicType::kUnpack2x16Unorm},
IntrinsicData{"unpack4x8snorm", IntrinsicType::kUnpack4x8Snorm},
IntrinsicData{"unpack4x8unorm", IntrinsicType::kUnpack4x8Unorm},
IntrinsicData{"workgroupBarrier", IntrinsicType::kWorkgroupBarrier}));
TEST_F(IntrinsicTypeTest, ParseNoMatch) {
EXPECT_EQ(ParseIntrinsicType("not_intrinsic"), IntrinsicType::kNone);
}
} // namespace
} // namespace sem
} // namespace tint

View File

@@ -0,0 +1,51 @@
// 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/ast/member_accessor_expression.h"
#include "src/sem/member_accessor_expression.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::MemberAccessorExpression);
TINT_INSTANTIATE_TYPEINFO(tint::sem::StructMemberAccess);
TINT_INSTANTIATE_TYPEINFO(tint::sem::Swizzle);
namespace tint {
namespace sem {
MemberAccessorExpression::MemberAccessorExpression(
ast::MemberAccessorExpression* declaration,
type::Type* type,
Statement* statement)
: Base(declaration, type, statement) {}
MemberAccessorExpression::~MemberAccessorExpression() = default;
StructMemberAccess::StructMemberAccess(
ast::MemberAccessorExpression* declaration,
type::Type* type,
Statement* statement,
const StructMember* member)
: Base(declaration, type, statement), member_(member) {}
StructMemberAccess::~StructMemberAccess() = default;
Swizzle::Swizzle(ast::MemberAccessorExpression* declaration,
type::Type* type,
Statement* statement,
std::vector<uint32_t> indices)
: Base(declaration, type, statement), indices_(std::move(indices)) {}
Swizzle::~Swizzle() = default;
} // namespace sem
} // namespace tint

25
src/sem/sem_node.cc Normal file
View File

@@ -0,0 +1,25 @@
// 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/sem/node.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Node);
namespace tint {
namespace sem {
Node::~Node() = default;
} // namespace sem
} // namespace tint

39
src/sem/sem_statement.cc Normal file
View File

@@ -0,0 +1,39 @@
// 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 <algorithm>
#include "src/ast/block_statement.h"
#include "src/debug.h"
#include "src/sem/statement.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Statement);
namespace tint {
namespace sem {
Statement::Statement(const ast::Statement* declaration,
const ast::BlockStatement* block)
: declaration_(declaration), block_(block) {
#ifndef NDEBUG
if (block) {
auto& stmts = block->statements();
TINT_ASSERT(std::find(stmts.begin(), stmts.end(), declaration) !=
stmts.end());
}
#endif // NDEBUG
}
} // namespace sem
} // namespace tint

59
src/sem/sem_struct.cc Normal file
View File

@@ -0,0 +1,59 @@
// 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/ast/struct_member.h"
#include "src/sem/struct.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Struct);
TINT_INSTANTIATE_TYPEINFO(tint::sem::StructMember);
namespace tint {
namespace sem {
Struct::Struct(type::Struct* type,
StructMemberList members,
uint32_t align,
uint32_t size,
uint32_t size_no_padding,
std::unordered_set<ast::StorageClass> storage_class_usage,
std::unordered_set<PipelineStageUsage> pipeline_stage_uses)
: type_(type),
members_(std::move(members)),
align_(align),
size_(size),
size_no_padding_(size_no_padding),
storage_class_usage_(std::move(storage_class_usage)),
pipeline_stage_uses_(std::move(pipeline_stage_uses)) {}
Struct::~Struct() = default;
const StructMember* Struct::FindMember(Symbol name) const {
for (auto* member : members_) {
if (member->Declaration()->symbol() == name) {
return member;
}
}
return nullptr;
}
StructMember::StructMember(ast::StructMember* declaration,
uint32_t offset,
uint32_t align,
uint32_t size)
: declaration_(declaration), offset_(offset), align_(align), size_(size) {}
StructMember::~StructMember() = default;
} // namespace sem
} // namespace tint

44
src/sem/sem_variable.cc Normal file
View File

@@ -0,0 +1,44 @@
// 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/sem/variable.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/variable.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::Variable);
TINT_INSTANTIATE_TYPEINFO(tint::sem::VariableUser);
namespace tint {
namespace sem {
Variable::Variable(const ast::Variable* declaration,
type::Type* type,
ast::StorageClass storage_class)
: declaration_(declaration), type_(type), storage_class_(storage_class) {}
Variable::~Variable() = default;
type::Type* Variable::DeclaredType() const {
return declaration_->declared_type();
}
VariableUser::VariableUser(ast::IdentifierExpression* declaration,
type::Type* type,
Statement* statement,
sem::Variable* variable)
: Base(declaration, type, statement), variable_(variable) {}
} // namespace sem
} // namespace tint

53
src/sem/statement.h Normal file
View File

@@ -0,0 +1,53 @@
// 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.
#ifndef SRC_SEM_STATEMENT_H_
#define SRC_SEM_STATEMENT_H_
#include "src/sem/node.h"
namespace tint {
// Forward declarations
namespace ast {
class BlockStatement;
class Statement;
} // namespace ast
namespace sem {
/// Statement holds the semantic information for a statement.
class Statement : public Castable<Statement, Node> {
public:
/// Constructor
/// @param declaration the AST node for this statement
/// @param block the owning AST block statement
Statement(const ast::Statement* declaration,
const ast::BlockStatement* block);
/// @return the AST node for this statement
const ast::Statement* Declaration() const { return declaration_; }
/// @return the owning AST block statement for this statement
const ast::BlockStatement* Block() const { return block_; }
private:
ast::Statement const* const declaration_;
ast::BlockStatement const* const block_;
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_STATEMENT_H_

177
src/sem/struct.h Normal file
View File

@@ -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.
#ifndef SRC_SEM_STRUCT_H_
#define SRC_SEM_STRUCT_H_
#include <stdint.h>
#include <unordered_set>
#include <vector>
#include "src/ast/storage_class.h"
#include "src/sem/node.h"
namespace tint {
// Forward declarations
namespace ast {
class StructMember;
} // namespace ast
namespace type {
class Struct;
} // namespace type
namespace sem {
class StructMember;
/// A vector of StructMember pointers.
using StructMemberList = std::vector<const StructMember*>;
/// Metadata to capture how a structure is used in a shader module.
enum class PipelineStageUsage {
kVertexInput,
kVertexOutput,
kFragmentInput,
kFragmentOutput,
kComputeInput,
kComputeOutput,
};
/// Struct holds the semantic information for structures.
class Struct : public Castable<Struct, Node> {
public:
/// Constructor
/// @param type the structure type
/// @param members the structure members
/// @param align the byte alignment of the structure
/// @param size the byte size of the structure
/// @param size_no_padding size of the members without the end of structure
/// alignment padding
/// @param storage_class_usage a set of all the storage class usages
/// @param pipeline_stage_uses a set of all the pipeline stage uses
Struct(type::Struct* type,
StructMemberList members,
uint32_t align,
uint32_t size,
uint32_t size_no_padding,
std::unordered_set<ast::StorageClass> storage_class_usage,
std::unordered_set<PipelineStageUsage> pipeline_stage_uses);
/// Destructor
~Struct() override;
/// @returns the structure type
type::Struct* Type() const { return type_; }
/// @returns the members of the structure
const StructMemberList& Members() const { return members_; }
/// @param name the member name to look for
/// @returns the member with the given name, or nullptr if it was not found.
const StructMember* FindMember(Symbol name) const;
/// @returns the byte alignment of the structure
/// @note this may differ from the alignment of a structure member of this
/// structure type, if the member is annotated with the `[[align(n)]]`
/// decoration.
uint32_t Align() const { return align_; }
/// @returns the byte size of the structure
/// @note this may differ from the size of a structure member of this
/// structure type, if the member is annotated with the `[[size(n)]]`
/// decoration.
uint32_t Size() const { return size_; }
/// @returns the byte size of the members without the end of structure
/// alignment padding
uint32_t SizeNoPadding() const { return size_no_padding_; }
/// @returns the set of storage class uses of this structure
const std::unordered_set<ast::StorageClass>& StorageClassUsage() const {
return storage_class_usage_;
}
/// @param usage the ast::StorageClass usage type to query
/// @returns true iff this structure has been used as the given storage class
bool UsedAs(ast::StorageClass usage) const {
return storage_class_usage_.count(usage) > 0;
}
/// @returns true iff this structure has been used by storage class that's
/// host-shareable.
bool IsHostShareable() const {
for (auto sc : storage_class_usage_) {
if (ast::IsHostShareable(sc)) {
return true;
}
}
return false;
}
/// @returns the set of entry point uses of this structure
const std::unordered_set<PipelineStageUsage>& PipelineStageUses() const {
return pipeline_stage_uses_;
}
private:
type::Struct* const type_;
StructMemberList const members_;
uint32_t const align_;
uint32_t const size_;
uint32_t const size_no_padding_;
std::unordered_set<ast::StorageClass> const storage_class_usage_;
std::unordered_set<PipelineStageUsage> const pipeline_stage_uses_;
};
/// StructMember holds the semantic information for structure members.
class StructMember : public Castable<StructMember, Node> {
public:
/// Constructor
/// @param declaration the AST declaration node
/// @param offset the byte offset from the base of the structure
/// @param align the byte alignment of the member
/// @param size the byte size of the member
StructMember(ast::StructMember* declaration,
uint32_t offset,
uint32_t align,
uint32_t size);
/// Destructor
~StructMember() override;
/// @returns the AST declaration node
ast::StructMember* Declaration() const { return declaration_; }
/// @returns byte offset from base of structure
uint32_t Offset() const { return offset_; }
/// @returns the alignment of the member in bytes
uint32_t Align() const { return align_; }
/// @returns byte size
uint32_t Size() const { return size_; }
private:
ast::StructMember* const declaration_;
uint32_t const offset_; // Byte offset from base of structure
uint32_t const align_; // Byte alignment of the member
uint32_t const size_; // Byte size of the member
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_STRUCT_H_

77
src/sem/type_mappings.h Normal file
View File

@@ -0,0 +1,77 @@
// 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.
#ifndef SRC_SEM_TYPE_MAPPINGS_H_
#define SRC_SEM_TYPE_MAPPINGS_H_
#include <type_traits>
namespace tint {
// Forward declarations
namespace ast {
class CallExpression;
class Expression;
class Function;
class MemberAccessorExpression;
class Statement;
class StructMember;
class Variable;
} // namespace ast
namespace type {
class Array;
class Struct;
} // namespace type
namespace sem {
// Forward declarations
class Array;
class Call;
class Expression;
class Function;
class MemberAccessorExpression;
class Statement;
class Struct;
class StructMember;
class Variable;
/// TypeMappings is a struct that holds undefined `operator()` methods that's
/// used by SemanticNodeTypeFor to map AST / type node types to their
/// corresponding semantic node types. The standard operator overload resolving
/// rules will be used to infer the return type based on the argument type.
struct TypeMappings {
//! @cond Doxygen_Suppress
Array* operator()(type::Array*);
Call* operator()(ast::CallExpression*);
Expression* operator()(ast::Expression*);
Function* operator()(ast::Function*);
MemberAccessorExpression* operator()(ast::MemberAccessorExpression*);
Statement* operator()(ast::Statement*);
Struct* operator()(type::Struct*);
StructMember* operator()(ast::StructMember*);
Variable* operator()(ast::Variable*);
//! @endcond
};
/// SemanticNodeTypeFor resolves to the appropriate sem::Node type for the
/// AST or type node `AST_OR_TYPE`.
template <typename AST_OR_TYPE>
using SemanticNodeTypeFor = typename std::remove_pointer<decltype(
TypeMappings()(std::declval<AST_OR_TYPE*>()))>::type;
} // namespace sem
} // namespace tint
#endif // SRC_SEM_TYPE_MAPPINGS_H_

101
src/sem/variable.h Normal file
View File

@@ -0,0 +1,101 @@
// 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.
#ifndef SRC_SEM_VARIABLE_H_
#define SRC_SEM_VARIABLE_H_
#include <vector>
#include "src/ast/storage_class.h"
#include "src/sem/expression.h"
namespace tint {
// Forward declarations
namespace ast {
class IdentifierExpression;
class Variable;
} // namespace ast
namespace type {
class Type;
} // namespace type
namespace sem {
class VariableUser;
/// Variable holds the semantic information for variables.
class Variable : public Castable<Variable, Node> {
public:
/// Constructor
/// @param declaration the AST declaration node
/// @param type the variable type
/// @param storage_class the variable storage class
Variable(const ast::Variable* declaration,
type::Type* type,
ast::StorageClass storage_class);
/// Destructor
~Variable() override;
/// @returns the AST declaration node
const ast::Variable* Declaration() const { return declaration_; }
/// @returns the canonical type for the variable
type::Type* Type() const { return type_; }
/// @returns the AST node's type. May be nullptr.
type::Type* DeclaredType() const;
/// @returns the storage class for the variable
ast::StorageClass StorageClass() const { return storage_class_; }
/// @returns the expressions that use the variable
const std::vector<const VariableUser*>& Users() const { return users_; }
/// @param user the user to add
void AddUser(const VariableUser* user) { users_.emplace_back(user); }
private:
const ast::Variable* const declaration_;
type::Type* const type_;
ast::StorageClass const storage_class_;
std::vector<const VariableUser*> users_;
};
/// VariableUser holds the semantic information for an identifier expression
/// node that resolves to a variable.
class VariableUser : public Castable<VariableUser, Expression> {
public:
/// Constructor
/// @param declaration the AST identifier node
/// @param type the resolved type of the expression
/// @param statement the statement that owns this expression
/// @param variable the semantic variable
VariableUser(ast::IdentifierExpression* declaration,
type::Type* type,
Statement* statement,
sem::Variable* variable);
/// @returns the variable that this expression refers to
const sem::Variable* Variable() const { return variable_; }
private:
sem::Variable const* const variable_;
};
} // namespace sem
} // namespace tint
#endif // SRC_SEM_VARIABLE_H_