| //===- 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", |
| "inlinehint", |
| "inreg", |
| "jumptable", |
| "minsize", |
| "naked", |
| "nest", |
| "noalias", |
| "nobuiltin", |
| "nocapture", |
| "noduplicate", |
| "noimplicitfloat", |
| "noinline", |
| "nonlazybind", |
| "nonnull", |
| "noredzone", |
| "noreturn", |
| "nounwind", |
| "nosanitize_coverage", |
| "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") |
| } |
| } |