Generator now adds null terminator to c-strings
This commit is contained in:
parent
37819645cd
commit
c5a61e15f6
@ -90,7 +90,7 @@ func (this *generator) generateLiteralArrayLoc (literal *entity.LiteralArray) (l
|
|||||||
func (this *generator) generateLiteralStringLoc (literal *entity.LiteralString) (llvm.Value, error) {
|
func (this *generator) generateLiteralStringLoc (literal *entity.LiteralString) (llvm.Value, error) {
|
||||||
base := analyzer.ReduceToBase(literal.Type())
|
base := analyzer.ReduceToBase(literal.Type())
|
||||||
|
|
||||||
makeData := func (anyElementType entity.Type) (llvm.Value, int64, error) {
|
makeData := func (anyElementType entity.Type, cstring bool) (llvm.Value, int64, error) {
|
||||||
elementType, ok := analyzer.ReduceToBase(anyElementType).(*entity.TypeInt)
|
elementType, ok := analyzer.ReduceToBase(anyElementType).(*entity.TypeInt)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, 0, errors.New(fmt.Sprintln("string can't be used as ", base))
|
return nil, 0, errors.New(fmt.Sprintln("string can't be used as ", base))
|
||||||
@ -99,57 +99,87 @@ func (this *generator) generateLiteralStringLoc (literal *entity.LiteralString)
|
|||||||
switch {
|
switch {
|
||||||
case elementType.Width >= 32:
|
case elementType.Width >= 32:
|
||||||
length := len(literal.ValueUTF32)
|
length := len(literal.ValueUTF32)
|
||||||
|
if cstring { length += 1 }
|
||||||
|
|
||||||
irArrayType, err := this.generateType(&entity.TypeArray {
|
irArrayType, err := this.generateType(&entity.TypeArray {
|
||||||
Element: elementType,
|
Element: elementType,
|
||||||
Length: length,
|
Length: length,
|
||||||
})
|
})
|
||||||
if err != nil { return nil, 0, err }
|
if err != nil { return nil, 0, err }
|
||||||
array := this.blockManager.newAllocaFront(irArrayType)
|
array := this.blockManager.newAllocaFront(irArrayType)
|
||||||
for index, element := range literal.ValueUTF32 {
|
|
||||||
|
for index := 0; index < length; index ++ {
|
||||||
|
var element int64
|
||||||
|
if index >= len(literal.ValueUTF32) {
|
||||||
|
element = 0
|
||||||
|
} else {
|
||||||
|
element = int64(literal.ValueUTF32[index])
|
||||||
|
}
|
||||||
|
|
||||||
elementPointer := this.blockManager.NewGetElementPtr (
|
elementPointer := this.blockManager.NewGetElementPtr (
|
||||||
irArrayType, array,
|
irArrayType, array,
|
||||||
llvm.NewConstInt(llvm.I32, 0),
|
llvm.NewConstInt(llvm.I32, 0),
|
||||||
llvm.NewConstInt(llvm.I32, int64(index)))
|
llvm.NewConstInt(llvm.I32, int64(index)))
|
||||||
this.blockManager.NewStore (
|
this.blockManager.NewStore (
|
||||||
llvm.NewConstInt(llvm.I32, int64(element)),
|
llvm.NewConstInt(llvm.I32, element),
|
||||||
elementPointer)
|
elementPointer)
|
||||||
}
|
}
|
||||||
return array, int64(length), nil
|
return array, int64(length), nil
|
||||||
|
|
||||||
case elementType.Width >= 16:
|
case elementType.Width >= 16:
|
||||||
length := len(literal.ValueUTF16)
|
length := len(literal.ValueUTF16)
|
||||||
|
if cstring { length += 1 }
|
||||||
|
|
||||||
irArrayType, err := this.generateType(&entity.TypeArray {
|
irArrayType, err := this.generateType(&entity.TypeArray {
|
||||||
Element: elementType,
|
Element: elementType,
|
||||||
Length: length,
|
Length: length,
|
||||||
})
|
})
|
||||||
if err != nil { return nil, 0, err }
|
if err != nil { return nil, 0, err }
|
||||||
array := this.blockManager.newAllocaFront(irArrayType)
|
array := this.blockManager.newAllocaFront(irArrayType)
|
||||||
for index, element := range literal.ValueUTF16 {
|
|
||||||
|
for index := 0; index < length; index ++ {
|
||||||
|
var element int64
|
||||||
|
if index >= len(literal.ValueUTF16) {
|
||||||
|
element = 0
|
||||||
|
} else {
|
||||||
|
element = int64(literal.ValueUTF16[index])
|
||||||
|
}
|
||||||
|
|
||||||
elementPointer := this.blockManager.NewGetElementPtr (
|
elementPointer := this.blockManager.NewGetElementPtr (
|
||||||
irArrayType, array,
|
irArrayType, array,
|
||||||
llvm.NewConstInt(llvm.I32, 0),
|
llvm.NewConstInt(llvm.I32, 0),
|
||||||
llvm.NewConstInt(llvm.I32, int64(index)))
|
llvm.NewConstInt(llvm.I32, int64(index)))
|
||||||
this.blockManager.NewStore (
|
this.blockManager.NewStore (
|
||||||
llvm.NewConstInt(llvm.I16, int64(element)),
|
llvm.NewConstInt(llvm.I16, element),
|
||||||
elementPointer)
|
elementPointer)
|
||||||
}
|
}
|
||||||
return array, int64(length), nil
|
return array, int64(length), nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
length := len(literal.ValueUTF8)
|
length := len(literal.ValueUTF8)
|
||||||
|
if cstring { length += 1 }
|
||||||
|
|
||||||
irArrayType, err := this.generateType(&entity.TypeArray {
|
irArrayType, err := this.generateType(&entity.TypeArray {
|
||||||
Element: elementType,
|
Element: elementType,
|
||||||
Length: length,
|
Length: length,
|
||||||
})
|
})
|
||||||
if err != nil { return nil, 0, err }
|
if err != nil { return nil, 0, err }
|
||||||
array := this.blockManager.newAllocaFront(irArrayType)
|
array := this.blockManager.newAllocaFront(irArrayType)
|
||||||
for index, element := range literal.ValueUTF8 {
|
|
||||||
|
for index := 0; index < length; index ++ {
|
||||||
|
var element int64
|
||||||
|
if index >= len(literal.ValueUTF8) {
|
||||||
|
element = 0
|
||||||
|
} else {
|
||||||
|
element = int64(literal.ValueUTF8[index])
|
||||||
|
}
|
||||||
|
|
||||||
elementPointer := this.blockManager.NewGetElementPtr (
|
elementPointer := this.blockManager.NewGetElementPtr (
|
||||||
irArrayType, array,
|
irArrayType, array,
|
||||||
llvm.NewConstInt(llvm.I32, 0),
|
llvm.NewConstInt(llvm.I32, 0),
|
||||||
llvm.NewConstInt(llvm.I32, int64(index)))
|
llvm.NewConstInt(llvm.I32, int64(index)))
|
||||||
this.blockManager.NewStore (
|
this.blockManager.NewStore (
|
||||||
llvm.NewConstInt(llvm.I8, int64(element)),
|
llvm.NewConstInt(llvm.I8, element),
|
||||||
elementPointer)
|
elementPointer)
|
||||||
}
|
}
|
||||||
return array, int64(length), nil
|
return array, int64(length), nil
|
||||||
@ -174,11 +204,11 @@ func (this *generator) generateLiteralStringLoc (literal *entity.LiteralString)
|
|||||||
return char, nil
|
return char, nil
|
||||||
|
|
||||||
case *entity.TypeArray:
|
case *entity.TypeArray:
|
||||||
value, _, err := makeData(base.Element)
|
value, _, err := makeData(base.Element, false)
|
||||||
return value, err
|
return value, err
|
||||||
|
|
||||||
case *entity.TypeSlice:
|
case *entity.TypeSlice:
|
||||||
array, length, err := makeData(base.Element)
|
array, length, err := makeData(base.Element, false)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
irType, err := this.generateType(base)
|
irType, err := this.generateType(base)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
@ -207,7 +237,7 @@ func (this *generator) generateLiteralStringLoc (literal *entity.LiteralString)
|
|||||||
return slice, nil
|
return slice, nil
|
||||||
|
|
||||||
case *entity.TypePointer:
|
case *entity.TypePointer:
|
||||||
array, _, err := makeData(base.Referenced)
|
array, _, err := makeData(base.Referenced, true)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
return this.valueToLocation(array), nil
|
return this.valueToLocation(array), nil
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user