mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-05 19:43:44 +00:00
all: add LLVM 22 support
Builder: - Update clang.cpp for LLVM 22 API changes: DiagnosticOptions is no longer ref-counted, TextDiagnosticPrinter and DiagnosticsEngine take references instead of pointers, createDiagnostics() signature changed. - Update cc1as.cpp: clang/Driver/Options.h moved to clang/Options/Options.h, namespace changed from clang::driver::options to clang::options, MCInstPrinter now passed as unique_ptr. - Add new LLVM 22 libraries to GNUmakefile: clangAnalysisLifetimeSafety, clangOptions, LLVMDTLTO, and dtlto component. - Add llvm22 build tag to all build/test commands. CGo: - Handle CXType_Unexposed in libclang.go by resolving via canonical type. LLVM 22 reports builtin type aliases (e.g. __size_t) as Unexposed instead of Typedef. - Always make C typedefs into Go type aliases. LLVM 22 changed getTypedefDeclUnderlyingType to return CXType_Enum directly instead of wrapping in an elaborated type. Compileopts: - Add build-tag-guarded ClangTriple() to substitute wasm32-unknown-wasi with wasm32-unknown-wasip1 for LLVM 22 (deprecated triple). - Add build-tag-guarded patchFeatures() to map renamed Xtensa features (atomctl, memctl, timerint, esp32s3) for LLVM 22. Targets: - Remove -zca from RISC-V target feature strings (esp32c3, esp32c6, fe310, k210, riscv-qemu, tkey). LLVM 22 now implies +zca from +c. - Remove -zcd from k210. LLVM 22 now implies +zcd from +c,+d. Tests: - Change TestClangAttributes to check individual feature flags instead of exact string match, allowing new LLVM features without failures. - Update TestBinarySize expected values for LLVM 22 codegen. Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
+60
-3
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
@@ -128,8 +129,10 @@ func testClangAttributes(t *testing.T, options *compileopts.Options) {
|
||||
defer mod.Dispose()
|
||||
|
||||
// Check whether the LLVM target matches.
|
||||
if mod.Target() != config.Triple() {
|
||||
t.Errorf("target has LLVM triple %#v but Clang makes it LLVM triple %#v", config.Triple(), mod.Target())
|
||||
// Use ClangTriple since LLVM 22 normalizes wasm32-unknown-wasi to wasip1.
|
||||
expectedTriple := compileopts.ClangTriple(config.Triple())
|
||||
if mod.Target() != expectedTriple {
|
||||
t.Errorf("target has LLVM triple %#v but Clang makes it LLVM triple %#v", expectedTriple, mod.Target())
|
||||
}
|
||||
|
||||
// Check the "target-cpu" and "target-features" string attribute of the add
|
||||
@@ -153,11 +156,65 @@ func testClangAttributes(t *testing.T, options *compileopts.Options) {
|
||||
// The reason is that Debian has patched Clang in a way that
|
||||
// modifies the LLVM features string, changing lots of FPU/float
|
||||
// related flags. We want to test vanilla Clang, not Debian Clang.
|
||||
t.Errorf("target has LLVM features\n\t%#v\nbut Clang makes it\n\t%#v", config.Features(), features)
|
||||
//
|
||||
// Rather than requiring an exact match (which breaks across LLVM
|
||||
// versions as new features are added), check that every feature
|
||||
// TinyGo specifies is consistent with what Clang produces:
|
||||
// - A "+feature" in TinyGo must appear in Clang's output.
|
||||
// - A "-feature" in TinyGo must not be "+feature" in Clang's output.
|
||||
checkFeatureFlags(t, config.Features(), features)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// checkFeatureFlags verifies that all features specified by TinyGo's target
|
||||
// configuration are consistent with Clang's output. This allows Clang to add
|
||||
// new features across LLVM versions without breaking the test.
|
||||
func checkFeatureFlags(t *testing.T, targetFeatures, clangFeatures string) {
|
||||
t.Helper()
|
||||
|
||||
// Build a set of Clang's features for fast lookup.
|
||||
clangSet := make(map[string]bool) // feature name -> enabled
|
||||
for _, f := range strings.Split(clangFeatures, ",") {
|
||||
f = strings.TrimSpace(f)
|
||||
if len(f) < 2 {
|
||||
continue
|
||||
}
|
||||
enabled := f[0] == '+'
|
||||
name := f[1:]
|
||||
clangSet[name] = enabled
|
||||
}
|
||||
|
||||
// Check each feature that TinyGo specifies.
|
||||
var missing, conflicts []string
|
||||
for _, f := range strings.Split(targetFeatures, ",") {
|
||||
f = strings.TrimSpace(f)
|
||||
if len(f) < 2 {
|
||||
continue
|
||||
}
|
||||
wantEnabled := f[0] == '+'
|
||||
name := f[1:]
|
||||
|
||||
clangEnabled, inClang := clangSet[name]
|
||||
if wantEnabled && (!inClang || !clangEnabled) {
|
||||
// TinyGo requires +feature but Clang doesn't enable it.
|
||||
missing = append(missing, f)
|
||||
} else if !wantEnabled && inClang && clangEnabled {
|
||||
// TinyGo requires -feature but Clang enables it.
|
||||
conflicts = append(conflicts, fmt.Sprintf("target has %q but Clang has %q", f, "+"+name))
|
||||
}
|
||||
}
|
||||
|
||||
if len(missing) > 0 {
|
||||
t.Errorf("target specifies features not present in Clang output: %s\n\ttarget features: %s\n\tclang features: %s",
|
||||
strings.Join(missing, ", "), targetFeatures, clangFeatures)
|
||||
}
|
||||
if len(conflicts) > 0 {
|
||||
t.Errorf("target disables features that Clang enables: %s",
|
||||
strings.Join(conflicts, "; "))
|
||||
}
|
||||
}
|
||||
|
||||
// This TestMain is necessary because TinyGo may also be invoked to run certain
|
||||
// LLVM tools in a separate process. Not capturing these invocations would lead
|
||||
// to recursive tests.
|
||||
|
||||
Reference in New Issue
Block a user