1//===- ir_test.go - Tests for ir ------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file tests bindings for the ir component.
11//
12//===----------------------------------------------------------------------===//
13
14package llvm
15
16import (
17	"strings"
18	"testing"
19)
20
21func testAttribute(t *testing.T, name string) {
22	mod := NewModule("")
23	defer mod.Dispose()
24
25	ftyp := FunctionType(VoidType(), nil, false)
26	fn := AddFunction(mod, "foo", ftyp)
27
28	kind := AttributeKindID(name)
29	attr := mod.Context().CreateEnumAttribute(kind, 0)
30
31	fn.AddFunctionAttr(attr)
32	newattr := fn.GetEnumFunctionAttribute(kind)
33	if attr != newattr {
34		t.Errorf("got attribute mask %d, want %d", newattr, attr)
35	}
36
37	text := mod.String()
38	if !strings.Contains(text, " "+name+" ") {
39		t.Errorf("expected attribute '%s', got:\n%s", name, text)
40	}
41
42	fn.RemoveEnumFunctionAttribute(kind)
43	newattr = fn.GetEnumFunctionAttribute(kind)
44	if !newattr.IsNil() {
45		t.Errorf("got attribute mask %d, want 0", newattr)
46	}
47}
48
49func TestAttributes(t *testing.T) {
50	// Tests that our attribute constants haven't drifted from LLVM's.
51	attrTests := []string{
52		"sanitize_address",
53		"alwaysinline",
54		"builtin",
55		"byval",
56		"convergent",
57		"inalloca",
58		"inlinehint",
59		"inreg",
60		"jumptable",
61		"minsize",
62		"naked",
63		"nest",
64		"noalias",
65		"nobuiltin",
66		"nocapture",
67		"noduplicate",
68		"noimplicitfloat",
69		"noinline",
70		"nonlazybind",
71		"nonnull",
72		"noredzone",
73		"noreturn",
74		"nounwind",
75		"optnone",
76		"optsize",
77		"readnone",
78		"readonly",
79		"returned",
80		"returns_twice",
81		"signext",
82		"safestack",
83		"ssp",
84		"sspreq",
85		"sspstrong",
86		"sret",
87		"sanitize_thread",
88		"sanitize_memory",
89		"uwtable",
90		"zeroext",
91		"cold",
92		"nocf_check",
93	}
94
95	for _, name := range attrTests {
96		testAttribute(t, name)
97	}
98}
99
100func TestDebugLoc(t *testing.T) {
101	mod := NewModule("")
102	defer mod.Dispose()
103
104	ctx := mod.Context()
105
106	b := ctx.NewBuilder()
107	defer b.Dispose()
108
109	d := NewDIBuilder(mod)
110	defer func() {
111		d.Destroy()
112	}()
113	file := d.CreateFile("dummy_file", "dummy_dir")
114	voidInfo := d.CreateBasicType(DIBasicType{Name: "void"})
115	typeInfo := d.CreateSubroutineType(DISubroutineType{
116		File:       file,
117		Parameters: []Metadata{voidInfo},
118		Flags:      0,
119	})
120	scope := d.CreateFunction(file, DIFunction{
121		Name:         "foo",
122		LinkageName:  "foo",
123		Line:         10,
124		ScopeLine:    10,
125		Type:         typeInfo,
126		File:         file,
127		IsDefinition: true,
128	})
129
130	b.SetCurrentDebugLocation(10, 20, scope, Metadata{})
131	loc := b.GetCurrentDebugLocation()
132	if loc.Line != 10 {
133		t.Errorf("Got line %d, though wanted 10", loc.Line)
134	}
135	if loc.Col != 20 {
136		t.Errorf("Got column %d, though wanted 20", loc.Col)
137	}
138	if loc.Scope.C != scope.C {
139		t.Errorf("Got metadata %v as scope, though wanted %v", loc.Scope.C, scope.C)
140	}
141}
142
143func TestSubtypes(t *testing.T) {
144	cont := NewContext()
145	defer cont.Dispose()
146
147	int_pointer := PointerType(cont.Int32Type(), 0)
148	int_inner := int_pointer.Subtypes()
149	if len(int_inner) != 1 {
150		t.Errorf("Got size %d, though wanted 1", len(int_inner))
151	}
152	if int_inner[0] != cont.Int32Type() {
153		t.Errorf("Expected int32 type")
154	}
155
156	st_pointer := cont.StructType([]Type{cont.Int32Type(), cont.Int8Type()}, false)
157	st_inner := st_pointer.Subtypes()
158	if len(st_inner) != 2 {
159		t.Errorf("Got size %d, though wanted 2", len(int_inner))
160	}
161	if st_inner[0] != cont.Int32Type() {
162		t.Errorf("Expected first struct field to be int32")
163	}
164	if st_inner[1] != cont.Int8Type() {
165		t.Errorf("Expected second struct field to be int8")
166	}
167}
168