resolver: Ensure that decorations aren't duplicated
Fixed: tint:525 Change-Id: I993b60f82ac5d5e07e1c76980604e6aaf1b94fb3 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/53806 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
c58738a49e
commit
241c16d626
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/access_decoration.h"
|
#include "src/ast/access_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::AccessDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::AccessDecoration);
|
||||||
|
@ -28,6 +30,10 @@ AccessDecoration::AccessDecoration(ProgramID program_id,
|
||||||
|
|
||||||
AccessDecoration::~AccessDecoration() = default;
|
AccessDecoration::~AccessDecoration() = default;
|
||||||
|
|
||||||
|
std::string AccessDecoration::name() const {
|
||||||
|
return "access";
|
||||||
|
}
|
||||||
|
|
||||||
void AccessDecoration::to_str(const sem::Info&,
|
void AccessDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef SRC_AST_ACCESS_DECORATION_H_
|
#ifndef SRC_AST_ACCESS_DECORATION_H_
|
||||||
#define SRC_AST_ACCESS_DECORATION_H_
|
#define SRC_AST_ACCESS_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/access.h"
|
#include "src/ast/access.h"
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
|
@ -35,6 +37,9 @@ class AccessDecoration : public Castable<AccessDecoration, Decoration> {
|
||||||
/// @returns the access control value
|
/// @returns the access control value
|
||||||
Access value() const { return value_; }
|
Access value() const { return value_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/binding_decoration.h"
|
#include "src/ast/binding_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::BindingDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::BindingDecoration);
|
||||||
|
@ -28,6 +30,10 @@ BindingDecoration::BindingDecoration(ProgramID program_id,
|
||||||
|
|
||||||
BindingDecoration::~BindingDecoration() = default;
|
BindingDecoration::~BindingDecoration() = default;
|
||||||
|
|
||||||
|
std::string BindingDecoration::name() const {
|
||||||
|
return "binding";
|
||||||
|
}
|
||||||
|
|
||||||
void BindingDecoration::to_str(const sem::Info&,
|
void BindingDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef SRC_AST_BINDING_DECORATION_H_
|
#ifndef SRC_AST_BINDING_DECORATION_H_
|
||||||
#define SRC_AST_BINDING_DECORATION_H_
|
#define SRC_AST_BINDING_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -33,6 +35,9 @@ class BindingDecoration : public Castable<BindingDecoration, Decoration> {
|
||||||
/// @returns the binding value
|
/// @returns the binding value
|
||||||
uint32_t value() const { return value_; }
|
uint32_t value() const { return value_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::BuiltinDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::BuiltinDecoration);
|
||||||
|
@ -28,6 +30,10 @@ BuiltinDecoration::BuiltinDecoration(ProgramID program_id,
|
||||||
|
|
||||||
BuiltinDecoration::~BuiltinDecoration() = default;
|
BuiltinDecoration::~BuiltinDecoration() = default;
|
||||||
|
|
||||||
|
std::string BuiltinDecoration::name() const {
|
||||||
|
return "builtin";
|
||||||
|
}
|
||||||
|
|
||||||
void BuiltinDecoration::to_str(const sem::Info&,
|
void BuiltinDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef SRC_AST_BUILTIN_DECORATION_H_
|
#ifndef SRC_AST_BUILTIN_DECORATION_H_
|
||||||
#define SRC_AST_BUILTIN_DECORATION_H_
|
#define SRC_AST_BUILTIN_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/builtin.h"
|
#include "src/ast/builtin.h"
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
|
@ -36,6 +38,9 @@ class BuiltinDecoration : public Castable<BuiltinDecoration, Decoration> {
|
||||||
/// @returns the builtin value
|
/// @returns the builtin value
|
||||||
Builtin value() const { return builtin_; }
|
Builtin value() const { return builtin_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#ifndef SRC_AST_DECORATION_H_
|
#ifndef SRC_AST_DECORATION_H_
|
||||||
#define SRC_AST_DECORATION_H_
|
#define SRC_AST_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/node.h"
|
#include "src/ast/node.h"
|
||||||
|
@ -27,6 +28,9 @@ class Decoration : public Castable<Decoration, Node> {
|
||||||
public:
|
public:
|
||||||
~Decoration() override;
|
~Decoration() override;
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
virtual std::string name() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param program_id the identifier of the program that owns this node
|
/// @param program_id the identifier of the program that owns this node
|
||||||
|
|
|
@ -28,7 +28,7 @@ DisableValidationDecoration::DisableValidationDecoration(
|
||||||
|
|
||||||
DisableValidationDecoration::~DisableValidationDecoration() = default;
|
DisableValidationDecoration::~DisableValidationDecoration() = default;
|
||||||
|
|
||||||
std::string DisableValidationDecoration::Name() const {
|
std::string DisableValidationDecoration::InternalName() const {
|
||||||
switch (validation_) {
|
switch (validation_) {
|
||||||
case DisabledValidation::kFunctionHasNoBody:
|
case DisabledValidation::kFunctionHasNoBody:
|
||||||
return "disable_validation__function_has_no_body";
|
return "disable_validation__function_has_no_body";
|
||||||
|
|
|
@ -56,7 +56,7 @@ class DisableValidationDecoration
|
||||||
|
|
||||||
/// @return a short description of the internal decoration which will be
|
/// @return a short description of the internal decoration which will be
|
||||||
/// displayed in WGSL as `[[internal(<name>)]]` (but is not parsable).
|
/// displayed in WGSL as `[[internal(<name>)]]` (but is not parsable).
|
||||||
std::string Name() const override;
|
std::string InternalName() const override;
|
||||||
|
|
||||||
/// Performs a deep clone of this object using the CloneContext `ctx`.
|
/// Performs a deep clone of this object using the CloneContext `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/group_decoration.h"
|
#include "src/ast/group_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::GroupDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::GroupDecoration);
|
||||||
|
@ -28,6 +30,10 @@ GroupDecoration::GroupDecoration(ProgramID program_id,
|
||||||
|
|
||||||
GroupDecoration::~GroupDecoration() = default;
|
GroupDecoration::~GroupDecoration() = default;
|
||||||
|
|
||||||
|
std::string GroupDecoration::name() const {
|
||||||
|
return "group";
|
||||||
|
}
|
||||||
|
|
||||||
void GroupDecoration::to_str(const sem::Info&,
|
void GroupDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef SRC_AST_GROUP_DECORATION_H_
|
#ifndef SRC_AST_GROUP_DECORATION_H_
|
||||||
#define SRC_AST_GROUP_DECORATION_H_
|
#define SRC_AST_GROUP_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -33,6 +35,9 @@ class GroupDecoration : public Castable<GroupDecoration, Decoration> {
|
||||||
/// @returns the group value
|
/// @returns the group value
|
||||||
uint32_t value() const { return value_; }
|
uint32_t value() const { return value_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -24,11 +24,15 @@ InternalDecoration::InternalDecoration(ProgramID program_id)
|
||||||
|
|
||||||
InternalDecoration::~InternalDecoration() = default;
|
InternalDecoration::~InternalDecoration() = default;
|
||||||
|
|
||||||
|
std::string InternalDecoration::name() const {
|
||||||
|
return "internal";
|
||||||
|
}
|
||||||
|
|
||||||
void InternalDecoration::to_str(const sem::Info&,
|
void InternalDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
make_indent(out, indent);
|
make_indent(out, indent);
|
||||||
out << "tint_internal(" << Name() << ")" << std::endl;
|
out << "tint_internal(" << InternalName() << ")" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|
|
@ -36,7 +36,10 @@ class InternalDecoration : public Castable<InternalDecoration, Decoration> {
|
||||||
|
|
||||||
/// @return a short description of the internal decoration which will be
|
/// @return a short description of the internal decoration which will be
|
||||||
/// displayed in WGSL as `[[internal(<name>)]]` (but is not parsable).
|
/// displayed in WGSL as `[[internal(<name>)]]` (but is not parsable).
|
||||||
virtual std::string Name() const = 0;
|
virtual std::string InternalName() const = 0;
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Writes a representation of the node to the output stream
|
/// Writes a representation of the node to the output stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/location_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::LocationDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::LocationDecoration);
|
||||||
|
@ -28,6 +30,10 @@ LocationDecoration::LocationDecoration(ProgramID program_id,
|
||||||
|
|
||||||
LocationDecoration::~LocationDecoration() = default;
|
LocationDecoration::~LocationDecoration() = default;
|
||||||
|
|
||||||
|
std::string LocationDecoration::name() const {
|
||||||
|
return "location";
|
||||||
|
}
|
||||||
|
|
||||||
void LocationDecoration::to_str(const sem::Info&,
|
void LocationDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef SRC_AST_LOCATION_DECORATION_H_
|
#ifndef SRC_AST_LOCATION_DECORATION_H_
|
||||||
#define SRC_AST_LOCATION_DECORATION_H_
|
#define SRC_AST_LOCATION_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -35,6 +37,9 @@ class LocationDecoration : public Castable<LocationDecoration, Decoration> {
|
||||||
/// @returns the location value
|
/// @returns the location value
|
||||||
uint32_t value() const { return value_; }
|
uint32_t value() const { return value_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/override_decoration.h"
|
#include "src/ast/override_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::OverrideDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::OverrideDecoration);
|
||||||
|
@ -32,6 +34,10 @@ OverrideDecoration::OverrideDecoration(ProgramID program_id,
|
||||||
|
|
||||||
OverrideDecoration::~OverrideDecoration() = default;
|
OverrideDecoration::~OverrideDecoration() = default;
|
||||||
|
|
||||||
|
std::string OverrideDecoration::name() const {
|
||||||
|
return "override";
|
||||||
|
}
|
||||||
|
|
||||||
void OverrideDecoration::to_str(const sem::Info&,
|
void OverrideDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef SRC_AST_OVERRIDE_DECORATION_H_
|
#ifndef SRC_AST_OVERRIDE_DECORATION_H_
|
||||||
#define SRC_AST_OVERRIDE_DECORATION_H_
|
#define SRC_AST_OVERRIDE_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -40,6 +42,9 @@ class OverrideDecoration : public Castable<OverrideDecoration, Decoration> {
|
||||||
/// @returns the override id value
|
/// @returns the override id value
|
||||||
uint32_t value() const { return value_; }
|
uint32_t value() const { return value_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/stage_decoration.h"
|
#include "src/ast/stage_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StageDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::StageDecoration);
|
||||||
|
@ -28,6 +30,10 @@ StageDecoration::StageDecoration(ProgramID program_id,
|
||||||
|
|
||||||
StageDecoration::~StageDecoration() = default;
|
StageDecoration::~StageDecoration() = default;
|
||||||
|
|
||||||
|
std::string StageDecoration::name() const {
|
||||||
|
return "stage";
|
||||||
|
}
|
||||||
|
|
||||||
void StageDecoration::to_str(const sem::Info&,
|
void StageDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef SRC_AST_STAGE_DECORATION_H_
|
#ifndef SRC_AST_STAGE_DECORATION_H_
|
||||||
#define SRC_AST_STAGE_DECORATION_H_
|
#define SRC_AST_STAGE_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
#include "src/ast/pipeline_stage.h"
|
#include "src/ast/pipeline_stage.h"
|
||||||
|
|
||||||
|
@ -36,6 +38,9 @@ class StageDecoration : public Castable<StageDecoration, Decoration> {
|
||||||
/// @returns the stage
|
/// @returns the stage
|
||||||
PipelineStage value() const { return stage_; }
|
PipelineStage value() const { return stage_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/stride_decoration.h"
|
#include "src/ast/stride_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StrideDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::StrideDecoration);
|
||||||
|
@ -28,6 +30,10 @@ StrideDecoration::StrideDecoration(ProgramID program_id,
|
||||||
|
|
||||||
StrideDecoration::~StrideDecoration() = default;
|
StrideDecoration::~StrideDecoration() = default;
|
||||||
|
|
||||||
|
std::string StrideDecoration::name() const {
|
||||||
|
return "stride";
|
||||||
|
}
|
||||||
|
|
||||||
void StrideDecoration::to_str(const sem::Info&,
|
void StrideDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef SRC_AST_STRIDE_DECORATION_H_
|
#ifndef SRC_AST_STRIDE_DECORATION_H_
|
||||||
#define SRC_AST_STRIDE_DECORATION_H_
|
#define SRC_AST_STRIDE_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -33,6 +35,9 @@ class StrideDecoration : public Castable<StrideDecoration, Decoration> {
|
||||||
/// @returns the stride value
|
/// @returns the stride value
|
||||||
uint32_t stride() const { return stride_; }
|
uint32_t stride() const { return stride_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/struct_block_decoration.h"
|
#include "src/ast/struct_block_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructBlockDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructBlockDecoration);
|
||||||
|
@ -27,6 +29,10 @@ StructBlockDecoration::StructBlockDecoration(ProgramID program_id,
|
||||||
|
|
||||||
StructBlockDecoration::~StructBlockDecoration() = default;
|
StructBlockDecoration::~StructBlockDecoration() = default;
|
||||||
|
|
||||||
|
std::string StructBlockDecoration::name() const {
|
||||||
|
return "block";
|
||||||
|
}
|
||||||
|
|
||||||
void StructBlockDecoration::to_str(const sem::Info&,
|
void StructBlockDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#ifndef SRC_AST_STRUCT_BLOCK_DECORATION_H_
|
#ifndef SRC_AST_STRUCT_BLOCK_DECORATION_H_
|
||||||
#define SRC_AST_STRUCT_BLOCK_DECORATION_H_
|
#define SRC_AST_STRUCT_BLOCK_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
@ -32,6 +33,9 @@ class StructBlockDecoration
|
||||||
StructBlockDecoration(ProgramID program_id, const Source& source);
|
StructBlockDecoration(ProgramID program_id, const Source& source);
|
||||||
~StructBlockDecoration() override;
|
~StructBlockDecoration() override;
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/struct_member_align_decoration.h"
|
#include "src/ast/struct_member_align_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/clone_context.h"
|
#include "src/clone_context.h"
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
|
@ -29,6 +31,10 @@ StructMemberAlignDecoration::StructMemberAlignDecoration(ProgramID program_id,
|
||||||
|
|
||||||
StructMemberAlignDecoration::~StructMemberAlignDecoration() = default;
|
StructMemberAlignDecoration::~StructMemberAlignDecoration() = default;
|
||||||
|
|
||||||
|
std::string StructMemberAlignDecoration::name() const {
|
||||||
|
return "align";
|
||||||
|
}
|
||||||
|
|
||||||
void StructMemberAlignDecoration::to_str(const sem::Info&,
|
void StructMemberAlignDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#define SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_
|
#define SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
|
@ -38,6 +39,9 @@ class StructMemberAlignDecoration
|
||||||
/// @returns the align value
|
/// @returns the align value
|
||||||
uint32_t align() const { return align_; }
|
uint32_t align() const { return align_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/struct_member_offset_decoration.h"
|
#include "src/ast/struct_member_offset_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberOffsetDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberOffsetDecoration);
|
||||||
|
@ -28,6 +30,10 @@ StructMemberOffsetDecoration::StructMemberOffsetDecoration(ProgramID program_id,
|
||||||
|
|
||||||
StructMemberOffsetDecoration::~StructMemberOffsetDecoration() = default;
|
StructMemberOffsetDecoration::~StructMemberOffsetDecoration() = default;
|
||||||
|
|
||||||
|
std::string StructMemberOffsetDecoration::name() const {
|
||||||
|
return "offset";
|
||||||
|
}
|
||||||
|
|
||||||
void StructMemberOffsetDecoration::to_str(const sem::Info&,
|
void StructMemberOffsetDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_
|
#ifndef SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_
|
||||||
#define SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_
|
#define SRC_AST_STRUCT_MEMBER_OFFSET_DECORATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -45,6 +47,9 @@ class StructMemberOffsetDecoration
|
||||||
/// @returns the offset value
|
/// @returns the offset value
|
||||||
uint32_t offset() const { return offset_; }
|
uint32_t offset() const { return offset_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/struct_member_size_decoration.h"
|
#include "src/ast/struct_member_size_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/clone_context.h"
|
#include "src/clone_context.h"
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
|
@ -29,6 +31,10 @@ StructMemberSizeDecoration::StructMemberSizeDecoration(ProgramID program_id,
|
||||||
|
|
||||||
StructMemberSizeDecoration::~StructMemberSizeDecoration() = default;
|
StructMemberSizeDecoration::~StructMemberSizeDecoration() = default;
|
||||||
|
|
||||||
|
std::string StructMemberSizeDecoration::name() const {
|
||||||
|
return "size";
|
||||||
|
}
|
||||||
|
|
||||||
void StructMemberSizeDecoration::to_str(const sem::Info&,
|
void StructMemberSizeDecoration::to_str(const sem::Info&,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#define SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_
|
#define SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
|
@ -38,6 +39,9 @@ class StructMemberSizeDecoration
|
||||||
/// @returns the size value
|
/// @returns the size value
|
||||||
uint32_t size() const { return size_; }
|
uint32_t size() const { return size_; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "src/ast/workgroup_decoration.h"
|
#include "src/ast/workgroup_decoration.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/program_builder.h"
|
#include "src/program_builder.h"
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::ast::WorkgroupDecoration);
|
TINT_INSTANTIATE_TYPEINFO(tint::ast::WorkgroupDecoration);
|
||||||
|
@ -30,6 +32,10 @@ WorkgroupDecoration::WorkgroupDecoration(ProgramID program_id,
|
||||||
|
|
||||||
WorkgroupDecoration::~WorkgroupDecoration() = default;
|
WorkgroupDecoration::~WorkgroupDecoration() = default;
|
||||||
|
|
||||||
|
std::string WorkgroupDecoration::name() const {
|
||||||
|
return "workgroup_size";
|
||||||
|
}
|
||||||
|
|
||||||
void WorkgroupDecoration::to_str(const sem::Info& sem,
|
void WorkgroupDecoration::to_str(const sem::Info& sem,
|
||||||
std::ostream& out,
|
std::ostream& out,
|
||||||
size_t indent) const {
|
size_t indent) const {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#define SRC_AST_WORKGROUP_DECORATION_H_
|
#define SRC_AST_WORKGROUP_DECORATION_H_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "src/ast/decoration.h"
|
#include "src/ast/decoration.h"
|
||||||
|
|
||||||
|
@ -45,6 +46,9 @@ class WorkgroupDecoration : public Castable<WorkgroupDecoration, Decoration> {
|
||||||
/// @returns the workgroup dimensions
|
/// @returns the workgroup dimensions
|
||||||
std::array<ast::Expression*, 3> values() const { return {x_, y_, z_}; }
|
std::array<ast::Expression*, 3> values() const { return {x_, y_, z_}; }
|
||||||
|
|
||||||
|
/// @returns the WGSL name for the decoration
|
||||||
|
std::string name() const override;
|
||||||
|
|
||||||
/// Outputs the decoration to the given stream
|
/// Outputs the decoration to the given stream
|
||||||
/// @param sem the semantic info for the program
|
/// @param sem the semantic info for the program
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
|
|
|
@ -1908,6 +1908,22 @@ class ProgramBuilder {
|
||||||
nullptr);
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an ast::WorkgroupDecoration
|
||||||
|
/// @param source the source information
|
||||||
|
/// @param x the x dimension expression
|
||||||
|
/// @param y the y dimension expression
|
||||||
|
/// @param z the z dimension expression
|
||||||
|
/// @returns the workgroup decoration pointer
|
||||||
|
template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z>
|
||||||
|
ast::WorkgroupDecoration* WorkgroupSize(const Source& source,
|
||||||
|
EXPR_X&& x,
|
||||||
|
EXPR_Y&& y,
|
||||||
|
EXPR_Z&& z) {
|
||||||
|
return create<ast::WorkgroupDecoration>(
|
||||||
|
source, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
|
||||||
|
Expr(std::forward<EXPR_Z>(z)));
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates an ast::WorkgroupDecoration
|
/// Creates an ast::WorkgroupDecoration
|
||||||
/// @param x the x dimension expression
|
/// @param x the x dimension expression
|
||||||
/// @param y the y dimension expression
|
/// @param y the y dimension expression
|
||||||
|
|
|
@ -159,6 +159,20 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
TestParams{DecorationKind::kWorkgroup, false},
|
TestParams{DecorationKind::kWorkgroup, false},
|
||||||
TestParams{DecorationKind::kBindingAndGroup, false}));
|
TestParams{DecorationKind::kBindingAndGroup, false}));
|
||||||
|
|
||||||
|
TEST_F(FunctionReturnTypeDecorationTest, DuplicateDecoration) {
|
||||||
|
Func("main", ast::VariableList{}, ty.f32(), ast::StatementList{Return(1.f)},
|
||||||
|
ast::DecorationList{Stage(ast::PipelineStage::kCompute)},
|
||||||
|
ast::DecorationList{
|
||||||
|
Location(Source{{12, 34}}, 2),
|
||||||
|
Location(Source{{56, 78}}, 3),
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
R"(56:78 error: duplicate location decoration
|
||||||
|
12:34 note: first decoration declared here)");
|
||||||
|
}
|
||||||
|
|
||||||
using ArrayDecorationTest = TestWithParams;
|
using ArrayDecorationTest = TestWithParams;
|
||||||
TEST_P(ArrayDecorationTest, IsValid) {
|
TEST_P(ArrayDecorationTest, IsValid) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
|
@ -232,6 +246,24 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
TestParams{DecorationKind::kWorkgroup, false},
|
TestParams{DecorationKind::kWorkgroup, false},
|
||||||
TestParams{DecorationKind::kBindingAndGroup, false}));
|
TestParams{DecorationKind::kBindingAndGroup, false}));
|
||||||
|
|
||||||
|
TEST_F(StructDecorationTest, DuplicateDecoration) {
|
||||||
|
Structure("mystruct",
|
||||||
|
{
|
||||||
|
Member("a", ty.i32()),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
create<ast::StructBlockDecoration>(Source{{12, 34}}),
|
||||||
|
create<ast::StructBlockDecoration>(Source{{56, 78}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
WrapInFunction();
|
||||||
|
|
||||||
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
R"(56:78 error: duplicate block decoration
|
||||||
|
12:34 note: first decoration declared here)");
|
||||||
|
}
|
||||||
|
|
||||||
using StructMemberDecorationTest = TestWithParams;
|
using StructMemberDecorationTest = TestWithParams;
|
||||||
TEST_P(StructMemberDecorationTest, IsValid) {
|
TEST_P(StructMemberDecorationTest, IsValid) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
|
@ -268,6 +300,25 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
TestParams{DecorationKind::kWorkgroup, false},
|
TestParams{DecorationKind::kWorkgroup, false},
|
||||||
TestParams{DecorationKind::kBindingAndGroup, false}));
|
TestParams{DecorationKind::kBindingAndGroup, false}));
|
||||||
|
|
||||||
|
TEST_F(StructMemberDecorationTest, DuplicateDecoration) {
|
||||||
|
Structure("mystruct", {
|
||||||
|
Member("a", ty.i32(),
|
||||||
|
{
|
||||||
|
create<ast::StructMemberAlignDecoration>(
|
||||||
|
Source{{12, 34}}, 4u),
|
||||||
|
create<ast::StructMemberAlignDecoration>(
|
||||||
|
Source{{56, 78}}, 8u),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
WrapInFunction();
|
||||||
|
|
||||||
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
R"(56:78 error: duplicate align decoration
|
||||||
|
12:34 note: first decoration declared here)");
|
||||||
|
}
|
||||||
|
|
||||||
using VariableDecorationTest = TestWithParams;
|
using VariableDecorationTest = TestWithParams;
|
||||||
TEST_P(VariableDecorationTest, IsValid) {
|
TEST_P(VariableDecorationTest, IsValid) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
|
@ -310,6 +361,22 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
TestParams{DecorationKind::kWorkgroup, false},
|
TestParams{DecorationKind::kWorkgroup, false},
|
||||||
TestParams{DecorationKind::kBindingAndGroup, true}));
|
TestParams{DecorationKind::kBindingAndGroup, true}));
|
||||||
|
|
||||||
|
TEST_F(VariableDecorationTest, DuplicateDecoration) {
|
||||||
|
Global("a", ty.sampler(ast::SamplerKind::kSampler),
|
||||||
|
ast::DecorationList{
|
||||||
|
create<ast::BindingDecoration>(Source{{12, 34}}, 2),
|
||||||
|
create<ast::GroupDecoration>(2),
|
||||||
|
create<ast::BindingDecoration>(Source{{56, 78}}, 3),
|
||||||
|
});
|
||||||
|
|
||||||
|
WrapInFunction();
|
||||||
|
|
||||||
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
R"(56:78 error: duplicate binding decoration
|
||||||
|
12:34 note: first decoration declared here)");
|
||||||
|
}
|
||||||
|
|
||||||
using ConstantDecorationTest = TestWithParams;
|
using ConstantDecorationTest = TestWithParams;
|
||||||
TEST_P(ConstantDecorationTest, IsValid) {
|
TEST_P(ConstantDecorationTest, IsValid) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
|
@ -344,6 +411,21 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
TestParams{DecorationKind::kWorkgroup, false},
|
TestParams{DecorationKind::kWorkgroup, false},
|
||||||
TestParams{DecorationKind::kBindingAndGroup, false}));
|
TestParams{DecorationKind::kBindingAndGroup, false}));
|
||||||
|
|
||||||
|
TEST_F(ConstantDecorationTest, DuplicateDecoration) {
|
||||||
|
GlobalConst("a", ty.f32(), Expr(1.23f),
|
||||||
|
ast::DecorationList{
|
||||||
|
create<ast::OverrideDecoration>(Source{{12, 34}}),
|
||||||
|
create<ast::OverrideDecoration>(Source{{56, 78}}, 1),
|
||||||
|
});
|
||||||
|
|
||||||
|
WrapInFunction();
|
||||||
|
|
||||||
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
R"(56:78 error: duplicate override decoration
|
||||||
|
12:34 note: first decoration declared here)");
|
||||||
|
}
|
||||||
|
|
||||||
using FunctionDecorationTest = TestWithParams;
|
using FunctionDecorationTest = TestWithParams;
|
||||||
TEST_P(FunctionDecorationTest, IsValid) {
|
TEST_P(FunctionDecorationTest, IsValid) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
|
@ -485,18 +567,19 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
ParamsFor<mat3x3<f32>>((default_mat3x3.align - 1) * 7, false),
|
ParamsFor<mat3x3<f32>>((default_mat3x3.align - 1) * 7, false),
|
||||||
ParamsFor<mat4x4<f32>>((default_mat4x4.align - 1) * 7, false)));
|
ParamsFor<mat4x4<f32>>((default_mat4x4.align - 1) * 7, false)));
|
||||||
|
|
||||||
TEST_F(ArrayStrideTest, MultipleDecorations) {
|
TEST_F(ArrayStrideTest, DuplicateDecoration) {
|
||||||
auto* arr = ty.array(Source{{12, 34}}, ty.i32(), 4,
|
auto* arr = ty.array(Source{{12, 34}}, ty.i32(), 4,
|
||||||
{
|
{
|
||||||
create<ast::StrideDecoration>(4),
|
create<ast::StrideDecoration>(Source{{12, 34}}, 4),
|
||||||
create<ast::StrideDecoration>(4),
|
create<ast::StrideDecoration>(Source{{56, 78}}, 4),
|
||||||
});
|
});
|
||||||
|
|
||||||
Global("myarray", arr, ast::StorageClass::kInput);
|
Global("myarray", arr, ast::StorageClass::kInput);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error: array must have at most one [[stride]] decoration");
|
R"(56:78 error: duplicate stride decoration
|
||||||
|
12:34 note: first decoration declared here)");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -700,15 +783,18 @@ TEST_F(WorkgroupDecoration, NotAComputeShader) {
|
||||||
"compute stages");
|
"compute stages");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WorkgroupDecoration, MultipleAttributes) {
|
TEST_F(WorkgroupDecoration, DuplicateDecoration) {
|
||||||
Func(Source{{12, 34}}, "main", {}, ty.void_(), {},
|
Func(Source{{12, 34}}, "main", {}, ty.void_(), {},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1),
|
{
|
||||||
WorkgroupSize(2)});
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(Source{{12, 34}}, 1, nullptr, nullptr),
|
||||||
|
WorkgroupSize(Source{{56, 78}}, 2, nullptr, nullptr),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error: only one workgroup_size attribute permitted per "
|
R"(56:78 error: duplicate workgroup_size decoration
|
||||||
"entry point");
|
12:34 note: first decoration declared here)");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -267,14 +267,14 @@ TEST_F(ResolverFunctionValidationTest, PipelineStage_MustBeUnique_Fail) {
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
ast::DecorationList{
|
ast::DecorationList{
|
||||||
Stage(ast::PipelineStage::kVertex),
|
Stage(Source{{12, 34}}, ast::PipelineStage::kVertex),
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(Source{{56, 78}}, ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-0020: only one stage decoration permitted per entry "
|
R"(56:78 error: duplicate stage decoration
|
||||||
"point");
|
12:34 note: first decoration declared here)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverFunctionValidationTest, NoPipelineEntryPoints) {
|
TEST_F(ResolverFunctionValidationTest, NoPipelineEntryPoints) {
|
||||||
|
|
|
@ -573,6 +573,10 @@ bool Resolver::GlobalVariable(ast::Variable* var) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ValidateNoDuplicateDecorations(var->decorations())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto bp = var->binding_point()) {
|
if (auto bp = var->binding_point()) {
|
||||||
info->binding_point = {bp.group->value(), bp.binding->value()};
|
info->binding_point = {bp.group->value(), bp.binding->value()};
|
||||||
}
|
}
|
||||||
|
@ -608,6 +612,10 @@ bool Resolver::ValidateGlobalVariable(const VariableInfo* info) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ValidateNoDuplicateDecorations(info->declaration->decorations())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto* deco : info->declaration->decorations()) {
|
for (auto* deco : info->declaration->decorations()) {
|
||||||
if (info->declaration->is_const()) {
|
if (info->declaration->is_const()) {
|
||||||
if (auto* override_deco = deco->As<ast::OverrideDecoration>()) {
|
if (auto* override_deco = deco->As<ast::OverrideDecoration>()) {
|
||||||
|
@ -872,18 +880,6 @@ bool Resolver::ValidateFunction(const ast::Function* func,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stage_deco_count > 1) {
|
|
||||||
diagnostics_.add_error(
|
|
||||||
"v-0020", "only one stage decoration permitted per entry point",
|
|
||||||
func->source());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (workgroup_deco_count > 1) {
|
|
||||||
diagnostics_.add_error(
|
|
||||||
"only one workgroup_size attribute permitted per entry point",
|
|
||||||
func->source());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto* param : func->params()) {
|
for (auto* param : func->params()) {
|
||||||
if (!ValidateParameter(variable_to_info_.at(param))) {
|
if (!ValidateParameter(variable_to_info_.at(param))) {
|
||||||
|
@ -1197,6 +1193,9 @@ bool Resolver::Function(ast::Function* func) {
|
||||||
for (auto* deco : param->decorations()) {
|
for (auto* deco : param->decorations()) {
|
||||||
Mark(deco);
|
Mark(deco);
|
||||||
}
|
}
|
||||||
|
if (!ValidateNoDuplicateDecorations(param->decorations())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
variable_stack_.set(param->symbol(), param_info);
|
variable_stack_.set(param->symbol(), param_info);
|
||||||
info->parameters.emplace_back(param_info);
|
info->parameters.emplace_back(param_info);
|
||||||
|
@ -1282,9 +1281,16 @@ bool Resolver::Function(ast::Function* func) {
|
||||||
for (auto* deco : func->decorations()) {
|
for (auto* deco : func->decorations()) {
|
||||||
Mark(deco);
|
Mark(deco);
|
||||||
}
|
}
|
||||||
|
if (!ValidateNoDuplicateDecorations(func->decorations())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto* deco : func->return_type_decorations()) {
|
for (auto* deco : func->return_type_decorations()) {
|
||||||
Mark(deco);
|
Mark(deco);
|
||||||
}
|
}
|
||||||
|
if (!ValidateNoDuplicateDecorations(func->return_type_decorations())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Set work-group size defaults.
|
// Set work-group size defaults.
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
|
@ -2777,16 +2783,15 @@ sem::Array* Resolver::Array(const ast::Array* arr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ValidateNoDuplicateDecorations(arr->decorations())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Look for explicit stride via [[stride(n)]] decoration
|
// Look for explicit stride via [[stride(n)]] decoration
|
||||||
uint32_t explicit_stride = 0;
|
uint32_t explicit_stride = 0;
|
||||||
for (auto* deco : arr->decorations()) {
|
for (auto* deco : arr->decorations()) {
|
||||||
Mark(deco);
|
Mark(deco);
|
||||||
if (auto* sd = deco->As<ast::StrideDecoration>()) {
|
if (auto* sd = deco->As<ast::StrideDecoration>()) {
|
||||||
if (explicit_stride) {
|
|
||||||
diagnostics_.add_error(
|
|
||||||
"array must have at most one [[stride]] decoration", source);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
explicit_stride = sd->stride();
|
explicit_stride = sd->stride();
|
||||||
if (!ValidateArrayStrideDecoration(sd, el_size, el_align, source)) {
|
if (!ValidateArrayStrideDecoration(sd, el_size, el_align, source)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -2916,6 +2921,9 @@ bool Resolver::ValidateStructure(const sem::Struct* str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Struct* Resolver::Structure(const ast::Struct* str) {
|
sem::Struct* Resolver::Structure(const ast::Struct* str) {
|
||||||
|
if (!ValidateNoDuplicateDecorations(str->decorations())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
for (auto* deco : str->decorations()) {
|
for (auto* deco : str->decorations()) {
|
||||||
Mark(deco);
|
Mark(deco);
|
||||||
}
|
}
|
||||||
|
@ -2961,6 +2969,10 @@ sem::Struct* Resolver::Structure(const ast::Struct* str) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ValidateNoDuplicateDecorations(member->decorations())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool has_offset_deco = false;
|
bool has_offset_deco = false;
|
||||||
bool has_align_deco = false;
|
bool has_align_deco = false;
|
||||||
bool has_size_deco = false;
|
bool has_size_deco = false;
|
||||||
|
@ -3201,6 +3213,22 @@ bool Resolver::ValidateAssignment(const ast::AssignmentStatement* a) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Resolver::ValidateNoDuplicateDecorations(
|
||||||
|
const ast::DecorationList& decorations) {
|
||||||
|
std::unordered_map<const TypeInfo*, Source> seen;
|
||||||
|
for (auto* d : decorations) {
|
||||||
|
auto res = seen.emplace(&d->TypeInfo(), d->source());
|
||||||
|
if (!res.second) {
|
||||||
|
diagnostics_.add_error("duplicate " + d->name() + " decoration",
|
||||||
|
d->source());
|
||||||
|
diagnostics_.add_note("first decoration declared here",
|
||||||
|
res.first->second);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Resolver::ApplyStorageClassUsageToType(ast::StorageClass sc,
|
bool Resolver::ApplyStorageClassUsageToType(ast::StorageClass sc,
|
||||||
sem::Type* ty,
|
sem::Type* ty,
|
||||||
const Source& usage) {
|
const Source& usage) {
|
||||||
|
|
|
@ -271,6 +271,7 @@ class Resolver {
|
||||||
bool ValidateVectorConstructor(const ast::TypeConstructorExpression* ctor,
|
bool ValidateVectorConstructor(const ast::TypeConstructorExpression* ctor,
|
||||||
const sem::Vector* vec_type);
|
const sem::Vector* vec_type);
|
||||||
bool ValidateTypeDecl(const ast::TypeDecl* named_type) const;
|
bool ValidateTypeDecl(const ast::TypeDecl* named_type) const;
|
||||||
|
bool ValidateNoDuplicateDecorations(const ast::DecorationList& decorations);
|
||||||
|
|
||||||
/// @returns the sem::Type for the ast::Type `ty`, building it if it
|
/// @returns the sem::Type for the ast::Type `ty`, building it if it
|
||||||
/// hasn't been constructed already. If an error is raised, nullptr is
|
/// hasn't been constructed already. If an error is raised, nullptr is
|
||||||
|
|
|
@ -56,7 +56,7 @@ CalculateArrayLength::BufferSizeIntrinsic::BufferSizeIntrinsic(
|
||||||
ProgramID program_id)
|
ProgramID program_id)
|
||||||
: Base(program_id) {}
|
: Base(program_id) {}
|
||||||
CalculateArrayLength::BufferSizeIntrinsic::~BufferSizeIntrinsic() = default;
|
CalculateArrayLength::BufferSizeIntrinsic::~BufferSizeIntrinsic() = default;
|
||||||
std::string CalculateArrayLength::BufferSizeIntrinsic::Name() const {
|
std::string CalculateArrayLength::BufferSizeIntrinsic::InternalName() const {
|
||||||
return "intrinsic_buffer_size";
|
return "intrinsic_buffer_size";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class CalculateArrayLength : public Transform {
|
||||||
~BufferSizeIntrinsic() override;
|
~BufferSizeIntrinsic() override;
|
||||||
|
|
||||||
/// @return "buffer_size"
|
/// @return "buffer_size"
|
||||||
std::string Name() const override;
|
std::string InternalName() const override;
|
||||||
|
|
||||||
/// Performs a deep clone of this object using the CloneContext `ctx`.
|
/// Performs a deep clone of this object using the CloneContext `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
|
|
|
@ -564,7 +564,7 @@ struct DecomposeStorageAccess::State {
|
||||||
DecomposeStorageAccess::Intrinsic::Intrinsic(ProgramID program_id, Type ty)
|
DecomposeStorageAccess::Intrinsic::Intrinsic(ProgramID program_id, Type ty)
|
||||||
: Base(program_id), type(ty) {}
|
: Base(program_id), type(ty) {}
|
||||||
DecomposeStorageAccess::Intrinsic::~Intrinsic() = default;
|
DecomposeStorageAccess::Intrinsic::~Intrinsic() = default;
|
||||||
std::string DecomposeStorageAccess::Intrinsic::Name() const {
|
std::string DecomposeStorageAccess::Intrinsic::InternalName() const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case kLoadU32:
|
case kLoadU32:
|
||||||
return "intrinsic_load_u32";
|
return "intrinsic_load_u32";
|
||||||
|
|
|
@ -74,7 +74,7 @@ class DecomposeStorageAccess : public Transform {
|
||||||
|
|
||||||
/// @return a short description of the internal decoration which will be
|
/// @return a short description of the internal decoration which will be
|
||||||
/// displayed as `[[internal(<name>)]]`
|
/// displayed as `[[internal(<name>)]]`
|
||||||
std::string Name() const override;
|
std::string InternalName() const override;
|
||||||
|
|
||||||
/// Performs a deep clone of this object using the CloneContext `ctx`.
|
/// Performs a deep clone of this object using the CloneContext `ctx`.
|
||||||
/// @param ctx the clone context
|
/// @param ctx the clone context
|
||||||
|
|
|
@ -667,7 +667,7 @@ bool GeneratorImpl::EmitDecorations(const ast::DecorationList& decos) {
|
||||||
} else if (auto* align = deco->As<ast::StructMemberAlignDecoration>()) {
|
} else if (auto* align = deco->As<ast::StructMemberAlignDecoration>()) {
|
||||||
out_ << "align(" << align->align() << ")";
|
out_ << "align(" << align->align() << ")";
|
||||||
} else if (auto* internal = deco->As<ast::InternalDecoration>()) {
|
} else if (auto* internal = deco->As<ast::InternalDecoration>()) {
|
||||||
out_ << "internal(" << internal->Name() << ")";
|
out_ << "internal(" << internal->InternalName() << ")";
|
||||||
} else {
|
} else {
|
||||||
TINT_ICE(diagnostics_)
|
TINT_ICE(diagnostics_)
|
||||||
<< "Unsupported decoration '" << deco->TypeInfo().name << "'";
|
<< "Unsupported decoration '" << deco->TypeInfo().name << "'";
|
||||||
|
|
Loading…
Reference in New Issue