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