diff --git a/lldb/source/Interpreter/OptionValueFormatEntity.cpp b/lldb/source/Interpreter/OptionValueFormatEntity.cpp
index 66d8d84..29c3b40 100644
--- a/lldb/source/Interpreter/OptionValueFormatEntity.cpp
+++ b/lldb/source/Interpreter/OptionValueFormatEntity.cpp
@@ -20,121 +20,96 @@
 using namespace lldb;
 using namespace lldb_private;
 
-
-OptionValueFormatEntity::OptionValueFormatEntity (const char *default_format) :
-    OptionValue(),
-    m_current_format (),
-    m_default_format (),
-    m_current_entry (),
-    m_default_entry ()
-{
-    if (default_format && default_format[0])
-    {
-        llvm::StringRef default_format_str(default_format);
-        Error error = FormatEntity::Parse(default_format_str, m_default_entry);
-        if (error.Success())
-        {
-            m_default_format = default_format;
-            m_current_format = default_format;
-            m_current_entry = m_default_entry;
-        }
+OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format)
+    : OptionValue(), m_current_format(), m_default_format(), m_current_entry(),
+      m_default_entry() {
+  if (default_format && default_format[0]) {
+    llvm::StringRef default_format_str(default_format);
+    Error error = FormatEntity::Parse(default_format_str, m_default_entry);
+    if (error.Success()) {
+      m_default_format = default_format;
+      m_current_format = default_format;
+      m_current_entry = m_default_entry;
     }
+  }
 }
 
-bool
-OptionValueFormatEntity::Clear ()
-{
-    m_current_entry = m_default_entry;
-    m_current_format = m_default_format;
-    m_value_was_set = false;
-    return true;
+bool OptionValueFormatEntity::Clear() {
+  m_current_entry = m_default_entry;
+  m_current_format = m_default_format;
+  m_value_was_set = false;
+  return true;
 }
 
-
-void
-OptionValueFormatEntity::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
-{
+void OptionValueFormatEntity::DumpValue(const ExecutionContext *exe_ctx,
+                                        Stream &strm, uint32_t dump_mask) {
+  if (dump_mask & eDumpOptionType)
+    strm.Printf("(%s)", GetTypeAsCString());
+  if (dump_mask & eDumpOptionValue) {
     if (dump_mask & eDumpOptionType)
-        strm.Printf ("(%s)", GetTypeAsCString ());
-    if (dump_mask & eDumpOptionValue)
-    {
-        if (dump_mask & eDumpOptionType)
-            strm.PutCString (" = \"");
-        strm << m_current_format.c_str() << '"';
+      strm.PutCString(" = \"");
+    strm << m_current_format.c_str() << '"';
+  }
+}
+
+Error OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str,
+                                                  VarSetOperationType op) {
+  Error error;
+  switch (op) {
+  case eVarSetOperationClear:
+    Clear();
+    NotifyValueChanged();
+    break;
+
+  case eVarSetOperationReplace:
+  case eVarSetOperationAssign: {
+    // Check if the string starts with a quote character after removing leading
+    // and trailing spaces.
+    // If it does start with a quote character, make sure it ends with the same
+    // quote character
+    // and remove the quotes before we parse the format string. If the string
+    // doesn't start with
+    // a quote, leave the string alone and parse as is.
+    llvm::StringRef trimmed_value_str = value_str.trim();
+    if (!trimmed_value_str.empty()) {
+      const char first_char = trimmed_value_str[0];
+      if (first_char == '"' || first_char == '\'') {
+        const size_t trimmed_len = trimmed_value_str.size();
+        if (trimmed_len == 1 || value_str[trimmed_len - 1] != first_char) {
+          error.SetErrorStringWithFormat("mismatched quotes");
+          return error;
+        }
+        value_str = trimmed_value_str.substr(1, trimmed_len - 2);
+      }
     }
-}
-
-Error
-OptionValueFormatEntity::SetValueFromString (llvm::StringRef value_str,
-                                             VarSetOperationType op)
-{
-    Error error;
-    switch (op)
-    {
-        case eVarSetOperationClear:
-            Clear();
-            NotifyValueChanged();
-            break;
-            
-        case eVarSetOperationReplace:
-        case eVarSetOperationAssign:
-            {
-                // Check if the string starts with a quote character after removing leading and trailing spaces.
-                // If it does start with a quote character, make sure it ends with the same quote character
-                // and remove the quotes before we parse the format string. If the string doesn't start with
-                // a quote, leave the string alone and parse as is.
-                llvm::StringRef trimmed_value_str = value_str.trim();
-                if (!trimmed_value_str.empty())
-                {
-                    const char first_char = trimmed_value_str[0];
-                    if (first_char == '"' || first_char == '\'')
-                    {
-                        const size_t trimmed_len = trimmed_value_str.size();
-                        if (trimmed_len == 1 || value_str[trimmed_len-1] != first_char)
-                        {
-                            error.SetErrorStringWithFormat("mismatched quotes");
-                            return error;
-                        }
-                        value_str = trimmed_value_str.substr(1,trimmed_len-2);
-                    }
-                }
-                FormatEntity::Entry entry;
-                error = FormatEntity::Parse(value_str, entry);
-                if (error.Success())
-                {
-                    m_current_entry = std::move(entry);
-                    m_current_format = value_str;
-                    m_value_was_set = true;
-                    NotifyValueChanged();
-                }
-            }
-            break;
-            
-        case eVarSetOperationInsertBefore:
-        case eVarSetOperationInsertAfter:
-        case eVarSetOperationRemove:
-        case eVarSetOperationAppend:
-        case eVarSetOperationInvalid:
-            error = OptionValue::SetValueFromString (value_str, op);
-            break;
+    FormatEntity::Entry entry;
+    error = FormatEntity::Parse(value_str, entry);
+    if (error.Success()) {
+      m_current_entry = std::move(entry);
+      m_current_format = value_str;
+      m_value_was_set = true;
+      NotifyValueChanged();
     }
-    return error;
+  } break;
+
+  case eVarSetOperationInsertBefore:
+  case eVarSetOperationInsertAfter:
+  case eVarSetOperationRemove:
+  case eVarSetOperationAppend:
+  case eVarSetOperationInvalid:
+    error = OptionValue::SetValueFromString(value_str, op);
+    break;
+  }
+  return error;
 }
 
-lldb::OptionValueSP
-OptionValueFormatEntity::DeepCopy () const
-{
-    return OptionValueSP(new OptionValueFormatEntity(*this));
+lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const {
+  return OptionValueSP(new OptionValueFormatEntity(*this));
 }
 
-size_t
-OptionValueFormatEntity::AutoComplete (CommandInterpreter &interpreter,
-                                       const char *s,
-                                       int match_start_point,
-                                       int max_return_elements,
-                                       bool &word_complete,
-                                       StringList &matches)
-{
-    return FormatEntity::AutoComplete (s, match_start_point, max_return_elements, word_complete, matches);
+size_t OptionValueFormatEntity::AutoComplete(
+    CommandInterpreter &interpreter, const char *s, int match_start_point,
+    int max_return_elements, bool &word_complete, StringList &matches) {
+  return FormatEntity::AutoComplete(s, match_start_point, max_return_elements,
+                                    word_complete, matches);
 }
-
