Example #1
0
File: job.go Project: cznic/c
func (j *Job) union(n cc.Node, t cc.Type) {
	j.body("\n_ [0]struct{")
	m, _ := t.Members()
	for _, v := range m {
		j.body("\n%s", xc.Dict.S(v.Name))
		j.typ(n, v.Type)
		if t := v.Type; t.Kind() != cc.Union && t.Kind() != cc.Struct {
			j.body(" // %s", v.Type)
		}
	}
	j.body("\n}")
	j.body("\nUnion [%v]byte", t.SizeOf())
}
Example #2
0
File: etc.go Project: cznic/c
func eqTypes(n cc.Node, a, b cc.Type) bool {
	if a.Kind() == cc.Ptr {
		if t := a.Element(); t.Kind() == cc.Function {
			a = t
		}
	}
	if b.Kind() == cc.Ptr {
		if t := b.Element(); t.Kind() == cc.Function {
			b = t
		}
	}
	return removeQualifiers(a.String()) == removeQualifiers(b.String())
}
Example #3
0
File: job.go Project: cznic/c
func (j *Job) addTag(t cc.Type) {
	for t.Kind() == cc.Ptr || t.Kind() == cc.Array {
		t = t.Element()
	}
	tag := t.Tag()
	if tag == 0 {
		return
	}

	n := j.In.Declarations.Tags[tag].Node
	d := t.Declarator()
	if j.ImportPath(n) == 0 && j.tags[tag] == nil {
		j.tags[tag] = d
	}
}
Example #4
0
File: job.go Project: cznic/c
func (j *Job) cast(ot cc.Type, n *cc.Expression) {
	j.imports[idUnsafe] = struct{}{}
	if ot.Kind() == cc.Ptr && n.Type.Kind() == cc.Ptr && n.Type.Element().Kind() != cc.Function {
		j.body("(")
		j.typ(n, ot)
		j.body(")(unsafe.Pointer(")
		j.expression(nil, n)
		j.body("))")
		return
	}

	j.body("(*(*")
	j.typ(n, ot)
	j.body(")(unsafe.Pointer(&struct{f ")
	j.typ(n, n.Type)
	j.body("}{")
	j.expression(nil, n)
	j.body("})))")
}
Example #5
0
File: job.go Project: cznic/c
func (j *Job) initializerList(st cc.Type, n *cc.InitializerList) {
	j.typ(n, st)
	j.body("{\n")
	defer j.body("\n}")

	if st.Kind() == cc.Union {
		return
	}

	if st.Kind() == cc.Array {
		t := st.Element()
		for ; n != nil; n = n.InitializerList {
			if n.DesignationOpt != nil {
				todo(n)
			}

			j.initializer(t, n.Initializer)
			j.body(",")
			j.body("\n")
		}
		return
	}

	var m []cc.Member
	if st != nil {
		m, _ = st.Members()
	}
	i := 0
	for ; n != nil; n = n.InitializerList {
		if n.DesignationOpt != nil {
			todo(n)
		}

		var t cc.Type
		if i < len(m) {
			t = m[i].Type
		}
		j.initializer(t, n.Initializer)
		j.body(",")
		j.body("\n")
		i++
	}
}
Example #6
0
File: job.go Project: cznic/c
func (j *Job) inc(ot cc.Type, n *cc.Expression, op string, post bool) {
	if ot != nil && ot.Kind() == cc.Void {
		todo(n, ot, n.Type)
		return
	}

	t := ot
	if t == nil {
		t = n.Type
	}
	j.body(" func() ")
	j.typ(n, t)
	j.body(" { p := &(")
	j.expression(nil, n.Expression)
	switch {
	case post:
		j.body("); r := *p; (*p)++; return r }()")
	default:
		j.body("); (*p)++; return *p }()")
	}
}
Example #7
0
File: job.go Project: cznic/c
func (j *Job) addTag2(t cc.Type) {
	for t.Kind() == cc.Ptr || t.Kind() == cc.Array {
		t = t.Element()
	}
	tag := t.Tag()
	var n cc.Node
	if tag != 0 {
		n = j.In.Declarations.Tags[tag].Node
	}
	d := t.Declarator()
	if (n != nil && j.ImportPath(n) != 0) || j.tags[tag] != nil {
		return
	}

	if tag != 0 {
		j.tags[tag] = d
	}
	m, _ := t.Members()
	for _, v := range m {
		j.addTag2(v.Type)
	}
}
Example #8
0
File: job.go Project: cznic/c
func (j *Job) expression(ot cc.Type, n *cc.Expression) {
	if ot != nil {
		switch {
		case n.Case == 25 /* '(' TypeName')' Expression */ && !eqTypes(n.Expression, ot, n.Expression.Type):
			j.convert(ot, n.Expression)
			return
		case !eqTypes(n, ot, n.Type):
			j.convert(ot, n)
			return
		}
	}

	if n.Value != nil {
		j.constExpr(ot, n)
		return
	}

	switch n.Case {
	case 0: // IDENTIFIER
		id := n.Token.Val
		bn := n.IdentResolutionScope().Lookup(cc.NSIdentifiers, id).Node
		if j.ImportPath(bn) != 0 && id == idErrno {
			j.body(" 0/*TODO747*/")
			break
		}

		j.qualifier(bn)
		j.body(" %s", xc.Dict.S(mangleIdent(id, bn.(*cc.DirectDeclarator).TopDeclarator().Linkage == cc.External)))
	case 1: // CHARCONST                                          // Case 1
		todo(n)
	case 2: // FLOATCONST                                         // Case 2
		todo(n)
	case 3: // INTCONST                                           // Case 3
		todo(n)
	case 4: // LONGCHARCONST                                      // Case 4
		todo(n)
	case 5: // LONGSTRINGLITERAL                                  // Case 5
		todo(n)
	case 6: // STRINGLITERAL                                      // Case 6
		todo(n)
	case 7: // '(' ExpressionList ')'                             // Case 7
		j.expressionList(n.Type, n.ExpressionList)
	case 8: // Expression '[' ExpressionList ']'                  // Case 8
		switch n.Expression.Type.Kind() {
		case cc.Array:
			j.expression(nil, n.Expression)
			j.body("[")
			j.expressionList(nil, n.ExpressionList)
			j.body("]")
		case cc.Ptr:
			j.imports[idUnsafe] = struct{}{}
			j.body("(*(")
			j.typ(nil, n.Expression.Type)
			j.body(")(unsafe.Pointer(uintptr(unsafe.Pointer(")
			j.expression(nil, n.Expression)
			j.body(")) + uintptr(")
			j.expressionList(nil, n.ExpressionList)
			j.body("))))")
		default:
			todo(n, n.Expression.Type, n.Expression.Type.Kind(), ot, n.Type)
		}
	case 9: // Expression '(' ArgumentExpressionListOpt ')'       // Case 9
		e := n.Expression
		if e.Case == 0 /* IDENTIFIER */ && e.Token.Val == idGO { // __GO__() magic.
			for n := n.ArgumentExpressionListOpt.ArgumentExpressionList; n != nil; n = n.ArgumentExpressionList {
				switch n := n.Expression; n.Case {
				case 6: // STRINGLITERAL
					j.body("%s", xc.Dict.S(int(n.Value.(cc.StringLitID))))
				default:
					panic("internal error")
				}
			}
			break
		}

		j.expression(n.Expression.Type, n.Expression)
		j.body("(")
		if o := n.ArgumentExpressionListOpt; o != nil {
			ps, _ := n.Expression.Type.Parameters()
			i := 0
			for n := o.ArgumentExpressionList; n != nil; n = n.ArgumentExpressionList {
				j.expression(ps[i].Type, n.Expression)
				j.body(", ")
				i++
			}
		}
		j.body(")")
	case 10: // Expression '.' IDENTIFIER                          // Case 10
		fallthrough
	case 11: // Expression "->" IDENTIFIER                         // Case 11
		j.selector(ot, n)
	case 12: // Expression "++"                                    // Case 12
		j.inc(ot, n, "++", true)
	case 13: // Expression "--"                                    // Case 13
		todo(n)
	case 14: // '(' TypeName ')' '{' InitializerList CommaOpt '}'  // Case 14
		todo(n)
	case 15: // "++" Expression                                    // Case 15
		j.inc(ot, n, "++", false)
	case 16: // "--" Expression                                    // Case 16
		todo(n)
	case 17: // '&' Expression                                     // Case 17
		j.body(" &")
		j.expression(nil, n.Expression)
	case 18: // '*' Expression                                     // Case 18
		j.body(" *")
		j.expression(n.Expression.Type, n.Expression)
	case 19: // '+' Expression                                     // Case 19
		todo(n)
	case 20: // '-' Expression                                     // Case 20
		todo(n)
	case 21: // '~' Expression                                     // Case 21
		j.body(" ^(")
		j.expression(ot, n.Expression)
		j.body(")")
	case 22: // '!' Expression                                     // Case 22
		switch t := n.Expression.Type; t.Kind() {
		case cc.Int:
			j.body(" libc.Not%s(", j.title(t.Kind()))
			j.expression(nil, n.Expression)
			j.body(")")
		default:
			todo(n, ot, t)
		}
	case 23: // "sizeof" Expression                                // Case 23
		todo(n)
	case 24: // "sizeof" '(' TypeName ')'                          // Case 24
		todo(n)
	case 25: // '(' TypeName')' Expression                        // Case 25
		j.expression(ot, n.Expression)
	case 26: // Expression '*' Expression                          // Case 26
		j.binary(ot, n, "*")
	case 27: // Expression '/' Expression                          // Case 27
		j.binary(ot, n, "/")
	case 28: // Expression '%' Expression                          // Case 28
		todo(n)
	case 29: // Expression '+' Expression                          // Case 29
		j.add(ot, n, "+")
	case 30: // Expression '-' Expression                          // Case 30
		j.add(ot, n, "-")
	case 31: // Expression "<<" Expression                         // Case 31
		j.shift(ot, n, "<<")
	case 32: // Expression ">>" Expression                         // Case 32
		todo(n)
	case 33: // Expression '<' Expression                          // Case 33
		j.compare(ot, n, "Lt")
	case 34: // Expression '>' Expression                          // Case 34
		j.compare(ot, n, "Gt")
	case 35: // Expression "<=" Expression                         // Case 35
		todo(n)
	case 36: // Expression ">=" Expression                         // Case 36
		todo(n)
	case 37: // Expression "==" Expression                         // Case 37
		j.compare(ot, n, "Eq")
	case 38: // Expression "!=" Expression                         // Case 38
		j.compare(ot, n, "Ne")
	case 39: // Expression '&' Expression                          // Case 39
		j.binary(ot, n, "&")
	case 40: // Expression '^' Expression                          // Case 40
		todo(n)
	case 41: // Expression '|' Expression                          // Case 41
		j.binary(ot, n, "|")
	case 42: // Expression "&&" Expression                         // Case 42
		j.boolean(ot, n, "&&")
	case 43: // Expression "||" Expression                         // Case 43
		j.boolean(ot, n, "||")
	case 44: // Expression '?' ExpressionList ':' Expression       // Case 44
		switch {
		case ot != nil && ot.Kind() == cc.Void:
			todo(n, ot)
		default:
			j.body(" func()")
			j.typ(n, n.Type)
			j.body("{ if ")
			switch n.Expression.Type.Kind() {
			case cc.Int, cc.UInt, cc.UShort:
				j.body("(")
				j.expression(nil, n.Expression)
				j.body(") != 0 { return ")
				j.expressionList(n.Type, n.ExpressionList)
				j.body(" } else { return ")
				j.expression(n.Type, n.Expression2)
			case cc.Ptr:
				j.body("(")
				j.expression(nil, n.Expression)
				j.body(") != nil { return ")
				j.expressionList(n.Type, n.ExpressionList)
				j.body(" } else { return ")
				j.expression(n.Type, n.Expression2)
			default:
				todo(n, n.Expression.Type)
			}
			j.body(" }}()")
		}
	case 45: // Expression '=' Expression                          // Case 45
		switch {
		case ot == nil: // Not an expression.
			switch {
			case n.Expression2.Case != 45: // Plain assignment.
				j.expression(nil, n.Expression)
				j.body(" = ")
				j.expression(n.Expression.Type, n.Expression2)
			default:
				todo(n)
			}
		default:
			j.body(" func() ")
			j.typ(n, n.Expression.Type)
			j.body(" { r := ")
			j.expression(n.Expression.Type, n.Expression2)
			j.body("; ")
			j.expression(nil, n.Expression)
			j.body(" = r; return r }()")
		}
	case 46: // Expression "*=" Expression                         // Case 46
		todo(n)
	case 47: // Expression "/=" Expression                         // Case 47
		todo(n)
	case 48: // Expression "%=" Expression                         // Case 48
		todo(n)
	case 49: // Expression "+=" Expression                         // Case 49
		todo(n)
	case 50: // Expression "-=" Expression                         // Case 50
		todo(n)
	case 51: // Expression "<<=" Expression                        // Case 51
		todo(n)
	case 52: // Expression ">>=" Expression                        // Case 52
		todo(n)
	case 53: // Expression "&=" Expression                         // Case 53
		todo(n)
	case 54: // Expression "^=" Expression                         // Case 54
		todo(n)
	case 55: // Expression "|=" Expression                         // Case 55
		todo(n)
	case 56: // "_Alignof" '(' TypeName ')'                        // Case 56
		todo(n)
	default:
		panic("internal errro")
	}
}
Example #9
0
File: job.go Project: cznic/c
func (j *Job) convert(ot cc.Type, n *cc.Expression) {
	t := n.Type
	switch otk := ot.Kind(); otk {
	case cc.Ptr:
		switch t.Kind() {
		case cc.Int:
			if v := n.Value; v != nil && isZero(n, v) {
				j.body(" nil")
				return
			}

			todo(n, ot, t)
		}

		if ot.Element().Kind() == cc.Void {
			switch t.Kind() {
			case cc.Ptr:
				j.imports[idUnsafe] = struct{}{}
				j.body(" unsafe.Pointer(uintptr(0)/*TODO536*/)")
				break
				//TODO j.body(" unsafe.Pointer/*DBG536 %v %s */(", n.Case, n.Type)
				//TODO j.expression(nil, n)
				//TODO j.body("/*DBG538*/)")
			case cc.Array:
				switch {
				case t.Elements() > 0:
					j.imports[idUnsafe] = struct{}{}
					j.body(" unsafe.Pointer(&")
					j.expression(nil, n)
					j.body("[0])")
				default:
					todo(n, ot, t)
				}
			default:
				todo(n, ot, t)
			}
			break
		}

		switch t.Kind() {
		case cc.Ptr:
			switch t.Element().Kind() {
			case cc.Void:
				j.body("(")
				j.typ(n, ot)
				j.body(")(")
				j.expression(nil, n)
				j.body(")")
			default:
				j.cast(ot, n)
			}
			return
		case cc.Array:
			switch {
			case t.Elements() > 0:
				j.body(" &")
				j.expression(nil, n)
				j.body("[0]")
			default:
				todo(n, ot, t)
			}
			return
		}

		switch l := ot.Element(); l.Kind() {
		case cc.Function:
			switch t.Kind() {
			case cc.Function:
				j.cast(ot, n)
			default:
				todo(n, l, t)
			}
		case cc.Char:
			switch t.Kind() {
			case cc.Ptr:
				switch r := t.Element(); r.Kind() {
				case cc.Char:
					j.expression(nil, n)
				default:
					todo(n, l, r)
				}
			default:
				todo(n, l, t)
			}
		default:
			todo(n, ot, t)
		}
	case cc.Char, cc.Int, cc.LongLong, cc.SChar, cc.Short, cc.UChar, cc.UInt,
		cc.ULong, cc.ULongLong, cc.UShort:
		j.body(" %s(", j.Model.Items[otk].More)
		j.expression(nil, n)
		j.body(")")
	case cc.Void:
		if isLiteral(n) {
			break
		}

		j.expression(nil, n)
	default:
		todo(n, ot, t)
	}
}
Example #10
0
File: job.go Project: cznic/c
func (j *Job) signature(n cc.Node, t cc.Type) {
	ps, variadic := t.Parameters()
	j.body("(")
	names := false
	var groups [][]cc.Parameter
	var group []cc.Parameter
	var prevT cc.Type
	for i, p := range ps {
		if p.Name != 0 {
			names = true
		}
		if i == 0 {
			group = []cc.Parameter{p}
			prevT = p.Type
			continue
		}

		if !eqTypes(n, prevT, p.Type) {
			groups = append(groups, group)
			group = []cc.Parameter{p}
			prevT = p.Type
			continue
		}

		group = append(group, p)
	}
	if group != nil {
		groups = append(groups, group)
	}
	for _, g := range groups {
		switch {
		case names:
			for i, p := range g {
				j.body("%s", xc.Dict.S(mangleIdent(p.Name, false)))
				if i < len(g)-1 {
					j.body(", ")
				}
			}
			t := g[0].Type
			if t.Kind() == cc.Array {
				j.body("*")
			}
			j.typ(g[0].Declarator, t)
			j.body(", ")
		default:
			t := g[0].Type
			for range g {
				if t.Kind() == cc.Array {
					j.body("*")
				}
				j.typ(g[0].Declarator, t)
				j.body(", ")
			}
		}
	}
	if variadic {
		if names {
			j.body("args")
		}
		j.body("...interface{}")
	}
	j.body(")")
	if t := t.Result(); t.Kind() != cc.Void {
		if t.Kind() == cc.Array {
			j.body("*")
		}
		j.typ(n, t)
	}
}
Example #11
0
File: job.go Project: cznic/c
func (j *Job) typ(n cc.Node, t cc.Type) {
	if t.Declarator().RawSpecifier().TypedefName() == idVaList {
		j.body("[]interface{}")
		return
	}

	stars := 0
	for t.Kind() == cc.Ptr {
		stars++
		t = t.Element()
	}
	stars0 := stars
	if (t.Kind() == cc.Void || t.Kind() == cc.Function) && stars > 0 {
		stars--
	}
	j.body("%s", strings.Repeat("*", stars))
	switch k := t.Kind(); k {
	case cc.Char, cc.Double, cc.Int, cc.Long, cc.LongDouble, cc.LongLong, cc.SChar,
		cc.Short, cc.UChar, cc.ULong, cc.ULongLong, cc.UInt, cc.UShort:
		j.body(" %s", j.Model.Items[k].More)
	case cc.Void:
		if stars0 == 0 {
			todo(n)
		}

		j.body(" unsafe.Pointer")
		j.imports[idUnsafe] = struct{}{}
	case cc.Struct, cc.Union:
		// Use tag if available.
		if tag := t.Tag(); tag != 0 {
			nm := mangleTag(tag, true)
			j.qualifier(j.In.Declarations.Tags[tag].Node)
			j.body(" %s", xc.Dict.S(nm))
			break
		}

		// Use typedef name if available.
		if tdn := t.Declarator().RawSpecifier().TypedefName(); tdn != 0 {
			nm := mangleIdent(tdn, true)
			j.qualifier(j.In.Declarations.Identifiers[tdn].Node)
			j.body(" %s", xc.Dict.S(nm))
			break
		}

		j.body(" struct {")
		switch m, incomplete := t.Members(); {
		case incomplete:
			j.body("// Incomplete type\n_ byte")
		case t.Kind() == cc.Union:
			j.union(n, t)
			var f func(cc.Type)
			f = func(t cc.Type) {
				j.addTag(t)
				m, _ := t.Members()
				for _, v := range m {
					f(v.Type)
				}
			}
		default:
			for _, v := range m {
				if v.Bits != 0 {
					j.bits(n, v)
					continue
				}

				j.addTag(v.Type)
				id := v.Name
				nm := mangleIdent(id, true)
				j.body("\n%s", xc.Dict.S(nm))
				j.typ(v.Declarator, v.Type)
				if t := v.Type; t.Kind() != cc.Union && t.Kind() != cc.Struct {
					j.body("// %s", v.Type)
				}
			}
		}
		j.body("\n}")
	case cc.Function:
		j.body(" func")
		j.signature(n, t)
	case cc.Array:
		j.arrayType(n, t)
	default:
		todo(n, t, t.Kind())
	}
}