165 lines
3.7 KiB
Go
165 lines
3.7 KiB
Go
|
//===- ir_test.go - Tests for ir ------------------------------------------===//
|
||
|
//
|
||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
//
|
||
|
// This file tests bindings for the ir component.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
package llvm
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
func testAttribute(t *testing.T, name string) {
|
||
|
mod := NewModule("")
|
||
|
defer mod.Dispose()
|
||
|
|
||
|
ftyp := FunctionType(VoidType(), nil, false)
|
||
|
fn := AddFunction(mod, "foo", ftyp)
|
||
|
|
||
|
kind := AttributeKindID(name)
|
||
|
attr := mod.Context().CreateEnumAttribute(kind, 0)
|
||
|
|
||
|
fn.AddFunctionAttr(attr)
|
||
|
newattr := fn.GetEnumFunctionAttribute(kind)
|
||
|
if attr != newattr {
|
||
|
t.Errorf("got attribute %p, want %p", newattr.C, attr.C)
|
||
|
}
|
||
|
|
||
|
text := mod.String()
|
||
|
if !strings.Contains(text, " "+name+" ") {
|
||
|
t.Errorf("expected attribute '%s', got:\n%s", name, text)
|
||
|
}
|
||
|
|
||
|
fn.RemoveEnumFunctionAttribute(kind)
|
||
|
newattr = fn.GetEnumFunctionAttribute(kind)
|
||
|
if !newattr.IsNil() {
|
||
|
t.Errorf("got attribute %p, want 0", newattr.C)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestAttributes(t *testing.T) {
|
||
|
// Tests that our attribute constants haven't drifted from LLVM's.
|
||
|
attrTests := []string{
|
||
|
"sanitize_address",
|
||
|
"alwaysinline",
|
||
|
"builtin",
|
||
|
"convergent",
|
||
|
"inalloca",
|
||
|
"inlinehint",
|
||
|
"inreg",
|
||
|
"jumptable",
|
||
|
"minsize",
|
||
|
"naked",
|
||
|
"nest",
|
||
|
"noalias",
|
||
|
"nobuiltin",
|
||
|
"nocapture",
|
||
|
"noduplicate",
|
||
|
"noimplicitfloat",
|
||
|
"noinline",
|
||
|
"nonlazybind",
|
||
|
"nonnull",
|
||
|
"noredzone",
|
||
|
"noreturn",
|
||
|
"nounwind",
|
||
|
"optnone",
|
||
|
"optsize",
|
||
|
"readnone",
|
||
|
"readonly",
|
||
|
"returned",
|
||
|
"returns_twice",
|
||
|
"signext",
|
||
|
"safestack",
|
||
|
"ssp",
|
||
|
"sspreq",
|
||
|
"sspstrong",
|
||
|
"sanitize_thread",
|
||
|
"sanitize_memory",
|
||
|
"uwtable",
|
||
|
"zeroext",
|
||
|
"cold",
|
||
|
"nocf_check",
|
||
|
}
|
||
|
|
||
|
for _, name := range attrTests {
|
||
|
testAttribute(t, name)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestDebugLoc(t *testing.T) {
|
||
|
mod := NewModule("")
|
||
|
defer mod.Dispose()
|
||
|
|
||
|
ctx := mod.Context()
|
||
|
|
||
|
b := ctx.NewBuilder()
|
||
|
defer b.Dispose()
|
||
|
|
||
|
d := NewDIBuilder(mod)
|
||
|
defer func() {
|
||
|
d.Destroy()
|
||
|
}()
|
||
|
file := d.CreateFile("dummy_file", "dummy_dir")
|
||
|
voidInfo := d.CreateBasicType(DIBasicType{Name: "void"})
|
||
|
typeInfo := d.CreateSubroutineType(DISubroutineType{
|
||
|
File: file,
|
||
|
Parameters: []Metadata{voidInfo},
|
||
|
Flags: 0,
|
||
|
})
|
||
|
scope := d.CreateFunction(file, DIFunction{
|
||
|
Name: "foo",
|
||
|
LinkageName: "foo",
|
||
|
Line: 10,
|
||
|
ScopeLine: 10,
|
||
|
Type: typeInfo,
|
||
|
File: file,
|
||
|
IsDefinition: true,
|
||
|
})
|
||
|
|
||
|
b.SetCurrentDebugLocation(10, 20, scope, Metadata{})
|
||
|
loc := b.GetCurrentDebugLocation()
|
||
|
if loc.Line != 10 {
|
||
|
t.Errorf("Got line %d, though wanted 10", loc.Line)
|
||
|
}
|
||
|
if loc.Col != 20 {
|
||
|
t.Errorf("Got column %d, though wanted 20", loc.Col)
|
||
|
}
|
||
|
if loc.Scope.C != scope.C {
|
||
|
t.Errorf("Got metadata %v as scope, though wanted %v", loc.Scope.C, scope.C)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestSubtypes(t *testing.T) {
|
||
|
cont := NewContext()
|
||
|
defer cont.Dispose()
|
||
|
|
||
|
int_pointer := PointerType(cont.Int32Type(), 0)
|
||
|
int_inner := int_pointer.Subtypes()
|
||
|
if len(int_inner) != 1 {
|
||
|
t.Errorf("Got size %d, though wanted 1", len(int_inner))
|
||
|
}
|
||
|
if int_inner[0] != cont.Int32Type() {
|
||
|
t.Errorf("Expected int32 type")
|
||
|
}
|
||
|
|
||
|
st_pointer := cont.StructType([]Type{cont.Int32Type(), cont.Int8Type()}, false)
|
||
|
st_inner := st_pointer.Subtypes()
|
||
|
if len(st_inner) != 2 {
|
||
|
t.Errorf("Got size %d, though wanted 2", len(int_inner))
|
||
|
}
|
||
|
if st_inner[0] != cont.Int32Type() {
|
||
|
t.Errorf("Expected first struct field to be int32")
|
||
|
}
|
||
|
if st_inner[1] != cont.Int8Type() {
|
||
|
t.Errorf("Expected second struct field to be int8")
|
||
|
}
|
||
|
}
|