1343171Sdim//===--- ItaniumManglingCanonicalizer.h -------------------------*- C++ -*-===//
2343171Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6343171Sdim//
7343171Sdim//===----------------------------------------------------------------------===//
8343171Sdim//
9343171Sdim// This file defines a class for computing equivalence classes of mangled names
10343171Sdim// given a set of equivalences between name fragments.
11343171Sdim//
12343171Sdim//===----------------------------------------------------------------------===//
13343171Sdim
14343171Sdim#ifndef LLVM_SUPPORT_ITANIUMMANGLINGCANONICALIZER_H
15343171Sdim#define LLVM_SUPPORT_ITANIUMMANGLINGCANONICALIZER_H
16343171Sdim
17343171Sdim#include "llvm/ADT/StringRef.h"
18343171Sdim
19343171Sdim#include <cstddef>
20343171Sdim
21343171Sdimnamespace llvm {
22343171Sdim/// Canonicalizer for mangled names.
23343171Sdim///
24343171Sdim/// This class allows specifying a list of "equivalent" manglings. For example,
25343171Sdim/// you can specify that Ss is equivalent to
26343171Sdim///   NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE
27343171Sdim/// and then manglings that refer to libstdc++'s 'std::string' will be
28343171Sdim/// considered equivalent to manglings that are the same except that they refer
29343171Sdim/// to libc++'s 'std::string'.
30343171Sdim///
31343171Sdim/// This can be used when data (eg, profiling data) is available for a version
32343171Sdim/// of a program built in a different configuration, with correspondingly
33343171Sdim/// different manglings.
34343171Sdimclass ItaniumManglingCanonicalizer {
35343171Sdimpublic:
36343171Sdim  ItaniumManglingCanonicalizer();
37343171Sdim  ItaniumManglingCanonicalizer(const ItaniumManglingCanonicalizer &) = delete;
38343171Sdim  void operator=(const ItaniumManglingCanonicalizer &) = delete;
39343171Sdim  ~ItaniumManglingCanonicalizer();
40343171Sdim
41343171Sdim  enum class EquivalenceError {
42343171Sdim    Success,
43343171Sdim
44343171Sdim    /// Both the equivalent manglings have already been used as components of
45343171Sdim    /// some other mangling we've looked at. It's too late to add this
46343171Sdim    /// equivalence.
47343171Sdim    ManglingAlreadyUsed,
48343171Sdim
49343171Sdim    /// The first equivalent mangling is invalid.
50343171Sdim    InvalidFirstMangling,
51343171Sdim
52343171Sdim    /// The second equivalent mangling is invalid.
53343171Sdim    InvalidSecondMangling,
54343171Sdim  };
55343171Sdim
56343171Sdim  enum class FragmentKind {
57343171Sdim    /// The mangling fragment is a <name> (or a predefined <substitution>).
58343171Sdim    Name,
59343171Sdim    /// The mangling fragment is a <type>.
60343171Sdim    Type,
61343171Sdim    /// The mangling fragment is an <encoding>.
62343171Sdim    Encoding,
63343171Sdim  };
64343171Sdim
65343171Sdim  /// Add an equivalence between \p First and \p Second. Both manglings must
66343171Sdim  /// live at least as long as the canonicalizer.
67343171Sdim  EquivalenceError addEquivalence(FragmentKind Kind, StringRef First,
68343171Sdim                                  StringRef Second);
69343171Sdim
70343171Sdim  using Key = uintptr_t;
71343171Sdim
72343171Sdim  /// Form a canonical key for the specified mangling. They key will be the
73343171Sdim  /// same for all equivalent manglings, and different for any two
74343171Sdim  /// non-equivalent manglings, but is otherwise unspecified.
75343171Sdim  ///
76343171Sdim  /// Returns Key() if (and only if) the mangling is not a valid Itanium C++
77343171Sdim  /// ABI mangling.
78343171Sdim  ///
79343171Sdim  /// The string denoted by Mangling must live as long as the canonicalizer.
80343171Sdim  Key canonicalize(StringRef Mangling);
81343171Sdim
82343171Sdim  /// Find a canonical key for the specified mangling, if one has already been
83343171Sdim  /// formed. Otherwise returns Key().
84343171Sdim  Key lookup(StringRef Mangling);
85343171Sdim
86343171Sdimprivate:
87343171Sdim  struct Impl;
88343171Sdim  Impl *P;
89343171Sdim};
90343171Sdim} // namespace llvm
91343171Sdim
92343171Sdim#endif // LLVM_SUPPORT_ITANIUMMANGLINGCANONICALIZER_H
93