47 context.
fErrors->
error(
pos,
"functions cannot be both 'inline' and 'noinline'");
60 errors.error(
pos,
"functions may not return structs containing arrays");
72 TArray<std::unique_ptr<Variable>>& parameters,
76 for (
auto& param : parameters) {
80 if (!
type.isOpaque()) {
83 if (
type.isStorageTexture()) {
92 context.
fErrors->
error(param->fPosition,
"storage texture parameters must specify "
93 "a pixel format layout-qualifier");
97 param->modifierFlags().checkPermittedFlags(context, param->modifiersPosition(),
99 param->layout().checkPermittedLayout(context, param->modifiersPosition(),
100 permittedLayoutFlags);
105 context.
fErrors->
error(param->fPosition,
"parameters of type '" +
type.displayName() +
116 "pure functions cannot have out parameters");
124 return type.isVector() &&
type.columns() == 4 &&
type.componentType().isFloat();
128 return type.isVector() &&
type.highPrecision() &&
type.columns() == 2 &&
129 type.componentType().isFloat();
133 TArray<std::unique_ptr<Variable>>& parameters) {
137 auto typeIsValidForAttributes = [](
const Type&
type) {
138 return type.isStruct() &&
type.name() ==
"Attributes";
141 auto typeIsValidForVaryings = [](
const Type&
type) {
142 return type.isStruct() &&
type.name() ==
"Varyings";
145 auto paramIsCoords = [&](
int idx) {
150 auto paramIsColor = [&](
int idx) {
155 auto paramIsConstInAttributes = [&](
int idx) {
160 auto paramIsConstInVaryings = [&](
int idx) {
165 auto paramIsOutColor = [&](
int idx) {
175 errors.error(
pos,
"'main' must return: 'vec4', 'float4', or 'half4'");
178 bool validParams = (parameters.size() == 1 && paramIsColor(0));
180 errors.error(
pos,
"'main' parameter must be 'vec4', 'float4', or 'half4'");
189 errors.error(
pos,
"'main' must return: 'vec4', 'float4', or 'half4'");
192 if (!(parameters.size() == 1 && paramIsCoords(0))) {
193 errors.error(
pos,
"'main' parameter must be 'float2' or 'vec2'");
202 errors.error(
pos,
"'main' must return: 'vec4', 'float4', or 'half4'");
205 if (!(parameters.size() == 2 && paramIsColor(0) && paramIsColor(1))) {
206 errors.error(
pos,
"'main' parameters must be (vec4|float4|half4, "
207 "vec4|float4|half4)");
214 if (!typeIsValidForVaryings(returnType)) {
215 errors.error(
pos,
"'main' must return 'Varyings'.");
218 if (!(parameters.size() == 1 && paramIsConstInAttributes(0))) {
219 errors.error(
pos,
"'main' parameter must be 'const Attributes'.");
227 errors.error(
pos,
"'main' must return: 'vec2' or 'float2'");
230 if (!((parameters.size() == 1 && paramIsConstInVaryings(0)) ||
231 (parameters.size() == 2 && paramIsConstInVaryings(0) && paramIsOutColor(1)))) {
233 "'main' parameters must be (const Varyings, (out (half4|float4))?)");
241 bool validParams = (parameters.size() == 0) ||
242 (parameters.size() == 1 && paramIsCoords(0));
244 errors.error(
pos,
"shader 'main' must be main() or main(float2)");
254 errors.error(
pos,
"'main' must return 'void'");
257 if (parameters.size()) {
258 errors.error(
pos,
"shader 'main' must have zero parameters");
271 const Type& genericType,
272 bool allowNarrowing) {
274 for (
size_t index = 0; index < genericTypes.
size(); ++index) {
275 if (concreteType.
canCoerceTo(*genericTypes[index], allowNarrowing)) {
286 : concreteType.
matches(maybeGenericType);
302 int genericIndex = -1;
303 for (
size_t i = 0;
i <
params.size(); ++
i) {
305 const Type* otherParamType = &otherParams[
i]->type();
310 if (genericIndexForThisParam == -1) {
314 if (genericIndex != -1 && genericIndex != genericIndexForThisParam) {
318 genericIndex = genericIndexForThisParam;
323 for (
size_t i = 0;
i <
params.size();
i++) {
325 const Type* otherParamType = &otherParams[
i]->type();
334 if (!paramType->
matches(*otherParamType)) {
350 std::string_view
name,
351 TArray<std::unique_ptr<Variable>>& parameters,
353 const Type* returnType,
355 auto invalidDeclDescription = [&]() -> std::string {
358 for (std::unique_ptr<Variable>& param : parameters) {
365 std::move(paramPtrs),
373 *outExistingDecl =
nullptr;
376 errors.error(
pos,
"symbol '" + std::string(
name) +
"' was already defined");
386 errors.error(returnTypePos,
"functions '" + invalidDeclDescription() +
"' and '" +
387 other->description() +
"' differ only in return type");
390 for (
int i = 0;
i < parameters.size();
i++) {
391 if (parameters[
i]->modifierFlags() != other->parameters()[
i]->modifierFlags() ||
392 parameters[
i]->layout() != other->parameters()[
i]->layout()) {
393 errors.error(parameters[
i]->fPosition,
395 " differ between declaration and definition");
399 if (other->definition() || other->isIntrinsic() ||
400 modifierFlags != other->modifierFlags()) {
401 errors.error(
pos,
"duplicate definition of '" + invalidDeclDescription() +
"'");
404 *outExistingDecl = other;
408 errors.error(
pos,
"duplicate definition of 'main'");
418 std::string_view
name,
420 const Type* returnType,
423 , fDefinition(nullptr)
424 , fParameters(
std::move(parameters))
425 , fReturnType(returnType)
426 , fModifierFlags(modifierFlags)
427 , fIntrinsicKind(intrinsicKind)
428 , fBuiltin(context.fConfig->fIsBuiltinCode)
429 , fIsMain(
name ==
"main") {
430 int builtinColorIndex = 0;
431 for (
const Variable* param : fParameters) {
444 fHasMainCoordsParameter =
true;
451 switch (builtinColorIndex++) {
452 case 0: fHasMainInputColorParameter =
true;
break;
453 case 1: fHasMainDestColorParameter =
true;
break;
465 std::string_view
name,
466 TArray<std::unique_ptr<Variable>> parameters,
468 const Type* returnType) {
495 for (std::unique_ptr<Variable>& param :
parameters) {
503 std::make_unique<FunctionDeclaration>(context,
507 std::move(finalParameters),
515 return std::string(this->
name());
519 std::string_view
name = this->
name();
520 const char* builtinMarker =
"";
522 name.remove_prefix(1);
526 std::string
result = std::string(
name) +
"_" + builtinMarker +
529 result +=
p->type().abbreviatedName();
535 std::string
result = (fModifierFlags ? fModifierFlags.
description() +
" " : std::string()) +
539 result += separator();
565 const Type** outReturnType)
const {
570 int genericIndex = -1;
571 for (
int i = 0;
i < arguments.
size();
i++) {
575 outParameterTypes->
push_back(¶meterType);
580 if (genericIndex == -1) {
583 if (genericIndex == -1) {
594 if (genericIndex == -1) {
constexpr size_t SkToSizeT(S x)
const std::unique_ptr< Type > fVoid
const BuiltinTypes & fTypes
SymbolTable * fSymbolTable
void error(Position position, std::string_view msg)
FunctionDeclaration * mutableNextOverload() const
std::string mangledName() const
bool matches(const FunctionDeclaration &f) const
bool determineFinalTypes(const ExpressionArray &arguments, ParamTypes *outParameterTypes, const Type **outReturnType) const
SkSpan< Variable *const > parameters() const
FunctionDeclaration(const Context &context, Position pos, ModifierFlags modifierFlags, std::string_view name, skia_private::TArray< Variable * > parameters, const Type *returnType, IntrinsicKind intrinsicKind)
std::string description() const override
const FunctionDefinition * definition() const
ModifierFlags modifierFlags() const
IntrinsicKind intrinsicKind() const
static FunctionDeclaration * Convert(const Context &context, Position pos, const Modifiers &modifiers, std::string_view name, skia_private::TArray< std::unique_ptr< Variable > > parameters, Position returnTypePos, const Type *returnType)
const Type & returnType() const
std::string description() const
bool checkPermittedFlags(const Context &context, Position pos, ModifierFlags permittedModifierFlags) const
T * takeOwnershipOfSymbol(std::unique_ptr< T > symbol)
T * add(const Context &context, std::unique_ptr< T > symbol)
Symbol * findMutable(std::string_view name) const
std::string_view name() const
const Type & type() const
virtual bool isArray() const
virtual const Type & componentType() const
virtual bool isOrContainsArray() const
const char * abbreviatedName() const
bool matches(const Type &other) const
virtual SkSpan< const Type *const > coercibleTypes() const
bool canCoerceTo(const Type &other, bool allowNarrowing) const
std::string displayName() const
constexpr size_t size() const
void reserve_exact(int n)
const EmbeddedViewParams * params
std::string void void auto Separator()
static bool type_is_valid_for_coords(const Type &type)
static bool find_existing_declaration(const Context &context, Position pos, ModifierFlags modifierFlags, IntrinsicKind intrinsicKind, std::string_view name, TArray< std::unique_ptr< Variable > > ¶meters, Position returnTypePos, const Type *returnType, FunctionDeclaration **outExistingDecl)
static bool type_generically_matches(const Type &concreteType, const Type &maybeGenericType)
static bool check_modifiers(const Context &context, Position pos, ModifierFlags modifierFlags)
static bool type_is_valid_for_color(const Type &type)
static bool check_main_signature(const Context &context, Position pos, const Type &returnType, TArray< std::unique_ptr< Variable > > ¶meters)
static bool parameters_match(SkSpan< const std::unique_ptr< Variable > > params, SkSpan< Variable *const > otherParams)
IntrinsicKind FindIntrinsicKind(std::string_view functionName)
static bool check_return_type(const Context &context, Position pos, const Type &returnType)
@ kPrivateRuntimeColorFilter
static int find_generic_index(const Type &concreteType, const Type &genericType, bool allowNarrowing)
static bool check_parameters(const Context &context, TArray< std::unique_ptr< Variable > > ¶meters, ModifierFlags modifierFlags, IntrinsicKind intrinsicKind)
DEF_SWITCHES_START aot vmservice shared library name
constexpr bool starts_with(std::string_view str, std::string_view prefix)
static SkString to_string(int n)
bool checkPermittedLayout(const Context &context, Position pos, LayoutFlags permittedLayoutFlags) const
SkSL::ModifierFlags fFlags
static bool IsRuntimeShader(ProgramKind kind)
bool strictES2Mode() const
ProgramSettings fSettings
static bool IsFragment(ProgramKind kind)
static bool IsRuntimeBlender(ProgramKind kind)
static bool IsRuntimeColorFilter(ProgramKind kind)