// Copyright 2021 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package noder import ( "fmt" "cmd/compile/internal/syntax" ) // typeExprEndPos returns the position that noder would leave base.Pos // after parsing the given type expression. // // Deprecated: This function exists to emulate position semantics from // Go 1.17, necessary for compatibility with the backend DWARF // generation logic that assigns variables to their appropriate scope. func typeExprEndPos(expr0 syntax.Expr) syntax.Pos { for { switch expr := expr0.(type) { case *syntax.Name: return expr.Pos() case *syntax.SelectorExpr: return expr.X.Pos() case *syntax.ParenExpr: expr0 = expr.X case *syntax.Operation: assert(expr.Op == syntax.Mul) assert(expr.Y == nil) expr0 = expr.X case *syntax.ArrayType: expr0 = expr.Elem case *syntax.ChanType: expr0 = expr.Elem case *syntax.DotsType: expr0 = expr.Elem case *syntax.MapType: expr0 = expr.Value case *syntax.SliceType: expr0 = expr.Elem case *syntax.StructType: return expr.Pos() case *syntax.InterfaceType: expr0 = lastFieldType(expr.MethodList) if expr0 == nil { return expr.Pos() } case *syntax.FuncType: expr0 = lastFieldType(expr.ResultList) if expr0 == nil { expr0 = lastFieldType(expr.ParamList) if expr0 == nil { return expr.Pos() } } case *syntax.IndexExpr: // explicit type instantiation targs := syntax.UnpackListExpr(expr.Index) expr0 = targs[len(targs)-1] default: panic(fmt.Sprintf("%s: unexpected type expression %v", expr.Pos(), syntax.String(expr))) } } } func lastFieldType(fields []*syntax.Field) syntax.Expr { if len(fields) == 0 { return nil } return fields[len(fields)-1].Type }