diff --git a/compiler/compiler.go b/compiler/compiler.go index 194e9844..f6186dd4 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -810,7 +810,12 @@ func (c *Compiler) parseFunc(frame *Frame) { fmt.Printf("\nfunc %s:\n", frame.fn.Function) } if !frame.fn.LLVMFn.IsDeclaration() { - c.addError(frame.fn.Pos(), "function is already defined:"+frame.fn.LLVMFn.Name()) + errValue := frame.fn.LLVMFn.Name() + " redeclared in this program" + fnPos := getPosition(frame.fn.LLVMFn) + if fnPos.IsValid() { + errValue += "\n\tprevious declaration at " + fnPos.String() + } + c.addError(frame.fn.Pos(), errValue) return } if !frame.fn.IsExported() { diff --git a/compiler/errors.go b/compiler/errors.go index f47ad991..b2d8cc76 100644 --- a/compiler/errors.go +++ b/compiler/errors.go @@ -31,20 +31,31 @@ func errorAt(inst llvm.Value, msg string) scanner.Error { } } -// getPosition returns the position information for the given instruction, as -// far as it is available. -func getPosition(inst llvm.Value) token.Position { - if inst.IsAInstruction().IsNil() { +// getPosition returns the position information for the given value, as far as +// it is available. +func getPosition(val llvm.Value) token.Position { + if !val.IsAInstruction().IsNil() { + loc := val.InstructionDebugLoc() + if loc.IsNil() { + return token.Position{} + } + file := loc.LocationScope().ScopeFile() + return token.Position{ + Filename: filepath.Join(file.FileDirectory(), file.FileFilename()), + Line: int(loc.LocationLine()), + Column: int(loc.LocationColumn()), + } + } else if !val.IsAFunction().IsNil() { + loc := val.Subprogram() + if loc.IsNil() { + return token.Position{} + } + file := loc.ScopeFile() + return token.Position{ + Filename: filepath.Join(file.FileDirectory(), file.FileFilename()), + Line: int(loc.SubprogramLine()), + } + } else { return token.Position{} } - loc := inst.InstructionDebugLoc() - if loc.IsNil() { - return token.Position{} - } - file := loc.LocationScope().ScopeFile() - return token.Position{ - Filename: filepath.Join(file.FileDirectory(), file.FileFilename()), - Line: int(loc.LocationLine()), - Column: int(loc.LocationColumn()), - } } diff --git a/go.mod b/go.mod index 810ebeed..b855dc46 100644 --- a/go.mod +++ b/go.mod @@ -10,5 +10,5 @@ require ( go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45 golang.org/x/sys v0.0.0-20191010194322-b09406accb47 // indirect golang.org/x/tools v0.0.0-20190227180812-8dcc6e70cdef - tinygo.org/x/go-llvm v0.0.0-20191124211856-b2db3df3f257 + tinygo.org/x/go-llvm v0.0.0-20191215173731-ad71f3d24aae ) diff --git a/go.sum b/go.sum index 6009c588..0c39e97e 100644 --- a/go.sum +++ b/go.sum @@ -30,3 +30,5 @@ tinygo.org/x/go-llvm v0.0.0-20191113125529-bad6d01809e8 h1:9Bfvso+tTVQg16UzOA614 tinygo.org/x/go-llvm v0.0.0-20191113125529-bad6d01809e8/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= tinygo.org/x/go-llvm v0.0.0-20191124211856-b2db3df3f257 h1:o8VDylrMN7gWemBMu8rEyuogKPhcLTdx5KrUAp9macc= tinygo.org/x/go-llvm v0.0.0-20191124211856-b2db3df3f257/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= +tinygo.org/x/go-llvm v0.0.0-20191215173731-ad71f3d24aae h1:s8J5EyxCkHxXB08UI3gk9W9IS/ekizRvSX+PfZxnAB0= +tinygo.org/x/go-llvm v0.0.0-20191215173731-ad71f3d24aae/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE=