xref: /freebsd-src/contrib/llvm-project/llvm/include/llvm/ProfileData/ItaniumManglingCanonicalizer.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1*06c3fb27SDimitry Andric //===--- ItaniumManglingCanonicalizer.h -------------------------*- C++ -*-===//
2*06c3fb27SDimitry Andric //
3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*06c3fb27SDimitry Andric //
7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
8*06c3fb27SDimitry Andric //
9*06c3fb27SDimitry Andric // This file defines a class for computing equivalence classes of mangled names
10*06c3fb27SDimitry Andric // given a set of equivalences between name fragments.
11*06c3fb27SDimitry Andric //
12*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
13*06c3fb27SDimitry Andric 
14*06c3fb27SDimitry Andric #ifndef LLVM_PROFILEDATA_ITANIUMMANGLINGCANONICALIZER_H
15*06c3fb27SDimitry Andric #define LLVM_PROFILEDATA_ITANIUMMANGLINGCANONICALIZER_H
16*06c3fb27SDimitry Andric 
17*06c3fb27SDimitry Andric #include <cstdint>
18*06c3fb27SDimitry Andric 
19*06c3fb27SDimitry Andric namespace llvm {
20*06c3fb27SDimitry Andric 
21*06c3fb27SDimitry Andric class StringRef;
22*06c3fb27SDimitry Andric 
23*06c3fb27SDimitry Andric /// Canonicalizer for mangled names.
24*06c3fb27SDimitry Andric ///
25*06c3fb27SDimitry Andric /// This class allows specifying a list of "equivalent" manglings. For example,
26*06c3fb27SDimitry Andric /// you can specify that Ss is equivalent to
27*06c3fb27SDimitry Andric ///   NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE
28*06c3fb27SDimitry Andric /// and then manglings that refer to libstdc++'s 'std::string' will be
29*06c3fb27SDimitry Andric /// considered equivalent to manglings that are the same except that they refer
30*06c3fb27SDimitry Andric /// to libc++'s 'std::string'.
31*06c3fb27SDimitry Andric ///
32*06c3fb27SDimitry Andric /// This can be used when data (eg, profiling data) is available for a version
33*06c3fb27SDimitry Andric /// of a program built in a different configuration, with correspondingly
34*06c3fb27SDimitry Andric /// different manglings.
35*06c3fb27SDimitry Andric class ItaniumManglingCanonicalizer {
36*06c3fb27SDimitry Andric public:
37*06c3fb27SDimitry Andric   ItaniumManglingCanonicalizer();
38*06c3fb27SDimitry Andric   ItaniumManglingCanonicalizer(const ItaniumManglingCanonicalizer &) = delete;
39*06c3fb27SDimitry Andric   void operator=(const ItaniumManglingCanonicalizer &) = delete;
40*06c3fb27SDimitry Andric   ~ItaniumManglingCanonicalizer();
41*06c3fb27SDimitry Andric 
42*06c3fb27SDimitry Andric   enum class EquivalenceError {
43*06c3fb27SDimitry Andric     Success,
44*06c3fb27SDimitry Andric 
45*06c3fb27SDimitry Andric     /// Both the equivalent manglings have already been used as components of
46*06c3fb27SDimitry Andric     /// some other mangling we've looked at. It's too late to add this
47*06c3fb27SDimitry Andric     /// equivalence.
48*06c3fb27SDimitry Andric     ManglingAlreadyUsed,
49*06c3fb27SDimitry Andric 
50*06c3fb27SDimitry Andric     /// The first equivalent mangling is invalid.
51*06c3fb27SDimitry Andric     InvalidFirstMangling,
52*06c3fb27SDimitry Andric 
53*06c3fb27SDimitry Andric     /// The second equivalent mangling is invalid.
54*06c3fb27SDimitry Andric     InvalidSecondMangling,
55*06c3fb27SDimitry Andric   };
56*06c3fb27SDimitry Andric 
57*06c3fb27SDimitry Andric   enum class FragmentKind {
58*06c3fb27SDimitry Andric     /// The mangling fragment is a <name> (or a predefined <substitution>).
59*06c3fb27SDimitry Andric     Name,
60*06c3fb27SDimitry Andric     /// The mangling fragment is a <type>.
61*06c3fb27SDimitry Andric     Type,
62*06c3fb27SDimitry Andric     /// The mangling fragment is an <encoding>.
63*06c3fb27SDimitry Andric     Encoding,
64*06c3fb27SDimitry Andric   };
65*06c3fb27SDimitry Andric 
66*06c3fb27SDimitry Andric   /// Add an equivalence between \p First and \p Second. Both manglings must
67*06c3fb27SDimitry Andric   /// live at least as long as the canonicalizer.
68*06c3fb27SDimitry Andric   EquivalenceError addEquivalence(FragmentKind Kind, StringRef First,
69*06c3fb27SDimitry Andric                                   StringRef Second);
70*06c3fb27SDimitry Andric 
71*06c3fb27SDimitry Andric   using Key = uintptr_t;
72*06c3fb27SDimitry Andric 
73*06c3fb27SDimitry Andric   /// Form a canonical key for the specified mangling. They key will be the
74*06c3fb27SDimitry Andric   /// same for all equivalent manglings, and different for any two
75*06c3fb27SDimitry Andric   /// non-equivalent manglings, but is otherwise unspecified.
76*06c3fb27SDimitry Andric   ///
77*06c3fb27SDimitry Andric   /// Returns Key() if (and only if) the mangling is not a valid Itanium C++
78*06c3fb27SDimitry Andric   /// ABI mangling.
79*06c3fb27SDimitry Andric   ///
80*06c3fb27SDimitry Andric   /// The string denoted by Mangling must live as long as the canonicalizer.
81*06c3fb27SDimitry Andric   Key canonicalize(StringRef Mangling);
82*06c3fb27SDimitry Andric 
83*06c3fb27SDimitry Andric   /// Find a canonical key for the specified mangling, if one has already been
84*06c3fb27SDimitry Andric   /// formed. Otherwise returns Key().
85*06c3fb27SDimitry Andric   Key lookup(StringRef Mangling);
86*06c3fb27SDimitry Andric 
87*06c3fb27SDimitry Andric private:
88*06c3fb27SDimitry Andric   struct Impl;
89*06c3fb27SDimitry Andric   Impl *P;
90*06c3fb27SDimitry Andric };
91*06c3fb27SDimitry Andric } // namespace llvm
92*06c3fb27SDimitry Andric 
93*06c3fb27SDimitry Andric #endif // LLVM_PROFILEDATA_ITANIUMMANGLINGCANONICALIZER_H
94