@@ -98,76 +98,75 @@ func (c *Compiler) checkValue(v llvm.Value, types map[llvm.Type]struct{}, specia
9898func (c * Compiler ) checkInstruction (inst llvm.Value , types map [llvm.Type ]struct {}, specials map [llvm.TypeKind ]llvm.Type ) error {
9999 // check value properties
100100 if err := c .checkValue (inst , types , specials ); err != nil {
101- return fmt . Errorf ( "failed to validate value of instruction %q: %s" , inst . Name () , err .Error ())
101+ return errorAt ( inst , err .Error ())
102102 }
103103
104104 // check operands
105105 for i := 0 ; i < inst .OperandsCount (); i ++ {
106106 if err := c .checkValue (inst .Operand (i ), types , specials ); err != nil {
107- return fmt .Errorf ("failed to validate argument %d of instruction %q: %s" , i , inst .Name (), err .Error ())
107+ return errorAt ( inst , fmt .Sprintf ("failed to validate operand %d of instruction %q: %s" , i , inst .Name (), err .Error () ))
108108 }
109109 }
110110
111111 return nil
112112}
113113
114- func (c * Compiler ) checkBasicBlock (bb llvm.BasicBlock , types map [llvm.Type ]struct {}, specials map [llvm.TypeKind ]llvm.Type ) error {
114+ func (c * Compiler ) checkBasicBlock (bb llvm.BasicBlock , types map [llvm.Type ]struct {}, specials map [llvm.TypeKind ]llvm.Type ) [] error {
115115 // check basic block value and type
116+ var errs []error
116117 if err := c .checkValue (bb .AsValue (), types , specials ); err != nil {
117- return fmt .Errorf ("failed to validate value of basic block %s: %s " , bb .AsValue ().Name (), err . Error ( ))
118+ errs = append ( errs , errorAt ( bb . Parent (), fmt .Sprintf ("failed to validate value of basic block %s: %v " , bb .AsValue ().Name (), err ) ))
118119 }
119120
120121 // check instructions
121122 for inst := bb .FirstInstruction (); ! inst .IsNil (); inst = llvm .NextInstruction (inst ) {
122123 if err := c .checkInstruction (inst , types , specials ); err != nil {
123- return fmt . Errorf ( "failed to validate basic block %q: %s" , bb . AsValue (). Name () , err . Error () )
124+ errs = append ( errs , err )
124125 }
125126 }
126127
127- return nil
128+ return errs
128129}
129130
130- func (c * Compiler ) checkFunction (fn llvm.Value , types map [llvm.Type ]struct {}, specials map [llvm.TypeKind ]llvm.Type ) error {
131+ func (c * Compiler ) checkFunction (fn llvm.Value , types map [llvm.Type ]struct {}, specials map [llvm.TypeKind ]llvm.Type ) [] error {
131132 // check function value and type
133+ var errs []error
132134 if err := c .checkValue (fn , types , specials ); err != nil {
133- return fmt .Errorf ("failed to validate value of function %s: %s" , fn .Name (), err .Error ())
135+ errs = append ( errs , fmt .Errorf ("failed to validate value of function %s: %s" , fn .Name (), err .Error () ))
134136 }
135137
136138 // check basic blocks
137139 for bb := fn .FirstBasicBlock (); ! bb .IsNil (); bb = llvm .NextBasicBlock (bb ) {
138- if err := c .checkBasicBlock (bb , types , specials ); err != nil {
139- return fmt .Errorf ("failed to validate basic block of function %s: %s" , fn .Name (), err .Error ())
140- }
140+ errs = append (errs , c .checkBasicBlock (bb , types , specials )... )
141141 }
142142
143- return nil
143+ return errs
144144}
145145
146- func (c * Compiler ) checkModule () error {
146+ func (c * Compiler ) checkModule () [] error {
147147 // check for any context mismatches
148+ var errs []error
148149 switch {
149150 case c .mod .Context () == c .ctx :
150151 // this is correct
151152 case c .mod .Context () == llvm .GlobalContext ():
152153 // somewhere we accidentally used the global context instead of a real context
153- return errors .New ("module uses global context" )
154+ errs = append ( errs , errors .New ("module uses global context" ) )
154155 default :
155156 // we used some other context by accident
156- return fmt .Errorf ("module uses context %v instead of the main context %v" , c .mod .Context (), c .ctx )
157+ errs = append ( errs , fmt .Errorf ("module uses context %v instead of the main context %v" , c .mod .Context (), c .ctx ) )
157158 }
158159
159160 types := map [llvm.Type ]struct {}{}
160161 specials := map [llvm.TypeKind ]llvm.Type {}
161162 for fn := c .mod .FirstFunction (); ! fn .IsNil (); fn = llvm .NextFunction (fn ) {
162- if err := c .checkFunction (fn , types , specials ); err != nil {
163- return err
164- }
163+ errs = append (errs , c .checkFunction (fn , types , specials )... )
165164 }
166165 for g := c .mod .FirstGlobal (); ! g .IsNil (); g = llvm .NextGlobal (g ) {
167166 if err := c .checkValue (g , types , specials ); err != nil {
168- return fmt .Errorf ("failed to verify global %s of module: %s" , g .Name (), err .Error ())
167+ errs = append ( errs , fmt .Errorf ("failed to verify global %s of module: %s" , g .Name (), err .Error () ))
169168 }
170169 }
171170
172- return nil
171+ return errs
173172}
0 commit comments