| 139 | } |
| 140 | |
| 141 | func (b *Builder) path(rootTy Type, rootName string, path ...ValueIndexOrName) (indices []llvm.Value, name string, target Type) { |
| 142 | err := func(i int) string { |
| 143 | full := b.pathName(rootName, path) |
| 144 | okay := b.pathName(rootName, path[:i]) |
| 145 | fail := b.pathName(rootName, path[:i+1]) |
| 146 | pad := strings.Repeat(" ", len(okay)) |
| 147 | highlight := strings.Repeat("^", len(fail)-len(okay)) |
| 148 | return fmt.Sprintf("\n%v\n%v%v", full, pad, highlight) |
| 149 | } |
| 150 | target = rootTy |
| 151 | indices = make([]llvm.Value, len(path)) |
| 152 | for i, p := range path { |
| 153 | switch t := target.(type) { |
| 154 | case Pointer: |
| 155 | if i == 0 { |
| 156 | switch p := p.(type) { |
| 157 | case int: |
| 158 | indices[i] = b.Scalar(uint32(p)).llvm |
| 159 | case *Value: |
| 160 | if !IsInteger(p.Type()) { |
| 161 | fail("Tried to index pointer with non-integer %v.%v", p.Type().TypeName(), err(i)) |
| 162 | } |
| 163 | indices[i] = p.llvm |
| 164 | default: |
| 165 | fail("Tried to index pointer with %T (%v).%v", p, err(i)) |
| 166 | } |
| 167 | target = t.Element |
| 168 | } else { |
| 169 | fail("Tried to index %v. Only the root pointer can be indexed.%v", target.TypeName(), err(i)) |
| 170 | } |
| 171 | case *Struct: |
| 172 | field, idx := field(t, p) |
| 173 | target = field.Type |
| 174 | indices[i] = b.Scalar(uint32(idx)).llvm |
| 175 | case *Array: |
| 176 | switch p := p.(type) { |
| 177 | case int: |
| 178 | indices[i] = b.Scalar(uint32(p)).llvm |
| 179 | case *Value: |
| 180 | indices[i] = p.llvm |
| 181 | default: |
| 182 | fail("Tried to index array with %T.%v", p, err(i)) |
| 183 | } |
| 184 | target = t.Element |
| 185 | default: |
| 186 | fail("Cannot index type %v.%v", target, err(i)) |
| 187 | } |
| 188 | } |
| 189 | return indices, b.pathName(rootName, path), target |
| 190 | } |
| 191 | |
| 192 | // Index returns a new pointer to the array or field element found by following |
| 193 | // the list of indices as specified by path. |