summaryrefslogtreecommitdiff
path: root/lldb/source/Core/IOHandler.cpp
AgeCommit message (Collapse)Author
2025-10-08[lldb] Ignore trailing spaces on quit confirmation (#162263)Ebuka Ezike
2025-09-23[lldb] Rework how we pass the execution context to the statusline (#159887)Jonas Devlieghere
Currently, we always pass the "selected" execution context to the statusline. When handling a process or thread event, we can be more precise, and build an execution context from the event data. This PR also adopts the new `StoppedExecutionContext` that was recently introduced.
2025-06-30[lldb] Correctly restore the cursor column after resizing the statusline ↵Jonas Devlieghere
(#146132) This PR ensures we correctly restore the cursor column after resizing the statusline. To ensure we have space for the statusline, we have to emit a newline to move up everything on screen. The newline causes the cursor to move to the start of the next line, which needs to be undone. Normally, we would use escape codes to save & restore the cursor position, but that doesn't work here, as the cursor position may have (purposely) changed. Instead, we move the cursor up one line using an escape code, but we weren't restoring the column. Interestingly, Editline was able to recover from this issue through the LineInfo struct which contains the buffer and the cursor location, which allows us to compute the column. This PR addresses the bug by having Editline "refresh" the cursor position. Fixes #134064
2025-04-22[lldb] Fix use-color settings not persistent (#135626)Ebuka Ezike
Fixes https://github.com/llvm/llvm-project/issues/22981 If `settings set use-color` is changed when lldb is running it does not take effect. This is fixes that. --------- Signed-off-by: Ebuka Ezike <yerimyah1@gmail.com> Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
2025-03-26[lldb] Implement a statusline in LLDB (#121860)Jonas Devlieghere
Add a statusline to command-line LLDB to display information about the current state of the debugger. The statusline is a dedicated area displayed at the bottom of the screen. The information displayed is configurable through a setting consisting of LLDB’s format strings. Enablement ---------- The statusline is enabled by default, but can be disabled with the following setting: ``` (lldb) settings set show-statusline false ``` Configuration ------------- The statusline is configurable through the `statusline-format` setting. The default configuration shows the target name, the current file, the stop reason and any ongoing progress events. ``` (lldb) settings show statusline-format statusline-format (format-string) = "${ansi.bg.blue}${ansi.fg.black}{${target.file.basename}}{ | ${line.file.basename}:${line.number}:${line.column}}{ | ${thread.stop-reason}}{ | {${progress.count} }${progress.message}}" ``` The statusline supersedes the current progress reporting implementation. Consequently, the following settings no longer have any effect (but continue to exist to not break anyone's `.lldbinit`): ``` show-progress -- Whether to show progress or not if the debugger's output is an interactive color-enabled terminal. show-progress-ansi-prefix -- When displaying progress in a color-enabled terminal, use the ANSI terminal code specified in this format immediately before the progress message. show-progress-ansi-suffix -- When displaying progress in a color-enabled terminal, use the ANSI terminal code specified in this format immediately after the progress message. ``` Format Strings -------------- LLDB's format strings are documented in the LLDB documentation and on the website: https://lldb.llvm.org/use/formatting.html#format-strings. The current implementation is relatively limited but various improvements have been discussed in the RFC. One such improvement is being to display a string when a format string is empty. Right now, when launching LLDB without a target, the statusline will be empty, which is expected, but looks rather odd. RFC --- The full RFC can be found on Discourse: https://discourse.llvm.org/t/rfc-lldb-statusline/83948
2025-02-19[lldb] Synchronize the debuggers output & error streamsJonas Devlieghere
This patch improves the synchronization of the debugger's output and error streams using two new abstractions: `LockableStreamFile` and `LockedStreamFile`. - `LockableStreamFile` is a wrapper around a `StreamFile` and a mutex. Client cannot use the `StreamFile` without calling `Lock`, which returns a `LockedStreamFile`. - `LockedStreamFile` is an RAII object that locks the stream for the duration of its existence. As long as you hold on to the returned object you are permitted to write to the stream. The destruction of the object automatically flush the output stream.
2025-01-21[lldb] Support format string in the prompt (#123430)Jonas Devlieghere
Implement ansi::StripAnsiTerminalCodes and fix a long standing bug where using format strings in lldb's prompt resulted in an incorrect prompt column width.
2023-09-13[lldb] Simplify color logic in (IOHandler)Editline (NFC)Jonas Devlieghere
This patch simplifies the color handling logic in Editline and IOHandlerEditline: - Remove the m_color_prompts property from Editline and use the prompt ANSI prefix and suffix as the single source of truth. This avoids having to redraw the prompt unnecessarily, for example when colors are enabled but the prompt prefix and suffix are empty. - Rename m_color_prompts to just m_color in IOHandlerEditline and use it to ensure consistency between colored prompts and colored auto-suggestions. Some IOHandler explicitly turn off colors (such as IOHandlerConfirm) and it doesn't really make sense to have one or the other.
2023-09-13[lldb] Add a setting to customize the prompt color (#66218)Jonas Devlieghere
Users often want to change the look of their prompt and currently the only way to do that is by using ANSI escape codes in the prompt itself. This is not only tedious, it also results in extra whitespace because our Editline wrapper, when computing the cursor column, doesn't ignore the invisible escape codes. We already have various *-ansi-{prefix,suffix} settings that allow the users to customize the color of auto-suggestions and progress events, using mnemonics like ${ansi.fg.yellow}. This patch brings the same mechanism to the prompt. rdar://115390406
2023-09-01[LLDB] Fix IOHandlerEditline::GetCurrentLines()walter erquinigo
This method was working as expected if LLDB_ENABLE_LIBEDIT is false, however, if it was true, then the variable m_current_lines_ptr was always pointing to an empty list, because Editline only updates its contents once the full input has been completed (see https://github.com/llvm/llvm-project/blob/main/lldb/source/Host/common/Editline.cpp#L1576). A simple fix is to invoke Editline::GetInputAsStringList() from GetCurrentLines(), which is already used in many places as the common way to get the full input list.
2023-08-09[lldb] Sink StreamFile into lldbHostAlex Langford
StreamFile subclasses Stream (from lldbUtility) and is backed by a File (from lldbHost). It does not depend on anything from lldbCore or any of its sibling libraries, so I think it makes sense for this to live in lldbHost instead. Differential Revision: https://reviews.llvm.org/D157460
2023-06-06[lldb/Commands] Add support to auto-completion for user commandsMed Ismail Bennani
This patch should allow the user to set specific auto-completion type for their custom commands. To do so, we had to hoist the `CompletionType` enum so the user can access it and add a new completion type flag to the CommandScriptAdd Command Object. So now, the user can specify which completion type will be used with their custom command, when they register it. This also makes the `crashlog` custom commands use disk-file completion type, to browse through the user file system and load the report. Differential Revision: https://reviews.llvm.org/D152011 Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2023-01-07[lldb] Remove remaining uses of llvm::Optional (NFC)Kazu Hirata
This patch removes the unused "using" declarations, updates comments, and removes #include "llvm/ADT/Optional.h". This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-07[lldb] Use std::optional instead of llvm::Optional (NFC)Kazu Hirata
This patch replaces (llvm::|)Optional< with std::optional<. I'll post a separate patch to clean up the "using" declarations, #include "llvm/ADT/Optional.h", etc. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-07[lldb] Add #include <optional> (NFC)Kazu Hirata
This patch adds #include <optional> to those files containing llvm::Optional<...> or Optional<...>. I'll post a separate patch to actually replace llvm::Optional with std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-05Remove "using llvm::None;" in *.cppKazu Hirata
These .cpp files do not use llvm::None anymore. Since these are not header files, we can remove them pretty safely without deprecating them first.
2022-12-04[lldb] Use std::nullopt instead of None (NFC)Kazu Hirata
This patch mechanically replaces None with std::nullopt where the compiler would warn if None were deprecated. The intent is to reduce the amount of manual work required in migrating from Optional to std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-09-19[lldb] Remove LLDB reproducersJonas Devlieghere
This patch removes the remaining reproducer code. The SBReproducer class remains for ABI stability but is just an empty shell. This completes the removal process outlined on the mailing list [1]. [1] https://lists.llvm.org/pipermail/lldb-dev/2021-September/017045.html
2022-06-20Don't use Optional::getValue (NFC)Kazu Hirata
2022-03-15Re-land "[lldb] Synchronize output through the IOHandler"Jonas Devlieghere
Add synchronization to the IOHandler to prevent multiple threads from writing concurrently to the output or error stream. A scenario where this could happen is when a thread (the default event thread for example) is using the debugger's asynchronous stream. We would delegate this operation to the IOHandler which might be running on another thread. Until this patch there was nothing to synchronize the two at the IOHandler level. Differential revision: https://reviews.llvm.org/D121500
2022-03-15Revert "[lldb] Synchronize output through the IOHandler"Jonas Devlieghere
This reverts commit 242c574dc03e4b90e992cc8d07436efc3954727f because it breaks the following tests on the bots: - TestGuiExpandThreadsTree.py - TestBreakpointCallbackCommandSource.py
2022-03-15[lldb] Synchronize output through the IOHandlerJonas Devlieghere
Add synchronization to the IOHandler to prevent multiple threads from writing concurrently to the output or error stream. A scenario where this could happen is when a thread (the default event thread for example) is using the debugger's asynchronous stream. We would delegate this operation to the IOHandler which might be running on another thread. Until this patch there was nothing to synchronize the two at the IOHandler level. Differential revision: https://reviews.llvm.org/D121500
2022-03-14[lldb] Fix the Windows build after D121536Jonas Devlieghere
2022-03-14[lldb] Use the IOHandler's stream instead of the debugger's in PrintAsyncJonas Devlieghere
PrintAsync is relying on the IOHandler to print to the output/error stream. In that context it doesn't make much sense that this is using the debugger's streams rather than the one from the IOHandler. Differential revision: https://reviews.llvm.org/D121536
2022-03-07[lldb] Add a setting to change the autosuggestion ANSI escape codesJonas Devlieghere
I'm a big fan of the autosuggestion feature but my terminal/color scheme doesn't display faint any differently than regular lldb output, which makes the feature a little confusing. This patch add a setting to change the autosuggestion ANSI escape codes. For example, to display the autosuggestion in italic, you can add this to your ~/.lldbinit settings set show-autosuggestion-ansi-prefix ${ansi.italic} setting set show-autosuggestion-ansi-suffix ${ansi.normal} Differential revision: https://reviews.llvm.org/D121064
2021-08-09[lldb][NFC] Remove never read member variable IOHandler::m_editingRaphael Isemann
The last read access to this variable was removed in 2015 in 4446487d71c52a925c04acfcae44dec8a8d62e00 .
2021-05-26[lldb][NFC] Use C++ versions of the deprecated C standard library headersRaphael Isemann
The C headers are deprecated so as requested in D102845, this is replacing them all with their (not deprecated) C++ equivalent. Reviewed By: shafik Differential Revision: https://reviews.llvm.org/D103084
2021-03-02Migrate to llvm::unique_function instead of static member functions for ↵Neal (nealsid)
callbacks A few cleanups suggested in another patch review's comments: 1. Use llvm:unique_function for storing & invoking callbacks from Editline to IOHandler 2. Change return type of one of the callback setters from bool to void, since it's return value was never used 3. Moved the callback setters inline & made them nonstatic, since that's more consistent with other setter definitions 4. Removed the baton parameter since we no longer need it anymore Differential revision: https://reviews.llvm.org/D50299
2020-09-16[lldb] Return FileSP and StreamFileSP by value in IOHandler (NFC)Jonas Devlieghere
Smart pointers should be returned by value.
2020-08-22[lldb] Extract reproducer providers & co into their own header.Jonas Devlieghere
Extract all the provider related logic from Reproducer.h and move it into its own header ReproducerProvider.h. These classes are seeing most of the development these days and this reorganization reduces incremental compilation from ~520 to ~110 files when making changes to the new header.
2020-08-14[lldb] Display autosuggestion part in gray if there is one possible suggestionShu Anzai
This is relanding D81001. The patch originally failed as on newer editline versions it seems CC_REFRESH will move the cursor to the start of the line via \r and then back to the original position. On older editline versions like the one used by default on macOS, CC_REFRESH doesn't move the cursor at all. As the patch changed the way we handle tab completion (previously we did REDISPLAY but now we're doing CC_REFRESH), this caused a few completion tests to receive this unexpected cursor movement in the output stream. This patch updates those tests to also accept output that contains the specific cursor movement commands (\r and then \x1b[XC). lldbpexpect.py received an utility method for generating the cursor movement escape sequence. Original summary: I implemented autosuggestion if there is one possible suggestion. I set the keybinds for every character. When a character is typed, Editline::TypedCharacter is called. Then, autosuggestion part is displayed in gray, and you can actually input by typing C-k. Editline::Autosuggest is a function for finding completion, and it is like Editline::TabCommand now, but I will add more features to it. Testing does not work well in my environment, so I can't confirm that it goes well, sorry. I am dealing with it now. Reviewed By: teemperor, JDevlieghere, #lldb Differential Revision: https://reviews.llvm.org/D81001
2020-08-12Revert "[lldb] Display autosuggestion part in gray if there is one possible ↵Raphael Isemann
suggestion" This reverts commit 246afe0cd17fce935a01171f3cca548e02523e5c. This broke the following tests on Linux it seems: lldb-api :: commands/expression/multiline-completion/TestMultilineCompletion.py lldb-api :: iohandler/completion/TestIOHandlerCompletion.py
2020-08-12[lldb] Display autosuggestion part in gray if there is one possible suggestionShu Anzai
I implemented autosuggestion if there is one possible suggestion. I set the keybinds for every character. When a character is typed, Editline::TypedCharacter is called. Then, autosuggestion part is displayed in gray, and you can actually input by typing C-k. Editline::Autosuggest is a function for finding completion, and it is like Editline::TabCommand now, but I will add more features to it. Testing does not work well in my environment, so I can't confirm that it goes well, sorry. I am dealing with it now. Reviewed By: teemperor, JDevlieghere, #lldb Differential Revision: https://reviews.llvm.org/D81001
2020-06-24[lldb] Use std::make_unique<> (NFC)Jonas Devlieghere
Update the rest of lldb to use std::make_unique<>. I used clang-tidy to automate this, which probably missed cases that are wrapped in ifdefs.
2020-06-19[lldb] Replace std::isprint/isspace with llvm's locale-independent versionRaphael Isemann
Summary: LLVM is using its own isPrint/isSpace implementation that doesn't change depending on the current locale. LLDB should do the same to prevent that internal logic changes depending on the set locale. Reviewers: JDevlieghere, labath, mib, totally_not_teemperor Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D82175
2020-06-19[lldb] Fix that SIGWINCH crashes IOHandlerEditline when we are not using the ↵Raphael Isemann
editline backend Summary: TerminalSizeChanged is called from our SIGWINCH signal handler but the IOHandlerEditline currently doesn't check if we are actually using the real editline backend. If we're not using the real editline backend, `m_editline_up` won't be set and `IOHandlerEditline::TerminalSizeChanged` will access the empty unique_ptr. In a real use case we don't use the editline backend when we for example read input from a file. We also create some temporary IOHandlerEditline's during LLDB startup it seems that are also treated as non-interactive (apparently to read startup commands). This patch just adds a nullptr check for`m_editline_up` as we do in the rest of IOHandlerEditline. Fixes rdar://problem/63921950 Reviewers: labath, friss Reviewed By: friss Subscribers: abidh, JDevlieghere Differential Revision: https://reviews.llvm.org/D81729
2020-05-12[lldb/Driver] Support terminal resizingFred Riss
Summary: The comment in the Editine.h header made it sound like editline was just unable to handle terminal resizing. We were not ever telling editline that the terminal had changed size, which might explain why it wasn't working. This patch threads a `TerminalSizeChanged()` callback through the IOHandler and invokes it from the SIGWINCH handler in the driver. Our `Editline` class already had a `TerminalSizeChanged()` method which was invoked only when editline was configured. This patch also changes `Editline` to not apply the changes right away in `TerminalSizeChanged()`, but instead defer that to the next character read. During my testing, it happened once that the signal was received while our `ConnectionFileDescriptor::Read` was allocating memory. As `el_resize` seems to allocate memory too, this crashed. Reviewers: labath, teemperor Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D79654
2020-03-03[lldb] Make sure we don't drop asynchronous output when sourcing filesPavel Labath
Summary: If a command from a sourced file produces asynchronous output, this output often does not make its way to the user. This happens because the asynchronous output machinery relies on the iohandler stack to ensure the output does not interfere with the things the iohandler is doing. However, if this happens near the end of the command stream then by the time the asynchronous output is produced we may already have already started tearing down the sourcing session. Specifically, we may already pop the relevant iohandler, leaving the stack empty. This patch makes sure this kind of output gets printed by adding a fallback to IOHandlerStack::PrintAsync to print the output directly if the stack is empty. This is safe because if we have no iohandlers then there is nothing to synchronize. Reviewers: JDevlieghere, clayborg Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D75454
2020-01-28Make llvm::StringRef to std::string conversions explicit.Benjamin Kramer
This is how it should've been and brings it more in line with std::string_view. There should be no functional change here. This is mostly mechanical from a custom clang-tidy check, with a lot of manual fixups. It uncovers a lot of minor inefficiencies. This doesn't actually modify StringRef yet, I'll do that in a follow-up.
2020-01-24[lldb][NFC] Fix all formatting errors in .cpp file headersRaphael Isemann
Summary: A *.cpp file header in LLDB (and in LLDB) should like this: ``` //===-- TestUtilities.cpp -------------------------------------------------===// ``` However in LLDB most of our source files have arbitrary changes to this format and these changes are spreading through LLDB as folks usually just use the existing source files as templates for their new files (most notably the unnecessary editor language indicator `-*- C++ -*-` is spreading and in every review someone is pointing out that this is wrong, resulting in people pointing out that this is done in the same way in other files). This patch removes most of these inconsistencies including the editor language indicators, all the different missing/additional '-' characters, files that center the file name, missing trailing `===//` (mostly caused by clang-format breaking the line). Reviewers: aprantl, espindola, jfb, shafik, JDevlieghere Reviewed By: JDevlieghere Subscribers: dexonsmith, wuzish, emaste, sdardis, nemanjai, kbarton, MaskRay, atanasyan, arphaman, jfb, abidh, jsji, JDevlieghere, usaxena95, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D73258
2019-12-12[lldb/Core] Add missing includeJonas Devlieghere
This got flagged by the modules build.
2019-12-12[lldb/CMake] Rename LLDB_DISABLE_LIBEDIT to LLDB_ENABLE_LIBEDITJonas Devlieghere
This matches the naming scheme used by LLVM. Differential revision: https://reviews.llvm.org/D71380
2019-12-03[lldb][NFC] Move Curses interface implementation to own fileRaphael Isemann
Summary: The IOHandler class source file is currently around 4600 LOC. However only 200 of these lines are concerned with the actual IOHandler class and the rest are the implementations for Editline, IOHandlerConfirm and the Curses interface. All these large features also cause that the IOHandler (which is in Core) has a large set of dependencies on other parts of LLDB. This patch splits out the code for the curses interface into its own file. This way the simple IOHandler code is no longer buried in-between much larger functionalities. Next up is splitting out the other IOHandlers into their own files and then move them to more appropriate parts of LLDB. Reviewers: labath, clayborg, JDevlieghere Reviewed By: labath Subscribers: mgorny, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D70946
2019-11-25[lldb][NFC] Allow range-based for-loops on VariableListRaphael Isemann
Summary: Adds support for doing range-based for-loops on LLDB's VariableList and modernises all the index-based for-loops in LLDB where possible. Reviewers: labath, jdoerfert Reviewed By: labath Subscribers: JDevlieghere, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D70668
2019-10-11IOHandler: fall back on File::Read if a FILE* isn't available.Lawrence D'Anna
Summary: IOHandler needs to read lines of input from a lldb::File. The way it currently does this using, FILE*, which is something we want to avoid now. I'd prefer to just replace the FILE* code with calls to File::Read, but it contains an awkward and delicate workaround specific to ctrl-C handling on windows, and it's not clear if or how that workaround would translate to lldb::File. So in this patch, we use use the FILE* if it's available, and only fall back on File::Read if that's the only option. I think this is a reasonable approach here for two reasons. First is that interactive terminal support is the one area where FILE* can't be avoided. We need them for libedit and curses anyway, and using them here as well is consistent with that pattern. The second reason is that the comments express a hope that the underlying windows bug that's being worked around will be fixed one day, so hopefully when that happens, that whole path can be deleted. Reviewers: JDevlieghere, jasonmolenda, labath, lanza Reviewed By: labath Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D68622 llvm-svn: 374576
2019-10-09remove a smattering of isolated, unnecessary uses of FILE*Lawrence D'Anna
Summary: There a a few call sites that use FILE* which are easy to fix without disrupting anything else. Reviewers: JDevlieghere, jasonmolenda, labath Reviewed By: JDevlieghere, labath Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D68444 llvm-svn: 374239
2019-10-09protect libedit and LLDB gui from receiving null FILE* streamsLawrence D'Anna
Summary: We now have valid files that will return NULL from GetStream(). libedit and the LLDB gui are the only places left that need FILE* streams. Both are doing curses-like user interaction that only make sense with a real terminal anyway, so there is no need to convert them off of their use of FILE*. But we should check for null streams before enabling these features. Reviewers: JDevlieghere, jasonmolenda, labath Reviewed By: JDevlieghere, labath Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D68677 llvm-svn: 374197
2019-09-27remove File::SetStream(), make new files instead.Lawrence D'Anna
Summary: This patch removes File::SetStream() and File::SetDescriptor(), and replaces most direct uses of File with pointers to File. Instead of calling SetStream() on a file, we make a new file and replace it. My ultimate goal here is to introduce a new API class SBFile, which has full support for python io.IOStream file objects. These can redirect read() and write() to python code, so lldb::Files will need a way to dispatch those methods. Additionally it will need some form of sharing and assigning files, as a SBFile will be passed in and assigned to the main IO streams of the debugger. In my prototype patch queue, I make File itself copyable and add a secondary class FileOps to manage the sharing and dispatch. In that case SBFile was a unique_ptr<File>. (here: https://github.com/smoofra/llvm-project/tree/files) However in review, Pavel Labath suggested that it be shared_ptr instead. (here: https://reviews.llvm.org/D67793) In order for SBFile to use shared_ptr<File>, everything else should as well. If this patch is accepted, I will make SBFile use a shared_ptr I will remove FileOps from future patches and use subclasses of File instead. Reviewers: JDevlieghere, jasonmolenda, zturner, jingham, labath Reviewed By: labath Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D67891 llvm-svn: 373090
2019-09-23[LLDB] Check for _WIN32 instead of _MSC_VER for code specific to windows in ↵Martin Storsjo
general These ifdefs contain code that isn't specific to MSVC but useful for any windows target, like MinGW. Differential Revision: https://reviews.llvm.org/D67893 llvm-svn: 372592
2019-09-22Use _WIN32 instead of _MSC_VERHaibo Huang
Summary: This way it works better with MinGW. Subscribers: mstorsjo, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D67887 llvm-svn: 372493