Fix type width for pointer types
Этот коммит содержится в:
		
							родитель
							
								
									e436ca7c8d
								
							
						
					
					
						коммит
						01d2cc566e
					
				
					 1 изменённых файлов: 31 добавлений и 5 удалений
				
			
		
							
								
								
									
										36
									
								
								tgo.go
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								tgo.go
									
										
									
									
									
								
							|  | @ -34,6 +34,7 @@ type Compiler struct { | ||||||
| 	ctx             llvm.Context | 	ctx             llvm.Context | ||||||
| 	builder         llvm.Builder | 	builder         llvm.Builder | ||||||
| 	machine         llvm.TargetMachine | 	machine         llvm.TargetMachine | ||||||
|  | 	targetData      llvm.TargetData | ||||||
| 	intType         llvm.Type | 	intType         llvm.Type | ||||||
| 	stringLenType   llvm.Type | 	stringLenType   llvm.Type | ||||||
| 	stringType      llvm.Type | 	stringType      llvm.Type | ||||||
|  | @ -73,6 +74,7 @@ func NewCompiler(pkgName, triple string) (*Compiler, error) { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	c.machine = target.CreateTargetMachine(triple, "", "", llvm.CodeGenLevelDefault, llvm.RelocDefault, llvm.CodeModelDefault) | 	c.machine = target.CreateTargetMachine(triple, "", "", llvm.CodeGenLevelDefault, llvm.RelocDefault, llvm.CodeModelDefault) | ||||||
|  | 	c.targetData = c.machine.CreateTargetData() | ||||||
| 
 | 
 | ||||||
| 	c.mod = llvm.NewModule(pkgName) | 	c.mod = llvm.NewModule(pkgName) | ||||||
| 	c.ctx = c.mod.Context() | 	c.ctx = c.mod.Context() | ||||||
|  | @ -269,6 +271,26 @@ func (c *Compiler) getLLVMType(goType types.Type) (llvm.Type, error) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (c *Compiler) getTypeWidth(typ types.Type) (int, error) { | ||||||
|  | 	switch typ := typ.(type) { | ||||||
|  | 	case *types.Basic: | ||||||
|  | 		if typ.Kind() == types.UnsafePointer { | ||||||
|  | 			return c.targetData.PointerSize(), nil | ||||||
|  | 		} | ||||||
|  | 		llvmType, err := c.getLLVMType(typ) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return 0, err | ||||||
|  | 		} | ||||||
|  | 		return llvmType.IntTypeWidth(), nil | ||||||
|  | 	case *types.Named: | ||||||
|  | 		return c.getTypeWidth(typ.Underlying()) | ||||||
|  | 	case *types.Pointer: | ||||||
|  | 		return c.targetData.PointerSize(), nil | ||||||
|  | 	default: | ||||||
|  | 		return 0, errors.New("todo: type width") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (c *Compiler) getInterfaceType(typ types.Type) llvm.Value { | func (c *Compiler) getInterfaceType(typ types.Type) llvm.Value { | ||||||
| 	if _, ok := c.itfTypeNumbers[typ]; !ok { | 	if _, ok := c.itfTypeNumbers[typ]; !ok { | ||||||
| 		num := uint64(len(c.itfTypes)) | 		num := uint64(len(c.itfTypes)) | ||||||
|  | @ -716,7 +738,7 @@ func (c *Compiler) parseConvert(frame *Frame, expr *ssa.Convert) (llvm.Value, er | ||||||
| 		return value, nil | 		return value, nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	typeFrom, err := c.getLLVMType(expr.X.Type()) | 	sizeFrom, err := c.getTypeWidth(expr.X.Type()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return llvm.Value{}, err | 		return llvm.Value{}, err | ||||||
| 	} | 	} | ||||||
|  | @ -724,11 +746,15 @@ func (c *Compiler) parseConvert(frame *Frame, expr *ssa.Convert) (llvm.Value, er | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return llvm.Value{}, err | 		return llvm.Value{}, err | ||||||
| 	} | 	} | ||||||
| 	sizeFrom := typeFrom.IntTypeWidth() | 	sizeTo, err := c.getTypeWidth(expr.Type()) | ||||||
| 	sizeTo := typeTo.IntTypeWidth() | 	if err != nil { | ||||||
|  | 		return llvm.Value{}, err | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if sizeFrom >= sizeTo { | 	if sizeFrom > sizeTo { | ||||||
| 		return c.builder.CreateTruncOrBitCast(value, typeTo, ""), nil | 		return c.builder.CreateTrunc(value, typeTo, ""), nil | ||||||
|  | 	} else if sizeFrom == sizeTo { | ||||||
|  | 		return c.builder.CreateBitCast(value, typeTo, ""), nil | ||||||
| 	} else { // sizeFrom < sizeTo: extend | 	} else { // sizeFrom < sizeTo: extend | ||||||
| 		switch typ := expr.X.Type().(type) { // typeFrom | 		switch typ := expr.X.Type().(type) { // typeFrom | ||||||
| 		case *types.Basic: | 		case *types.Basic: | ||||||
|  |  | ||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Ayke van Laethem
						Ayke van Laethem