Pro tip: If your function takes a StringBuilder by value, it doesn't
actually append anything to the caller's StringBuilder. On the plus
side, I probably won't make this mistake for a while? I hope?
This commit updates the Clang toolchain's version to 13.0.0, which comes
with better C++20 support and improved handling of new features by
clang-format. Due to the newly enabled `-Bsymbolic-functions` flag, our
Clang binaries will only be 2-4% slower than if we dynamically linked
them, but we save hundreds of megabytes of disk space.
The `BuildClang.sh` script has been reworked to build the entire
toolchain in just three steps: one for the compiler, one for GNU
binutils, and one for the runtime libraries. This reduces the complexity
of the build script, and will allow us to modify the CI configuration to
only rebuild the libraries when our libc headers change.
Most of the compile flags have been moved out to a separate CMake cache
file, similarly to how the Android and Fuchsia toolchains are
implemented within the LLVM repo. This provides a nicer interface than
the heaps of command-line arguments.
We no longer build separate toolchains for each architecture, as the
same Clang binary can compile code for multiple targets.
The horrible mess that `SERENITY_CLANG_ARCH` was, has been removed in
this commit. Clang happily accepts an `i686-pc-serenity` target triple,
which matches what our GCC toolchain accepts.
Previously we rejected all entries from Loader.so even if the faulting
address was located in it, i.e. the actual issue was with the dynamic
loader. We no longer do that to make debugging Loader crashes easier.
Our implementation (naively) assumes that there is a one-to-one
correspondence between compilation units and line programs, and that
their orders are identical. This is not the case for embedded resources,
as Clang only creates line programs for it, but not compilation units.
This mismatch caused an assertion failure, which made generating
backtraces for GUI applications impossible. This commit introduces a
hack that skips creating CompilationUnit objects for LinePrograms that
come from embedded resources.
These forms were introduced in DWARF5, and have a fair deal of
advantages over the more traditional encodings: they reduce the size of
the binary and the number of relocations.
GCC does not emit these with `-g1` by default, but Clang does at all
debug levels.
This will be needed when we add `DW_FORM_strx*` and `DW_FORM_addrx*`
support, which requires us to fetch `DW_AT_str_offsets_base` and
`DW_AT_addr_base` attributes from the parent compilation unit. This
can't be done as we read the values, because it would create infinite
recursion (as we might try to parse the compilation unit's
`DW_FORM_strx*` encoded name before we get to the attribute). Having
getters ensures that we will perform lookups if they are needed.
Our Clang toolchain uses versioned names for its shared libraries,
meaning that our applications link against `libc++.so.1.0`, not simply
`libc++.so`. Without this change, the LLVM runtime libraries are
excluded from backtraces, which makes debugging toolchain issues harder.
The `wcsxfrm` function copies a wide character string into a buffer,
such that comparing the new string against any similarly pre-processed
string with `wcscmp` produces the same result as if the original strings
were compared with `wcscoll`.
Our current `wcscoll` implementation is simply an alias for `wcscmp`, so
`wcsxfrm` needs to perform no actions other than copying the string.
The ELAST macro is used on many systems to refer to the largest possible
valid errno value. LLVM's libc++ uses errno values of ELAST+1 and
ELAST+2 internally, and defines an arbitrary fallback value for
platforms which don't have the macro. This means that it's possible for
their internal errno numbers could coincide with values we actually use,
which would be a very bad thing.
Note our Attribute class is what the spec refers to as just "Attr". The
main differences between the existing implementation and the spec are
just that the spec defines more fields.
Attributes can contain namespace URIs and prefixes. However, note that
these are not parsed in HTML documents unless the document content-type
is XML. So for now, these are initialized to null. Web pages are able to
set the namespace via JavaScript (setAttributeNS), so these fields may
be filled in when the corresponding APIs are implemented.
The main change to be aware of is that an attribute is a node. This has
implications on how attributes are stored in the Element class. Nodes
are non-copyable and non-movable because these constructors are deleted
by the EventTarget base class. This means attributes cannot be stored in
a Vector or HashMap as these containers assume copyability / movability.
So for now, the Vector holding attributes is changed to hold RefPtrs to
attributes instead. This might change when attribute storage is
implemented according to the spec (by way of NamedNodeMap).
I originally implemented this as something to use the new sequence
wrapper, however, after having a look at uses with grep.app, it's used
often, for example:
- Bootstrap 5 Dropdowns
- Polymer
- Angular
- Closure
Previously, when the last layer got deleted, the active layer was
set to nullptr, causing a crash.
Now, we create a new transparent background layer with the image
dimensions instead.
We want to check the last SimpleSelector, not the first one. We don't
have to check that a SimpleSelector exists since a CompoundSelector
without one is invalid.
Also, renamed `builder` to `s` to match spec comments, and fixed a
find-and-replace typo where some pseudo-class names were
"last-of-pseudo_class" instead of "last-of-type".
This implements these algorithms from the CSSOM-1 spec:
- serialize a string
- serialize a URL
Also, we now have two versions of each of the serialization functions:
One that returns a String as before, and the other that takes a
StringBuilder to write into. This saves creating extra StringBuilders
when they are not needed. :^)