aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h
blob: 68f80e73b7241e642932ddf6671a143a4de39cd8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//===-- RichManglingContext.h -----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_CORE_RICHMANGLINGCONTEXT_H
#define LLDB_CORE_RICHMANGLINGCONTEXT_H

#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"

#include "lldb/Utility/ConstString.h"

#include "llvm/ADT/Any.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Demangle/Demangle.h"

namespace lldb_private {

/// Uniform wrapper for access to rich mangling information from different
/// providers. See Mangled::DemangleWithRichManglingInfo()
class RichManglingContext {
public:
  RichManglingContext() : m_provider(None), m_ipd_buf_size(2048) {
    m_ipd_buf = static_cast<char *>(std::malloc(m_ipd_buf_size));
    m_ipd_buf[0] = '\0';
  }

  ~RichManglingContext() { std::free(m_ipd_buf); }

  /// Use the ItaniumPartialDemangler to obtain rich mangling information from
  /// the given mangled name.
  bool FromItaniumName(ConstString mangled);

  /// Use the legacy language parser implementation to obtain rich mangling
  /// information from the given demangled name.
  bool FromCxxMethodName(ConstString demangled);

  /// If this symbol describes a constructor or destructor.
  bool IsCtorOrDtor() const;

  /// If this symbol describes a function.
  bool IsFunction() const;

  /// Get the base name of a function. This doesn't include trailing template
  /// arguments, ie "a::b<int>" gives "b". The result will overwrite the
  /// internal buffer. It can be obtained via GetBufferRef().
  void ParseFunctionBaseName();

  /// Get the context name for a function. For "a::b::c", this function returns
  /// "a::b". The result will overwrite the internal buffer. It can be obtained
  /// via GetBufferRef().
  void ParseFunctionDeclContextName();

  /// Get the entire demangled name. The result will overwrite the internal
  /// buffer. It can be obtained via GetBufferRef().
  void ParseFullName();

  /// Obtain a StringRef to the internal buffer that holds the result of the
  /// most recent ParseXy() operation. The next ParseXy() call invalidates it.
  llvm::StringRef GetBufferRef() const {
    assert(m_provider != None && "Initialize a provider first");
    return m_buffer;
  }

private:
  enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage };

  /// Selects the rich mangling info provider.
  InfoProvider m_provider;

  /// Reference to the buffer used for results of ParseXy() operations.
  llvm::StringRef m_buffer;

  /// Members for ItaniumPartialDemangler
  llvm::ItaniumPartialDemangler m_ipd;
  char *m_ipd_buf;
  size_t m_ipd_buf_size;

  /// Members for PluginCxxLanguage
  /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The
  /// respective header is in Plugins and including it from here causes cyclic
  /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp.
  llvm::Any m_cxx_method_parser;

  /// Clean up memory and set a new info provider for this instance.
  void ResetProvider(InfoProvider new_provider);

  /// Uniform handling of string buffers for ItaniumPartialDemangler.
  void processIPDStrResult(char *ipd_res, size_t res_len);

  /// Cast the given parser to the given type. Ideally we would have a type
  /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we
  /// can't access CPlusPlusLanguage::MethodName from within the header.
  template <class ParserT> static ParserT *get(llvm::Any parser) {
    assert(parser.hasValue());
    assert(llvm::any_isa<ParserT *>(parser));
    return llvm::any_cast<ParserT *>(parser);
  }
};

} // namespace lldb_private

#endif