llir / llvm

Library for interacting with LLVM IR in pure Go.
https://llir.github.io/document/
BSD Zero Clause License
1.19k stars 78 forks source link

let string loading be easier #209

Closed dannypsnl closed 2 years ago

dannypsnl commented 2 years ago

A common string using is like

formatString = "array_def[%d]: %d\n"
fmtStr := mod.NewGlobalDef("x", constant.NewCharArrayFromString(formatString))
mainB := mod.NewFunc("main", types.I32).NewBlock("")
str := mainB.NewGetElementPtr(types.NewArray(uint64(len(formatString)), types.I8), fmtStr, CI32(0), CI32(0))

but that's quite annoying that we have to use GEP since in most cases we just want a pointer to the zero address of the string and the type of string is always the same.

Thus, I want to introduce API for this

fmtStr := mod.NewGlobalDef("x", constant.NewCharArrayFromString("array_def[%d]: %d\n"))
mainB := mod.NewFunc("main", types.I32).NewBlock("")
str := mainB.LoadString(fmtStr)
// or
str := fmtStr.LoadTo(mainB)

I think the second one make more sense, since this pattern only useful for string literal

mewmew commented 2 years ago

Since LLVM IR is front end language agnostic, we cannot assume that the strings are NULL-terminated or length-prefixed. Thus, there may exist more than one reasonable implementation of a "get string" method.

For this reason, it belong well in an irutil library. Perhaps we could include two standard versions, one for NULL-terminated strings, and one for length-prefixed strings.

Cheers, Robin

dannypsnl commented 2 years ago

sounds good

dannypsnl commented 2 years ago

I would create two API

  1. c-string
  2. p-string
dannypsnl commented 2 years ago

here, since we do have c-string now!

dannypsnl commented 2 years ago

ok...maybe the problem is should we add Len for CharArray?

mewmew commented 2 years ago

ok...maybe the problem is should we add Len for CharArray?

CharArray is modelled from the character array of LLVM. It handles any kind of string, not just length-prefixed strings, so I think using irutil for Pascal strings is the way to go.

To get the length of a CharArray, simply use len:

c := constant.NewCharArrayFromString("foo")
n := len(c.X)