func (c *Config) AddExtendedQuery(v ssa.Value, query string) (*Pointer, error) {
	ops, _, err := parseExtendedQuery(v.Type().Underlying(), query)
	if err != nil {
		return nil, fmt.Errorf("invalid query %q: %s", query, err)
	}
	if c.extendedQueries == nil {
		c.extendedQueries = make(map[ssa.Value][]*extendedQuery)
	}
	ptr := &Pointer{}
	c.extendedQueries[v] = append(c.extendedQueries[v], &extendedQuery{ops: ops, ptr: ptr})
	return ptr, nil
}
AddExtendedQuery adds an extended, AST-based query on v to the
analysis. The query, which must be a single Go expression, allows
destructuring the value.

The query must operate on a variable named 'x', which represents
the value, and result in a pointer-like object. Only a subset of
Go expressions are permitted in queries, namely channel receives,
pointer dereferences, field selectors, array/slice/map/tuple
indexing and grouping with parentheses. The specific indices when
indexing arrays, slices and maps have no significance. Indices used
on tuples must be numeric and within bounds.

All field selectors must be explicit, even ones usually elided
due to promotion of embedded fields.

The query 'x' is identical to using AddQuery. The query '*x' is
identical to using AddIndirectQuery.

On success, AddExtendedQuery returns a Pointer to the queried
value. This Pointer will be initialized during analysis. Using it
before analysis has finished has undefined behavior.

Example:
// given v, which represents a function call to 'fn() (int, []*T)', and
// 'type T struct { F *int }', the following query will access the field F.
c.AddExtendedQuery(v, "x[1][0].F")
package pointer
import (
	"bytes"
	"fmt"
	"go/token"
	"io"
	"golang.org/x/tools/container/intsets"
	"golang.org/x/tools/go/callgraph"
	"golang.org/x/tools/go/ssa"
	"golang.org/x/tools/go/types/typeutil"
)
type Config struct {
	Mains []*ssa.Package
	Reflection bool
	BuildCallGraph bool
	Queries         map[ssa.Value]struct{}
	IndirectQueries map[ssa.Value]struct{}
	extendedQueries map[ssa.Value][]*extendedQuery
	Log io.Writer
}
type track uint32
const (
	trackChan  track = 1 << iota  
	trackMap                      
	trackPtr                      
	trackSlice                    
	trackAll = ^track(0)
)
func (c *Config) AddQuery(v ssa.Value) {
	if !CanPoint(v.Type()) {
		panic(fmt.Sprintf("%s is not a pointer-like value: %s", v, v.Type()))
	}
	if c.Queries == nil {
		c.Queries = make(map[ssa.Value]struct{})
	}
	c.Queries[v] = struct{}{}
}
func (c *Config) AddIndirectQuery(v ssa.Value) {
	if c.IndirectQueries == nil {
		c.IndirectQueries = make(map[ssa.Value]struct{})
	}
	if !CanPoint(mustDeref(v.Type())) {
		panic(fmt.Sprintf("%s is not the address of a pointer-like value: %s", v, v.Type()))
	}
	c.IndirectQueries[v] = struct{}{}
}