github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/transpiler/declarations.go (about)

     1  // This file contains functions for transpiling declarations of variables and
     2  // types. The usage of variables is handled in variables.go.
     3  
     4  package transpiler
     5  
     6  import (
     7  	"fmt"
     8  	goast "go/ast"
     9  	"go/token"
    10  	"runtime/debug"
    11  	"strconv"
    12  	"strings"
    13  
    14  	"github.com/Konstantin8105/c4go/ast"
    15  	"github.com/Konstantin8105/c4go/program"
    16  	"github.com/Konstantin8105/c4go/types"
    17  	"github.com/Konstantin8105/c4go/util"
    18  )
    19  
    20  // Example of AST for union without name inside struct:
    21  // -RecordDecl 0x40d41b0 <...> line:453:8 struct EmptyName definition
    22  //  |-RecordDecl 0x40d4260 <...> line:454:2 union definition
    23  //  | |-FieldDecl 0x40d4328 <...> col:8 referenced l1 'long'
    24  //  | `-FieldDecl 0x40d4388 <...> col:8 referenced l2 'long'
    25  //  |-FieldDecl 0x40d4420 <...> col:2 implicit referenced 'union EmptyName::(anonymous at struct.c:454:2)'
    26  //  |-IndirectFieldDecl 0x40d4478 <...> col:8 implicit l1 'long'
    27  //  | |-Field 0x40d4420 '' 'union EmptyName::(anonymous at /struct.c:454:2)'
    28  //  | `-Field 0x40d4328 'l1' 'long'
    29  //  `-IndirectFieldDecl 0x40d44c8 <...> col:8 implicit l2 'long'
    30  //    |-Field 0x40d4420 '' 'union EmptyName::(anonymous at /struct.c:454:2)'
    31  //    `-Field 0x40d4388 'l2' 'long'
    32  
    33  func newFunctionField(p *program.Program, name, cType string) (
    34  	_ *goast.Field, err error) {
    35  	if name == "" {
    36  		err = fmt.Errorf("name of function field cannot be empty")
    37  		return
    38  	}
    39  	if !util.IsFunction(cType) {
    40  		err = fmt.Errorf("cannot create function field for type : %s", cType)
    41  		return
    42  	}
    43  
    44  	// TODO : add err handling
    45  	fieldType, _ := types.ResolveType(p, cType)
    46  
    47  	return &goast.Field{
    48  		Names: []*goast.Ident{util.NewIdent(name)},
    49  		Type:  goast.NewIdent(fieldType),
    50  	}, nil
    51  }
    52  
    53  func generateNameFieldDecl(t string) string {
    54  	return "implicit_" + strings.Replace(t, " ", "S", -1)
    55  }
    56  
    57  func transpileFieldDecl(p *program.Program, n *ast.FieldDecl) (
    58  	field *goast.Field, err error) {
    59  	defer func() {
    60  		if field != nil {
    61  			if field.Type == nil {
    62  				err = fmt.Errorf("found nil transpileFieldDecl in field Type %v , %v : %v",
    63  					n, field, err)
    64  				field.Type = util.NewIdent(n.Type)
    65  			}
    66  			if id, ok := field.Type.(*goast.Ident); ok && id.Name == "" {
    67  				id.Name = "C4GO_FIELD_DECL_NAME_EMPTY"
    68  			}
    69  		}
    70  	}()
    71  	if util.IsFunction(n.Type) {
    72  		field, err = newFunctionField(p, n.Name, n.Type)
    73  		if err == nil {
    74  			return
    75  		}
    76  	}
    77  
    78  	if n.Name == "" {
    79  		//&ast.FieldDecl{Addr:0x3157420, Pos:ast.Position{...}, Position2:"col:2", Name:"", Type:"union EmptyNameDD__at__home_lepricon_go_src_github_com_Konstantin8105_c4go_tests_struct_c_454_2_", Type2:"", Implicit:true, Referenced:true, ChildNodes:[]ast.Node{}}
    80  		n.Name = generateNameFieldDecl(n.Type)
    81  	}
    82  
    83  	name := n.Name
    84  
    85  	fieldType, err := types.ResolveType(p, n.Type)
    86  	p.AddMessage(p.GenerateWarningMessage(err, n))
    87  
    88  	// TODO: The name of a variable or field cannot be a reserved word
    89  	// https://github.com/Konstantin8105/c4go/issues/83
    90  	// Search for this issue in other areas of the codebase.
    91  	if util.IsGoKeyword(name) {
    92  		name += "_"
    93  	}
    94  
    95  	arrayType, arraySize := types.GetArrayTypeAndSize(n.Type)
    96  	if arraySize != -1 {
    97  		fieldType, err = types.ResolveType(p, arrayType)
    98  		p.AddMessage(p.GenerateWarningMessage(err, n))
    99  		fieldType = fmt.Sprintf("[%d]%s", arraySize, fieldType)
   100  	}
   101  
   102  	return &goast.Field{
   103  		Names: []*goast.Ident{util.NewIdent(name)},
   104  		Type:  util.NewTypeIdent(fieldType),
   105  	}, nil
   106  }
   107  
   108  func transpileRecordDecl(p *program.Program, n *ast.RecordDecl) (
   109  	decls []goast.Decl, err error) {
   110  
   111  	var addPackageUnsafe bool
   112  
   113  	n.Name = util.GenerateCorrectType(n.Name)
   114  	// |-RecordDecl 0x195a1e0 <line:168:1, line:170:1> line:168:1 struct definition
   115  	// | `-FieldDecl 0x195a298 <line:169:5, col:9> col:9 referenced aa 'int'
   116  	// |-VarDecl 0x195a348 <line:168:1, line:170:3> col:3 used mm 'struct (anonymous struct at /home/konstantin/go/src/github.com/K
   117  	// onstantin8105/c4go/tests/struct.c:168:1)':'struct (anonymous at /home/konstantin/go/src/github.com/Konstantin8105/c4go/tests
   118  	// /struct.c:168:1)'
   119  	if n.Name == "" {
   120  		n.Name = fmt.Sprintf("%s (anonymous %s at %s:%d:%d)", n.Kind, n.Kind, n.Pos.File, n.Pos.Line, n.Pos.Column)
   121  	}
   122  	n.Name = util.GenerateCorrectType(n.Name)
   123  	name := n.Name
   124  
   125  	defer func() {
   126  		if err != nil {
   127  			err = fmt.Errorf("cannot transpileRecordDecl `%v`. %v",
   128  				n.Name, err)
   129  		} else {
   130  			if addPackageUnsafe {
   131  				p.AddImports("unsafe")
   132  			}
   133  		}
   134  	}()
   135  
   136  	defer func() {
   137  		if r := recover(); r != nil {
   138  			err = fmt.Errorf("transpileRecordDecl: error - panic : %#v. %s", r, string(debug.Stack()))
   139  		}
   140  	}()
   141  
   142  	// ignore if haven`t definition
   143  	if !n.IsDefinition {
   144  		return
   145  	}
   146  
   147  	p.DefineType(name)
   148  	defer func() {
   149  		if err != nil {
   150  			p.UndefineType(name)
   151  		}
   152  	}()
   153  
   154  	var fields []*goast.Field
   155  
   156  	// repair name for anonymous RecordDecl
   157  	for pos := range n.Children() {
   158  		if rec, ok := n.Children()[pos].(*ast.RecordDecl); ok && rec.Name == "" {
   159  			if pos < len(n.Children()) {
   160  				switch v := n.Children()[pos+1].(type) {
   161  				case *ast.FieldDecl:
   162  					rec.Name = types.GetBaseType(util.GenerateCorrectType(v.Type))
   163  				default:
   164  					p.AddMessage(p.GenerateWarningMessage(
   165  						fmt.Errorf("cannot find name for anon RecordDecl: %T",
   166  							v), n))
   167  					rec.Name = "UndefinedNameC2GO"
   168  				}
   169  			}
   170  		}
   171  	}
   172  
   173  	for pos := range n.Children() {
   174  		switch field := n.Children()[pos].(type) {
   175  		case *ast.FieldDecl:
   176  			field.Type = util.GenerateCorrectType(field.Type)
   177  			field.Type2 = util.GenerateCorrectType(field.Type2)
   178  			var f *goast.Field
   179  			f, err = transpileFieldDecl(p, field)
   180  			if err != nil {
   181  				err = fmt.Errorf("cannot transpile field. %v", err)
   182  				p.AddMessage(p.GenerateWarningMessage(err, field))
   183  				// TODO ignore error
   184  				// return
   185  				err = nil
   186  			} else {
   187  				// ignore fields without name
   188  				if len(f.Names) != 1 {
   189  					p.AddMessage(p.GenerateWarningMessage(
   190  						fmt.Errorf("ignore FieldDecl with more then 1 names"+
   191  							" in RecordDecl : `%v`", n.Name), n))
   192  					continue
   193  				}
   194  				if f.Names[0].Name == "" {
   195  					p.AddMessage(p.GenerateWarningMessage(
   196  						fmt.Errorf("Ignore FieldDecl without name "+
   197  							" in RecordDecl : `%v`", n.Name), n))
   198  					continue
   199  				}
   200  				// remove duplicates of fields
   201  				var isDuplicate bool
   202  				for i := range fields {
   203  					if fields[i].Names[0].Name == f.Names[0].Name {
   204  						isDuplicate = true
   205  					}
   206  				}
   207  				if isDuplicate {
   208  					f.Names[0].Name += strconv.Itoa(pos)
   209  				}
   210  				fields = append(fields, f)
   211  			}
   212  
   213  		case *ast.IndirectFieldDecl:
   214  			// ignore
   215  
   216  		case *ast.TransparentUnionAttr:
   217  			// Don't do anything
   218  			// Example of AST:
   219  			// |-RecordDecl 0x3632d78 <...> line:67:9 union definition
   220  			// | |-TransparentUnionAttr 0x3633050 <...>
   221  			// | |-FieldDecl 0x3632ed0 <...> col:17 __uptr 'union wait *'
   222  			// | `-FieldDecl 0x3632f60 <...> col:10 __iptr 'int *'
   223  			// |-TypedefDecl 0x3633000 <...> col:5 __WAIT_STATUS 'union __WAIT_STATUS':'__WAIT_STATUS'
   224  			// | `-ElaboratedType 0x3632fb0 'union __WAIT_STATUS' sugar
   225  			// |   `-RecordType 0x3632e00 '__WAIT_STATUS'
   226  			// |     `-Record 0x3632d78 ''
   227  
   228  		default:
   229  			// For case anonymous enum:
   230  
   231  			// |-EnumDecl 0x26c3970 <...> line:77:5
   232  			// | `-EnumConstantDecl 0x26c3a50 <...> col:9 referenced SWE_ENUM_THREE 'int'
   233  			// |   `-IntegerLiteral 0x26c3a30 <...> 'int' 3
   234  			// |-FieldDecl 0x26c3af0 <...> col:7 EnumThree 'enum (anonymous enum at ...
   235  			if eDecl, ok := field.(*ast.EnumDecl); ok && eDecl.Name == "" {
   236  				if pos+1 <= len(n.Children())-1 {
   237  					if f, ok := n.Children()[pos+1].(*ast.FieldDecl); ok {
   238  						n.Children()[pos].(*ast.EnumDecl).Name = util.GenerateCorrectType(f.Type)
   239  					}
   240  				}
   241  			}
   242  
   243  			// default
   244  			var declsIn []goast.Decl
   245  			declsIn, err = transpileToNode(field, p)
   246  			if err != nil {
   247  				err = fmt.Errorf("cannot transpile %T : %v", field, err)
   248  				// p.AddMessage(p.GenerateWarningMessage(err, field))
   249  				return
   250  			}
   251  			decls = append(decls, declsIn...)
   252  		}
   253  	}
   254  
   255  	s, err := program.NewStruct(p, n)
   256  	if err != nil {
   257  		p.AddMessage(p.GenerateWarningMessage(err, n))
   258  		err = nil // ignore error
   259  		return
   260  	}
   261  	switch s.Type {
   262  	case program.UnionType:
   263  		if strings.HasPrefix(s.Name, "union ") {
   264  			p.Structs[s.Name] = s
   265  			defer func() {
   266  				if err != nil {
   267  					delete(p.Structs, s.Name)
   268  					p.UndefineType(s.Name)
   269  				}
   270  			}()
   271  		} else {
   272  			p.Unions["union "+s.Name] = s
   273  			defer func() {
   274  				if err != nil {
   275  					delete(p.Structs, "union "+s.Name)
   276  					p.UndefineType("union " + s.Name)
   277  				}
   278  			}()
   279  		}
   280  
   281  	case program.StructType:
   282  		if strings.HasPrefix(s.Name, "struct ") {
   283  			p.Structs[s.Name] = s
   284  			defer func() {
   285  				if err != nil {
   286  					delete(p.Structs, s.Name)
   287  					p.UndefineType(s.Name)
   288  				}
   289  			}()
   290  		} else {
   291  			p.Structs["struct "+s.Name] = s
   292  			defer func() {
   293  				if err != nil {
   294  					delete(p.Structs, "struct "+s.Name)
   295  					p.UndefineType("struct " + s.Name)
   296  				}
   297  			}()
   298  		}
   299  
   300  	default:
   301  		err = fmt.Errorf("undefine type of struct : %v", s.Type)
   302  		return
   303  	}
   304  
   305  	name = strings.TrimPrefix(name, "struct ")
   306  	name = strings.TrimPrefix(name, "union ")
   307  
   308  	var d []goast.Decl
   309  	switch s.Type {
   310  	case program.UnionType:
   311  		// Union size
   312  		var size int
   313  		size, err = types.SizeOf(p, "union "+name)
   314  
   315  		// In normal case no error is returned,
   316  		if err != nil {
   317  			// but if we catch one, send it as a warning
   318  			err = fmt.Errorf("could not determine the size of type `union %s`"+
   319  				" for that reason: %s", name, err)
   320  			return
   321  		}
   322  		// So, we got size, then
   323  		// Add imports needed
   324  		addPackageUnsafe = true
   325  
   326  		// Declaration for implementing union type
   327  		d, err = transpileUnion(name, size, fields)
   328  		if err != nil {
   329  			return nil, err
   330  		}
   331  
   332  	case program.StructType:
   333  		d = append(d, &goast.GenDecl{
   334  			Tok: token.TYPE,
   335  			Specs: []goast.Spec{
   336  				&goast.TypeSpec{
   337  					Name: util.NewIdent(name),
   338  					Type: &goast.StructType{
   339  						Fields: &goast.FieldList{
   340  							List: fields,
   341  						},
   342  					},
   343  				},
   344  			},
   345  		})
   346  
   347  	default:
   348  		err = fmt.Errorf("undefine type of struct : %v", s.Type)
   349  		return
   350  	}
   351  
   352  	decls = append(decls, d...)
   353  
   354  	return
   355  }
   356  
   357  func transpileCXXRecordDecl(p *program.Program, n *ast.RecordDecl) (
   358  	decls []goast.Decl, err error) {
   359  
   360  	n.Name = util.GenerateCorrectType(n.Name)
   361  	name := n.Name
   362  
   363  	defer func() {
   364  		if err != nil {
   365  			err = fmt.Errorf("cannot transpileCXXRecordDecl : `%v`. %v",
   366  				n.Name, err)
   367  			p.AddMessage(p.GenerateWarningMessage(err, n))
   368  		}
   369  	}()
   370  
   371  	defer func() {
   372  		if r := recover(); r != nil {
   373  			err = fmt.Errorf("transpileCXXRecordDecl: error - panic : %#v %s", r, string(debug.Stack()))
   374  		}
   375  	}()
   376  
   377  	// ignore if haven`t definition
   378  	if !n.IsDefinition {
   379  		return
   380  	}
   381  
   382  	if name == "" || p.IsTypeAlreadyDefined(name) {
   383  		err = nil
   384  		return
   385  	}
   386  
   387  	p.DefineType(n.Kind + " " + name)
   388  	defer func() {
   389  		if err != nil {
   390  			p.UndefineType(n.Kind + " " + name)
   391  		}
   392  	}()
   393  
   394  	var fields []*goast.Field
   395  	for _, v := range n.Children() {
   396  		switch v := v.(type) {
   397  		case *ast.CXXRecordDecl:
   398  			// ignore
   399  
   400  		case *ast.AccessSpecDecl:
   401  			// ignore
   402  
   403  		case *ast.FieldDecl:
   404  			var f *goast.Field
   405  			f, err = transpileFieldDecl(p, v)
   406  			if err != nil {
   407  				return
   408  			}
   409  			fields = append(fields, f)
   410  
   411  		default:
   412  			p.AddMessage(p.GenerateWarningMessage(
   413  				fmt.Errorf("cannot transpilation field: %T", v), n))
   414  		}
   415  	}
   416  
   417  	return []goast.Decl{&goast.GenDecl{
   418  		Tok: token.TYPE,
   419  		Specs: []goast.Spec{
   420  			&goast.TypeSpec{
   421  				Name: util.NewIdent(name),
   422  				Type: &goast.StructType{
   423  					Fields: &goast.FieldList{
   424  						List: fields,
   425  					},
   426  				},
   427  			},
   428  		},
   429  	}}, nil
   430  }
   431  
   432  func transpileTypedefDecl(p *program.Program, n *ast.TypedefDecl) (
   433  	decls []goast.Decl, err error) {
   434  
   435  	// implicit code from clang at the head of each clang AST tree
   436  	if n.IsImplicit && n.Pos.File == ast.PositionBuiltIn {
   437  		return
   438  	}
   439  	defer func() {
   440  		if err != nil {
   441  			err = fmt.Errorf("cannot transpile Typedef Decl : err = %v", err)
   442  		} else {
   443  			if !p.IncludeHeaderIsExists(n.Pos.File) {
   444  				// no need add struct from C STD
   445  				decls = nil
   446  				return
   447  			}
   448  		}
   449  	}()
   450  	n.Name = util.CleanCType(util.GenerateCorrectType(n.Name))
   451  	n.Type = util.CleanCType(util.GenerateCorrectType(n.Type))
   452  	n.Type2 = util.CleanCType(util.GenerateCorrectType(n.Type2))
   453  	name := n.Name
   454  
   455  	if ignoreVaListTypedef(n.Name) {
   456  		return
   457  	}
   458  
   459  	// |-RecordDecl 0x1b733f0 <line:603:9, line:606:1> line:603:9 struct definition
   460  	// | |-FieldDecl 0x1b734c0 <line:604:5, col:12> col:12 x 'pointx':'int'
   461  	// | `-FieldDecl 0x1b73528 <line:605:5, col:9> col:9 y 'int'
   462  	// |-TypedefDecl 0x1b735d8 <line:603:1, line:606:3> col:3 referenced Point2 'struct Point2':'Point2'
   463  	// | `-ElaboratedType 0x1b73580 'struct Point2' sugar
   464  	// |   `-RecordType 0x1b73470 'Point2'
   465  	// |     `-Record 0x1b733f0 ''
   466  	for _, pre := range []string{"struct ", "union "} {
   467  		if pre+n.Name == n.Type && n.Name == n.Type2 {
   468  			n.Type = fmt.Sprintf("%s(anonymous %sat %s:%d:%d)", pre, pre, n.Pos.File, n.Pos.Line, n.Pos.Column)
   469  			n.Type = util.GenerateCorrectType(n.Type)
   470  		}
   471  	}
   472  
   473  	if "struct "+n.Name == n.Type || "union "+n.Name == n.Type {
   474  		p.TypedefType[n.Name] = n.Type
   475  		return
   476  	}
   477  
   478  	if util.IsFunction(n.Type) {
   479  		var field *goast.Field
   480  		field, err = newFunctionField(p, n.Name, n.Type)
   481  		if err != nil {
   482  			p.AddMessage(p.GenerateWarningMessage(err, n))
   483  		} else {
   484  			// registration type
   485  			p.TypedefType[n.Name] = n.Type
   486  
   487  			decls = append(decls, &goast.GenDecl{
   488  				Tok: token.TYPE,
   489  				Specs: []goast.Spec{
   490  					&goast.TypeSpec{
   491  						Name:   util.NewIdent(name),
   492  						Assign: 1,
   493  						Type:   field.Type,
   494  					},
   495  				},
   496  			})
   497  			err = nil
   498  			return
   499  		}
   500  	}
   501  
   502  	// added for support "typedef enum {...} dd" with empty name of struct
   503  	// Result in Go: "type dd int"
   504  	if strings.Contains(n.Type, "enum ") {
   505  		// Registration new type in program.Program
   506  		if !p.IsTypeAlreadyDefined(n.Name) {
   507  			p.DefineType(n.Name)
   508  			p.EnumTypedefName[n.Name] = true
   509  		}
   510  		decls = append(decls, &goast.GenDecl{
   511  			Tok: token.TYPE,
   512  			Specs: []goast.Spec{
   513  				&goast.TypeSpec{
   514  					Name:   util.NewIdent(name),
   515  					Assign: 1,
   516  					Type:   util.NewTypeIdent("int32"),
   517  				},
   518  			},
   519  		})
   520  		err = nil
   521  		return
   522  	}
   523  
   524  	if p.IsTypeAlreadyDefined(name) {
   525  		err = nil
   526  		return
   527  	}
   528  
   529  	p.DefineType(name)
   530  
   531  	resolvedType, err := types.ResolveType(p, n.Type)
   532  	if err != nil {
   533  		p.AddMessage(p.GenerateWarningMessage(err, n))
   534  		err = nil // ignore error
   535  	}
   536  
   537  	// There is a case where the name of the type is also the definition,
   538  	// like:
   539  	//
   540  	//     type _RuneEntry _RuneEntry
   541  	//
   542  	// This of course is impossible and will cause the Go not to compile.
   543  	// It itself is caused by lack of understanding (at this time) about
   544  	// certain scenarios that types are defined as. The above example comes
   545  	// from:
   546  	//
   547  	//     typedef struct {
   548  	//        // ... some fields
   549  	//     } _RuneEntry;
   550  	//
   551  	// Until which time that we actually need this to work I am going to
   552  	// suppress these.
   553  	if name == resolvedType {
   554  		err = nil
   555  		return
   556  	}
   557  
   558  	err = nil
   559  	if resolvedType == "" {
   560  		resolvedType = "interface{}"
   561  	}
   562  
   563  	p.TypedefType[n.Name] = n.Type
   564  
   565  	// 0: *ast.GenDecl {
   566  	// .  Tok: type
   567  	// .  Specs: []ast.Spec (len = 1) {
   568  	// .  .  0: *ast.TypeSpec {
   569  	// .  .  .  Name: *ast.Ident {
   570  	// .  .  .  .  Name: "R"
   571  	// .  .  .  }
   572  	// .  .  .  Assign: 3:8        // <- This is important
   573  	// .  .  .  Type: *ast.Ident {
   574  	// .  .  .  .  Name: "int"
   575  	// .  .  .  }
   576  	// .  .  }
   577  	// .  }
   578  	// }
   579  	decls = append(decls, &goast.GenDecl{
   580  		Tok: token.TYPE,
   581  		Specs: []goast.Spec{
   582  			&goast.TypeSpec{
   583  				Name:   util.NewIdent(name),
   584  				Assign: 1,
   585  				Type:   util.NewTypeIdent(resolvedType),
   586  			},
   587  		},
   588  	})
   589  
   590  	return
   591  }
   592  
   593  func transpileVarDecl(p *program.Program, n *ast.VarDecl) (
   594  	decls []goast.Decl, theType string, err error) {
   595  	defer func() {
   596  		if err != nil {
   597  			err = fmt.Errorf("cannot transpileVarDecl : err = %v", err)
   598  		}
   599  	}()
   600  
   601  	n.Name = util.GenerateCorrectType(n.Name)
   602  	n.Type = util.GenerateCorrectType(n.Type)
   603  	n.Type2 = util.GenerateCorrectType(n.Type2)
   604  
   605  	// Ignore extern as there is no analogy for Go right now.
   606  	if n.IsExtern && len(n.ChildNodes) == 0 {
   607  		return
   608  	}
   609  
   610  	if strings.Contains(n.Type, "va_list") &&
   611  		strings.Contains(n.Type2, "va_list_tag") {
   612  		return VaListInit(p, n.Name), "", nil
   613  	}
   614  
   615  	// Example of DeclStmt for C code:
   616  	// void * a = NULL;
   617  	// void(*t)(void) = a;
   618  	// Example of AST:
   619  	// `-VarDecl 0x365fea8 <col:3, col:20> col:9 used t 'void (*)(void)' cinit
   620  	//   `-ImplicitCastExpr 0x365ff48 <col:20> 'void (*)(void)' <BitCast>
   621  	//     `-ImplicitCastExpr 0x365ff30 <col:20> 'void *' <LValueToRValue>
   622  	//       `-DeclRefExpr 0x365ff08 <col:20> 'void *' lvalue Var 0x365f8c8 'r' 'void *'
   623  
   624  	if len(n.Children()) > 0 {
   625  		if v, ok := (n.Children()[0]).(*ast.ImplicitCastExpr); ok {
   626  			if len(v.Type) > 0 {
   627  				// Is it function ?
   628  				if util.IsFunction(v.Type) {
   629  					var prefix string
   630  					var fields, returns []string
   631  					prefix, fields, returns, err = types.SeparateFunction(p, v.Type)
   632  					if err != nil {
   633  						err = fmt.Errorf("cannot resolve function : %v", err)
   634  						return
   635  					}
   636  					if len(prefix) != 0 {
   637  						p.AddMessage(p.GenerateWarningMessage(
   638  							fmt.Errorf("prefix is not used : `%v`", prefix), n))
   639  					}
   640  					functionType := GenerateFuncType(fields, returns)
   641  					nameVar1 := n.Name
   642  
   643  					if vv, ok := v.Children()[0].(*ast.ImplicitCastExpr); ok {
   644  						if decl, ok := vv.Children()[0].(*ast.DeclRefExpr); ok {
   645  							nameVar2 := decl.Name
   646  
   647  							return []goast.Decl{&goast.GenDecl{
   648  								Tok: token.VAR,
   649  								Specs: []goast.Spec{&goast.ValueSpec{
   650  									Names: []*goast.Ident{{Name: nameVar1}},
   651  									Type:  functionType,
   652  									Values: []goast.Expr{&goast.TypeAssertExpr{
   653  										X:    &goast.Ident{Name: nameVar2},
   654  										Type: functionType,
   655  									}},
   656  									Doc: p.GetMessageComments(),
   657  								},
   658  								}}}, "", nil
   659  						}
   660  					}
   661  				}
   662  			}
   663  		}
   664  	}
   665  
   666  	theType = n.Type
   667  
   668  	p.GlobalVariables[n.Name] = theType
   669  
   670  	preStmts := []goast.Stmt{}
   671  	postStmts := []goast.Stmt{}
   672  
   673  	defaultValue, _, newPre, newPost, err := getDefaultValueForVar(p, n)
   674  	if err != nil {
   675  		p.AddMessage(p.GenerateWarningMessage(err, n))
   676  		err = nil // Error is ignored
   677  	}
   678  	// for ignore zero value. example:
   679  	// int i = 0;
   680  	// transpile to:
   681  	// var i int // but not "var i int = 0"
   682  	if len(defaultValue) == 1 && defaultValue[0] != nil {
   683  		if bl, ok := defaultValue[0].(*goast.BasicLit); ok {
   684  			if bl.Kind == token.INT && bl.Value == "0" {
   685  				defaultValue = nil
   686  			}
   687  			if bl.Kind == token.FLOAT && bl.Value == "0" {
   688  				defaultValue = nil
   689  			}
   690  		} else if call, ok := defaultValue[0].(*goast.CallExpr); ok {
   691  			if len(call.Args) == 1 {
   692  				if bl, ok := call.Args[0].(*goast.BasicLit); ok {
   693  					if bl.Kind == token.INT && bl.Value == "0" {
   694  						defaultValue = nil
   695  					}
   696  					if bl.Kind == token.FLOAT && bl.Value == "0" {
   697  						defaultValue = nil
   698  					}
   699  				}
   700  			}
   701  		} else if ind, ok := defaultValue[0].(*goast.Ident); ok {
   702  			if ind.Name == "nil" {
   703  				defaultValue = nil
   704  			}
   705  		}
   706  	}
   707  
   708  	preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)
   709  
   710  	// Allocate slice so that it operates like a fixed size array.
   711  	arrayType, arraySize := types.GetArrayTypeAndSize(n.Type)
   712  
   713  	if arraySize != -1 && defaultValue == nil {
   714  		var goArrayType string
   715  		goArrayType, err = types.ResolveType(p, arrayType)
   716  		if err != nil {
   717  			p.AddMessage(p.GenerateWarningMessage(err, n))
   718  			err = nil // Error is ignored
   719  		}
   720  
   721  		defaultValue = []goast.Expr{
   722  			util.NewCallExpr(
   723  				"make",
   724  				&goast.ArrayType{
   725  					Elt: util.NewTypeIdent(goArrayType),
   726  				},
   727  				util.NewIntLit(arraySize),
   728  				// If len and capacity is same, then
   729  				// capacity is not need
   730  				// util.NewIntLit(arraySize),
   731  			),
   732  		}
   733  	}
   734  
   735  	if len(preStmts) != 0 || len(postStmts) != 0 {
   736  		p.AddMessage(p.GenerateWarningMessage(
   737  			fmt.Errorf("not acceptable length of Stmt : pre(%d), post(%d)",
   738  				len(preStmts), len(postStmts)), n))
   739  	}
   740  
   741  	names := map[string]string{
   742  		"ptrdiff_t": "noarch.PtrdiffT",
   743  	}
   744  
   745  	var typeResult goast.Expr
   746  
   747  	if n, ok := names[n.Type]; ok {
   748  		typeResult = util.NewTypeIdent(n)
   749  		goto ignoreType
   750  	}
   751  
   752  	theType, err = types.ResolveType(p, n.Type)
   753  	if err != nil {
   754  		p.AddMessage(p.GenerateWarningMessage(
   755  			fmt.Errorf("unknown type used C type, because %v", err), n))
   756  		err = nil // Error is ignored
   757  		theType = n.Type
   758  	}
   759  	typeResult = util.NewTypeIdent(theType)
   760  
   761  ignoreType:
   762  
   763  	return []goast.Decl{&goast.GenDecl{
   764  		Tok: token.VAR,
   765  		Specs: []goast.Spec{
   766  			&goast.ValueSpec{
   767  				Names:  []*goast.Ident{util.NewIdent(n.Name)},
   768  				Type:   typeResult,
   769  				Values: defaultValue,
   770  				Doc:    p.GetMessageComments(),
   771  			},
   772  		},
   773  	}}, "", nil
   774  }