Demangle.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. //===--- Demangle.h - Interface to Swift symbol demangling ------*- C++ -*-===//
  2. //
  3. // This source file is part of the Swift.org open source project
  4. //
  5. // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
  6. // Licensed under Apache License v2.0 with Runtime Library Exception
  7. //
  8. // See https://swift.org/LICENSE.txt for license information
  9. // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
  10. //
  11. //===----------------------------------------------------------------------===//
  12. //
  13. // This file is the public API of the demangler library.
  14. // Tools which use the demangler library (like lldb) must include this - and
  15. // only this - header file.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef SWIFT_DEMANGLING_DEMANGLE_H
  19. #define SWIFT_DEMANGLING_DEMANGLE_H
  20. #include <memory>
  21. #include <string>
  22. #include <cassert>
  23. #include <cstdint>
  24. #include <functional>
  25. #include "StringRef.h"
  26. #include "Config.h"
  27. namespace llvm {
  28. class raw_ostream;
  29. }
  30. namespace swift {
  31. namespace Demangle {
  32. enum class SymbolicReferenceKind : uint8_t;
  33. struct DemangleOptions {
  34. bool SynthesizeSugarOnTypes = false;
  35. bool DisplayDebuggerGeneratedModule = true;
  36. bool QualifyEntities = true;
  37. bool DisplayExtensionContexts = true;
  38. bool DisplayUnmangledSuffix = true;
  39. bool DisplayModuleNames = true;
  40. bool DisplayGenericSpecializations = true;
  41. bool DisplayProtocolConformances = true;
  42. bool DisplayWhereClauses = true;
  43. bool DisplayEntityTypes = true;
  44. bool ShortenPartialApply = false;
  45. bool ShortenThunk = false;
  46. bool ShortenValueWitness = false;
  47. bool ShortenArchetype = false;
  48. bool ShowPrivateDiscriminators = true;
  49. bool ShowFunctionArgumentTypes = true;
  50. DemangleOptions() {}
  51. static DemangleOptions SimplifiedUIDemangleOptions() {
  52. auto Opt = DemangleOptions();
  53. Opt.SynthesizeSugarOnTypes = true;
  54. Opt.QualifyEntities = true;
  55. Opt.DisplayExtensionContexts = false;
  56. Opt.DisplayUnmangledSuffix = false;
  57. Opt.DisplayModuleNames = false;
  58. Opt.DisplayGenericSpecializations = false;
  59. Opt.DisplayProtocolConformances = false;
  60. Opt.DisplayWhereClauses = false;
  61. Opt.DisplayEntityTypes = false;
  62. Opt.ShortenPartialApply = true;
  63. Opt.ShortenThunk = true;
  64. Opt.ShortenValueWitness = true;
  65. Opt.ShortenArchetype = true;
  66. Opt.ShowPrivateDiscriminators = false;
  67. Opt.ShowFunctionArgumentTypes = false;
  68. return Opt;
  69. };
  70. };
  71. class Node;
  72. using NodePointer = Node *;
  73. enum class FunctionSigSpecializationParamKind : unsigned {
  74. // Option Flags use bits 0-5. This give us 6 bits implying 64 entries to
  75. // work with.
  76. ConstantPropFunction = 0,
  77. ConstantPropGlobal = 1,
  78. ConstantPropInteger = 2,
  79. ConstantPropFloat = 3,
  80. ConstantPropString = 4,
  81. ClosureProp = 5,
  82. BoxToValue = 6,
  83. BoxToStack = 7,
  84. // Option Set Flags use bits 6-31. This gives us 26 bits to use for option
  85. // flags.
  86. Dead = 1 << 6,
  87. OwnedToGuaranteed = 1 << 7,
  88. SROA = 1 << 8,
  89. GuaranteedToOwned = 1 << 9,
  90. ExistentialToGeneric = 1 << 10,
  91. };
  92. /// The pass that caused the specialization to occur. We use this to make sure
  93. /// that two passes that generate similar changes do not yield the same
  94. /// mangling. This currently cannot happen, so this is just a safety measure
  95. /// that creates separate name spaces.
  96. enum class SpecializationPass : uint8_t {
  97. AllocBoxToStack,
  98. ClosureSpecializer,
  99. CapturePromotion,
  100. CapturePropagation,
  101. FunctionSignatureOpts,
  102. GenericSpecializer,
  103. };
  104. static inline char encodeSpecializationPass(SpecializationPass Pass) {
  105. return char(uint8_t(Pass)) + '0';
  106. }
  107. enum class ValueWitnessKind {
  108. #define VALUE_WITNESS(MANGLING, NAME) \
  109. NAME,
  110. #include "ValueWitnessMangling.def"
  111. };
  112. enum class Directness {
  113. Direct, Indirect
  114. };
  115. class NodeFactory;
  116. class Context;
  117. class Node {
  118. public:
  119. enum class Kind : uint16_t {
  120. #define NODE(ID) ID,
  121. #include "DemangleNodes.def"
  122. };
  123. using IndexType = uint64_t;
  124. friend class NodeFactory;
  125. private:
  126. Kind NodeKind;
  127. enum class PayloadKind : uint8_t {
  128. None, Text, Index
  129. };
  130. PayloadKind NodePayloadKind;
  131. union {
  132. llvm::StringRef TextPayload;
  133. IndexType IndexPayload;
  134. };
  135. NodePointer *Children = nullptr;
  136. size_t NumChildren = 0;
  137. size_t ReservedChildren = 0;
  138. Node(Kind k)
  139. : NodeKind(k), NodePayloadKind(PayloadKind::None) {
  140. }
  141. Node(Kind k, llvm::StringRef t)
  142. : NodeKind(k), NodePayloadKind(PayloadKind::Text) {
  143. TextPayload = t;
  144. }
  145. Node(Kind k, IndexType index)
  146. : NodeKind(k), NodePayloadKind(PayloadKind::Index) {
  147. IndexPayload = index;
  148. }
  149. Node(const Node &) = delete;
  150. Node &operator=(const Node &) = delete;
  151. public:
  152. Kind getKind() const { return NodeKind; }
  153. bool hasText() const { return NodePayloadKind == PayloadKind::Text; }
  154. llvm::StringRef getText() const {
  155. assert(hasText());
  156. return TextPayload;
  157. }
  158. bool hasIndex() const { return NodePayloadKind == PayloadKind::Index; }
  159. uint64_t getIndex() const {
  160. assert(hasIndex());
  161. return IndexPayload;
  162. }
  163. using iterator = NodePointer *;
  164. using const_iterator = const NodePointer *;
  165. using size_type = size_t;
  166. bool hasChildren() const { return NumChildren != 0; }
  167. size_t getNumChildren() const { return NumChildren; }
  168. iterator begin() { return Children; }
  169. iterator end() { return Children + NumChildren; }
  170. const_iterator begin() const { return Children; }
  171. const_iterator end() const { return Children + NumChildren; }
  172. NodePointer getFirstChild() const {
  173. assert(NumChildren >= 1);
  174. return Children[0];
  175. }
  176. NodePointer getChild(size_t index) const {
  177. assert(NumChildren > index);
  178. return Children[index];
  179. }
  180. // inline void addChild(NodePointer Child, Context &Ctx);
  181. // Only to be used by the demangler parsers.
  182. void addChild(NodePointer Child, NodeFactory &Factory);
  183. // Only to be used by the demangler parsers.
  184. void removeChildAt(unsigned Pos, NodeFactory &factory);
  185. // Reverses the order of children.
  186. void reverseChildren(size_t StartingAt = 0);
  187. /// Prints the whole node tree in readable form to stderr.
  188. ///
  189. /// Useful to be called from the debugger.
  190. void dump();
  191. };
  192. /// Returns the length of the swift mangling prefix of the \p SymbolName.
  193. ///
  194. /// Returns 0 if \p SymbolName is not a mangled swift (>= swift 4.x) name.
  195. int getManglingPrefixLength(llvm::StringRef mangledName);
  196. /// Returns true if \p SymbolName is a mangled swift name.
  197. ///
  198. /// This does not include the old (<= swift 3.x) mangling prefix "_T".
  199. inline bool isMangledName(llvm::StringRef mangledName) {
  200. return getManglingPrefixLength(mangledName) != 0;
  201. }
  202. /// Returns true if the mangledName starts with the swift mangling prefix.
  203. ///
  204. /// This includes the old (<= swift 3.x) mangling prefix "_T".
  205. bool isSwiftSymbol(llvm::StringRef mangledName);
  206. /// Returns true if the mangledName starts with the swift mangling prefix.
  207. ///
  208. /// This includes the old (<= swift 3.x) mangling prefix "_T".
  209. bool isSwiftSymbol(const char *mangledName);
  210. /// Drops the Swift mangling prefix from the given mangled name, if there is
  211. /// one.
  212. ///
  213. /// This does not include the old (<= swift 3.x) mangling prefix "_T".
  214. llvm::StringRef dropSwiftManglingPrefix(llvm::StringRef mangledName);
  215. /// Returns true if the mangled name is an alias type name.
  216. ///
  217. /// \param mangledName A null-terminated string containing a mangled name.
  218. bool isAlias(llvm::StringRef mangledName);
  219. /// Returns true if the mangled name is a class type name.
  220. ///
  221. /// \param mangledName A null-terminated string containing a mangled name.
  222. bool isClass(llvm::StringRef mangledName);
  223. /// Returns true if the mangled name is an enum type name.
  224. ///
  225. /// \param mangledName A null-terminated string containing a mangled name.
  226. bool isEnum(llvm::StringRef mangledName);
  227. /// Returns true if the mangled name is a protocol type name.
  228. ///
  229. /// \param mangledName A null-terminated string containing a mangled name.
  230. bool isProtocol(llvm::StringRef mangledName);
  231. /// Returns true if the mangled name is a structure type name.
  232. ///
  233. /// \param mangledName A null-terminated string containing a mangled name.
  234. bool isStruct(llvm::StringRef mangledName);
  235. /// Returns true if the mangled name is an Objective-C symbol.
  236. ///
  237. /// \param mangledName A null-terminated string containing a mangled name.
  238. bool isObjCSymbol(llvm::StringRef mangledName);
  239. /// Returns true if the mangled name has the old scheme of function type
  240. /// mangling where labels are part of the type.
  241. ///
  242. /// \param mangledName A null-terminated string containing a mangled name.
  243. bool isOldFunctionTypeMangling(llvm::StringRef mangledName);
  244. class Demangler;
  245. /// The demangler context.
  246. ///
  247. /// It owns the allocated nodes which are created during demangling.
  248. /// It is always preferable to use the demangling via this context class as it
  249. /// ensures efficient memory management. Especially if demangling is done for
  250. /// multiple symbols. Typical usage:
  251. /// \code
  252. /// Context Ctx;
  253. /// for (...) {
  254. /// NodePointer Root = Ctx.demangleSymbolAsNode(MangledName);
  255. /// // Do something with Root
  256. /// Ctx.clear(); // deallocates Root
  257. /// }
  258. /// \endcode
  259. /// Declaring the context out of the loop minimizes the amount of needed memory
  260. /// allocations.
  261. ///
  262. class Context {
  263. Demangler *D;
  264. friend class Node;
  265. public:
  266. Context();
  267. ~Context();
  268. /// Demangle the given symbol and return the parse tree.
  269. ///
  270. /// \param MangledName The mangled symbol string, which start a mangling
  271. /// prefix: _T, _T0, $S, _$S.
  272. ///
  273. /// \returns A parse tree for the demangled string - or a null pointer
  274. /// on failure.
  275. /// The lifetime of the returned node tree ends with the lifetime of the
  276. /// context or with a call of clear().
  277. NodePointer demangleSymbolAsNode(llvm::StringRef MangledName);
  278. /// Demangle the given type and return the parse tree.
  279. ///
  280. /// \param MangledName The mangled symbol string, which start a mangling
  281. /// prefix: _T, _T0, $S, _$S.
  282. ///
  283. /// \returns A parse tree for the demangled string - or a null pointer
  284. /// on failure.
  285. /// The lifetime of the returned node tree ends with the lifetime of the
  286. /// context or with a call of clear().
  287. NodePointer demangleTypeAsNode(llvm::StringRef MangledName);
  288. /// Demangle the given symbol and return the readable name.
  289. ///
  290. /// \param MangledName The mangled symbol string, which start a mangling
  291. /// prefix: _T, _T0, $S, _$S.
  292. ///
  293. /// \returns The demangled string.
  294. std::string demangleSymbolAsString(llvm::StringRef MangledName,
  295. const DemangleOptions &Options = DemangleOptions());
  296. /// Demangle the given type and return the readable name.
  297. ///
  298. /// \param MangledName The mangled type string, which does _not_ start with
  299. /// a mangling prefix.
  300. ///
  301. /// \returns The demangled string.
  302. std::string demangleTypeAsString(llvm::StringRef MangledName,
  303. const DemangleOptions &Options = DemangleOptions());
  304. /// Returns true if the mangledName refers to a thunk function.
  305. ///
  306. /// Thunk functions are either (ObjC) partial apply forwarder, swift-as-ObjC
  307. /// or ObjC-as-swift thunks or allocating init functions.
  308. bool isThunkSymbol(llvm::StringRef MangledName);
  309. /// Returns the mangled name of the target of a thunk.
  310. ///
  311. /// \returns Returns the remaining name after removing the thunk mangling
  312. /// characters from \p MangledName. If \p MangledName is not a thunk symbol
  313. /// or the thunk target cannot be derived from the mangling, an empty string
  314. /// is returned.
  315. std::string getThunkTarget(llvm::StringRef MangledName);
  316. /// Returns true if the \p mangledName refers to a function which conforms to
  317. /// the Swift calling convention.
  318. ///
  319. /// The return value is unspecified if the \p MangledName does not refer to a
  320. /// function symbol.
  321. bool hasSwiftCallingConvention(llvm::StringRef MangledName);
  322. /// Deallocates all nodes.
  323. ///
  324. /// The memory which is used for nodes is not freed but recycled for the next
  325. /// demangling operation.
  326. void clear();
  327. };
  328. /// Standalone utility function to demangle the given symbol as string.
  329. ///
  330. /// If performance is an issue when demangling multiple symbols,
  331. /// Context::demangleSymbolAsString should be used instead.
  332. /// \param mangledName The mangled name string pointer.
  333. /// \param mangledNameLength The length of the mangledName string.
  334. /// \returns The demangled string.
  335. std::string
  336. demangleSymbolAsString(const char *mangledName, size_t mangledNameLength,
  337. const DemangleOptions &options = DemangleOptions());
  338. /// Standalone utility function to demangle the given symbol as string.
  339. ///
  340. /// If performance is an issue when demangling multiple symbols,
  341. /// Context::demangleSymbolAsString should be used instead.
  342. /// \param mangledName The mangled name string.
  343. /// \returns The demangled string.
  344. inline std::string
  345. demangleSymbolAsString(const std::string &mangledName,
  346. const DemangleOptions &options = DemangleOptions()) {
  347. return demangleSymbolAsString(mangledName.data(), mangledName.size(),
  348. options);
  349. }
  350. /// Standalone utility function to demangle the given symbol as string.
  351. ///
  352. /// If performance is an issue when demangling multiple symbols,
  353. /// Context::demangleSymbolAsString should be used instead.
  354. /// \param MangledName The mangled name string.
  355. /// \returns The demangled string.
  356. // inline std::string
  357. // demangleSymbolAsString(llvm::StringRef MangledName,
  358. // const DemangleOptions &Options = DemangleOptions()) {
  359. // return demangleSymbolAsString(MangledName.data(),
  360. // MangledName.size(), Options);
  361. // }
  362. /// Standalone utility function to demangle the given type as string.
  363. ///
  364. /// If performance is an issue when demangling multiple symbols,
  365. /// Context::demangleTypeAsString should be used instead.
  366. /// \param mangledName The mangled name string pointer.
  367. /// \param mangledNameLength The length of the mangledName string.
  368. /// \returns The demangled string.
  369. std::string
  370. demangleTypeAsString(const char *mangledName, size_t mangledNameLength,
  371. const DemangleOptions &options = DemangleOptions());
  372. /// Standalone utility function to demangle the given type as string.
  373. ///
  374. /// If performance is an issue when demangling multiple symbols,
  375. /// Context::demangleTypeAsString should be used instead.
  376. /// \param mangledName The mangled name string.
  377. /// \returns The demangled string.
  378. inline std::string
  379. demangleTypeAsString(const std::string &mangledName,
  380. const DemangleOptions &options = DemangleOptions()) {
  381. return demangleTypeAsString(mangledName.data(), mangledName.size(), options);
  382. }
  383. /// Standalone utility function to demangle the given type as string.
  384. ///
  385. /// If performance is an issue when demangling multiple symbols,
  386. /// Context::demangleTypeAsString should be used instead.
  387. /// \param MangledName The mangled name string.
  388. /// \returns The demangled string.
  389. inline std::string
  390. demangleTypeAsString(llvm::StringRef MangledName,
  391. const DemangleOptions &Options = DemangleOptions()) {
  392. return demangleTypeAsString(MangledName.data(),
  393. MangledName.size(), Options);
  394. }
  395. enum class OperatorKind {
  396. NotOperator,
  397. Prefix,
  398. Postfix,
  399. Infix,
  400. };
  401. /// Mangle an identifier using Swift's mangling rules.
  402. void mangleIdentifier(const char *data, size_t length,
  403. OperatorKind operatorKind, std::string &out,
  404. bool usePunycode = true);
  405. // /// Remangle a demangled parse tree.
  406. // ///
  407. // /// This should always round-trip perfectly with demangleSymbolAsNode.
  408. // std::string mangleNode(NodePointer root);
  409. //
  410. // using SymbolicResolver =
  411. // llvm::function_ref<Demangle::NodePointer (SymbolicReferenceKind,
  412. // const void *)>;
  413. //
  414. // /// Remangle a demangled parse tree, using a callback to resolve
  415. // /// symbolic references.
  416. // ///
  417. // /// This should always round-trip perfectly with demangleSymbolAsNode.
  418. // std::string mangleNode(NodePointer root, SymbolicResolver resolver);
  419. //
  420. // /// Remangle in the old mangling scheme.
  421. // ///
  422. // /// This is only used for objc-runtime names and should be removed as soon as
  423. // /// we switch to the new mangling for those names as well.
  424. // std::string mangleNodeOld(NodePointer root);
  425. //
  426. /// Transform the node structure to a string.
  427. ///
  428. /// Typical usage:
  429. /// \code
  430. /// std::string aDemangledName =
  431. /// swift::Demangler::nodeToString(aNode)
  432. /// \endcode
  433. ///
  434. /// \param Root A pointer to a parse tree generated by the demangler.
  435. /// \param Options An object encapsulating options to use to perform this demangling.
  436. ///
  437. /// \returns A string representing the demangled name.
  438. ///
  439. std::string nodeToString(NodePointer Root,
  440. const DemangleOptions &Options = DemangleOptions());
  441. /// A class for printing to a std::string.
  442. class DemanglerPrinter {
  443. public:
  444. DemanglerPrinter() = default;
  445. DemanglerPrinter &operator<<(llvm::StringRef Value) & {
  446. Stream.append(Value.data(), Value.size());
  447. return *this;
  448. }
  449. DemanglerPrinter &operator<<(char c) & {
  450. Stream.push_back(c);
  451. return *this;
  452. }
  453. DemanglerPrinter &operator<<(unsigned long long n) &;
  454. DemanglerPrinter &operator<<(long long n) &;
  455. DemanglerPrinter &operator<<(unsigned long n) & {
  456. return *this << (unsigned long long)n;
  457. }
  458. DemanglerPrinter &operator<<(long n) & {
  459. return *this << (long long)n;
  460. }
  461. DemanglerPrinter &operator<<(unsigned n) & {
  462. return *this << (unsigned long long)n;
  463. }
  464. DemanglerPrinter &operator<<(int n) & {
  465. return *this << (long long)n;
  466. }
  467. template<typename T>
  468. DemanglerPrinter &&operator<<(T &&x) && {
  469. return std::move(*this << std::forward<T>(x));
  470. }
  471. DemanglerPrinter &writeHex(unsigned long long n) &;
  472. std::string &&str() && { return std::move(Stream); }
  473. llvm::StringRef getStringRef() const { return Stream; }
  474. /// Shrinks the buffer.
  475. void resetSize(size_t toPos) {
  476. assert(toPos <= Stream.size());
  477. Stream.resize(toPos);
  478. }
  479. private:
  480. std::string Stream;
  481. };
  482. /// Returns a the node kind \p k as string.
  483. const char *getNodeKindString(swift::Demangle::Node::Kind k);
  484. /// Prints the whole node tree \p Root in readable form into a std::string.
  485. ///
  486. /// Useful for debugging.
  487. std::string getNodeTreeAsString(NodePointer Root);
  488. bool nodeConsumesGenericArgs(Node *node);
  489. bool isSpecialized(Node *node);
  490. NodePointer getUnspecialized(Node *node, NodeFactory &Factory);
  491. std::string archetypeName(Node::IndexType index, Node::IndexType depth);
  492. /// Form a StringRef around the mangled name starting at base, if the name may
  493. /// contain symbolic references.
  494. llvm::StringRef makeSymbolicMangledNameStringRef(const char *base);
  495. } // end namespace Demangle
  496. } // end namespace swift
  497. // NB: This function is not used directly in the Swift codebase, but is
  498. // exported for Xcode support and is used by the sanitizers. Please coordinate
  499. // before changing.
  500. //
  501. /// Demangles a Swift symbol name.
  502. ///
  503. /// \param mangledName is the symbol name that needs to be demangled.
  504. /// \param mangledNameLength is the length of the string that should be
  505. /// demangled.
  506. /// \param outputBuffer is the user provided buffer where the demangled name
  507. /// will be placed. If nullptr, a new buffer will be malloced. In that case,
  508. /// the user of this API is responsible for freeing the returned buffer.
  509. /// \param outputBufferSize is the size of the output buffer. If the demangled
  510. /// name does not fit into the outputBuffer, the output will be truncated and
  511. /// the size will be updated, indicating how large the buffer should be.
  512. /// \param flags can be used to select the demangling style. TODO: We should
  513. //// define what these will be.
  514. /// \returns the demangled name. Returns nullptr if the input String is not a
  515. /// Swift mangled name.
  516. SWIFT_RUNTIME_EXPORT
  517. char *swift_demangle(const char *mangledName,
  518. size_t mangledNameLength,
  519. char *outputBuffer,
  520. size_t *outputBufferSize,
  521. uint32_t flags);
  522. #endif // SWIFT_DEMANGLING_DEMANGLE_H