Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:58

0001 //===-- Stream.h ------------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_UTILITY_STREAM_H
0010 #define LLDB_UTILITY_STREAM_H
0011 
0012 #include "lldb/Utility/Flags.h"
0013 #include "lldb/lldb-defines.h"
0014 #include "lldb/lldb-enumerations.h"
0015 #include "llvm/ADT/StringRef.h"
0016 #include "llvm/Support/FormatVariadic.h"
0017 #include "llvm/Support/raw_ostream.h"
0018 
0019 #include <cstdarg>
0020 #include <cstddef>
0021 #include <cstdint>
0022 #include <type_traits>
0023 
0024 namespace lldb_private {
0025 
0026 /// \class Stream Stream.h "lldb/Utility/Stream.h"
0027 /// A stream class that can stream formatted output to a file.
0028 class Stream {
0029 public:
0030   /// \a m_flags bit values.
0031   enum {
0032     eBinary = (1 << 0) ///< Get and put data as binary instead of as the default
0033                        /// string mode.
0034   };
0035 
0036   /// Struct to store information for color highlighting in the stream.
0037   struct HighlightSettings {
0038     llvm::StringRef pattern; ///< Regex pattern for highlighting.
0039     llvm::StringRef prefix;  ///< ANSI color code to start colorization.
0040     llvm::StringRef suffix;  ///< ANSI color code to end colorization.
0041 
0042     HighlightSettings(llvm::StringRef p, llvm::StringRef pre,
0043                       llvm::StringRef suf)
0044         : pattern(p), prefix(pre), suffix(suf) {}
0045   };
0046 
0047   /// Utility class for counting the bytes that were written to a stream in a
0048   /// certain time span.
0049   ///
0050   /// \example
0051   ///   ByteDelta delta(*this);
0052   ///   WriteDataToStream("foo");
0053   ///   return *delta;
0054   class ByteDelta {
0055     Stream *m_stream;
0056     /// Bytes we have written so far when ByteDelta was created.
0057     size_t m_start;
0058 
0059   public:
0060     ByteDelta(Stream &s) : m_stream(&s), m_start(s.GetWrittenBytes()) {}
0061     /// Returns the number of bytes written to the given Stream since this
0062     /// ByteDelta object was created.
0063     size_t operator*() const { return m_stream->GetWrittenBytes() - m_start; }
0064   };
0065 
0066   /// Construct with flags and address size and byte order.
0067   ///
0068   /// Construct with dump flags \a flags and the default address size. \a
0069   /// flags can be any of the above enumeration logical OR'ed together.
0070   Stream(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order,
0071          bool colors = false);
0072 
0073   /// Construct a default Stream, not binary, host byte order and host addr
0074   /// size.
0075   ///
0076   Stream(bool colors = false);
0077 
0078   // FIXME: Streams should not be copyable.
0079   Stream(const Stream &other) : m_forwarder(*this) { (*this) = other; }
0080 
0081   Stream &operator=(const Stream &rhs) {
0082     m_flags = rhs.m_flags;
0083     m_addr_size = rhs.m_addr_size;
0084     m_byte_order = rhs.m_byte_order;
0085     m_indent_level = rhs.m_indent_level;
0086     return *this;
0087   }
0088 
0089   /// Destructor
0090   virtual ~Stream();
0091 
0092   // Subclasses must override these methods
0093 
0094   /// Flush the stream.
0095   ///
0096   /// Subclasses should flush the stream to make any output appear if the
0097   /// stream has any buffering.
0098   virtual void Flush() = 0;
0099 
0100   /// Output character bytes to the stream.
0101   ///
0102   /// Appends \a src_len characters from the buffer \a src to the stream.
0103   ///
0104   /// \param[in] src
0105   ///     A buffer containing at least \a src_len bytes of data.
0106   ///
0107   /// \param[in] src_len
0108   ///     A number of bytes to append to the stream.
0109   ///
0110   /// \return
0111   ///     The number of bytes that were appended to the stream.
0112   size_t Write(const void *src, size_t src_len) {
0113     size_t appended_byte_count = WriteImpl(src, src_len);
0114     m_bytes_written += appended_byte_count;
0115     return appended_byte_count;
0116   }
0117 
0118   size_t GetWrittenBytes() const { return m_bytes_written; }
0119 
0120   // Member functions
0121   size_t PutChar(char ch);
0122 
0123   /// Set the byte_order value.
0124   ///
0125   /// Sets the byte order of the data to extract. Extracted values will be
0126   /// swapped if necessary when decoding.
0127   ///
0128   /// \param[in] byte_order
0129   ///     The byte order value to use when extracting data.
0130   ///
0131   /// \return
0132   ///     The old byte order value.
0133   lldb::ByteOrder SetByteOrder(lldb::ByteOrder byte_order);
0134 
0135   /// Format a C string from a printf style format and variable arguments and
0136   /// encode and append the resulting C string as hex bytes.
0137   ///
0138   /// \param[in] format
0139   ///     A printf style format string.
0140   ///
0141   /// \param[in] ...
0142   ///     Any additional arguments needed for the printf format string.
0143   ///
0144   /// \return
0145   ///     The number of bytes that were appended to the stream.
0146   size_t PrintfAsRawHex8(const char *format, ...)
0147       __attribute__((__format__(__printf__, 2, 3)));
0148 
0149   /// Append an uint8_t value in the hexadecimal format to the stream.
0150   ///
0151   /// \param[in] uvalue
0152   ///     The value to append.
0153   ///
0154   /// \return
0155   ///     The number of bytes that were appended to the stream.
0156   size_t PutHex8(uint8_t uvalue);
0157 
0158   size_t PutNHex8(size_t n, uint8_t uvalue);
0159 
0160   size_t PutHex16(uint16_t uvalue,
0161                   lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
0162 
0163   size_t PutHex32(uint32_t uvalue,
0164                   lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
0165 
0166   size_t PutHex64(uint64_t uvalue,
0167                   lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
0168 
0169   size_t PutMaxHex64(uint64_t uvalue, size_t byte_size,
0170                      lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
0171   size_t PutFloat(float f,
0172                   lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
0173 
0174   size_t PutDouble(double d,
0175                    lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
0176 
0177   size_t PutLongDouble(long double ld,
0178                        lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
0179 
0180   size_t PutPointer(void *ptr);
0181 
0182   // Append \a src_len bytes from \a src to the stream as hex characters (two
0183   // ascii characters per byte of input data)
0184   size_t
0185   PutBytesAsRawHex8(const void *src, size_t src_len,
0186                     lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid,
0187                     lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid);
0188 
0189   // Append \a src_len bytes from \a s to the stream as binary data.
0190   size_t PutRawBytes(const void *s, size_t src_len,
0191                      lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid,
0192                      lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid);
0193 
0194   size_t PutStringAsRawHex8(llvm::StringRef s);
0195 
0196   /// Output a NULL terminated C string \a cstr to the stream \a s.
0197   ///
0198   /// \param[in] cstr
0199   ///     A NULL terminated C string.
0200   ///
0201   /// \return
0202   ///     A reference to this class so multiple things can be streamed
0203   ///     in one statement.
0204   Stream &operator<<(const char *cstr);
0205 
0206   Stream &operator<<(llvm::StringRef str);
0207 
0208   /// Output a pointer value \a p to the stream \a s.
0209   ///
0210   /// \param[in] p
0211   ///     A void pointer.
0212   ///
0213   /// \return
0214   ///     A reference to this class so multiple things can be streamed
0215   ///     in one statement.
0216   Stream &operator<<(const void *p);
0217 
0218   /// Output a character \a ch to the stream \a s.
0219   ///
0220   /// \param[in] ch
0221   ///     A printable character value.
0222   ///
0223   /// \return
0224   ///     A reference to this class so multiple things can be streamed
0225   ///     in one statement.
0226   Stream &operator<<(char ch);
0227 
0228   Stream &operator<<(uint8_t uval) = delete;
0229   Stream &operator<<(uint16_t uval) = delete;
0230   Stream &operator<<(uint32_t uval) = delete;
0231   Stream &operator<<(uint64_t uval) = delete;
0232   Stream &operator<<(int8_t sval) = delete;
0233   Stream &operator<<(int16_t sval) = delete;
0234   Stream &operator<<(int32_t sval) = delete;
0235   Stream &operator<<(int64_t sval) = delete;
0236 
0237   /// Output a C string to the stream.
0238   ///
0239   /// Print a C string \a cstr to the stream.
0240   ///
0241   /// \param[in] cstr
0242   ///     The string to be output to the stream.
0243   size_t PutCString(llvm::StringRef cstr);
0244 
0245   /// Output a C string to the stream with color highlighting.
0246   ///
0247   /// Print a C string \a text to the stream, applying color highlighting to
0248   /// the portions of the string that match the regex pattern \a pattern. The
0249   /// pattern is matched as many times as possible throughout the string. If \a
0250   /// pattern is nullptr, then no highlighting is applied.
0251   ///
0252   /// The highlighting is applied by enclosing the matching text in ANSI color
0253   /// codes. The \a prefix parameter specifies the ANSI code to start the color
0254   /// (the standard value is assumed to be 'ansi.fg.red', representing red
0255   /// foreground), and the \a suffix parameter specifies the ANSI code to end
0256   /// the color (the standard value is assumed to be 'ansi.normal', resetting to
0257   /// default text style). These constants should be defined appropriately in
0258   /// your environment.
0259   ///
0260   /// \param[in] text
0261   ///     The string to be output to the stream.
0262   ///
0263   /// \param[in] pattern
0264   ///     The regex pattern to match against the \a text string. Portions of \a
0265   ///     text matching this pattern will be colorized. If this parameter is
0266   ///     nullptr, highlighting is not performed.
0267   /// \param[in] prefix
0268   ///     The ANSI color code to start colorization. This is
0269   ///     environment-dependent.
0270   /// \param[in] suffix
0271   ///     The ANSI color code to end colorization. This is
0272   ///     environment-dependent.
0273 
0274   void PutCStringColorHighlighted(
0275       llvm::StringRef text,
0276       std::optional<HighlightSettings> settings = std::nullopt);
0277 
0278   /// Output and End of Line character to the stream.
0279   size_t EOL();
0280 
0281   /// Get the address size in bytes.
0282   ///
0283   /// \return
0284   ///     The size of an address in bytes that is used when outputting
0285   ///     address and pointer values to the stream.
0286   uint32_t GetAddressByteSize() const;
0287 
0288   /// The flags accessor.
0289   ///
0290   /// \return
0291   ///     A reference to the Flags member variable.
0292   Flags &GetFlags();
0293 
0294   /// The flags const accessor.
0295   ///
0296   /// \return
0297   ///     A const reference to the Flags member variable.
0298   const Flags &GetFlags() const;
0299 
0300   //// The byte order accessor.
0301   ////
0302   //// \return
0303   ////     The byte order.
0304   lldb::ByteOrder GetByteOrder() const;
0305 
0306   /// Get the current indentation level.
0307   ///
0308   /// \return
0309   ///     The current indentation level.
0310   unsigned GetIndentLevel() const;
0311 
0312   /// Indent the current line in the stream.
0313   ///
0314   /// Indent the current line using the current indentation level and print an
0315   /// optional string following the indentation spaces.
0316   ///
0317   /// \param[in] s
0318   ///     A string to print following the indentation.
0319   size_t Indent(llvm::StringRef s = "");
0320 
0321   /// Decrement the current indentation level.
0322   void IndentLess(unsigned amount = 2);
0323 
0324   /// Increment the current indentation level.
0325   void IndentMore(unsigned amount = 2);
0326 
0327   /// Output an offset value.
0328   ///
0329   /// Put an offset \a uval out to the stream using the printf format in \a
0330   /// format.
0331   ///
0332   /// \param[in] offset
0333   ///     The offset value.
0334   ///
0335   /// \param[in] format
0336   ///     The printf style format to use when outputting the offset.
0337   void Offset(uint32_t offset, const char *format = "0x%8.8x: ");
0338 
0339   /// Output printf formatted output to the stream.
0340   ///
0341   /// Print some formatted output to the stream.
0342   ///
0343   /// \param[in] format
0344   ///     A printf style format string.
0345   ///
0346   /// \param[in] ...
0347   ///     Variable arguments that are needed for the printf style
0348   ///     format string \a format.
0349   size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
0350 
0351   size_t PrintfVarArg(const char *format, va_list args);
0352 
0353   template <typename... Args> void Format(const char *format, Args &&... args) {
0354     PutCString(llvm::formatv(format, std::forward<Args>(args)...).str());
0355   }
0356 
0357   /// Output a quoted C string value to the stream.
0358   ///
0359   /// Print a double quoted NULL terminated C string to the stream using the
0360   /// printf format in \a format.
0361   ///
0362   /// \param[in] cstr
0363   ///     A NULL terminated C string value.
0364   ///
0365   /// \param[in] format
0366   ///     The optional C string format that can be overridden.
0367   void QuotedCString(const char *cstr, const char *format = "\"%s\"");
0368 
0369   /// Set the address size in bytes.
0370   ///
0371   /// \param[in] addr_size
0372   ///     The new size in bytes of an address to use when outputting
0373   ///     address and pointer values.
0374   void SetAddressByteSize(uint32_t addr_size);
0375 
0376   /// Set the current indentation level.
0377   ///
0378   /// \param[in] level
0379   ///     The new indentation level.
0380   void SetIndentLevel(unsigned level);
0381 
0382   /// Output a SLEB128 number to the stream.
0383   ///
0384   /// Put an SLEB128 \a uval out to the stream using the printf format in \a
0385   /// format.
0386   ///
0387   /// \param[in] uval
0388   ///     A uint64_t value that was extracted as a SLEB128 value.
0389   size_t PutSLEB128(int64_t uval);
0390 
0391   /// Output a ULEB128 number to the stream.
0392   ///
0393   /// Put an ULEB128 \a uval out to the stream using the printf format in \a
0394   /// format.
0395   ///
0396   /// \param[in] uval
0397   ///     A uint64_t value that was extracted as a ULEB128 value.
0398   size_t PutULEB128(uint64_t uval);
0399 
0400   /// Returns a raw_ostream that forwards the data to this Stream object.
0401   llvm::raw_ostream &AsRawOstream() {
0402     return m_forwarder;
0403   }
0404 
0405 protected:
0406   // Member variables
0407   Flags m_flags;        ///< Dump flags.
0408   uint32_t m_addr_size = 4; ///< Size of an address in bytes.
0409   lldb::ByteOrder
0410       m_byte_order;   ///< Byte order to use when encoding scalar types.
0411   unsigned m_indent_level = 0;     ///< Indention level.
0412   std::size_t m_bytes_written = 0; ///< Number of bytes written so far.
0413 
0414   void _PutHex8(uint8_t uvalue, bool add_prefix);
0415 
0416   /// Output character bytes to the stream.
0417   ///
0418   /// Appends \a src_len characters from the buffer \a src to the stream.
0419   ///
0420   /// \param[in] src
0421   ///     A buffer containing at least \a src_len bytes of data.
0422   ///
0423   /// \param[in] src_len
0424   ///     A number of bytes to append to the stream.
0425   ///
0426   /// \return
0427   ///     The number of bytes that were appended to the stream.
0428   virtual size_t WriteImpl(const void *src, size_t src_len) = 0;
0429 
0430   /// \class RawOstreamForward Stream.h "lldb/Utility/Stream.h"
0431   /// This is a wrapper class that exposes a raw_ostream interface that just
0432   /// forwards to an LLDB stream, allowing to reuse LLVM algorithms that take
0433   /// a raw_ostream within the LLDB code base.
0434   class RawOstreamForward : public llvm::raw_ostream {
0435     // Note: This stream must *not* maintain its own buffer, but instead
0436     // directly write everything to the internal Stream class. Without this,
0437     // we would run into the problem that the Stream written byte count would
0438     // differ from the actually written bytes by the size of the internal
0439     // raw_ostream buffer.
0440 
0441     Stream &m_target;
0442     void write_impl(const char *Ptr, size_t Size) override {
0443       m_target.Write(Ptr, Size);
0444     }
0445 
0446     uint64_t current_pos() const override {
0447       return m_target.GetWrittenBytes();
0448     }
0449 
0450   public:
0451     RawOstreamForward(Stream &target, bool colors = false)
0452         : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) {
0453       enable_colors(colors);
0454     }
0455   };
0456   RawOstreamForward m_forwarder;
0457 };
0458 
0459 /// Output an address value to this stream.
0460 ///
0461 /// Put an address \a addr out to the stream with optional \a prefix and \a
0462 /// suffix strings.
0463 ///
0464 /// \param[in] s
0465 ///     The output stream.
0466 ///
0467 /// \param[in] addr
0468 ///     An address value.
0469 ///
0470 /// \param[in] addr_size
0471 ///     Size in bytes of the address, used for formatting.
0472 ///
0473 /// \param[in] prefix
0474 ///     A prefix C string. If nullptr, no prefix will be output.
0475 ///
0476 /// \param[in] suffix
0477 ///     A suffix C string. If nullptr, no suffix will be output.
0478 void DumpAddress(llvm::raw_ostream &s, uint64_t addr, uint32_t addr_size,
0479                  const char *prefix = nullptr, const char *suffix = nullptr);
0480 
0481 /// Output an address range to this stream.
0482 ///
0483 /// Put an address range \a lo_addr - \a hi_addr out to the stream with
0484 /// optional \a prefix and \a suffix strings.
0485 ///
0486 /// \param[in] s
0487 ///     The output stream.
0488 ///
0489 /// \param[in] lo_addr
0490 ///     The start address of the address range.
0491 ///
0492 /// \param[in] hi_addr
0493 ///     The end address of the address range.
0494 ///
0495 /// \param[in] addr_size
0496 ///     Size in bytes of the address, used for formatting.
0497 ///
0498 /// \param[in] prefix
0499 ///     A prefix C string. If nullptr, no prefix will be output.
0500 ///
0501 /// \param[in] suffix
0502 ///     A suffix C string. If nullptr, no suffix will be output.
0503 void DumpAddressRange(llvm::raw_ostream &s, uint64_t lo_addr, uint64_t hi_addr,
0504                       uint32_t addr_size, const char *prefix = nullptr,
0505                       const char *suffix = nullptr);
0506 
0507 } // namespace lldb_private
0508 
0509 #endif // LLDB_UTILITY_STREAM_H