Po sześciu miesiącach rozwoju zostaje zaprezentowane wydanie projektu LLVM 16.0 — zestawu narzędzi kompatybilnego z GCC (kompilatory, optymalizatory i generatory kodu), który kompiluje programy w pośredni kod bitowy instrukcji wirtualnych podobnych do RISC (maszyna wirtualna niskiego poziomu z wielopoziomowy system optymalizacji). Wygenerowany pseudokod może zostać przekształcony przez kompilator JIT w instrukcje maszynowe w momencie wykonywania programu.
Główne ulepszenia w Clang 16.0:
- Domyślny standard C++/ObjC++ jest ustawiony na gnu++17 (wcześniej gnu++14), co oznacza domyślnie obsługę funkcji C++17 z rozszerzeniami GNU. Możesz użyć opcji „-std=gnu++14”, aby powrócić do poprzedniego zachowania.
- Zaimplementowane zaawansowane funkcje związane ze standardem C++20:
- Warunkowo trywialne specjalne funkcje składowe,
- przechwytywanie powiązań strukturalnych w funkcjach lambda,
- Operator równości wewnątrz wyrażeń,
- Możliwość nie określania słowa kluczowego typename w niektórych kontekstach,
- Dopuszczalność inicjalizacji agregatu w nawiasach („Aggr(val1, val2)”).
- Zaimplementowane funkcje zdefiniowane w przyszłym standardzie C++2b:
- Etykiety są dozwolone na końcu wyrażeń złożonych,
- operator statyczny(),
- operator statyczny [],
- Zapewniona kompatybilność z typem char8_t,
- Zakres znaków dozwolonych w "\N{...}" został rozszerzony,
- Dodano możliwość używania zmiennych zadeklarowanych jako "static constexpr" w funkcjach zadeklarowanych jako constexpr.
- Zaimplementowane funkcje zdefiniowane w przyszłym standardzie C2x C:
- Aby wyłączyć ostrzeżenie „-Wunused-label”, można zastosować atrybut „[[maybe_unused]]” do etykiet
- Etykiety można umieszczać w dowolnym miejscu wewnątrz wyrażeń złożonych,
- Dodano operatory typeof i typeof_unqual,
- Nowy typ nullptr_t i stała nullptr do definiowania wskaźników o wartości null, które można przekonwertować na dowolny typ wskaźnika, i reprezentują wariant wartości NULL, który nie jest powiązany z typami całkowitymi i wartością void*.
- W trybie C2x dozwolone jest wywołanie makra va_start ze zmienną liczbą argumentów (variadic).
- W trybach zgodności C99, C11 i C17 opcje „-Wimplicit-function-declaration” i „-Wimplicit-int” domyślnie generują teraz błąd zamiast ostrzeżenia.
- Pośrednie użycie "void *" (na przykład "void func(void *p) { *p; }") w trybie C++ generuje teraz błąd, podobny do ISO C++, GCC, ICC i MSVC.
- Określanie pól bitowych jako operandów instrukcji (np. „__asm { mov eax, s.bf }”) w blokach asemblera inline w stylu firmy Microsoft generuje teraz błąd.
- Dodano diagnostykę obecności różnych struktur i związków o tych samych nazwach w różnych modułach.
- Rozszerzone możliwości związane z obsługą OpenCL i OpenMP. Ulepszona diagnostyka szablonów C++ używanych w argumentach jądra OpenCL. Ulepszona obsługa bloków kolejkowania dla AMDGPU. Atrybut nounwind jest niejawnie dodawany do wszystkich funkcji. Ulepszona obsługa wbudowanych funkcji.
- Zapewniono możliwość użycia zmiennej środowiskowej CLANG_CRASH_DIAGNOSTICS_DIR do zdefiniowania katalogu, w którym zapisywane są dane diagnostyczne awarii.
- Obsługa Unicode została zaktualizowana do specyfikacji Unicode 15.0. Niektóre symbole matematyczne są dozwolone w identyfikatorach, takie jak „₊” (na przykład „double xₖ₊₁”).
- Dodano obsługę ładowania wielu plików konfiguracyjnych (najpierw ładowane są domyślne pliki konfiguracyjne, a następnie te określone za pomocą flagi „--config=”, którą można teraz określić wielokrotnie). Zmieniono domyślną kolejność ładowania pliku konfiguracyjnego: clang próbuje najpierw załadować plik - .cfg i jeśli nie zostanie znaleziony, spróbuje załadować dwa pliki .cfg i cfg. Dodano flagę „--no-default-config”, aby domyślnie wyłączyć ładowanie plików konfiguracyjnych.
- Aby zapewnić powtarzalność kompilacji, możliwe jest zastąpienie aktualnych wartości daty i czasu w makrach __DATE__, __TIME__ i __TIMESTAMP__ czasem określonym w zmiennej środowiskowej SOURCE_DATE_EPOCH.
- Aby sprawdzić wbudowane funkcje (wbudowane), których można użyć w kontekście stałych, dodano makro „__has_constexpr_builtin”.
- Dodano nową flagę kompilacji „-fcoro-aligned-allocation” dla wyrównanej alokacji ramek współprogramu.
- Flaga "-fstrict-flex-arrays=" implementuje obsługę trzeciego poziomu sprawdzania elastycznego elementu tablicy w strukturach (Flexible Array Members, tablica o nieokreślonym rozmiarze na końcu struktury). Na trzecim poziomie tylko rozmiar „[]” (na przykład „int b[]”) jest traktowany jako tablica elastyczna, ale rozmiar „[0]” (na przykład „int b[0]”) nie jest.
- Dodano flagę „-fmodule-output”, aby włączyć model kompilacji jednofazowej dla standardowych modułów C++.
- Dodano tryb „-Rpass-analysis=stack-frame-layout”, który umożliwia diagnozowanie problemów z układem ramek stosu.
- Dodano nowy atrybut __attribute__((target_version("cpu_features"))) oraz rozszerzono funkcjonalność atrybutu __attribute__((target_clones("cpu_features1″,"cpu_features2",…))) w celu wybrania określonych wersji dostarczonych funkcji przez procesor AArch64.
- Udoskonalone narzędzia diagnostyczne:
- Dodano ostrzeżenie „-Wsingle-bit-bitfield-constant-conversion”, aby wykryć niejawne obcięcie podczas przypisywania jednego do jednobitowego pola bitowego ze znakiem.
- Rozszerzona diagnostyka niezainicjowanych zmiennych constexpr.
- Dodano ostrzeżenia „-Wcast-function-type-strict” i „-Win Compatible-function-pointer-types-strict” w celu wykrycia potencjalnych problemów z rzutowaniem typów funkcji.
- Dodano diagnostykę używania nieprawidłowych lub zarezerwowanych nazw modułów w blokach eksportu.
- Poprawione wykrywanie brakujących słów kluczowych „auto” w definicjach.
- Dodano sprawdzanie dodatkowych sytuacji przepełnienia do implementacji ostrzeżenia „-Winteger-overflow”.
- Zaimplementowano obsługę architektury zestawu instrukcji LoongArch (-march=loongarch64 lub -march=la464) używanej w procesorach Loongson 3 5000, która implementuje nowy RISC ISA podobny do MIPS i RISC-V.
Kluczowe innowacje w LLVM 16.0:
- W kodzie LLVM dozwolone jest stosowanie elementów zdefiniowanych w standardzie C++17.
- Zwiększone wymagania środowiskowe dla budowania LLVM. Zestaw narzędzi do budowania powinien teraz obsługiwać standard C++ 17, tj. kompilacja wymaga co najmniej GCC 7.1, Clang 5.0, Apple Clang 10.0 lub Visual Studio 2019 16.7.
- Do backendu AArch64 dodano obsługę procesorów Cortex-A715, Cortex-X3 i Neoverse V2, asemblera RME MEC (Memory Encryption Contexts), rozszerzeń Armv8.3 (Complex Number) i Function Multi Versioning.
- Backend architektury ARM nie obsługuje już platform docelowych Armv2, Armv2A, Armv3 i Armv3M, dla których nie było zagwarantowane poprawne generowanie kodu. Dodano możliwość generowania kodu instrukcji do pracy z liczbami zespolonymi.
- Dodano obsługę architektur zestawu instrukcji (ISA) AMX-FP86, CMPCXADD, AVX-IFMA, AVX-VNNI-INT16, AVX-NE-CONVERT do zaplecza X8. Dodano obsługę instrukcji RDMSRLIST, RMSRLIST i WRMSRNS. Zaimplementowano opcje "-mcpu=raptorlake", "-mcpu=meteorlake", "-mcpu=emeraldrapids", "-mcpu=sierraforest", "-mcpu=graniterapids" i "-mcpu=grandridge".
- Dodano oficjalne wsparcie dla platformy LoongArch.
- Ulepszone backendy dla architektur MIPS, PowerPC i RISC-V
- Do debugera LLDB dodano obsługę debugowania 64-bitowych plików wykonywalnych dla architektury LoongArch. Poprawiona obsługa symboli debugowania COFF. Dodano filtrowanie zduplikowanych bibliotek DLL na liście załadowanych modułów systemu Windows.
- W bibliotece Libc++ główne prace koncentrowały się na implementacji obsługi nowych funkcji standardów C++20 i C++23.
- Czas łączenia został znacznie skrócony w konsolidatorze LDD dzięki zrównolegleniu skanowania relokacji adresów i operacji inicjalizacji sekcji. Dodano obsługę kompresji sekcji przy użyciu algorytmu ZSTD.
Źródło: opennet.ru