blob: 522302b7213fc96a82ba4d994d35345b34229121 [file] [log] [blame]
// Copyright (C) 2014 The Android Open Source Project
//
// 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.
package resolver
import "android.googlesource.com/platform/tools/gpu/api/semantic"
func assignable(lhs semantic.Type, rhs semantic.Type) bool {
if lhs == semantic.VoidType || rhs == semantic.VoidType {
return false
}
if lhs == semantic.AnyType || rhs == semantic.AnyType {
return true
}
return lhs == rhs
}
func comparable(lhs semantic.Type, rhs semantic.Type) bool {
if lhs == semantic.VoidType || rhs == semantic.VoidType {
return false
}
if lhs == semantic.AnyType || rhs == semantic.AnyType {
return true
}
return lhs == rhs
}
func equal(lhs semantic.Type, rhs semantic.Type) bool {
return lhs == rhs
}
func enumExtends(t *semantic.Enum, base *semantic.Enum) bool {
for _, e := range t.Extends {
if equal(e, base) || enumExtends(e, base) {
return true
}
}
return false
}
func isNumber(t semantic.Type) bool {
switch t {
case semantic.IntType, semantic.UintType,
semantic.Int8Type, semantic.Uint8Type,
semantic.Int16Type, semantic.Uint16Type,
semantic.Int32Type, semantic.Uint32Type,
semantic.Int64Type, semantic.Uint64Type,
semantic.Float32Type, semantic.Float64Type:
return true
default:
return false
}
}
func castable(from semantic.Type, to semantic.Type) bool {
fromBase := baseType(to)
toBase := baseType(from)
if assignable(toBase, fromBase) {
return true
}
fromEnum, fromIsEnum := fromBase.(*semantic.Enum)
toEnum, toIsEnum := toBase.(*semantic.Enum)
if fromIsEnum && toIsEnum {
if enumExtends(toEnum, fromEnum) {
return true // enum downcast
}
if enumExtends(fromEnum, toEnum) {
return true // enum upcast, needed but unsafe
}
}
if fromIsEnum && isNumber(toBase) {
return true // enum -> number
}
if isNumber(fromBase) && toIsEnum {
return true // number -> enum
}
if isNumber(fromBase) && isNumber(toBase) {
return true // any numeric conversion
}
return false
}
func baseType(t semantic.Type) semantic.Type {
for p, ok := t.(*semantic.Pseudonym); ok; p, ok = t.(*semantic.Pseudonym) {
t = p.To
}
return t
}