|
|
|
|
@@ -69,7 +69,7 @@ func (this *generator) generateMethodCall (call *entity.MethodCall) (llvm.Value,
|
|
|
|
|
if sourceType, ok := pointerType.Referenced.(*entity.TypeNamed); ok {
|
|
|
|
|
method, err := this.method(sourceType.Name, call.Name)
|
|
|
|
|
if err != errNotFound {
|
|
|
|
|
source, err := this.generateExpression(call.Source)
|
|
|
|
|
source, err := this.generateExpressionVal(call.Source)
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
args[0] = source
|
|
|
|
|
return this.blockManager.NewCall(method, method.Signature, args...), nil
|
|
|
|
|
@@ -141,7 +141,7 @@ func (this *generator) generateLength (length *entity.Length) (llvm.Value, error
|
|
|
|
|
|
|
|
|
|
func (this *generator) generateValueCast (cast *entity.ValueCast) (llvm.Value, error) {
|
|
|
|
|
generateFrom := func () (llvm.Value, error) {
|
|
|
|
|
return this.generateExpression(cast.Value)
|
|
|
|
|
return this.generateExpressionVal(cast.Value)
|
|
|
|
|
}
|
|
|
|
|
generateFromLoc := func () (llvm.Value, error) {
|
|
|
|
|
return this.generateExpressionLoc(cast.Value)
|
|
|
|
|
@@ -155,7 +155,7 @@ func (this *generator) generateValueCast (cast *entity.ValueCast) (llvm.Value, e
|
|
|
|
|
// Attempt to short circuit if types are equal to avoid LLVM bitching at
|
|
|
|
|
// us
|
|
|
|
|
if llvm.TypesEqual(irFromType, irToType) {
|
|
|
|
|
return this.generateExpression(cast.Value)
|
|
|
|
|
return this.generateExpressionVal(cast.Value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fail := func () (llvm.Value, error) {
|
|
|
|
|
@@ -225,7 +225,7 @@ func (this *generator) generateValueCast (cast *entity.ValueCast) (llvm.Value, e
|
|
|
|
|
// cast from pointer to pointer:
|
|
|
|
|
// basic forceful value assignment
|
|
|
|
|
// (all IR pointer types are equal)
|
|
|
|
|
return this.generateExpression(cast.Value)
|
|
|
|
|
return this.generateExpressionVal(cast.Value)
|
|
|
|
|
default: return fail()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -235,7 +235,7 @@ func (this *generator) generateValueCast (cast *entity.ValueCast) (llvm.Value, e
|
|
|
|
|
// cast from slice to slice:
|
|
|
|
|
// basic forceful value assignment
|
|
|
|
|
// (assume structural equivalence)
|
|
|
|
|
return this.generateExpression(cast.Value)
|
|
|
|
|
return this.generateExpressionVal(cast.Value)
|
|
|
|
|
default: return fail()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -245,7 +245,7 @@ func (this *generator) generateValueCast (cast *entity.ValueCast) (llvm.Value, e
|
|
|
|
|
// cast from array to array:
|
|
|
|
|
// basic forceful value assignment
|
|
|
|
|
// (assume structural equivalence)
|
|
|
|
|
return this.generateExpression(cast.Value)
|
|
|
|
|
return this.generateExpressionVal(cast.Value)
|
|
|
|
|
default: return fail()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -255,7 +255,7 @@ func (this *generator) generateValueCast (cast *entity.ValueCast) (llvm.Value, e
|
|
|
|
|
// cast from struct to struct:
|
|
|
|
|
// basic forceful value assignment
|
|
|
|
|
// (assume structural equivalence)
|
|
|
|
|
return this.generateExpression(cast.Value)
|
|
|
|
|
return this.generateExpressionVal(cast.Value)
|
|
|
|
|
default: return fail()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -272,10 +272,10 @@ func (this *generator) generateBitCast (cast *entity.BitCast) (llvm.Value, error
|
|
|
|
|
// Attempt to short circuit if types are equal to avoid LLVM bitching at
|
|
|
|
|
// us
|
|
|
|
|
if llvm.TypesEqual(irFromType, irToType) {
|
|
|
|
|
return this.generateExpression(cast.Value)
|
|
|
|
|
return this.generateExpressionVal(cast.Value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
from, err := this.generateExpression(cast.Value)
|
|
|
|
|
from, err := this.generateExpressionVal(cast.Value)
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
return this.blockManager.NewBitCast(from, irToType), nil
|
|
|
|
|
}
|
|
|
|
|
@@ -283,10 +283,10 @@ func (this *generator) generateBitCast (cast *entity.BitCast) (llvm.Value, error
|
|
|
|
|
|
|
|
|
|
func (this *generator) generateOperation (operation *entity.Operation) (llvm.Value, error) {
|
|
|
|
|
nSameType := func (binary func (x, y llvm.Value) llvm.Value) (llvm.Value, error) {
|
|
|
|
|
irX, err := this.generateExpression(operation.Arguments[0])
|
|
|
|
|
irX, err := this.generateExpressionVal(operation.Arguments[0])
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
for _, argument := range operation.Arguments[1:] {
|
|
|
|
|
irY, err := this.generateExpression(argument)
|
|
|
|
|
irY, err := this.generateExpressionVal(argument)
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
irX = binary(irX, irY)
|
|
|
|
|
}
|
|
|
|
|
@@ -354,7 +354,7 @@ func (this *generator) generateOperation (operation *entity.Operation) (llvm.Val
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case entity.OperatorIncrement:
|
|
|
|
|
irX, err := this.generateExpression(operation.Arguments[0])
|
|
|
|
|
irX, err := this.generateExpressionVal(operation.Arguments[0])
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
irType := irType.(*llvm.TypeInt)
|
|
|
|
|
|
|
|
|
|
@@ -370,7 +370,7 @@ func (this *generator) generateOperation (operation *entity.Operation) (llvm.Val
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case entity.OperatorDecrement:
|
|
|
|
|
irX, err := this.generateExpression(operation.Arguments[0])
|
|
|
|
|
irX, err := this.generateExpressionVal(operation.Arguments[0])
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
irType := irType.(*llvm.TypeInt)
|
|
|
|
|
|
|
|
|
|
@@ -405,7 +405,7 @@ func (this *generator) generateOperation (operation *entity.Operation) (llvm.Val
|
|
|
|
|
|
|
|
|
|
// logic
|
|
|
|
|
case entity.OperatorLogicalNot:
|
|
|
|
|
irX, err := this.generateExpression(operation.Arguments[0])
|
|
|
|
|
irX, err := this.generateExpressionVal(operation.Arguments[0])
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
return this.blockManager.NewICmp(llvm.IPredicateEQ, irX, llvm.NewConstBool(false)), nil
|
|
|
|
|
|
|
|
|
|
@@ -414,7 +414,7 @@ func (this *generator) generateOperation (operation *entity.Operation) (llvm.Val
|
|
|
|
|
exit := this.blockManager.newBlock()
|
|
|
|
|
|
|
|
|
|
for index, argument := range operation.Arguments {
|
|
|
|
|
irX, err := this.generateExpression(argument)
|
|
|
|
|
irX, err := this.generateExpressionVal(argument)
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
|
|
|
|
|
incomings[index] = &llvm.Incoming {
|
|
|
|
|
@@ -440,7 +440,7 @@ func (this *generator) generateOperation (operation *entity.Operation) (llvm.Val
|
|
|
|
|
exit := this.blockManager.newBlock()
|
|
|
|
|
|
|
|
|
|
for index, argument := range operation.Arguments {
|
|
|
|
|
irX, err := this.generateExpression(argument)
|
|
|
|
|
irX, err := this.generateExpressionVal(argument)
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
|
|
|
|
|
incomings[index] = &llvm.Incoming {
|
|
|
|
|
@@ -471,7 +471,7 @@ func (this *generator) generateOperation (operation *entity.Operation) (llvm.Val
|
|
|
|
|
|
|
|
|
|
// bit manipulation
|
|
|
|
|
case entity.OperatorNot:
|
|
|
|
|
irX, err := this.generateExpression(operation.Arguments[0])
|
|
|
|
|
irX, err := this.generateExpressionVal(operation.Arguments[0])
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
return this.blockManager.NewXor (
|
|
|
|
|
irX,
|
|
|
|
|
@@ -493,16 +493,16 @@ func (this *generator) generateOperation (operation *entity.Operation) (llvm.Val
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
case entity.OperatorLeftShift:
|
|
|
|
|
irX, err := this.generateExpression(operation.Arguments[0])
|
|
|
|
|
irX, err := this.generateExpressionVal(operation.Arguments[0])
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
irY, err := this.generateExpression(operation.Arguments[1])
|
|
|
|
|
irY, err := this.generateExpressionVal(operation.Arguments[1])
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
return this.blockManager.NewShl(irX, irY), nil
|
|
|
|
|
|
|
|
|
|
case entity.OperatorRightShift:
|
|
|
|
|
irX, err := this.generateExpression(operation.Arguments[0])
|
|
|
|
|
irX, err := this.generateExpressionVal(operation.Arguments[0])
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
irY, err := this.generateExpression(operation.Arguments[1])
|
|
|
|
|
irY, err := this.generateExpressionVal(operation.Arguments[1])
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
if analyzer.IsUnsigned(ty) {
|
|
|
|
|
return this.blockManager.NewLShr(irX, irY), nil
|
|
|
|
|
@@ -630,7 +630,7 @@ func (this *generator) generateBlock (block *entity.Block) (llvm.Value, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (this *generator) generateIfElse (ifelse *entity.IfElse, loc bool) (llvm.Value, error) {
|
|
|
|
|
condition, err := this.generateExpression(ifelse.Condition)
|
|
|
|
|
condition, err := this.generateExpressionVal(ifelse.Condition)
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
previous := this.blockManager.Block
|
|
|
|
|
|
|
|
|
|
@@ -643,7 +643,7 @@ func (this *generator) generateIfElse (ifelse *entity.IfElse, loc bool) (llvm.Va
|
|
|
|
|
if loc {
|
|
|
|
|
tru, err = this.generateExpressionLoc(ifelse.True)
|
|
|
|
|
} else {
|
|
|
|
|
tru, err = this.generateExpression(ifelse.True)
|
|
|
|
|
tru, err = this.generateExpressionVal(ifelse.True)
|
|
|
|
|
}
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
if !this.blockManager.Terminated() { this.blockManager.NewBr(exitBlock) }
|
|
|
|
|
@@ -654,7 +654,7 @@ func (this *generator) generateIfElse (ifelse *entity.IfElse, loc bool) (llvm.Va
|
|
|
|
|
if loc {
|
|
|
|
|
fals, err = this.generateExpressionLoc(ifelse.False)
|
|
|
|
|
} else {
|
|
|
|
|
fals, err = this.generateExpression(ifelse.False)
|
|
|
|
|
fals, err = this.generateExpressionVal(ifelse.False)
|
|
|
|
|
}
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
if !this.blockManager.Terminated() { this.blockManager.NewBr(exitBlock) }
|
|
|
|
|
@@ -667,7 +667,7 @@ func (this *generator) generateIfElse (ifelse *entity.IfElse, loc bool) (llvm.Va
|
|
|
|
|
if loc {
|
|
|
|
|
fals, err = this.generateExpressionLoc(ifelse.False)
|
|
|
|
|
} else {
|
|
|
|
|
fals, err = this.generateExpression(ifelse.False)
|
|
|
|
|
fals, err = this.generateExpressionVal(ifelse.False)
|
|
|
|
|
}
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
if !this.blockManager.Terminated() { this.blockManager.NewBr(exitBlock) }
|
|
|
|
|
@@ -700,7 +700,7 @@ func (this *generator) generateLoop (loop *entity.Loop, loc bool) (llvm.Value, e
|
|
|
|
|
loopEntry := this.blockManager.pushLoop(loc)
|
|
|
|
|
defer this.blockManager.popLoop()
|
|
|
|
|
|
|
|
|
|
_, err := this.generateExpression(loop.Body)
|
|
|
|
|
_, err := this.generateExpressionVal(loop.Body)
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
|
|
|
|
|
this.blockManager.NewBr(body)
|
|
|
|
|
@@ -717,7 +717,7 @@ func (this *generator) generateLoop (loop *entity.Loop, loc bool) (llvm.Value, e
|
|
|
|
|
func (this *generator) generateBreak (brk *entity.Break) (llvm.Value, error) {
|
|
|
|
|
loopEntry := this.blockManager.topLoop()
|
|
|
|
|
if brk.Value != nil {
|
|
|
|
|
value, err := this.generateExpression(brk.Value)
|
|
|
|
|
value, err := this.generateExpressionVal(brk.Value)
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
loopEntry.value = value
|
|
|
|
|
}
|
|
|
|
|
@@ -730,7 +730,7 @@ func (this *generator) generateReturn (ret *entity.Return) (llvm.Value, error) {
|
|
|
|
|
if ret.Value == nil {
|
|
|
|
|
this.blockManager.NewRet(nil)
|
|
|
|
|
} else {
|
|
|
|
|
value, err := this.generateExpression(ret.Value)
|
|
|
|
|
value, err := this.generateExpressionVal(ret.Value)
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
this.blockManager.NewRet(value)
|
|
|
|
|
}
|
|
|
|
|
|