[Lldb-commits] [lldb] r280751 - *** This commit represents a complete reformatting of the LLDB source code

Kate Stone via lldb-commits lldb-commits at lists.llvm.org
Tue Sep 6 13:58:36 PDT 2016


Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h Tue Sep  6 15:57:50 2016
@@ -16,26 +16,26 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "ASTStructExtractor.h"
 #include "ASTResultSynthesizer.h"
+#include "ASTStructExtractor.h"
 #include "ClangExpressionDeclMap.h"
 #include "ClangExpressionHelper.h"
 #include "ClangExpressionVariable.h"
 #include "IRForTarget.h"
 
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
 #include "lldb/Core/Address.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Expression/LLVMUserExpression.h"
 #include "lldb/Expression/Materializer.h"
 #include "lldb/Target/ExecutionContext.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
 
-namespace lldb_private
-{
+namespace lldb_private {
 
 //----------------------------------------------------------------------
-/// @class ClangUserExpression ClangUserExpression.h "lldb/Expression/ClangUserExpression.h"
+/// @class ClangUserExpression ClangUserExpression.h
+/// "lldb/Expression/ClangUserExpression.h"
 /// @brief Encapsulates a single expression for use with Clang
 ///
 /// LLDB uses expressions for various purposes, notably to call functions
@@ -43,172 +43,154 @@ namespace lldb_private
 /// the objects needed to parse and interpret or JIT an expression.  It
 /// uses the Clang parser to produce LLVM IR from the expression.
 //----------------------------------------------------------------------
-class ClangUserExpression : public LLVMUserExpression
-{
+class ClangUserExpression : public LLVMUserExpression {
 public:
-    enum { kDefaultTimeout = 500000u };
-
-    class ClangUserExpressionHelper : public ClangExpressionHelper
-    {
-    public:
-        ClangUserExpressionHelper(Target &target, bool top_level) : m_target(target), m_top_level(top_level) {}
-
-        ~ClangUserExpressionHelper() override = default;
-
-        //------------------------------------------------------------------
-        /// Return the object that the parser should use when resolving external
-        /// values.  May be NULL if everything should be self-contained.
-        //------------------------------------------------------------------
-        ClangExpressionDeclMap *
-        DeclMap() override
-        {
-            return m_expr_decl_map_up.get();
-        }
-        
-        void
-        ResetDeclMap()
-        {
-            m_expr_decl_map_up.reset();
-        }
-        
-        void
-        ResetDeclMap (ExecutionContext & exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory);
-        
-        //------------------------------------------------------------------
-        /// Return the object that the parser should allow to access ASTs.
-        /// May be NULL if the ASTs do not need to be transformed.
-        ///
-        /// @param[in] passthrough
-        ///     The ASTConsumer that the returned transformer should send
-        ///     the ASTs to after transformation.
-        //------------------------------------------------------------------
-        clang::ASTConsumer *
-        ASTTransformer(clang::ASTConsumer *passthrough) override;
-
-        void
-        CommitPersistentDecls() override;
-
-    private:
-        Target &m_target;
-        std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
-        std::unique_ptr<ASTStructExtractor>
-            m_struct_extractor_up; ///< The class that generates the argument struct layout.
-        std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
-        bool m_top_level;
-    };
+  enum { kDefaultTimeout = 500000u };
 
-    //------------------------------------------------------------------
-    /// Constructor
-    ///
-    /// @param[in] expr
-    ///     The expression to parse.
-    ///
-    /// @param[in] expr_prefix
-    ///     If non-NULL, a C string containing translation-unit level
-    ///     definitions to be included when the expression is parsed.
-    ///
-    /// @param[in] language
-    ///     If not eLanguageTypeUnknown, a language to use when parsing
-    ///     the expression.  Currently restricted to those languages
-    ///     supported by Clang.
-    ///
-    /// @param[in] desired_type
-    ///     If not eResultTypeAny, the type to use for the expression
-    ///     result.
-    //------------------------------------------------------------------
-    ClangUserExpression (ExecutionContextScope &exe_scope,
-                         const char *expr,
-                         const char *expr_prefix,
-                         lldb::LanguageType language,
-                         ResultType desired_type,
-                         const EvaluateExpressionOptions &options);
+  class ClangUserExpressionHelper : public ClangExpressionHelper {
+  public:
+    ClangUserExpressionHelper(Target &target, bool top_level)
+        : m_target(target), m_top_level(top_level) {}
 
-    ~ClangUserExpression() override;
+    ~ClangUserExpressionHelper() override = default;
 
     //------------------------------------------------------------------
-    /// Parse the expression
-    ///
-    /// @param[in] diagnostic_manager
-    ///     A diagnostic manager to report parse errors and warnings to.
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to use when looking up entities that
-    ///     are needed for parsing (locations of functions, types of
-    ///     variables, persistent variables, etc.)
-    ///
-    /// @param[in] execution_policy
-    ///     Determines whether interpretation is possible or mandatory.
-    ///
-    /// @param[in] keep_result_in_memory
-    ///     True if the resulting persistent variable should reside in
-    ///     target memory, if applicable.
-    ///
-    /// @return
-    ///     True on success (no errors); false otherwise.
+    /// Return the object that the parser should use when resolving external
+    /// values.  May be NULL if everything should be self-contained.
     //------------------------------------------------------------------
-    bool
-    Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
-          lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
-          bool generate_debug_info) override;
-
-    ExpressionTypeSystemHelper *
-    GetTypeSystemHelper () override
-    {
-        return &m_type_system_helper;
-    }
-    
-    ClangExpressionDeclMap *
-    DeclMap ()
-    {
-        return m_type_system_helper.DeclMap();
-    }
-    
-    void
-    ResetDeclMap ()
-    {
-        m_type_system_helper.ResetDeclMap();
-    }
-    
-    void
-    ResetDeclMap (ExecutionContext & exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory)
-    {
-        m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate, keep_result_in_memory);
+    ClangExpressionDeclMap *DeclMap() override {
+      return m_expr_decl_map_up.get();
     }
 
-    lldb::ExpressionVariableSP
-    GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
-    
+    void ResetDeclMap() { m_expr_decl_map_up.reset(); }
+
+    void ResetDeclMap(ExecutionContext &exe_ctx,
+                      Materializer::PersistentVariableDelegate &result_delegate,
+                      bool keep_result_in_memory);
+
+    //------------------------------------------------------------------
+    /// Return the object that the parser should allow to access ASTs.
+    /// May be NULL if the ASTs do not need to be transformed.
+    ///
+    /// @param[in] passthrough
+    ///     The ASTConsumer that the returned transformer should send
+    ///     the ASTs to after transformation.
+    //------------------------------------------------------------------
+    clang::ASTConsumer *
+    ASTTransformer(clang::ASTConsumer *passthrough) override;
+
+    void CommitPersistentDecls() override;
+
+  private:
+    Target &m_target;
+    std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
+    std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class
+                                                               ///that generates
+                                                               ///the argument
+                                                               ///struct layout.
+    std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
+    bool m_top_level;
+  };
+
+  //------------------------------------------------------------------
+  /// Constructor
+  ///
+  /// @param[in] expr
+  ///     The expression to parse.
+  ///
+  /// @param[in] expr_prefix
+  ///     If non-NULL, a C string containing translation-unit level
+  ///     definitions to be included when the expression is parsed.
+  ///
+  /// @param[in] language
+  ///     If not eLanguageTypeUnknown, a language to use when parsing
+  ///     the expression.  Currently restricted to those languages
+  ///     supported by Clang.
+  ///
+  /// @param[in] desired_type
+  ///     If not eResultTypeAny, the type to use for the expression
+  ///     result.
+  //------------------------------------------------------------------
+  ClangUserExpression(ExecutionContextScope &exe_scope, const char *expr,
+                      const char *expr_prefix, lldb::LanguageType language,
+                      ResultType desired_type,
+                      const EvaluateExpressionOptions &options);
+
+  ~ClangUserExpression() override;
+
+  //------------------------------------------------------------------
+  /// Parse the expression
+  ///
+  /// @param[in] diagnostic_manager
+  ///     A diagnostic manager to report parse errors and warnings to.
+  ///
+  /// @param[in] exe_ctx
+  ///     The execution context to use when looking up entities that
+  ///     are needed for parsing (locations of functions, types of
+  ///     variables, persistent variables, etc.)
+  ///
+  /// @param[in] execution_policy
+  ///     Determines whether interpretation is possible or mandatory.
+  ///
+  /// @param[in] keep_result_in_memory
+  ///     True if the resulting persistent variable should reside in
+  ///     target memory, if applicable.
+  ///
+  /// @return
+  ///     True on success (no errors); false otherwise.
+  //------------------------------------------------------------------
+  bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+             lldb_private::ExecutionPolicy execution_policy,
+             bool keep_result_in_memory, bool generate_debug_info) override;
+
+  ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
+    return &m_type_system_helper;
+  }
+
+  ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
+
+  void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
+
+  void ResetDeclMap(ExecutionContext &exe_ctx,
+                    Materializer::PersistentVariableDelegate &result_delegate,
+                    bool keep_result_in_memory) {
+    m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate,
+                                      keep_result_in_memory);
+  }
+
+  lldb::ExpressionVariableSP
+  GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
+
 private:
-    //------------------------------------------------------------------
-    /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment.
-    //------------------------------------------------------------------
+  //------------------------------------------------------------------
+  /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the
+  /// environment.
+  //------------------------------------------------------------------
+
+  void ScanContext(ExecutionContext &exe_ctx,
+                   lldb_private::Error &err) override;
+
+  bool AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
+                    lldb::addr_t struct_address,
+                    DiagnosticManager &diagnostic_manager) override;
+
+  ClangUserExpressionHelper m_type_system_helper;
+
+  class ResultDelegate : public Materializer::PersistentVariableDelegate {
+  public:
+    ResultDelegate();
+    ConstString GetName() override;
+    void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
+
+    void RegisterPersistentState(PersistentExpressionState *persistent_state);
+    lldb::ExpressionVariableSP &GetVariable();
+
+  private:
+    PersistentExpressionState *m_persistent_state;
+    lldb::ExpressionVariableSP m_variable;
+  };
 
-    void
-    ScanContext (ExecutionContext &exe_ctx,
-                 lldb_private::Error &err) override;
-
-    bool
-    AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, lldb::addr_t struct_address,
-                 DiagnosticManager &diagnostic_manager) override;
-
-    ClangUserExpressionHelper m_type_system_helper;
-
-    class ResultDelegate : public Materializer::PersistentVariableDelegate
-    {
-    public:
-        ResultDelegate();
-        ConstString GetName() override;
-        void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
-        
-        void RegisterPersistentState(PersistentExpressionState *persistent_state);
-        lldb::ExpressionVariableSP &GetVariable();
-
-    private:
-        PersistentExpressionState *m_persistent_state;
-        lldb::ExpressionVariableSP m_variable;
-    };
-    
-    ResultDelegate                                          m_result_delegate;
+  ResultDelegate m_result_delegate;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp Tue Sep  6 15:57:50 2016
@@ -1,4 +1,5 @@
-//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
+//===-- ClangUserExpression.cpp -------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,14 +8,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "ClangUtilityFunction.h"
 #include "ClangExpressionDeclMap.h"
 #include "ClangExpressionParser.h"
-#include "ClangUtilityFunction.h"
 
 // C Includes
 #include <stdio.h>
 #if HAVE_SYS_TYPES_H
-#  include <sys/types.h>
+#include <sys/types.h>
 #endif
 
 // C++ Includes
@@ -41,16 +42,11 @@ using namespace lldb_private;
 /// @param[in] name
 ///     The name of the function, as used in the text.
 //------------------------------------------------------------------
-ClangUtilityFunction::ClangUtilityFunction (ExecutionContextScope &exe_scope,
-                                            const char *text,
-                                            const char *name) :
-    UtilityFunction (exe_scope, text, name)
-{
-}
+ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
+                                           const char *text, const char *name)
+    : UtilityFunction(exe_scope, text, name) {}
 
-ClangUtilityFunction::~ClangUtilityFunction ()
-{
-}
+ClangUtilityFunction::~ClangUtilityFunction() {}
 
 //------------------------------------------------------------------
 /// Install the utility function into a process
@@ -64,94 +60,85 @@ ClangUtilityFunction::~ClangUtilityFunct
 /// @return
 ///     True on success (no errors); false otherwise.
 //------------------------------------------------------------------
-bool
-ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx)
-{
-    if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
-    {
-        diagnostic_manager.PutCString(eDiagnosticSeverityWarning, "already installed");
-        return false;
-    }
+bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager,
+                                   ExecutionContext &exe_ctx) {
+  if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
+    diagnostic_manager.PutCString(eDiagnosticSeverityWarning,
+                                  "already installed");
+    return false;
+  }
+
+  ////////////////////////////////////
+  // Set up the target and compiler
+  //
+
+  Target *target = exe_ctx.GetTargetPtr();
+
+  if (!target) {
+    diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
+    return false;
+  }
+
+  Process *process = exe_ctx.GetProcessPtr();
+
+  if (!process) {
+    diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid process");
+    return false;
+  }
+
+  //////////////////////////
+  // Parse the expression
+  //
+
+  bool keep_result_in_memory = false;
+
+  ResetDeclMap(exe_ctx, keep_result_in_memory);
+
+  if (!DeclMap()->WillParse(exe_ctx, NULL)) {
+    diagnostic_manager.PutCString(
+        eDiagnosticSeverityError,
+        "current process state is unsuitable for expression parsing");
+    return false;
+  }
+
+  const bool generate_debug_info = true;
+  ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
+                               generate_debug_info);
 
-    ////////////////////////////////////
-    // Set up the target and compiler
-    //
-    
-    Target *target = exe_ctx.GetTargetPtr();
-
-    if (!target)
-    {
-        diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
-        return false;
-    }
+  unsigned num_errors = parser.Parse(diagnostic_manager);
 
-    Process *process = exe_ctx.GetProcessPtr();
+  if (num_errors) {
+    ResetDeclMap();
 
-    if (!process)
-    {
-        diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid process");
-        return false;
-    }
+    return false;
+  }
 
-    //////////////////////////
-    // Parse the expression
-    //
-    
-    bool keep_result_in_memory = false;
-    
-    ResetDeclMap(exe_ctx, keep_result_in_memory);
-
-    if (!DeclMap()->WillParse(exe_ctx, NULL))
-    {
-        diagnostic_manager.PutCString(eDiagnosticSeverityError,
-                                      "current process state is unsuitable for expression parsing");
-        return false;
+  //////////////////////////////////
+  // JIT the output of the parser
+  //
+
+  bool can_interpret = false; // should stay that way
+
+  Error jit_error = parser.PrepareForExecution(
+      m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
+      can_interpret, eExecutionPolicyAlways);
+
+  if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
+    m_jit_process_wp = process->shared_from_this();
+    if (parser.GetGenerateDebugInfo()) {
+      lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
+
+      if (jit_module_sp) {
+        ConstString const_func_name(FunctionName());
+        FileSpec jit_file;
+        jit_file.GetFilename() = const_func_name;
+        jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
+        m_jit_module_wp = jit_module_sp;
+        target->GetImages().Append(jit_module_sp);
+      }
     }
+  }
 
-    const bool generate_debug_info = true;
-    ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this, generate_debug_info);
-
-    unsigned num_errors = parser.Parse(diagnostic_manager);
-
-    if (num_errors)
-    {
-        ResetDeclMap();
-
-        return false;
-    }
-    
-    //////////////////////////////////
-    // JIT the output of the parser
-    //
-        
-    bool can_interpret = false; // should stay that way
-    
-    Error jit_error = parser.PrepareForExecution (m_jit_start_addr, 
-                                                  m_jit_end_addr,
-                                                  m_execution_unit_sp,
-                                                  exe_ctx,
-                                                  can_interpret,
-                                                  eExecutionPolicyAlways);
-    
-    if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
-    {
-        m_jit_process_wp = process->shared_from_this();
-        if (parser.GetGenerateDebugInfo())
-        {
-            lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
-            
-            if (jit_module_sp)
-            {
-                ConstString const_func_name(FunctionName());
-                FileSpec jit_file;
-                jit_file.GetFilename() = const_func_name;
-                jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
-                m_jit_module_wp = jit_module_sp;
-                target->GetImages().Append(jit_module_sp);
-            }
-        }
-    }
-    
 #if 0
 	// jingham: look here
     StreamFile logfile ("/tmp/exprs.txt", "a");
@@ -161,31 +148,26 @@ ClangUtilityFunction::Install(Diagnostic
                     m_function_text.c_str());
 #endif
 
-    DeclMap()->DidParse();
-    
-    ResetDeclMap();
-    
-    if (jit_error.Success())
-    {
-        return true;
-    }
-    else
-    {
-        const char *error_cstr = jit_error.AsCString();
-        if (error_cstr && error_cstr[0])
-        {
-            diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
-        }
-        else
-        {
-            diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
-        }
-        return false;
+  DeclMap()->DidParse();
+
+  ResetDeclMap();
+
+  if (jit_error.Success()) {
+    return true;
+  } else {
+    const char *error_cstr = jit_error.AsCString();
+    if (error_cstr && error_cstr[0]) {
+      diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
+    } else {
+      diagnostic_manager.PutCString(eDiagnosticSeverityError,
+                                    "expression can't be interpreted or run");
     }
+    return false;
+  }
 }
 
-void
-ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory)
-{
-    m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));
+void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(
+    ExecutionContext &exe_ctx, bool keep_result_in_memory) {
+  m_expr_decl_map_up.reset(
+      new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));
 }

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h Tue Sep  6 15:57:50 2016
@@ -12,24 +12,24 @@
 
 // C Includes
 // C++ Includes
-#include <string>
 #include <map>
+#include <string>
 #include <vector>
 
 // Other libraries and framework includes
 // Project includes
 #include "ClangExpressionHelper.h"
 
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Expression/UtilityFunction.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
 
-namespace lldb_private 
-{
+namespace lldb_private {
 
 //----------------------------------------------------------------------
-/// @class ClangUtilityFunction ClangUtilityFunction.h "lldb/Expression/ClangUtilityFunction.h"
+/// @class ClangUtilityFunction ClangUtilityFunction.h
+/// "lldb/Expression/ClangUtilityFunction.h"
 /// @brief Encapsulates a single expression for use with Clang
 ///
 /// LLDB uses expressions for various purposes, notably to call functions
@@ -39,97 +39,75 @@ namespace lldb_private
 /// simply provide a way to push a function into the target for the debugger to
 /// call later on.
 //----------------------------------------------------------------------
-class ClangUtilityFunction : public UtilityFunction
-{
+class ClangUtilityFunction : public UtilityFunction {
 public:
-    class ClangUtilityFunctionHelper : public ClangExpressionHelper
-    {
-    public:
-        ClangUtilityFunctionHelper ()
-        {
-        }
-        
-        ~ClangUtilityFunctionHelper() override {}
-        
-        //------------------------------------------------------------------
-        /// Return the object that the parser should use when resolving external
-        /// values.  May be NULL if everything should be self-contained.
-        //------------------------------------------------------------------
-        ClangExpressionDeclMap *
-        DeclMap() override
-        {
-            return m_expr_decl_map_up.get();
-        }
-        
-        void
-        ResetDeclMap()
-        {
-            m_expr_decl_map_up.reset();
-        }
-        
-        void
-        ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory);
-
-        //------------------------------------------------------------------
-        /// Return the object that the parser should allow to access ASTs.
-        /// May be NULL if the ASTs do not need to be transformed.
-        ///
-        /// @param[in] passthrough
-        ///     The ASTConsumer that the returned transformer should send
-        ///     the ASTs to after transformation.
-        //------------------------------------------------------------------
-        clang::ASTConsumer *
-        ASTTransformer(clang::ASTConsumer *passthrough) override
-        {
-            return nullptr;
-        }
-    private:
-        std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
-    };
+  class ClangUtilityFunctionHelper : public ClangExpressionHelper {
+  public:
+    ClangUtilityFunctionHelper() {}
+
+    ~ClangUtilityFunctionHelper() override {}
+
     //------------------------------------------------------------------
-    /// Constructor
-    ///
-    /// @param[in] text
-    ///     The text of the function.  Must be a full translation unit.
-    ///
-    /// @param[in] name
-    ///     The name of the function, as used in the text.
+    /// Return the object that the parser should use when resolving external
+    /// values.  May be NULL if everything should be self-contained.
     //------------------------------------------------------------------
-    ClangUtilityFunction (ExecutionContextScope &exe_scope,
-                          const char *text,
-                          const char *name);
-    
-    ~ClangUtilityFunction() override;
-    
-    ExpressionTypeSystemHelper *
-    GetTypeSystemHelper () override
-    {
-        return &m_type_system_helper;
+    ClangExpressionDeclMap *DeclMap() override {
+      return m_expr_decl_map_up.get();
     }
 
-    ClangExpressionDeclMap *
-    DeclMap()
-    {
-        return m_type_system_helper.DeclMap();
-    }
+    void ResetDeclMap() { m_expr_decl_map_up.reset(); }
 
-    void
-    ResetDeclMap ()
-    {
-        m_type_system_helper.ResetDeclMap();
-    }
-    
-    void
-    ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory)
-    {
-        m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
+    void ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory);
+
+    //------------------------------------------------------------------
+    /// Return the object that the parser should allow to access ASTs.
+    /// May be NULL if the ASTs do not need to be transformed.
+    ///
+    /// @param[in] passthrough
+    ///     The ASTConsumer that the returned transformer should send
+    ///     the ASTs to after transformation.
+    //------------------------------------------------------------------
+    clang::ASTConsumer *
+    ASTTransformer(clang::ASTConsumer *passthrough) override {
+      return nullptr;
     }
 
-    bool
-    Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) override;
+  private:
+    std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
+  };
+  //------------------------------------------------------------------
+  /// Constructor
+  ///
+  /// @param[in] text
+  ///     The text of the function.  Must be a full translation unit.
+  ///
+  /// @param[in] name
+  ///     The name of the function, as used in the text.
+  //------------------------------------------------------------------
+  ClangUtilityFunction(ExecutionContextScope &exe_scope, const char *text,
+                       const char *name);
+
+  ~ClangUtilityFunction() override;
+
+  ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
+    return &m_type_system_helper;
+  }
+
+  ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
+
+  void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
+
+  void ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory) {
+    m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
+  }
+
+  bool Install(DiagnosticManager &diagnostic_manager,
+               ExecutionContext &exe_ctx) override;
 
 private:
-    ClangUtilityFunctionHelper m_type_system_helper; ///< The map to use when parsing and materializing the expression.
+  ClangUtilityFunctionHelper m_type_system_helper; ///< The map to use when
+                                                   ///parsing and materializing
+                                                   ///the expression.
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp Tue Sep  6 15:57:50 2016
@@ -11,17 +11,17 @@
 
 #include "ClangExpressionDeclMap.h"
 
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Module.h"
 #include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Transforms/IPO.h"
 #include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
 #include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/IPO.h"
 
 #include "clang/AST/ASTContext.h"
 
@@ -44,2116 +44,2047 @@ using namespace llvm;
 
 static char ID;
 
-IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) :
-    m_maker(maker),
-    m_values()
-{
-}
+IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
+    : m_maker(maker), m_values() {}
 
-IRForTarget::FunctionValueCache::~FunctionValueCache()
-{
-}
+IRForTarget::FunctionValueCache::~FunctionValueCache() {}
 
 llvm::Value *
-IRForTarget::FunctionValueCache::GetValue(llvm::Function *function)
-{
-    if (!m_values.count(function))
-    {
-        llvm::Value *ret = m_maker(function);
-        m_values[function] = ret;
-        return ret;
-    }
-    return m_values[function];
-}
-
-static llvm::Value *
-FindEntryInstruction (llvm::Function *function)
-{
-    if (function->empty())
-        return NULL;
-
-    return function->getEntryBlock().getFirstNonPHIOrDbg();
-}
-
-IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map,
-                          bool resolve_vars,
-                          lldb_private::IRExecutionUnit &execution_unit,
-                          lldb_private::Stream &error_stream,
-                          const char *func_name) :
-    ModulePass(ID),
-    m_resolve_vars(resolve_vars),
-    m_func_name(func_name),
-    m_module(NULL),
-    m_decl_map(decl_map),
-    m_CFStringCreateWithBytes(NULL),
-    m_sel_registerName(NULL),
-    m_intptr_ty(NULL),
-    m_error_stream(error_stream),
-    m_execution_unit(execution_unit),
-    m_result_store(NULL),
-    m_result_is_pointer(false),
-    m_reloc_placeholder(NULL),
-    m_entry_instruction_finder (FindEntryInstruction)
-{
+IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
+  if (!m_values.count(function)) {
+    llvm::Value *ret = m_maker(function);
+    m_values[function] = ret;
+    return ret;
+  }
+  return m_values[function];
 }
 
-/* Handy utility functions used at several places in the code */
+static llvm::Value *FindEntryInstruction(llvm::Function *function) {
+  if (function->empty())
+    return NULL;
 
-static std::string
-PrintValue(const Value *value, bool truncate = false)
-{
-    std::string s;
-    if (value)
-    {
-        raw_string_ostream rso(s);
-        value->print(rso);
-        rso.flush();
-        if (truncate)
-            s.resize(s.length() - 1);
-    }
-    return s;
+  return function->getEntryBlock().getFirstNonPHIOrDbg();
 }
 
-static std::string
-PrintType(const llvm::Type *type, bool truncate = false)
-{
-    std::string s;
+IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
+                         bool resolve_vars,
+                         lldb_private::IRExecutionUnit &execution_unit,
+                         lldb_private::Stream &error_stream,
+                         const char *func_name)
+    : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
+      m_module(NULL), m_decl_map(decl_map), m_CFStringCreateWithBytes(NULL),
+      m_sel_registerName(NULL), m_intptr_ty(NULL), m_error_stream(error_stream),
+      m_execution_unit(execution_unit), m_result_store(NULL),
+      m_result_is_pointer(false), m_reloc_placeholder(NULL),
+      m_entry_instruction_finder(FindEntryInstruction) {}
+
+/* Handy utility functions used at several places in the code */
+
+static std::string PrintValue(const Value *value, bool truncate = false) {
+  std::string s;
+  if (value) {
     raw_string_ostream rso(s);
-    type->print(rso);
+    value->print(rso);
     rso.flush();
     if (truncate)
-        s.resize(s.length() - 1);
-    return s;
+      s.resize(s.length() - 1);
+  }
+  return s;
 }
 
-IRForTarget::~IRForTarget()
-{
+static std::string PrintType(const llvm::Type *type, bool truncate = false) {
+  std::string s;
+  raw_string_ostream rso(s);
+  type->print(rso);
+  rso.flush();
+  if (truncate)
+    s.resize(s.length() - 1);
+  return s;
 }
 
-bool
-IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function)
-{
-    llvm_function.setLinkage(GlobalValue::ExternalLinkage);
+IRForTarget::~IRForTarget() {}
 
-    return true;
+bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
+  llvm_function.setLinkage(GlobalValue::ExternalLinkage);
+
+  return true;
 }
 
-clang::NamedDecl *
-IRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module)
-{
-    NamedMDNode *named_metadata = module->getNamedMetadata("clang.global.decl.ptrs");
-
-    if (!named_metadata)
-        return NULL;
-
-    unsigned num_nodes = named_metadata->getNumOperands();
-    unsigned node_index;
-
-    for (node_index = 0;
-         node_index < num_nodes;
-         ++node_index)
-    {
-        llvm::MDNode *metadata_node = dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
-        if (!metadata_node)
-            return NULL;
+clang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,
+                                             Module *module) {
+  NamedMDNode *named_metadata =
+      module->getNamedMetadata("clang.global.decl.ptrs");
 
-        if (metadata_node->getNumOperands() != 2)
-            continue;
+  if (!named_metadata)
+    return NULL;
 
-        if (mdconst::dyn_extract_or_null<GlobalValue>(metadata_node->getOperand(0)) != global_val)
-            continue;
+  unsigned num_nodes = named_metadata->getNumOperands();
+  unsigned node_index;
 
-        ConstantInt *constant_int = mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
+  for (node_index = 0; node_index < num_nodes; ++node_index) {
+    llvm::MDNode *metadata_node =
+        dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
+    if (!metadata_node)
+      return NULL;
+
+    if (metadata_node->getNumOperands() != 2)
+      continue;
+
+    if (mdconst::dyn_extract_or_null<GlobalValue>(
+            metadata_node->getOperand(0)) != global_val)
+      continue;
 
-        if (!constant_int)
-            return NULL;
+    ConstantInt *constant_int =
+        mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
 
-        uintptr_t ptr = constant_int->getZExtValue();
+    if (!constant_int)
+      return NULL;
 
-        return reinterpret_cast<clang::NamedDecl *>(ptr);
-    }
+    uintptr_t ptr = constant_int->getZExtValue();
 
-    return NULL;
-}
+    return reinterpret_cast<clang::NamedDecl *>(ptr);
+  }
 
-clang::NamedDecl *
-IRForTarget::DeclForGlobal (GlobalValue *global_val)
-{
-    return DeclForGlobal(global_val, m_module);
+  return NULL;
 }
 
-bool
-IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
+  return DeclForGlobal(global_val, m_module);
+}
 
-    if (!m_resolve_vars)
-        return true;
+bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    // Find the result variable.  If it doesn't exist, we can give up right here.
+  if (!m_resolve_vars)
+    return true;
 
-    ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
+  // Find the result variable.  If it doesn't exist, we can give up right here.
 
-    std::string result_name_str;
-    const char *result_name = NULL;
+  ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
 
-    for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
-         vi != ve;
-         ++vi)
-    {
-        result_name_str = vi->first().str();
-        const char *value_name = result_name_str.c_str();
+  std::string result_name_str;
+  const char *result_name = NULL;
 
-        if (strstr(value_name, "$__lldb_expr_result_ptr") &&
-            strncmp(value_name, "_ZGV", 4))
-        {
-            result_name = value_name;
-            m_result_is_pointer = true;
-            break;
-        }
+  for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
+                                  ve = value_symbol_table.end();
+       vi != ve; ++vi) {
+    result_name_str = vi->first().str();
+    const char *value_name = result_name_str.c_str();
 
-        if (strstr(value_name, "$__lldb_expr_result") &&
-            strncmp(value_name, "_ZGV", 4))
-        {
-            result_name = value_name;
-            m_result_is_pointer = false;
-            break;
-        }
+    if (strstr(value_name, "$__lldb_expr_result_ptr") &&
+        strncmp(value_name, "_ZGV", 4)) {
+      result_name = value_name;
+      m_result_is_pointer = true;
+      break;
     }
 
-    if (!result_name)
-    {
-        if (log)
-            log->PutCString("Couldn't find result variable");
-
-        return true;
+    if (strstr(value_name, "$__lldb_expr_result") &&
+        strncmp(value_name, "_ZGV", 4)) {
+      result_name = value_name;
+      m_result_is_pointer = false;
+      break;
     }
+  }
 
+  if (!result_name) {
     if (log)
-        log->Printf("Result name: \"%s\"", result_name);
-
-    Value *result_value = m_module->getNamedValue(result_name);
+      log->PutCString("Couldn't find result variable");
 
-    if (!result_value)
-    {
-        if (log)
-            log->PutCString("Result variable had no data");
+    return true;
+  }
 
-        m_error_stream.Printf("Internal error [IRForTarget]: Result variable's name (%s) exists, but not its definition\n", result_name);
+  if (log)
+    log->Printf("Result name: \"%s\"", result_name);
 
-        return false;
-    }
+  Value *result_value = m_module->getNamedValue(result_name);
 
+  if (!result_value) {
     if (log)
-        log->Printf("Found result in the IR: \"%s\"", PrintValue(result_value, false).c_str());
-
-    GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
+      log->PutCString("Result variable had no data");
 
-    if (!result_global)
-    {
-        if (log)
-            log->PutCString("Result variable isn't a GlobalVariable");
+    m_error_stream.Printf("Internal error [IRForTarget]: Result variable's "
+                          "name (%s) exists, but not its definition\n",
+                          result_name);
 
-        m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) is defined, but is not a global variable\n", result_name);
-
-        return false;
-    }
-
-    clang::NamedDecl *result_decl = DeclForGlobal (result_global);
-    if (!result_decl)
-    {
-        if (log)
-            log->PutCString("Result variable doesn't have a corresponding Decl");
+    return false;
+  }
 
-        m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) does not have a corresponding Clang entity\n", result_name);
+  if (log)
+    log->Printf("Found result in the IR: \"%s\"",
+                PrintValue(result_value, false).c_str());
 
-        return false;
-    }
+  GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
 
+  if (!result_global) {
     if (log)
-    {
-        std::string decl_desc_str;
-        raw_string_ostream decl_desc_stream(decl_desc_str);
-        result_decl->print(decl_desc_stream);
-        decl_desc_stream.flush();
+      log->PutCString("Result variable isn't a GlobalVariable");
 
-        log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
-    }
-
-    clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
-    if (!result_var)
-    {
-        if (log)
-            log->PutCString("Result variable Decl isn't a VarDecl");
+    m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
+                          "is defined, but is not a global variable\n",
+                          result_name);
 
-        m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s)'s corresponding Clang entity isn't a variable\n", result_name);
-
-        return false;
-    }
-
-    // Get the next available result name from m_decl_map and create the persistent
-    // variable for it
-
-    // If the result is an Lvalue, it is emitted as a pointer; see
-    // ASTResultSynthesizer::SynthesizeBodyResult.
-    if (m_result_is_pointer)
-    {
-        clang::QualType pointer_qual_type = result_var->getType();
-        const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
-
-        const clang::PointerType *pointer_pointertype = pointer_type->getAs<clang::PointerType>();
-        const clang::ObjCObjectPointerType *pointer_objcobjpointertype = pointer_type->getAs<clang::ObjCObjectPointerType>();
-
-        if (pointer_pointertype)
-        {
-            clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
-
-            m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
-                                                         lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
-        }
-        else if (pointer_objcobjpointertype)
-        {
-            clang::QualType element_qual_type = clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
-
-            m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
-                                                         lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
-        }
-        else
-        {
-            if (log)
-                log->PutCString("Expected result to have pointer type, but it did not");
-
-            m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) is not a pointer variable\n", result_name);
+    return false;
+  }
 
-            return false;
-        }
-    }
-    else
-    {
-        m_result_type = lldb_private::TypeFromParser(result_var->getType().getAsOpaquePtr(),
-                                                     lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
-    }
+  clang::NamedDecl *result_decl = DeclForGlobal(result_global);
+  if (!result_decl) {
+    if (log)
+      log->PutCString("Result variable doesn't have a corresponding Decl");
 
+    m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
+                          "does not have a corresponding Clang entity\n",
+                          result_name);
 
-    lldb::TargetSP target_sp (m_execution_unit.GetTarget());
-    lldb_private::ExecutionContext exe_ctx (target_sp, true);
-    if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0)
-    {
-        lldb_private::StreamString type_desc_stream;
-        m_result_type.DumpTypeDescription(&type_desc_stream);
+    return false;
+  }
 
-        if (log)
-            log->Printf("Result type has size 0");
+  if (log) {
+    std::string decl_desc_str;
+    raw_string_ostream decl_desc_stream(decl_desc_str);
+    result_decl->print(decl_desc_stream);
+    decl_desc_stream.flush();
 
-        m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' couldn't be determined\n",
-                                   type_desc_stream.GetData());
-        return false;
-    }
+    log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
+  }
 
+  clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
+  if (!result_var) {
     if (log)
-    {
-        lldb_private::StreamString type_desc_stream;
-        m_result_type.DumpTypeDescription(&type_desc_stream);
+      log->PutCString("Result variable Decl isn't a VarDecl");
 
-        log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
-    }
+    m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
+                          "(%s)'s corresponding Clang entity isn't a "
+                          "variable\n",
+                          result_name);
 
-    m_result_name = lldb_private::ConstString("$RESULT_NAME");
+    return false;
+  }
 
-    if (log)
-        log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
-                    m_result_name.GetCString(),
-                    m_result_type.GetByteSize(nullptr));
-
-    // Construct a new result global and set up its metadata
-
-    GlobalVariable *new_result_global = new GlobalVariable((*m_module),
-                                                           result_global->getType()->getElementType(),
-                                                           false, /* not constant */
-                                                           GlobalValue::ExternalLinkage,
-                                                           NULL, /* no initializer */
-                                                           m_result_name.GetCString ());
-
-    // It's too late in compilation to create a new VarDecl for this, but we don't
-    // need to.  We point the metadata at the old VarDecl.  This creates an odd
-    // anomaly: a variable with a Value whose name is something like $0 and a
-    // Decl whose name is $__lldb_expr_result.  This condition is handled in
-    // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
-    // fixed up.
-
-    ConstantInt *new_constant_int = ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
-                                                     reinterpret_cast<uint64_t>(result_decl),
-                                                     false);
-
-    llvm::Metadata *values[2];
-    values[0] = ConstantAsMetadata::get(new_result_global);
-    values[1] = ConstantAsMetadata::get(new_constant_int);
-
-    ArrayRef<Metadata *> value_ref(values, 2);
-
-    MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
-    NamedMDNode *named_metadata = m_module->getNamedMetadata("clang.global.decl.ptrs");
-    named_metadata->addOperand(persistent_global_md);
+  // Get the next available result name from m_decl_map and create the
+  // persistent
+  // variable for it
+
+  // If the result is an Lvalue, it is emitted as a pointer; see
+  // ASTResultSynthesizer::SynthesizeBodyResult.
+  if (m_result_is_pointer) {
+    clang::QualType pointer_qual_type = result_var->getType();
+    const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
+
+    const clang::PointerType *pointer_pointertype =
+        pointer_type->getAs<clang::PointerType>();
+    const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
+        pointer_type->getAs<clang::ObjCObjectPointerType>();
+
+    if (pointer_pointertype) {
+      clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
+
+      m_result_type = lldb_private::TypeFromParser(
+          element_qual_type.getAsOpaquePtr(),
+          lldb_private::ClangASTContext::GetASTContext(
+              &result_decl->getASTContext()));
+    } else if (pointer_objcobjpointertype) {
+      clang::QualType element_qual_type =
+          clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
+
+      m_result_type = lldb_private::TypeFromParser(
+          element_qual_type.getAsOpaquePtr(),
+          lldb_private::ClangASTContext::GetASTContext(
+              &result_decl->getASTContext()));
+    } else {
+      if (log)
+        log->PutCString("Expected result to have pointer type, but it did not");
+
+      m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) "
+                            "is not a pointer variable\n",
+                            result_name);
+
+      return false;
+    }
+  } else {
+    m_result_type = lldb_private::TypeFromParser(
+        result_var->getType().getAsOpaquePtr(),
+        lldb_private::ClangASTContext::GetASTContext(
+            &result_decl->getASTContext()));
+  }
+
+  lldb::TargetSP target_sp(m_execution_unit.GetTarget());
+  lldb_private::ExecutionContext exe_ctx(target_sp, true);
+  if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0) {
+    lldb_private::StreamString type_desc_stream;
+    m_result_type.DumpTypeDescription(&type_desc_stream);
 
     if (log)
-        log->Printf("Replacing \"%s\" with \"%s\"",
-                    PrintValue(result_global).c_str(),
-                    PrintValue(new_result_global).c_str());
+      log->Printf("Result type has size 0");
 
-    if (result_global->use_empty())
-    {
-        // We need to synthesize a store for this variable, because otherwise
-        // there's nothing to put into its equivalent persistent variable.
-
-        BasicBlock &entry_block(llvm_function.getEntryBlock());
-        Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
-
-        if (!first_entry_instruction)
-            return false;
+    m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
+                          "couldn't be determined\n",
+                          type_desc_stream.GetData());
+    return false;
+  }
 
-        if (!result_global->hasInitializer())
-        {
-            if (log)
-                log->Printf("Couldn't find initializer for unused variable");
+  if (log) {
+    lldb_private::StreamString type_desc_stream;
+    m_result_type.DumpTypeDescription(&type_desc_stream);
+
+    log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
+  }
+
+  m_result_name = lldb_private::ConstString("$RESULT_NAME");
+
+  if (log)
+    log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
+                m_result_name.GetCString(), m_result_type.GetByteSize(nullptr));
+
+  // Construct a new result global and set up its metadata
+
+  GlobalVariable *new_result_global = new GlobalVariable(
+      (*m_module), result_global->getType()->getElementType(),
+      false,                              /* not constant */
+      GlobalValue::ExternalLinkage, NULL, /* no initializer */
+      m_result_name.GetCString());
+
+  // It's too late in compilation to create a new VarDecl for this, but we don't
+  // need to.  We point the metadata at the old VarDecl.  This creates an odd
+  // anomaly: a variable with a Value whose name is something like $0 and a
+  // Decl whose name is $__lldb_expr_result.  This condition is handled in
+  // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
+  // fixed up.
+
+  ConstantInt *new_constant_int =
+      ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
+                       reinterpret_cast<uint64_t>(result_decl), false);
+
+  llvm::Metadata *values[2];
+  values[0] = ConstantAsMetadata::get(new_result_global);
+  values[1] = ConstantAsMetadata::get(new_constant_int);
+
+  ArrayRef<Metadata *> value_ref(values, 2);
+
+  MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
+  NamedMDNode *named_metadata =
+      m_module->getNamedMetadata("clang.global.decl.ptrs");
+  named_metadata->addOperand(persistent_global_md);
+
+  if (log)
+    log->Printf("Replacing \"%s\" with \"%s\"",
+                PrintValue(result_global).c_str(),
+                PrintValue(new_result_global).c_str());
+
+  if (result_global->use_empty()) {
+    // We need to synthesize a store for this variable, because otherwise
+    // there's nothing to put into its equivalent persistent variable.
 
-            m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) has no writes and no initializer\n", result_name);
+    BasicBlock &entry_block(llvm_function.getEntryBlock());
+    Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
 
-            return false;
-        }
+    if (!first_entry_instruction)
+      return false;
 
-        Constant *initializer = result_global->getInitializer();
+    if (!result_global->hasInitializer()) {
+      if (log)
+        log->Printf("Couldn't find initializer for unused variable");
 
-        StoreInst *synthesized_store = new StoreInst(initializer,
-                                                     new_result_global,
-                                                     first_entry_instruction);
+      m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
+                            "(%s) has no writes and no initializer\n",
+                            result_name);
 
-        if (log)
-            log->Printf("Synthesized result store \"%s\"\n", PrintValue(synthesized_store).c_str());
-    }
-    else
-    {
-        result_global->replaceAllUsesWith(new_result_global);
+      return false;
     }
 
-    if (!m_decl_map->AddPersistentVariable(result_decl,
-                                           m_result_name,
-                                           m_result_type,
-                                           true,
-                                           m_result_is_pointer))
-        return false;
+    Constant *initializer = result_global->getInitializer();
 
-    result_global->eraseFromParent();
+    StoreInst *synthesized_store =
+        new StoreInst(initializer, new_result_global, first_entry_instruction);
 
-    return true;
-}
+    if (log)
+      log->Printf("Synthesized result store \"%s\"\n",
+                  PrintValue(synthesized_store).c_str());
+  } else {
+    result_global->replaceAllUsesWith(new_result_global);
+  }
 
-bool
-IRForTarget::RewriteObjCConstString (llvm::GlobalVariable *ns_str,
-                                     llvm::GlobalVariable *cstr)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
-    Type *ns_str_ty = ns_str->getType();
-
-    Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
-    Type *i32_ty = Type::getInt32Ty(m_module->getContext());
-    Type *i8_ty = Type::getInt8Ty(m_module->getContext());
+  if (!m_decl_map->AddPersistentVariable(
+          result_decl, m_result_name, m_result_type, true, m_result_is_pointer))
+    return false;
 
-    if (!m_CFStringCreateWithBytes)
-    {
-        lldb::addr_t CFStringCreateWithBytes_addr;
+  result_global->eraseFromParent();
 
-        static lldb_private::ConstString g_CFStringCreateWithBytes_str ("CFStringCreateWithBytes");
+  return true;
+}
 
-        CFStringCreateWithBytes_addr = m_execution_unit.FindSymbol (g_CFStringCreateWithBytes_str);
-        if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS)
-        {
-            if (log)
-                log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
+bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
+                                         llvm::GlobalVariable *cstr) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-            m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C constant string requires CFStringCreateWithBytes\n");
+  Type *ns_str_ty = ns_str->getType();
 
-            return false;
-        }
+  Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
+  Type *i32_ty = Type::getInt32Ty(m_module->getContext());
+  Type *i8_ty = Type::getInt8Ty(m_module->getContext());
 
-        if (log)
-            log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, CFStringCreateWithBytes_addr);
+  if (!m_CFStringCreateWithBytes) {
+    lldb::addr_t CFStringCreateWithBytes_addr;
 
-        // Build the function type:
-        //
-        // CFStringRef CFStringCreateWithBytes (
-        //   CFAllocatorRef alloc,
-        //   const UInt8 *bytes,
-        //   CFIndex numBytes,
-        //   CFStringEncoding encoding,
-        //   Boolean isExternalRepresentation
-        // );
-        //
-        // We make the following substitutions:
-        //
-        // CFStringRef -> i8*
-        // CFAllocatorRef -> i8*
-        // UInt8 * -> i8*
-        // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its pointer size for now)
-        // CFStringEncoding -> i32
-        // Boolean -> i8
-
-        Type *arg_type_array[5];
-
-        arg_type_array[0] = i8_ptr_ty;
-        arg_type_array[1] = i8_ptr_ty;
-        arg_type_array[2] = m_intptr_ty;
-        arg_type_array[3] = i32_ty;
-        arg_type_array[4] = i8_ty;
-
-        ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
-
-        llvm::Type *CFSCWB_ty = FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
-
-        // Build the constant containing the pointer to the function
-        PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
-        Constant *CFSCWB_addr_int = ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
-        m_CFStringCreateWithBytes = ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty);
-    }
-
-    ConstantDataSequential *string_array = NULL;
-
-    if (cstr)
-        string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
-
-    Constant *alloc_arg         = Constant::getNullValue(i8_ptr_ty);
-    Constant *bytes_arg         = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty) : Constant::getNullValue(i8_ptr_ty);
-    Constant *numBytes_arg      = ConstantInt::get(m_intptr_ty, cstr ? string_array->getNumElements() - 1 : 0, false);
-    Constant *encoding_arg      = ConstantInt::get(i32_ty, 0x0600, false); /* 0x0600 is kCFStringEncodingASCII */
-    Constant *isExternal_arg    = ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
-
-    Value *argument_array[5];
-
-    argument_array[0] = alloc_arg;
-    argument_array[1] = bytes_arg;
-    argument_array[2] = numBytes_arg;
-    argument_array[3] = encoding_arg;
-    argument_array[4] = isExternal_arg;
-
-    ArrayRef <Value *> CFSCWB_arguments(argument_array, 5);
-
-    FunctionValueCache CFSCWB_Caller ([this, &CFSCWB_arguments] (llvm::Function *function)->llvm::Value * {
-        return CallInst::Create(m_CFStringCreateWithBytes,
-                                CFSCWB_arguments,
-                                "CFStringCreateWithBytes",
-                                llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function)));
-    });
+    static lldb_private::ConstString g_CFStringCreateWithBytes_str(
+        "CFStringCreateWithBytes");
 
-    if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder, m_error_stream))
-    {
-        if (log)
-            log->PutCString("Couldn't replace the NSString with the result of the call");
+    CFStringCreateWithBytes_addr =
+        m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str);
+    if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS) {
+      if (log)
+        log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
 
-        m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an Objective-C constant string with a dynamic string\n");
+      m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
+                            "constant string requires "
+                            "CFStringCreateWithBytes\n");
 
-        return false;
+      return false;
     }
 
-    ns_str->eraseFromParent();
-
-    return true;
-}
+    if (log)
+      log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64,
+                  CFStringCreateWithBytes_addr);
 
-bool
-IRForTarget::RewriteObjCConstStrings()
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
-    ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
-
-    for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
-         vi != ve;
-         ++vi)
-    {
-        std::string value_name = vi->first().str();
-        const char *value_name_cstr = value_name.c_str();
+    // Build the function type:
+    //
+    // CFStringRef CFStringCreateWithBytes (
+    //   CFAllocatorRef alloc,
+    //   const UInt8 *bytes,
+    //   CFIndex numBytes,
+    //   CFStringEncoding encoding,
+    //   Boolean isExternalRepresentation
+    // );
+    //
+    // We make the following substitutions:
+    //
+    // CFStringRef -> i8*
+    // CFAllocatorRef -> i8*
+    // UInt8 * -> i8*
+    // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
+    // pointer size for now)
+    // CFStringEncoding -> i32
+    // Boolean -> i8
+
+    Type *arg_type_array[5];
+
+    arg_type_array[0] = i8_ptr_ty;
+    arg_type_array[1] = i8_ptr_ty;
+    arg_type_array[2] = m_intptr_ty;
+    arg_type_array[3] = i32_ty;
+    arg_type_array[4] = i8_ty;
+
+    ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
+
+    llvm::Type *CFSCWB_ty =
+        FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
+
+    // Build the constant containing the pointer to the function
+    PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
+    Constant *CFSCWB_addr_int =
+        ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
+    m_CFStringCreateWithBytes =
+        ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty);
+  }
+
+  ConstantDataSequential *string_array = NULL;
+
+  if (cstr)
+    string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
+
+  Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
+  Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty)
+                             : Constant::getNullValue(i8_ptr_ty);
+  Constant *numBytes_arg = ConstantInt::get(
+      m_intptr_ty, cstr ? string_array->getNumElements() - 1 : 0, false);
+  Constant *encoding_arg = ConstantInt::get(
+      i32_ty, 0x0600, false); /* 0x0600 is kCFStringEncodingASCII */
+  Constant *isExternal_arg =
+      ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
+
+  Value *argument_array[5];
+
+  argument_array[0] = alloc_arg;
+  argument_array[1] = bytes_arg;
+  argument_array[2] = numBytes_arg;
+  argument_array[3] = encoding_arg;
+  argument_array[4] = isExternal_arg;
+
+  ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
+
+  FunctionValueCache CFSCWB_Caller(
+      [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
+        return CallInst::Create(
+            m_CFStringCreateWithBytes, CFSCWB_arguments,
+            "CFStringCreateWithBytes",
+            llvm::cast<Instruction>(
+                m_entry_instruction_finder.GetValue(function)));
+      });
 
-        if (strstr(value_name_cstr, "_unnamed_cfstring_"))
-        {
-            Value *nsstring_value = vi->second;
+  if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller,
+                      m_entry_instruction_finder, m_error_stream)) {
+    if (log)
+      log->PutCString(
+          "Couldn't replace the NSString with the result of the call");
 
-            GlobalVariable *nsstring_global = dyn_cast<GlobalVariable>(nsstring_value);
+    m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
+                          "Objective-C constant string with a dynamic "
+                          "string\n");
 
-            if (!nsstring_global)
-            {
-                if (log)
-                    log->PutCString("NSString variable is not a GlobalVariable");
+    return false;
+  }
 
-                m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string is not a global variable\n");
+  ns_str->eraseFromParent();
 
-                return false;
-            }
+  return true;
+}
 
-            if (!nsstring_global->hasInitializer())
-            {
-                if (log)
-                    log->PutCString("NSString variable does not have an initializer");
+bool IRForTarget::RewriteObjCConstStrings() {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-                m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string does not have an initializer\n");
+  ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
 
-                return false;
-            }
+  for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
+                                  ve = value_symbol_table.end();
+       vi != ve; ++vi) {
+    std::string value_name = vi->first().str();
+    const char *value_name_cstr = value_name.c_str();
 
-            ConstantStruct *nsstring_struct = dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
+    if (strstr(value_name_cstr, "_unnamed_cfstring_")) {
+      Value *nsstring_value = vi->second;
 
-            if (!nsstring_struct)
-            {
-                if (log)
-                    log->PutCString("NSString variable's initializer is not a ConstantStruct");
+      GlobalVariable *nsstring_global =
+          dyn_cast<GlobalVariable>(nsstring_value);
 
-                m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string is not a structure constant\n");
+      if (!nsstring_global) {
+        if (log)
+          log->PutCString("NSString variable is not a GlobalVariable");
 
-                return false;
-            }
+        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+                              "constant string is not a global variable\n");
 
-            // We expect the following structure:
-            //
-            // struct {
-            //   int *isa;
-            //   int flags;
-            //   char *str;
-            //   long length;
-            // };
-
-            if (nsstring_struct->getNumOperands() != 4)
-            {
-                if (log)
-                    log->Printf("NSString variable's initializer structure has an unexpected number of members.  Should be 4, is %d", nsstring_struct->getNumOperands());
+        return false;
+      }
 
-                m_error_stream.Printf("Internal error [IRForTarget]: The struct for an Objective-C constant string is not as expected\n");
+      if (!nsstring_global->hasInitializer()) {
+        if (log)
+          log->PutCString("NSString variable does not have an initializer");
 
-                return false;
-            }
+        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+                              "constant string does not have an initializer\n");
 
-            Constant *nsstring_member = nsstring_struct->getOperand(2);
+        return false;
+      }
 
-            if (!nsstring_member)
-            {
-                if (log)
-                    log->PutCString("NSString initializer's str element was empty");
+      ConstantStruct *nsstring_struct =
+          dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
 
-                m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string does not have a string initializer\n");
+      if (!nsstring_struct) {
+        if (log)
+          log->PutCString(
+              "NSString variable's initializer is not a ConstantStruct");
 
-                return false;
-            }
+        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+                              "constant string is not a structure constant\n");
 
-            ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
+        return false;
+      }
 
-            if (!nsstring_expr)
-            {
-                if (log)
-                    log->PutCString("NSString initializer's str element is not a ConstantExpr");
+      // We expect the following structure:
+      //
+      // struct {
+      //   int *isa;
+      //   int flags;
+      //   char *str;
+      //   long length;
+      // };
 
-                m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not constant\n");
+      if (nsstring_struct->getNumOperands() != 4) {
+        if (log)
+          log->Printf("NSString variable's initializer structure has an "
+                      "unexpected number of members.  Should be 4, is %d",
+                      nsstring_struct->getNumOperands());
 
-                return false;
-            }
+        m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
+                              "Objective-C constant string is not as "
+                              "expected\n");
 
-            if (nsstring_expr->getOpcode() != Instruction::GetElementPtr)
-            {
-                if (log)
-                    log->Printf("NSString initializer's str element is not a GetElementPtr expression, it's a %s", nsstring_expr->getOpcodeName());
+        return false;
+      }
 
-                m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not an array\n");
+      Constant *nsstring_member = nsstring_struct->getOperand(2);
 
-                return false;
-            }
+      if (!nsstring_member) {
+        if (log)
+          log->PutCString("NSString initializer's str element was empty");
 
-            Constant *nsstring_cstr = nsstring_expr->getOperand(0);
+        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+                              "constant string does not have a string "
+                              "initializer\n");
 
-            GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
+        return false;
+      }
 
-            if (!cstr_global)
-            {
-                if (log)
-                    log->PutCString("NSString initializer's str element is not a GlobalVariable");
+      ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
 
-                m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a global\n");
+      if (!nsstring_expr) {
+        if (log)
+          log->PutCString(
+              "NSString initializer's str element is not a ConstantExpr");
 
-                return false;
-            }
+        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+                              "constant string's string initializer is not "
+                              "constant\n");
 
-            if (!cstr_global->hasInitializer())
-            {
-                if (log)
-                    log->PutCString("NSString initializer's str element does not have an initializer");
+        return false;
+      }
 
-                m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to initialized data\n");
+      if (nsstring_expr->getOpcode() != Instruction::GetElementPtr) {
+        if (log)
+          log->Printf("NSString initializer's str element is not a "
+                      "GetElementPtr expression, it's a %s",
+                      nsstring_expr->getOpcodeName());
 
-                return false;
-            }
+        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+                              "constant string's string initializer is not an "
+                              "array\n");
 
-            /*
-            if (!cstr_array)
-            {
-                if (log)
-                    log->PutCString("NSString initializer's str element is not a ConstantArray");
+        return false;
+      }
 
-                if (m_error_stream)
-                    m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to an array\n");
+      Constant *nsstring_cstr = nsstring_expr->getOperand(0);
 
-                return false;
-            }
+      GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
 
-            if (!cstr_array->isCString())
-            {
-                if (log)
-                    log->PutCString("NSString initializer's str element is not a C string array");
+      if (!cstr_global) {
+        if (log)
+          log->PutCString(
+              "NSString initializer's str element is not a GlobalVariable");
 
-                if (m_error_stream)
-                    m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a C string\n");
+        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+                              "constant string's string initializer doesn't "
+                              "point to a global\n");
 
-                return false;
-            }
-            */
+        return false;
+      }
 
-            ConstantDataArray *cstr_array = dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
+      if (!cstr_global->hasInitializer()) {
+        if (log)
+          log->PutCString("NSString initializer's str element does not have an "
+                          "initializer");
 
-            if (log)
-            {
-                if (cstr_array)
-                    log->Printf("Found NSString constant %s, which contains \"%s\"", value_name_cstr, cstr_array->getAsString().str().c_str());
-                else
-                    log->Printf("Found NSString constant %s, which contains \"\"", value_name_cstr);
-            }
+        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
+                              "constant string's string initializer doesn't "
+                              "point to initialized data\n");
+
+        return false;
+      }
+
+      /*
+      if (!cstr_array)
+      {
+          if (log)
+              log->PutCString("NSString initializer's str element is not a
+      ConstantArray");
+
+          if (m_error_stream)
+              m_error_stream.Printf("Internal error [IRForTarget]: An
+      Objective-C constant string's string initializer doesn't point to an
+      array\n");
+
+          return false;
+      }
+
+      if (!cstr_array->isCString())
+      {
+          if (log)
+              log->PutCString("NSString initializer's str element is not a C
+      string array");
+
+          if (m_error_stream)
+              m_error_stream.Printf("Internal error [IRForTarget]: An
+      Objective-C constant string's string initializer doesn't point to a C
+      string\n");
+
+          return false;
+      }
+      */
+
+      ConstantDataArray *cstr_array =
+          dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
+
+      if (log) {
+        if (cstr_array)
+          log->Printf("Found NSString constant %s, which contains \"%s\"",
+                      value_name_cstr, cstr_array->getAsString().str().c_str());
+        else
+          log->Printf("Found NSString constant %s, which contains \"\"",
+                      value_name_cstr);
+      }
 
-            if (!cstr_array)
-                cstr_global = NULL;
+      if (!cstr_array)
+        cstr_global = NULL;
 
-            if (!RewriteObjCConstString(nsstring_global, cstr_global))
-            {
-                if (log)
-                    log->PutCString("Error rewriting the constant string");
+      if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
+        if (log)
+          log->PutCString("Error rewriting the constant string");
 
-                // We don't print an error message here because RewriteObjCConstString has done so for us.
+        // We don't print an error message here because RewriteObjCConstString
+        // has done so for us.
 
-                return false;
-            }
-        }
+        return false;
+      }
     }
+  }
 
-    for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
-         vi != ve;
-         ++vi)
-    {
-        std::string value_name = vi->first().str();
-        const char *value_name_cstr = value_name.c_str();
+  for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
+                                  ve = value_symbol_table.end();
+       vi != ve; ++vi) {
+    std::string value_name = vi->first().str();
+    const char *value_name_cstr = value_name.c_str();
 
-        if (!strcmp(value_name_cstr, "__CFConstantStringClassReference"))
-        {
-            GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
+    if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) {
+      GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
 
-            if (!gv)
-            {
-                if (log)
-                    log->PutCString("__CFConstantStringClassReference is not a global variable");
+      if (!gv) {
+        if (log)
+          log->PutCString(
+              "__CFConstantStringClassReference is not a global variable");
 
-                m_error_stream.Printf("Internal error [IRForTarget]: Found a CFConstantStringClassReference, but it is not a global object\n");
+        m_error_stream.Printf("Internal error [IRForTarget]: Found a "
+                              "CFConstantStringClassReference, but it is not a "
+                              "global object\n");
 
-                return false;
-            }
+        return false;
+      }
 
-            gv->eraseFromParent();
+      gv->eraseFromParent();
 
-            break;
-        }
+      break;
     }
+  }
 
-    return true;
+  return true;
 }
 
-static bool IsObjCSelectorRef (Value *value)
-{
-    GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
+static bool IsObjCSelectorRef(Value *value) {
+  GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
 
-    if (!global_variable || !global_variable->hasName() || !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
-        return false;
+  if (!global_variable || !global_variable->hasName() ||
+      !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
+    return false;
 
-    return true;
+  return true;
 }
 
 // This function does not report errors; its callers are responsible.
-bool
-IRForTarget::RewriteObjCSelector (Instruction* selector_load)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    LoadInst *load = dyn_cast<LoadInst>(selector_load);
+  LoadInst *load = dyn_cast<LoadInst>(selector_load);
 
-    if (!load)
-        return false;
+  if (!load)
+    return false;
 
-    // Unpack the message name from the selector.  In LLVM IR, an objc_msgSend gets represented as
-    //
-    // %tmp     = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*>
-    // %call    = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
-    //
-    // where %obj is the object pointer and %tmp is the selector.
-    //
-    // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
-    // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
+  // Unpack the message name from the selector.  In LLVM IR, an objc_msgSend
+  // gets represented as
+  //
+  // %tmp     = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*>
+  // %call    = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...)
+  // ; <i8*>
+  //
+  // where %obj is the object pointer and %tmp is the selector.
+  //
+  // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
+  // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
+  // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
 
-    // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target
+  // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr)
+  // and get the string from its target
 
-    GlobalVariable *_objc_selector_references_ = dyn_cast<GlobalVariable>(load->getPointerOperand());
+  GlobalVariable *_objc_selector_references_ =
+      dyn_cast<GlobalVariable>(load->getPointerOperand());
 
-    if (!_objc_selector_references_ || !_objc_selector_references_->hasInitializer())
-        return false;
+  if (!_objc_selector_references_ ||
+      !_objc_selector_references_->hasInitializer())
+    return false;
 
-    Constant *osr_initializer = _objc_selector_references_->getInitializer();
+  Constant *osr_initializer = _objc_selector_references_->getInitializer();
 
-    ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
+  ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
 
-    if (!osr_initializer_expr || osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
-        return false;
+  if (!osr_initializer_expr ||
+      osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
+    return false;
 
-    Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
+  Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
 
-    if (!osr_initializer_base)
-        return false;
+  if (!osr_initializer_base)
+    return false;
 
-    // Find the string's initializer (a ConstantArray) and get the string from it
+  // Find the string's initializer (a ConstantArray) and get the string from it
 
-    GlobalVariable *_objc_meth_var_name_ = dyn_cast<GlobalVariable>(osr_initializer_base);
+  GlobalVariable *_objc_meth_var_name_ =
+      dyn_cast<GlobalVariable>(osr_initializer_base);
 
-    if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
-        return false;
+  if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
+    return false;
 
-    Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
+  Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
 
-    ConstantDataArray *omvn_initializer_array = dyn_cast<ConstantDataArray>(omvn_initializer);
+  ConstantDataArray *omvn_initializer_array =
+      dyn_cast<ConstantDataArray>(omvn_initializer);
 
-    if (!omvn_initializer_array->isString())
-        return false;
+  if (!omvn_initializer_array->isString())
+    return false;
 
-    std::string omvn_initializer_string = omvn_initializer_array->getAsString();
+  std::string omvn_initializer_string = omvn_initializer_array->getAsString();
 
-    if (log)
-        log->Printf("Found Objective-C selector reference \"%s\"", omvn_initializer_string.c_str());
+  if (log)
+    log->Printf("Found Objective-C selector reference \"%s\"",
+                omvn_initializer_string.c_str());
 
-    // Construct a call to sel_registerName
+  // Construct a call to sel_registerName
 
-    if (!m_sel_registerName)
-    {
-        lldb::addr_t sel_registerName_addr;
+  if (!m_sel_registerName) {
+    lldb::addr_t sel_registerName_addr;
 
-        static lldb_private::ConstString g_sel_registerName_str ("sel_registerName");
-        sel_registerName_addr = m_execution_unit.FindSymbol (g_sel_registerName_str);
-        if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
-            return false;
+    static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
+    sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str);
+    if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
+      return false;
 
-        if (log)
-            log->Printf("Found sel_registerName at 0x%" PRIx64, sel_registerName_addr);
+    if (log)
+      log->Printf("Found sel_registerName at 0x%" PRIx64,
+                  sel_registerName_addr);
 
-        // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
+    // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
 
-        // The below code would be "more correct," but in actuality what's required is uint8_t*
-        //Type *sel_type = StructType::get(m_module->getContext());
-        //Type *sel_ptr_type = PointerType::getUnqual(sel_type);
-        Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
+    // The below code would be "more correct," but in actuality what's required
+    // is uint8_t*
+    // Type *sel_type = StructType::get(m_module->getContext());
+    // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
+    Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
 
-        Type *type_array[1];
+    Type *type_array[1];
 
-        type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
+    type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
 
-        ArrayRef<Type *> srN_arg_types(type_array, 1);
+    ArrayRef<Type *> srN_arg_types(type_array, 1);
 
-        llvm::Type *srN_type = FunctionType::get(sel_ptr_type, srN_arg_types, false);
+    llvm::Type *srN_type =
+        FunctionType::get(sel_ptr_type, srN_arg_types, false);
 
-        // Build the constant containing the pointer to the function
-        PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
-        Constant *srN_addr_int = ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
-        m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
-    }
+    // Build the constant containing the pointer to the function
+    PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
+    Constant *srN_addr_int =
+        ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
+    m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
+  }
 
-    Value *argument_array[1];
+  Value *argument_array[1];
 
-    Constant *omvn_pointer = ConstantExpr::getBitCast(_objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
+  Constant *omvn_pointer = ConstantExpr::getBitCast(
+      _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
 
-    argument_array[0] = omvn_pointer;
+  argument_array[0] = omvn_pointer;
 
-    ArrayRef<Value *> srN_arguments(argument_array, 1);
+  ArrayRef<Value *> srN_arguments(argument_array, 1);
 
-    CallInst *srN_call = CallInst::Create(m_sel_registerName,
-                                          srN_arguments,
-                                          "sel_registerName",
-                                          selector_load);
+  CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments,
+                                        "sel_registerName", selector_load);
 
-    // Replace the load with the call in all users
+  // Replace the load with the call in all users
 
-    selector_load->replaceAllUsesWith(srN_call);
+  selector_load->replaceAllUsesWith(srN_call);
 
-    selector_load->eraseFromParent();
+  selector_load->eraseFromParent();
 
-    return true;
+  return true;
 }
 
-bool
-IRForTarget::RewriteObjCSelectors (BasicBlock &basic_block)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    BasicBlock::iterator ii;
+  BasicBlock::iterator ii;
 
-    typedef SmallVector <Instruction*, 2> InstrList;
-    typedef InstrList::iterator InstrIterator;
+  typedef SmallVector<Instruction *, 2> InstrList;
+  typedef InstrList::iterator InstrIterator;
 
-    InstrList selector_loads;
+  InstrList selector_loads;
 
-    for (ii = basic_block.begin();
-         ii != basic_block.end();
-         ++ii)
-    {
-        Instruction &inst = *ii;
+  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+    Instruction &inst = *ii;
 
-        if (LoadInst *load = dyn_cast<LoadInst>(&inst))
-            if (IsObjCSelectorRef(load->getPointerOperand()))
-                selector_loads.push_back(&inst);
-    }
+    if (LoadInst *load = dyn_cast<LoadInst>(&inst))
+      if (IsObjCSelectorRef(load->getPointerOperand()))
+        selector_loads.push_back(&inst);
+  }
 
-    InstrIterator iter;
+  InstrIterator iter;
 
-    for (iter = selector_loads.begin();
-         iter != selector_loads.end();
-         ++iter)
-    {
-        if (!RewriteObjCSelector(*iter))
-        {
-            m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a static reference to an Objective-C selector to a dynamic reference\n");
+  for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) {
+    if (!RewriteObjCSelector(*iter)) {
+      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
+                            "static reference to an Objective-C selector to a "
+                            "dynamic reference\n");
 
-            if (log)
-                log->PutCString("Couldn't rewrite a reference to an Objective-C selector");
+      if (log)
+        log->PutCString(
+            "Couldn't rewrite a reference to an Objective-C selector");
 
-            return false;
-        }
+      return false;
     }
+  }
 
-    return true;
+  return true;
 }
 
 // This function does not report errors; its callers are responsible.
-bool
-IRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
+  AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
 
-    MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
+  MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
 
-    if (!alloc_md || !alloc_md->getNumOperands())
-        return false;
+  if (!alloc_md || !alloc_md->getNumOperands())
+    return false;
 
-    ConstantInt *constant_int = mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
+  ConstantInt *constant_int =
+      mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
 
-    if (!constant_int)
-        return false;
+  if (!constant_int)
+    return false;
 
-    // We attempt to register this as a new persistent variable with the DeclMap.
+  // We attempt to register this as a new persistent variable with the DeclMap.
 
-    uintptr_t ptr = constant_int->getZExtValue();
+  uintptr_t ptr = constant_int->getZExtValue();
 
-    clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
+  clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
 
-    lldb_private::TypeFromParser result_decl_type (decl->getType().getAsOpaquePtr(),
-                                                   lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
+  lldb_private::TypeFromParser result_decl_type(
+      decl->getType().getAsOpaquePtr(),
+      lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
 
-    StringRef decl_name (decl->getName());
-    lldb_private::ConstString persistent_variable_name (decl_name.data(), decl_name.size());
-    if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name, result_decl_type, false, false))
-        return false;
+  StringRef decl_name(decl->getName());
+  lldb_private::ConstString persistent_variable_name(decl_name.data(),
+                                                     decl_name.size());
+  if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
+                                         result_decl_type, false, false))
+    return false;
 
-    GlobalVariable *persistent_global = new GlobalVariable((*m_module),
-                                                           alloc->getType(),
-                                                           false, /* not constant */
-                                                           GlobalValue::ExternalLinkage,
-                                                           NULL, /* no initializer */
-                                                           alloc->getName().str().c_str());
+  GlobalVariable *persistent_global = new GlobalVariable(
+      (*m_module), alloc->getType(), false, /* not constant */
+      GlobalValue::ExternalLinkage, NULL,   /* no initializer */
+      alloc->getName().str().c_str());
 
-    // What we're going to do here is make believe this was a regular old external
-    // variable.  That means we need to make the metadata valid.
+  // What we're going to do here is make believe this was a regular old external
+  // variable.  That means we need to make the metadata valid.
 
-    NamedMDNode *named_metadata = m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
+  NamedMDNode *named_metadata =
+      m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
 
-    llvm::Metadata *values[2];
-    values[0] = ConstantAsMetadata::get(persistent_global);
-    values[1] = ConstantAsMetadata::get(constant_int);
+  llvm::Metadata *values[2];
+  values[0] = ConstantAsMetadata::get(persistent_global);
+  values[1] = ConstantAsMetadata::get(constant_int);
 
-    ArrayRef<llvm::Metadata *> value_ref(values, 2);
+  ArrayRef<llvm::Metadata *> value_ref(values, 2);
 
-    MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
-    named_metadata->addOperand(persistent_global_md);
+  MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
+  named_metadata->addOperand(persistent_global_md);
 
-    // Now, since the variable is a pointer variable, we will drop in a load of that
-    // pointer variable.
+  // Now, since the variable is a pointer variable, we will drop in a load of
+  // that
+  // pointer variable.
 
-    LoadInst *persistent_load = new LoadInst (persistent_global, "", alloc);
+  LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
 
-    if (log)
-        log->Printf("Replacing \"%s\" with \"%s\"",
-                    PrintValue(alloc).c_str(),
-                    PrintValue(persistent_load).c_str());
+  if (log)
+    log->Printf("Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(),
+                PrintValue(persistent_load).c_str());
 
-    alloc->replaceAllUsesWith(persistent_load);
-    alloc->eraseFromParent();
+  alloc->replaceAllUsesWith(persistent_load);
+  alloc->eraseFromParent();
 
-    return true;
+  return true;
 }
 
-bool
-IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block)
-{
-    if (!m_resolve_vars)
-        return true;
+bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
+  if (!m_resolve_vars)
+    return true;
 
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    BasicBlock::iterator ii;
+  BasicBlock::iterator ii;
 
-    typedef SmallVector <Instruction*, 2> InstrList;
-    typedef InstrList::iterator InstrIterator;
+  typedef SmallVector<Instruction *, 2> InstrList;
+  typedef InstrList::iterator InstrIterator;
 
-    InstrList pvar_allocs;
+  InstrList pvar_allocs;
 
-    for (ii = basic_block.begin();
-         ii != basic_block.end();
-         ++ii)
-    {
-        Instruction &inst = *ii;
+  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+    Instruction &inst = *ii;
 
-        if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst))
-        {
-            llvm::StringRef alloc_name = alloc->getName();
-
-            if (alloc_name.startswith("$") &&
-                !alloc_name.startswith("$__lldb"))
-            {
-                if (alloc_name.find_first_of("0123456789") == 1)
-                {
-                    if (log)
-                        log->Printf("Rejecting a numeric persistent variable.");
+    if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
+      llvm::StringRef alloc_name = alloc->getName();
 
-                    m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, $1, ... are reserved for use as result names\n");
+      if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
+        if (alloc_name.find_first_of("0123456789") == 1) {
+          if (log)
+            log->Printf("Rejecting a numeric persistent variable.");
 
-                    return false;
-                }
+          m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
+                                "$1, ... are reserved for use as result "
+                                "names\n");
 
-                pvar_allocs.push_back(alloc);
-            }
+          return false;
         }
+
+        pvar_allocs.push_back(alloc);
+      }
     }
+  }
 
-    InstrIterator iter;
+  InstrIterator iter;
 
-    for (iter = pvar_allocs.begin();
-         iter != pvar_allocs.end();
-         ++iter)
-    {
-        if (!RewritePersistentAlloc(*iter))
-        {
-            m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite the creation of a persistent variable\n");
+  for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) {
+    if (!RewritePersistentAlloc(*iter)) {
+      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
+                            "the creation of a persistent variable\n");
 
-            if (log)
-                log->PutCString("Couldn't rewrite the creation of a persistent variable");
+      if (log)
+        log->PutCString(
+            "Couldn't rewrite the creation of a persistent variable");
 
-            return false;
-        }
+      return false;
     }
+  }
 
-    return true;
+  return true;
 }
 
-bool
-IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer)
-{
-    if (!initializer)
-        return true;
+bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
+  if (!initializer)
+    return true;
 
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    if (log && log->GetVerbose())
-        log->Printf("  MaterializeInitializer(%p, %s)", (void *)data, PrintValue(initializer).c_str());
+  if (log && log->GetVerbose())
+    log->Printf("  MaterializeInitializer(%p, %s)", (void *)data,
+                PrintValue(initializer).c_str());
 
-    Type *initializer_type = initializer->getType();
+  Type *initializer_type = initializer->getType();
 
-    if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer))
-    {
-        size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
-        lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8);
+  if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) {
+    size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
+    lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(
+        llvm::NextPowerOf2(constant_size) * 8);
 
-        lldb_private::Error get_data_error;
-        if (!scalar.GetAsMemoryData(data, constant_size, lldb_private::endian::InlHostByteOrder(), get_data_error))
-            return false;
+    lldb_private::Error get_data_error;
+    if (!scalar.GetAsMemoryData(data, constant_size,
+                                lldb_private::endian::InlHostByteOrder(),
+                                get_data_error))
+      return false;
 
-        return true;
-    }
-    else if (ConstantDataArray *array_initializer = dyn_cast<ConstantDataArray>(initializer))
-    {
-        if (array_initializer->isString())
-        {
-            std::string array_initializer_string = array_initializer->getAsString();
-            memcpy (data, array_initializer_string.c_str(), m_target_data->getTypeStoreSize(initializer_type));
-        }
-        else
-        {
-            ArrayType *array_initializer_type = array_initializer->getType();
-            Type *array_element_type = array_initializer_type->getElementType();
-
-            size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
-
-            for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i)
-            {
-                Value *operand_value = array_initializer->getOperand(i);
-                Constant *operand_constant = dyn_cast<Constant>(operand_value);
+    return true;
+  } else if (ConstantDataArray *array_initializer =
+                 dyn_cast<ConstantDataArray>(initializer)) {
+    if (array_initializer->isString()) {
+      std::string array_initializer_string = array_initializer->getAsString();
+      memcpy(data, array_initializer_string.c_str(),
+             m_target_data->getTypeStoreSize(initializer_type));
+    } else {
+      ArrayType *array_initializer_type = array_initializer->getType();
+      Type *array_element_type = array_initializer_type->getElementType();
 
-                if (!operand_constant)
-                    return false;
+      size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
 
-                if (!MaterializeInitializer(data + (i * element_size), operand_constant))
-                    return false;
-            }
-        }
-        return true;
-    }
-    else if (ConstantStruct *struct_initializer = dyn_cast<ConstantStruct>(initializer))
-    {
-        StructType *struct_initializer_type = struct_initializer->getType();
-        const StructLayout *struct_layout = m_target_data->getStructLayout(struct_initializer_type);
+      for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) {
+        Value *operand_value = array_initializer->getOperand(i);
+        Constant *operand_constant = dyn_cast<Constant>(operand_value);
 
-        for (unsigned i = 0;
-             i < struct_initializer->getNumOperands();
-             ++i)
-        {
-            if (!MaterializeInitializer(data + struct_layout->getElementOffset(i), struct_initializer->getOperand(i)))
-                return false;
-        }
-        return true;
+        if (!operand_constant)
+          return false;
+
+        if (!MaterializeInitializer(data + (i * element_size),
+                                    operand_constant))
+          return false;
+      }
     }
-    else if (isa<ConstantAggregateZero>(initializer))
-    {
-        memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
-        return true;
+    return true;
+  } else if (ConstantStruct *struct_initializer =
+                 dyn_cast<ConstantStruct>(initializer)) {
+    StructType *struct_initializer_type = struct_initializer->getType();
+    const StructLayout *struct_layout =
+        m_target_data->getStructLayout(struct_initializer_type);
+
+    for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) {
+      if (!MaterializeInitializer(data + struct_layout->getElementOffset(i),
+                                  struct_initializer->getOperand(i)))
+        return false;
     }
-    return false;
+    return true;
+  } else if (isa<ConstantAggregateZero>(initializer)) {
+    memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
+    return true;
+  }
+  return false;
 }
 
 // This function does not report errors; its callers are responsible.
-bool
-IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+  if (log)
+    log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
+
+  if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
+    switch (constant_expr->getOpcode()) {
+    default:
+      break;
+    case Instruction::GetElementPtr:
+    case Instruction::BitCast:
+      Value *s = constant_expr->getOperand(0);
+      if (!MaybeHandleVariable(s))
+        return false;
+    }
+  } else if (GlobalVariable *global_variable =
+                 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
+    if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
+      return true;
 
-    if (log)
-        log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
+    clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
 
-    if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr))
-    {
-        switch (constant_expr->getOpcode())
-        {
-        default:
-            break;
-        case Instruction::GetElementPtr:
-        case Instruction::BitCast:
-            Value *s = constant_expr->getOperand(0);
-            if (!MaybeHandleVariable(s))
-                return false;
-        }
-    }
-    else if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(llvm_value_ptr))
-    {
-        if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
-            return true;
+    if (!named_decl) {
+      if (IsObjCSelectorRef(llvm_value_ptr))
+        return true;
 
-        clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
+      if (!global_variable->hasExternalLinkage())
+        return true;
 
-        if (!named_decl)
-        {
-            if (IsObjCSelectorRef(llvm_value_ptr))
-                return true;
+      if (log)
+        log->Printf("Found global variable \"%s\" without metadata",
+                    global_variable->getName().str().c_str());
+
+      return false;
+    }
+
+    std::string name(named_decl->getName().str());
+
+    clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
+    if (value_decl == NULL)
+      return false;
+
+    lldb_private::CompilerType compiler_type(&value_decl->getASTContext(),
+                                             value_decl->getType());
+
+    const Type *value_type = NULL;
+
+    if (name[0] == '$') {
+      // The $__lldb_expr_result name indicates the return value has allocated
+      // as
+      // a static variable.  Per the comment at
+      // ASTResultSynthesizer::SynthesizeBodyResult,
+      // accesses to this static variable need to be redirected to the result of
+      // dereferencing
+      // a pointer that is passed in as one of the arguments.
+      //
+      // Consequently, when reporting the size of the type, we report a pointer
+      // type pointing
+      // to the type of $__lldb_expr_result, not the type itself.
+      //
+      // We also do this for any user-declared persistent variables.
+      compiler_type = compiler_type.GetPointerType();
+      value_type = PointerType::get(global_variable->getType(), 0);
+    } else {
+      value_type = global_variable->getType();
+    }
+
+    const uint64_t value_size = compiler_type.GetByteSize(nullptr);
+    lldb::offset_t value_alignment =
+        (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
+
+    if (log) {
+      log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64
+                  ", align %" PRIu64 "]",
+                  name.c_str(),
+                  lldb_private::ClangUtil::GetQualType(compiler_type)
+                      .getAsString()
+                      .c_str(),
+                  PrintType(value_type).c_str(), value_size, value_alignment);
+    }
+
+    if (named_decl &&
+        !m_decl_map->AddValueToStruct(
+            named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr,
+            value_size, value_alignment)) {
+      if (!global_variable->hasExternalLinkage())
+        return true;
+      else
+        return true;
+    }
+  } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
+    if (log)
+      log->Printf("Function pointers aren't handled right now");
 
-            if (!global_variable->hasExternalLinkage())
-                return true;
+    return false;
+  }
 
-            if (log)
-                log->Printf("Found global variable \"%s\" without metadata", global_variable->getName().str().c_str());
+  return true;
+}
 
-            return false;
-        }
+// This function does not report errors; its callers are responsible.
+bool IRForTarget::HandleSymbol(Value *symbol) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-        std::string name (named_decl->getName().str());
+  lldb_private::ConstString name(symbol->getName().str().c_str());
 
-        clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
-        if (value_decl == NULL)
-            return false;
+  lldb::addr_t symbol_addr =
+      m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
 
-        lldb_private::CompilerType compiler_type(&value_decl->getASTContext(), value_decl->getType());
+  if (symbol_addr == LLDB_INVALID_ADDRESS) {
+    if (log)
+      log->Printf("Symbol \"%s\" had no address", name.GetCString());
 
-        const Type *value_type = NULL;
+    return false;
+  }
 
-        if (name[0] == '$')
-        {
-            // The $__lldb_expr_result name indicates the return value has allocated as
-            // a static variable.  Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
-            // accesses to this static variable need to be redirected to the result of dereferencing
-            // a pointer that is passed in as one of the arguments.
-            //
-            // Consequently, when reporting the size of the type, we report a pointer type pointing
-            // to the type of $__lldb_expr_result, not the type itself.
-            //
-            // We also do this for any user-declared persistent variables.
-            compiler_type = compiler_type.GetPointerType();
-            value_type = PointerType::get(global_variable->getType(), 0);
-        }
-        else
-        {
-            value_type = global_variable->getType();
-        }
+  if (log)
+    log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
 
-        const uint64_t value_size = compiler_type.GetByteSize(nullptr);
-        lldb::offset_t value_alignment = (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
+  Type *symbol_type = symbol->getType();
 
-        if (log)
-        {
-            log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRIu64 "]",
-                        name.c_str(), lldb_private::ClangUtil::GetQualType(compiler_type).getAsString().c_str(),
-                        PrintType(value_type).c_str(), value_size, value_alignment);
-        }
+  Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
 
+  Value *symbol_addr_ptr =
+      ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
 
-        if (named_decl && !m_decl_map->AddValueToStruct(named_decl,
-                                                        lldb_private::ConstString (name.c_str()),
-                                                        llvm_value_ptr,
-                                                        value_size,
-                                                        value_alignment))
-        {
-            if (!global_variable->hasExternalLinkage())
-                return true;
-            else
-                return true;
-        }
-    }
-    else if (dyn_cast<llvm::Function>(llvm_value_ptr))
-    {
-        if (log)
-            log->Printf("Function pointers aren't handled right now");
+  if (log)
+    log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(),
+                PrintValue(symbol_addr_ptr).c_str());
 
-        return false;
-    }
+  symbol->replaceAllUsesWith(symbol_addr_ptr);
 
-    return true;
+  return true;
 }
 
-// This function does not report errors; its callers are responsible.
-bool
-IRForTarget::HandleSymbol (Value *symbol)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    lldb_private::ConstString name(symbol->getName().str().c_str());
+  if (log)
+    log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
 
-    lldb::addr_t symbol_addr = m_decl_map->GetSymbolAddress (name, lldb::eSymbolTypeAny);
-
-    if (symbol_addr == LLDB_INVALID_ADDRESS)
+  for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
+       op_index < num_ops; ++op_index)
+    if (!MaybeHandleVariable(Old->getArgOperand(
+            op_index))) // conservatively believe that this is a store
     {
-        if (log)
-            log->Printf ("Symbol \"%s\" had no address", name.GetCString());
+      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
+                            "one of the arguments of a function call.\n");
 
-        return false;
+      return false;
     }
 
-    if (log)
-        log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
+  return true;
+}
 
-    Type *symbol_type = symbol->getType();
+bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
+  GlobalVariable *global_variable =
+      dyn_cast<GlobalVariable>(classlist_reference);
 
-    Value *symbol_addr_ptr = ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
+  if (!global_variable)
+    return false;
 
-    if (log)
-        log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(), PrintValue(symbol_addr_ptr).c_str());
+  Constant *initializer = global_variable->getInitializer();
 
-    symbol->replaceAllUsesWith(symbol_addr_ptr);
+  if (!initializer)
+    return false;
 
-    return true;
-}
+  if (!initializer->hasName())
+    return false;
 
-bool
-IRForTarget::MaybeHandleCallArguments (CallInst *Old)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+  StringRef name(initializer->getName());
+  lldb_private::ConstString name_cstr(name.str().c_str());
+  lldb::addr_t class_ptr =
+      m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
+
+  if (log)
+    log->Printf("Found reference to Objective-C class %s (0x%llx)",
+                name_cstr.AsCString(), (unsigned long long)class_ptr);
 
-    if (log)
-        log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
+  if (class_ptr == LLDB_INVALID_ADDRESS)
+    return false;
 
-    for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
-         op_index < num_ops;
-         ++op_index)
-        if (!MaybeHandleVariable(Old->getArgOperand(op_index))) // conservatively believe that this is a store
-        {
-            m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite one of the arguments of a function call.\n");
+  if (global_variable->use_empty())
+    return false;
 
-            return false;
-        }
+  SmallVector<LoadInst *, 2> load_instructions;
 
-    return true;
-}
+  for (llvm::User *u : global_variable->users()) {
+    if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
+      load_instructions.push_back(load_instruction);
+  }
 
-bool
-IRForTarget::HandleObjCClass(Value *classlist_reference)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+  if (load_instructions.empty())
+    return false;
 
-    GlobalVariable *global_variable = dyn_cast<GlobalVariable>(classlist_reference);
+  Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
 
-    if (!global_variable)
-        return false;
+  for (LoadInst *load_instruction : load_instructions) {
+    Constant *class_bitcast =
+        ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
 
-    Constant *initializer = global_variable->getInitializer();
+    load_instruction->replaceAllUsesWith(class_bitcast);
 
-    if (!initializer)
-        return false;
+    load_instruction->eraseFromParent();
+  }
 
-    if (!initializer->hasName())
-        return false;
+  return true;
+}
 
-    StringRef name(initializer->getName());
-    lldb_private::ConstString name_cstr(name.str().c_str());
-    lldb::addr_t class_ptr = m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
+bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
+  BasicBlock::iterator ii;
 
-    if (log)
-        log->Printf("Found reference to Objective-C class %s (0x%llx)", name_cstr.AsCString(), (unsigned long long)class_ptr);
+  std::vector<CallInst *> calls_to_remove;
 
-    if (class_ptr == LLDB_INVALID_ADDRESS)
-        return false;
+  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+    Instruction &inst = *ii;
 
-    if (global_variable->use_empty())
-        return false;
+    CallInst *call = dyn_cast<CallInst>(&inst);
 
-    SmallVector<LoadInst *, 2> load_instructions;
+    // MaybeHandleCallArguments handles error reporting; we are silent here
+    if (!call)
+      continue;
 
-    for (llvm::User *u : global_variable->users())
-    {
-        if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
-            load_instructions.push_back(load_instruction);
-    }
+    bool remove = false;
 
-    if (load_instructions.empty())
-        return false;
+    llvm::Function *func = call->getCalledFunction();
 
-    Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
+    if (func && func->getName() == "__cxa_atexit")
+      remove = true;
 
-    for (LoadInst *load_instruction : load_instructions)
-    {
-        Constant *class_bitcast = ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
+    llvm::Value *val = call->getCalledValue();
 
-        load_instruction->replaceAllUsesWith(class_bitcast);
+    if (val && val->getName() == "__cxa_atexit")
+      remove = true;
 
-        load_instruction->eraseFromParent();
-    }
+    if (remove)
+      calls_to_remove.push_back(call);
+  }
 
-    return true;
-}
+  for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(),
+                                         ce = calls_to_remove.end();
+       ci != ce; ++ci) {
+    (*ci)->eraseFromParent();
+  }
 
-bool
-IRForTarget::RemoveCXAAtExit (BasicBlock &basic_block)
-{
-    BasicBlock::iterator ii;
-
-    std::vector<CallInst *> calls_to_remove;
-
-    for (ii = basic_block.begin();
-         ii != basic_block.end();
-         ++ii)
-    {
-        Instruction &inst = *ii;
-
-        CallInst *call = dyn_cast<CallInst>(&inst);
+  return true;
+}
 
-        // MaybeHandleCallArguments handles error reporting; we are silent here
-        if (!call)
-            continue;
+bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
+  /////////////////////////////////////////////////////////////////////////
+  // Prepare the current basic block for execution in the remote process
+  //
 
-        bool remove = false;
+  BasicBlock::iterator ii;
 
-        llvm::Function *func = call->getCalledFunction();
+  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+    Instruction &inst = *ii;
 
-        if (func && func->getName() == "__cxa_atexit")
-            remove = true;
+    CallInst *call = dyn_cast<CallInst>(&inst);
 
-        llvm::Value *val = call->getCalledValue();
+    // MaybeHandleCallArguments handles error reporting; we are silent here
+    if (call && !MaybeHandleCallArguments(call))
+      return false;
+  }
 
-        if (val && val->getName() == "__cxa_atexit")
-            remove = true;
+  return true;
+}
 
-        if (remove)
-            calls_to_remove.push_back(call);
-    }
+bool IRForTarget::ResolveExternals(Function &llvm_function) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(), ce = calls_to_remove.end();
-         ci != ce;
-         ++ci)
-    {
-        (*ci)->eraseFromParent();
-    }
+  for (GlobalVariable &global_var : m_module->globals()) {
+    std::string global_name = global_var.getName().str();
 
-    return true;
-}
+    if (log)
+      log->Printf("Examining %s, DeclForGlobalValue returns %p",
+                  global_name.c_str(),
+                  static_cast<void *>(DeclForGlobal(&global_var)));
 
-bool
-IRForTarget::ResolveCalls(BasicBlock &basic_block)
-{
-    /////////////////////////////////////////////////////////////////////////
-    // Prepare the current basic block for execution in the remote process
-    //
+    if (global_name.find("OBJC_IVAR") == 0) {
+      if (!HandleSymbol(&global_var)) {
+        m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C "
+                              "indirect ivar symbol %s\n",
+                              global_name.c_str());
 
-    BasicBlock::iterator ii;
+        return false;
+      }
+    } else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") !=
+               global_name.npos) {
+      if (!HandleObjCClass(&global_var)) {
+        m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
+                              "for an Objective-C static method call\n");
 
-    for (ii = basic_block.begin();
-         ii != basic_block.end();
-         ++ii)
-    {
-        Instruction &inst = *ii;
+        return false;
+      }
+    } else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") !=
+               global_name.npos) {
+      if (!HandleObjCClass(&global_var)) {
+        m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
+                              "for an Objective-C static method call\n");
 
-        CallInst *call = dyn_cast<CallInst>(&inst);
+        return false;
+      }
+    } else if (DeclForGlobal(&global_var)) {
+      if (!MaybeHandleVariable(&global_var)) {
+        m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
+                              "external variable %s\n",
+                              global_name.c_str());
 
-        // MaybeHandleCallArguments handles error reporting; we are silent here
-        if (call && !MaybeHandleCallArguments(call))
-            return false;
+        return false;
+      }
     }
+  }
 
-    return true;
+  return true;
 }
 
-bool
-IRForTarget::ResolveExternals (Function &llvm_function)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+static bool isGuardVariableRef(Value *V) {
+  Constant *Old = NULL;
 
-    for (GlobalVariable &global_var : m_module->globals())
-    {
-        std::string global_name = global_var.getName().str();
+  if (!(Old = dyn_cast<Constant>(V)))
+    return false;
 
-        if (log)
-            log->Printf("Examining %s, DeclForGlobalValue returns %p",
-                        global_name.c_str(),
-                        static_cast<void*>(DeclForGlobal(&global_var)));
-
-        if (global_name.find("OBJC_IVAR") == 0)
-        {
-            if (!HandleSymbol(&global_var))
-            {
-                m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C indirect ivar symbol %s\n", global_name.c_str());
+  ConstantExpr *CE = NULL;
 
-                return false;
-            }
-        }
-        else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") != global_name.npos)
-        {
-            if (!HandleObjCClass(&global_var))
-            {
-                m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");
+  if ((CE = dyn_cast<ConstantExpr>(V))) {
+    if (CE->getOpcode() != Instruction::BitCast)
+      return false;
 
-                return false;
-            }
-        }
-        else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") != global_name.npos)
-        {
-            if (!HandleObjCClass(&global_var))
-            {
-                m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");
+    Old = CE->getOperand(0);
+  }
 
-                return false;
-            }
-        }
-        else if (DeclForGlobal(&global_var))
-        {
-            if (!MaybeHandleVariable (&global_var))
-            {
-                m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite external variable %s\n", global_name.c_str());
+  GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
 
-                return false;
-            }
-        }
-    }
+  if (!GV || !GV->hasName() ||
+      (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
+       !GV->getName().endswith("@4IA")))    // Microsoft ABI guard variable
+  {
+    return false;
+  }
 
-    return true;
+  return true;
 }
 
-static bool isGuardVariableRef(Value *V)
-{
-    Constant *Old = NULL;
+void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
+  Constant *zero(Constant::getNullValue(guard_load->getType()));
+  guard_load->replaceAllUsesWith(zero);
+  guard_load->eraseFromParent();
+}
 
-    if (!(Old = dyn_cast<Constant>(V)))
-        return false;
+static void ExciseGuardStore(Instruction *guard_store) {
+  guard_store->eraseFromParent();
+}
 
-    ConstantExpr *CE = NULL;
+bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
+  ///////////////////////////////////////////////////////
+  // Eliminate any reference to guard variables found.
+  //
 
-    if ((CE = dyn_cast<ConstantExpr>(V)))
-    {
-        if (CE->getOpcode() != Instruction::BitCast)
-            return false;
+  BasicBlock::iterator ii;
 
-        Old = CE->getOperand(0);
-    }
+  typedef SmallVector<Instruction *, 2> InstrList;
+  typedef InstrList::iterator InstrIterator;
 
-    GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
+  InstrList guard_loads;
+  InstrList guard_stores;
 
-    if (!GV || !GV->hasName() ||
-        (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
-         !GV->getName().endswith("@4IA")))    // Microsoft ABI guard variable
-    {
-        return false;
-    }
+  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
+    Instruction &inst = *ii;
 
-    return true;
-}
+    if (LoadInst *load = dyn_cast<LoadInst>(&inst))
+      if (isGuardVariableRef(load->getPointerOperand()))
+        guard_loads.push_back(&inst);
 
-void
-IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction* guard_load)
-{
-    Constant *zero(Constant::getNullValue(guard_load->getType()));
-    guard_load->replaceAllUsesWith(zero);
-    guard_load->eraseFromParent();
-}
-
-static void ExciseGuardStore(Instruction* guard_store)
-{
-    guard_store->eraseFromParent();
-}
-
-bool
-IRForTarget::RemoveGuards(BasicBlock &basic_block)
-{
-    ///////////////////////////////////////////////////////
-    // Eliminate any reference to guard variables found.
-    //
+    if (StoreInst *store = dyn_cast<StoreInst>(&inst))
+      if (isGuardVariableRef(store->getPointerOperand()))
+        guard_stores.push_back(&inst);
+  }
 
-    BasicBlock::iterator ii;
+  InstrIterator iter;
 
-    typedef SmallVector <Instruction*, 2> InstrList;
-    typedef InstrList::iterator InstrIterator;
+  for (iter = guard_loads.begin(); iter != guard_loads.end(); ++iter)
+    TurnGuardLoadIntoZero(*iter);
 
-    InstrList guard_loads;
-    InstrList guard_stores;
+  for (iter = guard_stores.begin(); iter != guard_stores.end(); ++iter)
+    ExciseGuardStore(*iter);
 
-    for (ii = basic_block.begin();
-         ii != basic_block.end();
-         ++ii)
-    {
-        Instruction &inst = *ii;
+  return true;
+}
+
+// This function does not report errors; its callers are responsible.
+bool IRForTarget::UnfoldConstant(Constant *old_constant,
+                                 llvm::Function *llvm_function,
+                                 FunctionValueCache &value_maker,
+                                 FunctionValueCache &entry_instruction_finder,
+                                 lldb_private::Stream &error_stream) {
+  SmallVector<User *, 16> users;
+
+  // We do this because the use list might change, invalidating our iterator.
+  // Much better to keep a work list ourselves.
+  for (llvm::User *u : old_constant->users())
+    users.push_back(u);
 
-        if (LoadInst *load = dyn_cast<LoadInst>(&inst))
-            if (isGuardVariableRef(load->getPointerOperand()))
-                guard_loads.push_back(&inst);
+  for (size_t i = 0; i < users.size(); ++i) {
+    User *user = users[i];
 
-        if (StoreInst *store = dyn_cast<StoreInst>(&inst))
-            if (isGuardVariableRef(store->getPointerOperand()))
-                guard_stores.push_back(&inst);
-    }
+    if (Constant *constant = dyn_cast<Constant>(user)) {
+      // synthesize a new non-constant equivalent of the constant
 
-    InstrIterator iter;
+      if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
+        switch (constant_expr->getOpcode()) {
+        default:
+          error_stream.Printf("error [IRForTarget internal]: Unhandled "
+                              "constant expression type: \"%s\"",
+                              PrintValue(constant_expr).c_str());
+          return false;
+        case Instruction::BitCast: {
+          FunctionValueCache bit_cast_maker(
+              [&value_maker, &entry_instruction_finder, old_constant,
+               constant_expr](llvm::Function *function) -> llvm::Value * {
+                // UnaryExpr
+                //   OperandList[0] is value
+
+                if (constant_expr->getOperand(0) != old_constant)
+                  return constant_expr;
+
+                return new BitCastInst(
+                    value_maker.GetValue(function), constant_expr->getType(),
+                    "", llvm::cast<Instruction>(
+                            entry_instruction_finder.GetValue(function)));
+              });
+
+          if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
+                              entry_instruction_finder, error_stream))
+            return false;
+        } break;
+        case Instruction::GetElementPtr: {
+          // GetElementPtrConstantExpr
+          //   OperandList[0] is base
+          //   OperandList[1]... are indices
+
+          FunctionValueCache get_element_pointer_maker(
+              [&value_maker, &entry_instruction_finder, old_constant,
+               constant_expr](llvm::Function *function) -> llvm::Value * {
+                Value *ptr = constant_expr->getOperand(0);
+
+                if (ptr == old_constant)
+                  ptr = value_maker.GetValue(function);
+
+                std::vector<Value *> index_vector;
+
+                unsigned operand_index;
+                unsigned num_operands = constant_expr->getNumOperands();
+
+                for (operand_index = 1; operand_index < num_operands;
+                     ++operand_index) {
+                  Value *operand = constant_expr->getOperand(operand_index);
 
-    for (iter = guard_loads.begin();
-         iter != guard_loads.end();
-         ++iter)
-        TurnGuardLoadIntoZero(*iter);
+                  if (operand == old_constant)
+                    operand = value_maker.GetValue(function);
 
-    for (iter = guard_stores.begin();
-         iter != guard_stores.end();
-         ++iter)
-        ExciseGuardStore(*iter);
+                  index_vector.push_back(operand);
+                }
 
-    return true;
-}
+                ArrayRef<Value *> indices(index_vector);
 
-// This function does not report errors; its callers are responsible.
-bool
-IRForTarget::UnfoldConstant(Constant *old_constant,
-                            llvm::Function *llvm_function,
-                            FunctionValueCache &value_maker,
-                            FunctionValueCache &entry_instruction_finder,
-                            lldb_private::Stream &error_stream)
-{
-    SmallVector<User*, 16> users;
-
-    // We do this because the use list might change, invalidating our iterator.
-    // Much better to keep a work list ourselves.
-    for (llvm::User *u : old_constant->users())
-        users.push_back(u);
-
-    for (size_t i = 0;
-         i < users.size();
-         ++i)
-    {
-        User *user = users[i];
+                return GetElementPtrInst::Create(
+                    nullptr, ptr, indices, "",
+                    llvm::cast<Instruction>(
+                        entry_instruction_finder.GetValue(function)));
+              });
 
-        if (Constant *constant = dyn_cast<Constant>(user))
-        {
-            // synthesize a new non-constant equivalent of the constant
-
-            if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
-            {
-                switch (constant_expr->getOpcode())
-                {
-                default:
-                    error_stream.Printf("error [IRForTarget internal]: Unhandled constant expression type: \"%s\"", PrintValue(constant_expr).c_str());
-                    return false;
-                case Instruction::BitCast:
-                    {
-                        FunctionValueCache bit_cast_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* {
-                            // UnaryExpr
-                            //   OperandList[0] is value
-
-                            if (constant_expr->getOperand(0) != old_constant)
-                                return constant_expr;
-
-                            return new BitCastInst(value_maker.GetValue(function),
-                                                   constant_expr->getType(),
-                                                   "",
-                                                   llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
-                        });
-
-                        if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker, entry_instruction_finder, error_stream))
-                            return false;
-                    }
-                    break;
-                case Instruction::GetElementPtr:
-                    {
-                        // GetElementPtrConstantExpr
-                        //   OperandList[0] is base
-                        //   OperandList[1]... are indices
-
-                        FunctionValueCache get_element_pointer_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* {
-                            Value *ptr = constant_expr->getOperand(0);
-
-                            if (ptr == old_constant)
-                                ptr = value_maker.GetValue(function);
-
-                            std::vector<Value*> index_vector;
-
-                            unsigned operand_index;
-                            unsigned num_operands = constant_expr->getNumOperands();
-
-                            for (operand_index = 1;
-                                 operand_index < num_operands;
-                                 ++operand_index)
-                            {
-                                Value *operand = constant_expr->getOperand(operand_index);
-
-                                if (operand == old_constant)
-                                    operand = value_maker.GetValue(function);
-
-                                index_vector.push_back(operand);
-                            }
-
-                            ArrayRef <Value*> indices(index_vector);
-
-                            return GetElementPtrInst::Create(nullptr, ptr, indices, "", llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
-                        });
-
-                        if (!UnfoldConstant(constant_expr, llvm_function, get_element_pointer_maker, entry_instruction_finder, error_stream))
-                            return false;
-                    }
-                    break;
-                }
-            }
-            else
-            {
-                error_stream.Printf("error [IRForTarget internal]: Unhandled constant type: \"%s\"", PrintValue(constant).c_str());
-                return false;
-            }
+          if (!UnfoldConstant(constant_expr, llvm_function,
+                              get_element_pointer_maker,
+                              entry_instruction_finder, error_stream))
+            return false;
+        } break;
         }
-        else
-        {
-            if (Instruction *inst = llvm::dyn_cast<Instruction>(user))
-            {
-                if (llvm_function && inst->getParent()->getParent() != llvm_function)
-                {
-                    error_stream.PutCString("error: Capturing non-local variables in expressions is unsupported.\n");
-                    return false;
-                }
-                inst->replaceUsesOfWith(old_constant, value_maker.GetValue(inst->getParent()->getParent()));
-            }
-            else
-            {
-                error_stream.Printf("error [IRForTarget internal]: Unhandled non-constant type: \"%s\"", PrintValue(user).c_str());
-                return false;
-            }
+      } else {
+        error_stream.Printf(
+            "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
+            PrintValue(constant).c_str());
+        return false;
+      }
+    } else {
+      if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
+        if (llvm_function && inst->getParent()->getParent() != llvm_function) {
+          error_stream.PutCString("error: Capturing non-local variables in "
+                                  "expressions is unsupported.\n");
+          return false;
         }
+        inst->replaceUsesOfWith(
+            old_constant, value_maker.GetValue(inst->getParent()->getParent()));
+      } else {
+        error_stream.Printf(
+            "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
+            PrintValue(user).c_str());
+        return false;
+      }
     }
+  }
 
-    if (!isa<GlobalValue>(old_constant))
-    {
-        old_constant->destroyConstant();
-    }
+  if (!isa<GlobalValue>(old_constant)) {
+    old_constant->destroyConstant();
+  }
 
-    return true;
+  return true;
 }
 
-bool
-IRForTarget::ReplaceVariables (Function &llvm_function)
-{
-    if (!m_resolve_vars)
-        return true;
+bool IRForTarget::ReplaceVariables(Function &llvm_function) {
+  if (!m_resolve_vars)
+    return true;
 
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    m_decl_map->DoStructLayout();
+  m_decl_map->DoStructLayout();
 
-    if (log)
-        log->Printf("Element arrangement:");
+  if (log)
+    log->Printf("Element arrangement:");
 
-    uint32_t num_elements;
-    uint32_t element_index;
+  uint32_t num_elements;
+  uint32_t element_index;
 
-    size_t size;
-    lldb::offset_t alignment;
+  size_t size;
+  lldb::offset_t alignment;
 
-    if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
-        return false;
+  if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
+    return false;
 
-    Function::arg_iterator iter(llvm_function.getArgumentList().begin());
+  Function::arg_iterator iter(llvm_function.getArgumentList().begin());
 
-    if (iter == llvm_function.getArgumentList().end())
-    {
-        m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no arguments (should take at least a struct pointer)");
+  if (iter == llvm_function.getArgumentList().end()) {
+    m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
+                          "arguments (should take at least a struct pointer)");
 
-        return false;
-    }
+    return false;
+  }
 
-    Argument *argument = &*iter;
+  Argument *argument = &*iter;
 
-    if (argument->getName().equals("this"))
-    {
-        ++iter;
+  if (argument->getName().equals("this")) {
+    ++iter;
 
-        if (iter == llvm_function.getArgumentList().end())
-        {
-            m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only 'this' argument (should take a struct pointer too)");
+    if (iter == llvm_function.getArgumentList().end()) {
+      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
+                            "'this' argument (should take a struct pointer "
+                            "too)");
 
-            return false;
-        }
-
-        argument = &*iter;
+      return false;
     }
-    else if (argument->getName().equals("self"))
-    {
-        ++iter;
 
-        if (iter == llvm_function.getArgumentList().end())
-        {
-            m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only 'self' argument (should take '_cmd' and a struct pointer too)");
+    argument = &*iter;
+  } else if (argument->getName().equals("self")) {
+    ++iter;
 
-            return false;
-        }
+    if (iter == llvm_function.getArgumentList().end()) {
+      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
+                            "'self' argument (should take '_cmd' and a struct "
+                            "pointer too)");
 
-        if (!iter->getName().equals("_cmd"))
-        {
-            m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' after 'self' argument (should take '_cmd')", iter->getName().str().c_str());
-
-            return false;
-        }
-
-        ++iter;
+      return false;
+    }
 
-        if (iter == llvm_function.getArgumentList().end())
-        {
-            m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only 'self' and '_cmd' arguments (should take a struct pointer too)");
+    if (!iter->getName().equals("_cmd")) {
+      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' "
+                            "after 'self' argument (should take '_cmd')",
+                            iter->getName().str().c_str());
 
-            return false;
-        }
-
-        argument = &*iter;
+      return false;
     }
 
-    if (!argument->getName().equals("$__lldb_arg"))
-    {
-        m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an argument named '%s' instead of the struct pointer", argument->getName().str().c_str());
+    ++iter;
 
-        return false;
+    if (iter == llvm_function.getArgumentList().end()) {
+      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
+                            "'self' and '_cmd' arguments (should take a struct "
+                            "pointer too)");
+
+      return false;
     }
 
-    if (log)
-        log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
+    argument = &*iter;
+  }
 
-    BasicBlock &entry_block(llvm_function.getEntryBlock());
-    Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
+  if (!argument->getName().equals("$__lldb_arg")) {
+    m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an "
+                          "argument named '%s' instead of the struct pointer",
+                          argument->getName().str().c_str());
 
-    if (!FirstEntryInstruction)
-    {
-        m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the first instruction in the wrapper for use in rewriting");
+    return false;
+  }
 
-        return false;
-    }
+  if (log)
+    log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
 
-    LLVMContext &context(m_module->getContext());
-    IntegerType *offset_type(Type::getInt32Ty(context));
+  BasicBlock &entry_block(llvm_function.getEntryBlock());
+  Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
 
-    if (!offset_type)
-    {
-        m_error_stream.Printf("Internal error [IRForTarget]: Couldn't produce an offset type");
+  if (!FirstEntryInstruction) {
+    m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
+                          "first instruction in the wrapper for use in "
+                          "rewriting");
 
-        return false;
-    }
+    return false;
+  }
 
-    for (element_index = 0; element_index < num_elements; ++element_index)
-    {
-        const clang::NamedDecl *decl = NULL;
-        Value *value = NULL;
-        lldb::offset_t offset;
-        lldb_private::ConstString name;
-
-        if (!m_decl_map->GetStructElement (decl, value, offset, name, element_index))
-        {
-            m_error_stream.Printf("Internal error [IRForTarget]: Structure information is incomplete");
+  LLVMContext &context(m_module->getContext());
+  IntegerType *offset_type(Type::getInt32Ty(context));
 
-            return false;
-        }
+  if (!offset_type) {
+    m_error_stream.Printf(
+        "Internal error [IRForTarget]: Couldn't produce an offset type");
 
-        if (log)
-            log->Printf("  \"%s\" (\"%s\") placed at %" PRIu64,
-                        name.GetCString(),
-                        decl->getNameAsString().c_str(),
-                        offset);
-
-        if (value)
-        {
-            if (log)
-                log->Printf("    Replacing [%s]", PrintValue(value).c_str());
-
-            FunctionValueCache body_result_maker ([this, name, offset_type, offset, argument, value] (llvm::Function *function)->llvm::Value * {
-                // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in cases where the result
-                // variable is an rvalue, we have to synthesize a dereference of the appropriate structure
-                // entry in order to produce the static variable that the AST thinks it is accessing.
-
-                llvm::Instruction *entry_instruction = llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function));
-
-                ConstantInt *offset_int(ConstantInt::get(offset_type, offset, true));
-                GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(nullptr,
-                                                                               argument,
-                                                                               offset_int,
-                                                                               "",
-                                                                               entry_instruction);
-
-                if (name == m_result_name && !m_result_is_pointer)
-                {
-                    BitCastInst *bit_cast = new BitCastInst(get_element_ptr,
-                                                            value->getType()->getPointerTo(),
-                                                            "",
-                                                            entry_instruction);
+    return false;
+  }
 
-                    LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
+  for (element_index = 0; element_index < num_elements; ++element_index) {
+    const clang::NamedDecl *decl = NULL;
+    Value *value = NULL;
+    lldb::offset_t offset;
+    lldb_private::ConstString name;
+
+    if (!m_decl_map->GetStructElement(decl, value, offset, name,
+                                      element_index)) {
+      m_error_stream.Printf(
+          "Internal error [IRForTarget]: Structure information is incomplete");
 
-                    return load;
-                }
-                else
-                {
-                    BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", entry_instruction);
+      return false;
+    }
 
-                    return bit_cast;
-                }
-            });
+    if (log)
+      log->Printf("  \"%s\" (\"%s\") placed at %" PRIu64, name.GetCString(),
+                  decl->getNameAsString().c_str(), offset);
 
-            if (Constant *constant = dyn_cast<Constant>(value))
-            {
-                if (!UnfoldConstant(constant, &llvm_function, body_result_maker, m_entry_instruction_finder, m_error_stream))
-                {
-                    return false;
-                }
-            }
-            else if (Instruction *instruction = dyn_cast<Instruction>(value))
-            {
-                if (instruction->getParent()->getParent() != &llvm_function)
-                {
-                    m_error_stream.PutCString("error: Capturing non-local variables in expressions is unsupported.\n");
-                    return false;
-                }
-                value->replaceAllUsesWith(body_result_maker.GetValue(instruction->getParent()->getParent()));
-            }
-            else
-            {
-                if (log)
-                    log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(value).c_str());
-                return false;
-            }
+    if (value) {
+      if (log)
+        log->Printf("    Replacing [%s]", PrintValue(value).c_str());
+
+      FunctionValueCache body_result_maker(
+          [this, name, offset_type, offset, argument,
+           value](llvm::Function *function) -> llvm::Value * {
+            // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in
+            // cases where the result
+            // variable is an rvalue, we have to synthesize a dereference of the
+            // appropriate structure
+            // entry in order to produce the static variable that the AST thinks
+            // it is accessing.
+
+            llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
+                m_entry_instruction_finder.GetValue(function));
+
+            ConstantInt *offset_int(
+                ConstantInt::get(offset_type, offset, true));
+            GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
+                nullptr, argument, offset_int, "", entry_instruction);
+
+            if (name == m_result_name && !m_result_is_pointer) {
+              BitCastInst *bit_cast = new BitCastInst(
+                  get_element_ptr, value->getType()->getPointerTo(), "",
+                  entry_instruction);
+
+              LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
+
+              return load;
+            } else {
+              BitCastInst *bit_cast = new BitCastInst(
+                  get_element_ptr, value->getType(), "", entry_instruction);
+
+              return bit_cast;
+            }
+          });
+
+      if (Constant *constant = dyn_cast<Constant>(value)) {
+        if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
+                            m_entry_instruction_finder, m_error_stream)) {
+          return false;
+        }
+      } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
+        if (instruction->getParent()->getParent() != &llvm_function) {
+          m_error_stream.PutCString("error: Capturing non-local variables in "
+                                    "expressions is unsupported.\n");
+          return false;
+        }
+        value->replaceAllUsesWith(
+            body_result_maker.GetValue(instruction->getParent()->getParent()));
+      } else {
+        if (log)
+          log->Printf("Unhandled non-constant type: \"%s\"",
+                      PrintValue(value).c_str());
+        return false;
+      }
 
-            if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
-                var->eraseFromParent();
-        }
+      if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
+        var->eraseFromParent();
     }
+  }
 
-    if (log)
-        log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]", (int64_t)alignment, (uint64_t)size);
+  if (log)
+    log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]",
+                (int64_t)alignment, (uint64_t)size);
 
-    return true;
+  return true;
 }
 
-llvm::Constant *
-IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset)
-{
-    llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
+llvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type,
+                                             uint64_t offset) {
+  llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
 
-    llvm::Constant *offset_array[1];
+  llvm::Constant *offset_array[1];
 
-    offset_array[0] = offset_int;
+  offset_array[0] = offset_int;
 
-    llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
-    llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
-    llvm::Type *char_pointer_type = char_type->getPointerTo();
+  llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
+  llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
+  llvm::Type *char_pointer_type = char_type->getPointerTo();
 
-    llvm::Constant *reloc_placeholder_bitcast = ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
-    llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(char_type, reloc_placeholder_bitcast, offsets);
-    llvm::Constant *reloc_bitcast = ConstantExpr::getBitCast(reloc_getelementptr, type);
+  llvm::Constant *reloc_placeholder_bitcast =
+      ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
+  llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(
+      char_type, reloc_placeholder_bitcast, offsets);
+  llvm::Constant *reloc_bitcast =
+      ConstantExpr::getBitCast(reloc_getelementptr, type);
 
-    return reloc_bitcast;
+  return reloc_bitcast;
 }
 
-bool
-IRForTarget::runOnModule (Module &llvm_module)
-{
-    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+bool IRForTarget::runOnModule(Module &llvm_module) {
+  lldb_private::Log *log(
+      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-    m_module = &llvm_module;
-    m_target_data.reset(new DataLayout(m_module));
-    m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(), m_target_data->getPointerSizeInBits());
+  m_module = &llvm_module;
+  m_target_data.reset(new DataLayout(m_module));
+  m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
+                                      m_target_data->getPointerSizeInBits());
 
-    if (log)
-    {
-        std::string s;
-        raw_string_ostream oss(s);
+  if (log) {
+    std::string s;
+    raw_string_ostream oss(s);
 
-        m_module->print(oss, NULL);
+    m_module->print(oss, NULL);
 
-        oss.flush();
+    oss.flush();
 
-        log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
-    }
+    log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
+  }
 
-    Function *const main_function = m_func_name.IsEmpty() ? nullptr : m_module->getFunction(m_func_name.GetStringRef());
+  Function *const main_function =
+      m_func_name.IsEmpty() ? nullptr
+                            : m_module->getFunction(m_func_name.GetStringRef());
 
-    if (!m_func_name.IsEmpty() && !main_function)
-    {
-        if (log)
-            log->Printf("Couldn't find \"%s()\" in the module", m_func_name.AsCString());
+  if (!m_func_name.IsEmpty() && !main_function) {
+    if (log)
+      log->Printf("Couldn't find \"%s()\" in the module",
+                  m_func_name.AsCString());
 
-         m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper '%s' in the module",
-                               m_func_name.AsCString());
+    m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper "
+                          "'%s' in the module",
+                          m_func_name.AsCString());
 
-        return false;
-    }
+    return false;
+  }
 
-    if (main_function)
-    {
-        if (!FixFunctionLinkage(*main_function))
-        {
-            if (log)
-                log->Printf("Couldn't fix the linkage for the function");
+  if (main_function) {
+    if (!FixFunctionLinkage(*main_function)) {
+      if (log)
+        log->Printf("Couldn't fix the linkage for the function");
 
-            return false;
-        }
+      return false;
     }
+  }
 
-    llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
+  llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
 
-    m_reloc_placeholder = new llvm::GlobalVariable((*m_module),
-                                                   int8_ty,
-                                                   false /* IsConstant */,
-                                                   GlobalVariable::InternalLinkage,
-                                                   Constant::getNullValue(int8_ty),
-                                                   "reloc_placeholder",
-                                                   NULL /* InsertBefore */,
-                                                   GlobalVariable::NotThreadLocal /* ThreadLocal */,
-                                                   0 /* AddressSpace */);
+  m_reloc_placeholder = new llvm::GlobalVariable(
+      (*m_module), int8_ty, false /* IsConstant */,
+      GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
+      "reloc_placeholder", NULL /* InsertBefore */,
+      GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
 
-    ////////////////////////////////////////////////////////////
-    // Replace $__lldb_expr_result with a persistent variable
-    //
+  ////////////////////////////////////////////////////////////
+  // Replace $__lldb_expr_result with a persistent variable
+  //
 
-    if (main_function)
-    {
-        if (!CreateResultVariable(*main_function))
-        {
-            if (log)
-                log->Printf("CreateResultVariable() failed");
+  if (main_function) {
+    if (!CreateResultVariable(*main_function)) {
+      if (log)
+        log->Printf("CreateResultVariable() failed");
 
-            // CreateResultVariable() reports its own errors, so we don't do so here
+      // CreateResultVariable() reports its own errors, so we don't do so here
 
-            return false;
-        }
+      return false;
     }
+  }
 
-    if (log && log->GetVerbose())
-    {
-        std::string s;
-        raw_string_ostream oss(s);
+  if (log && log->GetVerbose()) {
+    std::string s;
+    raw_string_ostream oss(s);
 
-        m_module->print(oss, NULL);
+    m_module->print(oss, NULL);
 
-        oss.flush();
+    oss.flush();
 
-        log->Printf("Module after creating the result variable: \n\"%s\"", s.c_str());
-    }
+    log->Printf("Module after creating the result variable: \n\"%s\"",
+                s.c_str());
+  }
 
-    for (Module::iterator fi = m_module->begin(), fe = m_module->end();
-         fi != fe;
-         ++fi)
-    {
-        llvm::Function *function = &*fi;
+  for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
+       ++fi) {
+    llvm::Function *function = &*fi;
 
-        if (function->begin() == function->end())
-            continue;
+    if (function->begin() == function->end())
+      continue;
 
-        Function::iterator bbi;
+    Function::iterator bbi;
 
-        for (bbi = function->begin();
-             bbi != function->end();
-             ++bbi)
-        {
-            if (!RemoveGuards(*bbi))
-            {
-                if (log)
-                    log->Printf("RemoveGuards() failed");
+    for (bbi = function->begin(); bbi != function->end(); ++bbi) {
+      if (!RemoveGuards(*bbi)) {
+        if (log)
+          log->Printf("RemoveGuards() failed");
 
-                // RemoveGuards() reports its own errors, so we don't do so here
+        // RemoveGuards() reports its own errors, so we don't do so here
 
-                return false;
-            }
+        return false;
+      }
 
-            if (!RewritePersistentAllocs(*bbi))
-            {
-                if (log)
-                    log->Printf("RewritePersistentAllocs() failed");
+      if (!RewritePersistentAllocs(*bbi)) {
+        if (log)
+          log->Printf("RewritePersistentAllocs() failed");
 
-                // RewritePersistentAllocs() reports its own errors, so we don't do so here
+        // RewritePersistentAllocs() reports its own errors, so we don't do so
+        // here
 
-                return false;
-            }
+        return false;
+      }
 
-            if (!RemoveCXAAtExit(*bbi))
-            {
-                if (log)
-                    log->Printf("RemoveCXAAtExit() failed");
+      if (!RemoveCXAAtExit(*bbi)) {
+        if (log)
+          log->Printf("RemoveCXAAtExit() failed");
 
-                // RemoveCXAAtExit() reports its own errors, so we don't do so here
+        // RemoveCXAAtExit() reports its own errors, so we don't do so here
 
-                return false;
-            }
-        }
+        return false;
+      }
     }
+  }
 
-    ///////////////////////////////////////////////////////////////////////////////
-    // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
-    //
-
-    if (!RewriteObjCConstStrings())
-    {
-        if (log)
-            log->Printf("RewriteObjCConstStrings() failed");
+  ///////////////////////////////////////////////////////////////////////////////
+  // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
+  //
 
-        // RewriteObjCConstStrings() reports its own errors, so we don't do so here
+  if (!RewriteObjCConstStrings()) {
+    if (log)
+      log->Printf("RewriteObjCConstStrings() failed");
 
-        return false;
-    }
+    // RewriteObjCConstStrings() reports its own errors, so we don't do so here
 
-    for (Module::iterator fi = m_module->begin(), fe = m_module->end();
-         fi != fe;
-         ++fi)
-    {
-        llvm::Function *function = &*fi;
+    return false;
+  }
 
-        for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
-             bbi != bbe;
-             ++bbi)
-        {
-            if (!RewriteObjCSelectors(*bbi))
-            {
-                if (log)
-                    log->Printf("RewriteObjCSelectors() failed");
+  for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
+       ++fi) {
+    llvm::Function *function = &*fi;
+
+    for (llvm::Function::iterator bbi = function->begin(),
+                                  bbe = function->end();
+         bbi != bbe; ++bbi) {
+      if (!RewriteObjCSelectors(*bbi)) {
+        if (log)
+          log->Printf("RewriteObjCSelectors() failed");
 
-                // RewriteObjCSelectors() reports its own errors, so we don't do so here
+        // RewriteObjCSelectors() reports its own errors, so we don't do so here
 
-                return false;
-            }
-        }
+        return false;
+      }
     }
+  }
 
-    for (Module::iterator fi = m_module->begin(), fe = m_module->end();
-         fi != fe;
-         ++fi)
-    {
-        llvm::Function *function = &*fi;
+  for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
+       ++fi) {
+    llvm::Function *function = &*fi;
 
-        for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
-             bbi != bbe;
-             ++bbi)
-        {
-            if (!ResolveCalls(*bbi))
-            {
-                if (log)
-                    log->Printf("ResolveCalls() failed");
+    for (llvm::Function::iterator bbi = function->begin(),
+                                  bbe = function->end();
+         bbi != bbe; ++bbi) {
+      if (!ResolveCalls(*bbi)) {
+        if (log)
+          log->Printf("ResolveCalls() failed");
 
-                // ResolveCalls() reports its own errors, so we don't do so here
+        // ResolveCalls() reports its own errors, so we don't do so here
 
-                return false;
-            }
-        }
+        return false;
+      }
     }
+  }
 
-    ////////////////////////////////////////////////////////////////////////
-    // Run function-level passes that only make sense on the main function
-    //
+  ////////////////////////////////////////////////////////////////////////
+  // Run function-level passes that only make sense on the main function
+  //
 
-    if (main_function)
-    {
-        if (!ResolveExternals(*main_function))
-        {
-            if (log)
-                log->Printf("ResolveExternals() failed");
+  if (main_function) {
+    if (!ResolveExternals(*main_function)) {
+      if (log)
+        log->Printf("ResolveExternals() failed");
 
-            // ResolveExternals() reports its own errors, so we don't do so here
+      // ResolveExternals() reports its own errors, so we don't do so here
 
-            return false;
-        }
+      return false;
+    }
 
-        if (!ReplaceVariables(*main_function))
-        {
-            if (log)
-                log->Printf("ReplaceVariables() failed");
+    if (!ReplaceVariables(*main_function)) {
+      if (log)
+        log->Printf("ReplaceVariables() failed");
 
-            // ReplaceVariables() reports its own errors, so we don't do so here
+      // ReplaceVariables() reports its own errors, so we don't do so here
 
-            return false;
-        }
+      return false;
     }
+  }
 
-    if (log && log->GetVerbose())
-    {
-        std::string s;
-        raw_string_ostream oss(s);
+  if (log && log->GetVerbose()) {
+    std::string s;
+    raw_string_ostream oss(s);
 
-        m_module->print(oss, NULL);
+    m_module->print(oss, NULL);
 
-        oss.flush();
+    oss.flush();
 
-        log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
-    }
+    log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
+  }
 
-    return true;
+  return true;
 }
 
-void
-IRForTarget::assignPassManager (PMStack &pass_mgr_stack, PassManagerType pass_mgr_type)
-{
-}
+void IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
+                                    PassManagerType pass_mgr_type) {}
 
-PassManagerType
-IRForTarget::getPotentialPassManagerType() const
-{
-    return PMT_ModulePassManager;
+PassManagerType IRForTarget::getPotentialPassManagerType() const {
+  return PMT_ModulePassManager;
 }

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.h Tue Sep  6 15:57:50 2016
@@ -1,4 +1,5 @@
-//===-- IRForTarget.h ---------------------------------------------*- C++ -*-===//
+//===-- IRForTarget.h ---------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -10,38 +11,38 @@
 #ifndef liblldb_IRForTarget_h_
 #define liblldb_IRForTarget_h_
 
-#include "lldb/lldb-public.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/lldb-public.h"
 #include "llvm/Pass.h"
 
-#include <map>
 #include <functional>
+#include <map>
 
 namespace llvm {
-    class BasicBlock;
-    class CallInst;
-    class Constant;
-    class ConstantInt;
-    class Function;
-    class GlobalValue;
-    class GlobalVariable;
-    class Instruction;
-    class IntegerType;
-    class Module;
-    class StoreInst;
-    class DataLayout;
-    class Type;
-    class Value;
+class BasicBlock;
+class CallInst;
+class Constant;
+class ConstantInt;
+class Function;
+class GlobalValue;
+class GlobalVariable;
+class Instruction;
+class IntegerType;
+class Module;
+class StoreInst;
+class DataLayout;
+class Type;
+class Value;
 }
 
 namespace lldb_private {
-    class ClangExpressionDeclMap;
-    class IRExecutionUnit;
-    class IRMemoryMap;
+class ClangExpressionDeclMap;
+class IRExecutionUnit;
+class IRMemoryMap;
 }
 
 //----------------------------------------------------------------------
@@ -58,596 +59,578 @@ namespace lldb_private {
 /// transformations are discussed in more detail next to their relevant
 /// functions.
 //----------------------------------------------------------------------
-class IRForTarget : public llvm::ModulePass
-{
+class IRForTarget : public llvm::ModulePass {
 public:
-    enum class LookupResult {
-        Success,
-        Fail,
-        Ignore
-    };
-    
-    //------------------------------------------------------------------
-    /// Constructor
-    ///
-    /// @param[in] decl_map
-    ///     The list of externally-referenced variables for the expression,
-    ///     for use in looking up globals and allocating the argument
-    ///     struct.  See the documentation for ClangExpressionDeclMap.
-    ///
-    /// @param[in] resolve_vars
-    ///     True if the external variable references (including persistent
-    ///     variables) should be resolved.  If not, only external functions
-    ///     are resolved.
-    ///
-    /// @param[in] execution_policy
-    ///     Determines whether an IR interpreter can be used to statically
-    ///     evaluate the expression.
-    ///
-    /// @param[in] const_result
-    ///     This variable is populated with the statically-computed result
-    ///     of the function, if it has no side-effects and the result can
-    ///     be computed statically.
-    ///
-    /// @param[in] execution_unit
-    ///     The holder for raw data associated with the expression.
-    ///
-    /// @param[in] error_stream
-    ///     If non-NULL, a stream on which errors can be printed.
-    ///
-    /// @param[in] func_name
-    ///     The name of the function to prepare for execution in the target.
-    //------------------------------------------------------------------
-    IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
-                bool resolve_vars,
-                lldb_private::IRExecutionUnit &execution_unit,
-                lldb_private::Stream &error_stream,
-                const char* func_name = "$__lldb_expr");
-    
-    //------------------------------------------------------------------
-    /// Destructor
-    //------------------------------------------------------------------
-    ~IRForTarget() override;
-    
-    //------------------------------------------------------------------
-    /// Run this IR transformer on a single module
-    ///
-    /// Implementation of the llvm::ModulePass::runOnModule() function.
-    ///
-    /// @param[in] llvm_module
-    ///     The module to run on.  This module is searched for the function
-    ///     $__lldb_expr, and that function is passed to the passes one by 
-    ///     one.
-    ///
-    /// @param[in] interpreter_error
-    ///     An error.  If the expression fails to be interpreted, this error
-    ///     is set to a reason why.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    runOnModule(llvm::Module &llvm_module) override;
-    
-    //------------------------------------------------------------------
-    /// Interface stub
-    ///
-    /// Implementation of the llvm::ModulePass::assignPassManager() 
-    /// function.
-    //------------------------------------------------------------------
-    void
-    assignPassManager(llvm::PMStack &pass_mgr_stack,
-		      llvm::PassManagerType pass_mgr_type = llvm::PMT_ModulePassManager) override;
-    
-    //------------------------------------------------------------------
-    /// Returns PMT_ModulePassManager
-    ///
-    /// Implementation of the llvm::ModulePass::getPotentialPassManagerType() 
-    /// function.
-    //------------------------------------------------------------------
-    llvm::PassManagerType
-    getPotentialPassManagerType() const override;
+  enum class LookupResult { Success, Fail, Ignore };
+
+  //------------------------------------------------------------------
+  /// Constructor
+  ///
+  /// @param[in] decl_map
+  ///     The list of externally-referenced variables for the expression,
+  ///     for use in looking up globals and allocating the argument
+  ///     struct.  See the documentation for ClangExpressionDeclMap.
+  ///
+  /// @param[in] resolve_vars
+  ///     True if the external variable references (including persistent
+  ///     variables) should be resolved.  If not, only external functions
+  ///     are resolved.
+  ///
+  /// @param[in] execution_policy
+  ///     Determines whether an IR interpreter can be used to statically
+  ///     evaluate the expression.
+  ///
+  /// @param[in] const_result
+  ///     This variable is populated with the statically-computed result
+  ///     of the function, if it has no side-effects and the result can
+  ///     be computed statically.
+  ///
+  /// @param[in] execution_unit
+  ///     The holder for raw data associated with the expression.
+  ///
+  /// @param[in] error_stream
+  ///     If non-NULL, a stream on which errors can be printed.
+  ///
+  /// @param[in] func_name
+  ///     The name of the function to prepare for execution in the target.
+  //------------------------------------------------------------------
+  IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, bool resolve_vars,
+              lldb_private::IRExecutionUnit &execution_unit,
+              lldb_private::Stream &error_stream,
+              const char *func_name = "$__lldb_expr");
+
+  //------------------------------------------------------------------
+  /// Destructor
+  //------------------------------------------------------------------
+  ~IRForTarget() override;
+
+  //------------------------------------------------------------------
+  /// Run this IR transformer on a single module
+  ///
+  /// Implementation of the llvm::ModulePass::runOnModule() function.
+  ///
+  /// @param[in] llvm_module
+  ///     The module to run on.  This module is searched for the function
+  ///     $__lldb_expr, and that function is passed to the passes one by
+  ///     one.
+  ///
+  /// @param[in] interpreter_error
+  ///     An error.  If the expression fails to be interpreted, this error
+  ///     is set to a reason why.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool runOnModule(llvm::Module &llvm_module) override;
+
+  //------------------------------------------------------------------
+  /// Interface stub
+  ///
+  /// Implementation of the llvm::ModulePass::assignPassManager()
+  /// function.
+  //------------------------------------------------------------------
+  void assignPassManager(llvm::PMStack &pass_mgr_stack,
+                         llvm::PassManagerType pass_mgr_type =
+                             llvm::PMT_ModulePassManager) override;
+
+  //------------------------------------------------------------------
+  /// Returns PMT_ModulePassManager
+  ///
+  /// Implementation of the llvm::ModulePass::getPotentialPassManagerType()
+  /// function.
+  //------------------------------------------------------------------
+  llvm::PassManagerType getPotentialPassManagerType() const override;
 
 private:
-    //------------------------------------------------------------------
-    /// Ensures that the current function's linkage is set to external.
-    /// Otherwise the JIT may not return an address for it.
-    ///
-    /// @param[in] llvm_function
-    ///     The function whose linkage is to be fixed.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool 
-    FixFunctionLinkage (llvm::Function &llvm_function);
-    
-    //------------------------------------------------------------------
-    /// A module-level pass to replace all function pointers with their
-    /// integer equivalents.
-    //------------------------------------------------------------------
-    
-    //------------------------------------------------------------------
-    /// The top-level pass implementation
-    ///
-    /// @param[in] llvm_module
-    ///     The module currently being processed.
-    ///
-    /// @param[in] llvm_function
-    ///     The function currently being processed.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool 
-    HasSideEffects (llvm::Function &llvm_function);
-    
-    //------------------------------------------------------------------
-    /// A function-level pass to check whether the function has side
-    /// effects.
-    //------------------------------------------------------------------
-    
-    //------------------------------------------------------------------
-    /// Get the address of a function, and a location to put the complete
-    /// Value of the function if one is available.
-    ///
-    /// @param[in] function
-    ///     The function to find the location of.
-    ///
-    /// @param[out] ptr
-    ///     The location of the function in the target.
-    ///
-    /// @param[out] name
-    ///     The resolved name of the function (matters for intrinsics).
-    ///
-    /// @param[out] value_ptr
-    ///     A variable to put the function's completed Value* in, or NULL
-    ///     if the Value* shouldn't be stored anywhere.
-    ///
-    /// @return
-    ///     The pointer.
-    //------------------------------------------------------------------ 
-    LookupResult
-    GetFunctionAddress (llvm::Function *function,
-                        uint64_t &ptr,
-                        lldb_private::ConstString &name,
-                        llvm::Constant **&value_ptr);
-    
-    //------------------------------------------------------------------
-    /// A function-level pass to take the generated global value
-    /// $__lldb_expr_result and make it into a persistent variable.
-    /// Also see ASTResultSynthesizer.
-    //------------------------------------------------------------------
-    
-    //------------------------------------------------------------------
-    /// Find the NamedDecl corresponding to a Value.  This interface is
-    /// exposed for the IR interpreter.
-    ///
-    /// @param[in] module
-    ///     The module containing metadata to search
-    ///
-    /// @param[in] global
-    ///     The global entity to search for
-    ///
-    /// @return
-    ///     The corresponding variable declaration
-    //------------------------------------------------------------------
+  //------------------------------------------------------------------
+  /// Ensures that the current function's linkage is set to external.
+  /// Otherwise the JIT may not return an address for it.
+  ///
+  /// @param[in] llvm_function
+  ///     The function whose linkage is to be fixed.
+  ///
+  /// @return
+  ///     True on success; false otherwise.
+  //------------------------------------------------------------------
+  bool FixFunctionLinkage(llvm::Function &llvm_function);
+
+  //------------------------------------------------------------------
+  /// A module-level pass to replace all function pointers with their
+  /// integer equivalents.
+  //------------------------------------------------------------------
+
+  //------------------------------------------------------------------
+  /// The top-level pass implementation
+  ///
+  /// @param[in] llvm_module
+  ///     The module currently being processed.
+  ///
+  /// @param[in] llvm_function
+  ///     The function currently being processed.
+  ///
+  /// @return
+  ///     True on success; false otherwise.
+  //------------------------------------------------------------------
+  bool HasSideEffects(llvm::Function &llvm_function);
+
+  //------------------------------------------------------------------
+  /// A function-level pass to check whether the function has side
+  /// effects.
+  //------------------------------------------------------------------
+
+  //------------------------------------------------------------------
+  /// Get the address of a function, and a location to put the complete
+  /// Value of the function if one is available.
+  ///
+  /// @param[in] function
+  ///     The function to find the location of.
+  ///
+  /// @param[out] ptr
+  ///     The location of the function in the target.
+  ///
+  /// @param[out] name
+  ///     The resolved name of the function (matters for intrinsics).
+  ///
+  /// @param[out] value_ptr
+  ///     A variable to put the function's completed Value* in, or NULL
+  ///     if the Value* shouldn't be stored anywhere.
+  ///
+  /// @return
+  ///     The pointer.
+  //------------------------------------------------------------------
+  LookupResult GetFunctionAddress(llvm::Function *function, uint64_t &ptr,
+                                  lldb_private::ConstString &name,
+                                  llvm::Constant **&value_ptr);
+
+  //------------------------------------------------------------------
+  /// A function-level pass to take the generated global value
+  /// $__lldb_expr_result and make it into a persistent variable.
+  /// Also see ASTResultSynthesizer.
+  //------------------------------------------------------------------
+
+  //------------------------------------------------------------------
+  /// Find the NamedDecl corresponding to a Value.  This interface is
+  /// exposed for the IR interpreter.
+  ///
+  /// @param[in] module
+  ///     The module containing metadata to search
+  ///
+  /// @param[in] global
+  ///     The global entity to search for
+  ///
+  /// @return
+  ///     The corresponding variable declaration
+  //------------------------------------------------------------------
 public:
-    static clang::NamedDecl *
-    DeclForGlobal (const llvm::GlobalValue *global_val, llvm::Module *module);
+  static clang::NamedDecl *DeclForGlobal(const llvm::GlobalValue *global_val,
+                                         llvm::Module *module);
+
 private:
-    clang::NamedDecl *
-    DeclForGlobal (llvm::GlobalValue *global);
-    
-    //------------------------------------------------------------------
-    /// Set the constant result variable m_const_result to the provided
-    /// constant, assuming it can be evaluated.  The result variable
-    /// will be reset to NULL later if the expression has side effects.
-    ///
-    /// @param[in] initializer
-    ///     The constant initializer for the variable.
-    ///
-    /// @param[in] name
-    ///     The name of the result variable.
-    ///
-    /// @param[in] type
-    ///     The Clang type of the result variable.
-    //------------------------------------------------------------------    
-    void 
-    MaybeSetConstantResult (llvm::Constant *initializer,
-                            const lldb_private::ConstString &name,
-                            lldb_private::TypeFromParser type);
-    
-    //------------------------------------------------------------------
-    /// If the IR represents a cast of a variable, set m_const_result
-    /// to the result of the cast.  The result variable will be reset to
-    /// NULL latger if the expression has side effects.
-    ///
-    /// @param[in] type
-    ///     The Clang type of the result variable.
-    //------------------------------------------------------------------  
-    void
-    MaybeSetCastResult (lldb_private::TypeFromParser type);
-    
-    //------------------------------------------------------------------
-    /// The top-level pass implementation
-    ///
-    /// @param[in] llvm_function
-    ///     The function currently being processed.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    CreateResultVariable (llvm::Function &llvm_function);
-    
-    //------------------------------------------------------------------
-    /// A module-level pass to find Objective-C constant strings and
-    /// transform them to calls to CFStringCreateWithBytes.
-    //------------------------------------------------------------------
-
-    //------------------------------------------------------------------
-    /// Rewrite a single Objective-C constant string.
-    ///
-    /// @param[in] NSStr
-    ///     The constant NSString to be transformed
-    ///
-    /// @param[in] CStr
-    ///     The constant C string inside the NSString.  This will be
-    ///     passed as the bytes argument to CFStringCreateWithBytes.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    RewriteObjCConstString (llvm::GlobalVariable *NSStr,
-                            llvm::GlobalVariable *CStr);    
-    
-    //------------------------------------------------------------------
-    /// The top-level pass implementation
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    RewriteObjCConstStrings ();
-
-    //------------------------------------------------------------------
-    /// A basic block-level pass to find all Objective-C method calls and
-    /// rewrite them to use sel_registerName instead of statically allocated
-    /// selectors.  The reason is that the selectors are created on the
-    /// assumption that the Objective-C runtime will scan the appropriate
-    /// section and prepare them.  This doesn't happen when code is copied
-    /// into the target, though, and there's no easy way to induce the
-    /// runtime to scan them.  So instead we get our selectors from
-    /// sel_registerName.
-    //------------------------------------------------------------------
-
-    //------------------------------------------------------------------
-    /// Replace a single selector reference
-    ///
-    /// @param[in] selector_load
-    ///     The load of the statically-allocated selector.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    RewriteObjCSelector (llvm::Instruction* selector_load);
-    
-    //------------------------------------------------------------------
-    /// The top-level pass implementation
-    ///
-    /// @param[in] basic_block
-    ///     The basic block currently being processed.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    RewriteObjCSelectors (llvm::BasicBlock &basic_block);
-    
-    //------------------------------------------------------------------
-    /// A basic block-level pass to find all newly-declared persistent
-    /// variables and register them with the ClangExprDeclMap.  This 
-    /// allows them to be materialized and dematerialized like normal
-    /// external variables.  Before transformation, these persistent
-    /// variables look like normal locals, so they have an allocation.
-    /// This pass excises these allocations and makes references look
-    /// like external references where they will be resolved -- like all
-    /// other external references -- by ResolveExternals().
-    //------------------------------------------------------------------
-
-    //------------------------------------------------------------------
-    /// Handle a single allocation of a persistent variable
-    ///
-    /// @param[in] persistent_alloc
-    ///     The allocation of the persistent variable.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    RewritePersistentAlloc (llvm::Instruction *persistent_alloc);
-    
-    //------------------------------------------------------------------
-    /// The top-level pass implementation
-    ///
-    /// @param[in] basic_block
-    ///     The basic block currently being processed.
-    //------------------------------------------------------------------
-    bool 
-    RewritePersistentAllocs (llvm::BasicBlock &basic_block);
-    
-    //------------------------------------------------------------------
-    /// A function-level pass to find all external variables and functions 
-    /// used in the IR.  Each found external variable is added to the 
-    /// struct, and each external function is resolved in place, its call
-    /// replaced with a call to a function pointer whose value is the 
-    /// address of the function in the target process.
-    //------------------------------------------------------------------
-    
-    //------------------------------------------------------------------
-    /// Write an initializer to a memory array of assumed sufficient
-    /// size.
-    ///
-    /// @param[in] data
-    ///     A pointer to the data to write to.
-    ///
-    /// @param[in] initializer
-    ///     The initializer itself.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool
-    MaterializeInitializer (uint8_t *data, llvm::Constant *initializer);
-    
-    //------------------------------------------------------------------
-    /// Move an internal variable into the static allocation section.
-    ///
-    /// @param[in] global_variable
-    ///     The variable.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool
-    MaterializeInternalVariable (llvm::GlobalVariable *global_variable);
-    
-    //------------------------------------------------------------------
-    /// Handle a single externally-defined variable
-    ///
-    /// @param[in] value
-    ///     The variable.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    MaybeHandleVariable (llvm::Value *value);
-    
-    //------------------------------------------------------------------
-    /// Handle a single externally-defined symbol
-    ///
-    /// @param[in] symbol
-    ///     The symbol.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool
-    HandleSymbol (llvm::Value *symbol);
-    
-    //------------------------------------------------------------------
-    /// Handle a single externally-defined Objective-C class
-    ///
-    /// @param[in] classlist_reference
-    ///     The reference, usually "01L_OBJC_CLASSLIST_REFERENCES_$_n"
-    ///     where n (if present) is an index.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool
-    HandleObjCClass(llvm::Value *classlist_reference);
-
-    //------------------------------------------------------------------
-    /// Handle all the arguments to a function call
-    ///
-    /// @param[in] C
-    ///     The call instruction.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    MaybeHandleCallArguments (llvm::CallInst *call_inst);
-    
-    //------------------------------------------------------------------
-    /// Resolve variable references in calls to external functions
-    ///
-    /// @param[in] basic_block
-    ///     The basic block currently being processed.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    ResolveCalls (llvm::BasicBlock &basic_block);
-    
-    //------------------------------------------------------------------
-    /// Remove calls to __cxa_atexit, which should never be generated by
-    /// expressions.
-    ///
-    /// @param[in] call_inst
-    ///     The call instruction.
-    ///
-    /// @return
-    ///     True if the scan was successful; false if some operation
-    ///     failed
-    //------------------------------------------------------------------
-    bool
-    RemoveCXAAtExit (llvm::BasicBlock &basic_block);
-    
-    //------------------------------------------------------------------
-    /// The top-level pass implementation
-    ///
-    /// @param[in] basic_block
-    ///     The function currently being processed.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    ResolveExternals (llvm::Function &llvm_function);
-    
-    //------------------------------------------------------------------
-    /// A basic block-level pass to excise guard variables from the code.
-    /// The result for the function is passed through Clang as a static
-    /// variable.  Static variables normally have guard variables to
-    /// ensure that they are only initialized once.  
-    //------------------------------------------------------------------
-    
-    //------------------------------------------------------------------
-    /// Rewrite a load to a guard variable to return constant 0.
-    ///
-    /// @param[in] guard_load
-    ///     The load instruction to zero out.
-    //------------------------------------------------------------------
-    void
-    TurnGuardLoadIntoZero(llvm::Instruction* guard_load);
-    
-    //------------------------------------------------------------------
-    /// The top-level pass implementation
-    ///
-    /// @param[in] basic_block
-    ///     The basic block currently being processed.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    RemoveGuards (llvm::BasicBlock &basic_block);
-    
-    //------------------------------------------------------------------
-    /// A function-level pass to make all external variable references
-    /// point at the correct offsets from the void* passed into the
-    /// function.  ClangExpressionDeclMap::DoStructLayout() must be called
-    /// beforehand, so that the offsets are valid.
-    //------------------------------------------------------------------
-    
-    //------------------------------------------------------------------
-    /// The top-level pass implementation
-    ///
-    /// @param[in] llvm_function
-    ///     The function currently being processed.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool
-    ReplaceVariables(llvm::Function &llvm_function);
-
-    /// Flags
-    bool m_resolve_vars; ///< True if external variable references and persistent variable references should be resolved
-    lldb_private::ConstString m_func_name;      ///< The name of the function to translate
-    lldb_private::ConstString m_result_name;    ///< The name of the result variable ($0, $1, ...)
-    lldb_private::TypeFromParser m_result_type; ///< The type of the result variable.
-    llvm::Module *m_module; ///< The module being processed, or NULL if that has not been determined yet.
-    std::unique_ptr<llvm::DataLayout>
-        m_target_data; ///< The target data for the module being processed, or NULL if there is no module.
-    lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls
-    llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the
-                                               ///appropriate function pointer type
-    llvm::Constant *m_sel_registerName;   ///< The address of the function sel_registerName, cast to the appropriate
-                                          ///function pointer type
-    llvm::IntegerType *m_intptr_ty;       ///< The type of an integer large enough to hold a pointer.
-    lldb_private::Stream &m_error_stream; ///< The stream on which errors should be printed
-    lldb_private::IRExecutionUnit &m_execution_unit; ///< The execution unit containing the IR being created.
-
-    llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable.  If
-                                     ///m_has_side_effects is true, this is NULL.
-    bool m_result_is_pointer;        ///< True if the function's result in the AST is a pointer (see comments in
-                                     ///ASTResultSynthesizer::SynthesizeBodyResult)
-
-    llvm::GlobalVariable *m_reloc_placeholder; ///< A placeholder that will be replaced by a pointer to the final
-                                               ///location of the static allocation.
-
-    //------------------------------------------------------------------
-    /// UnfoldConstant operates on a constant [Old] which has just been
-    /// replaced with a value [New].  We assume that new_value has
-    /// been properly placed early in the function, in front of the
-    /// first instruction in the entry basic block
-    /// [FirstEntryInstruction].
-    ///
-    /// UnfoldConstant reads through the uses of Old and replaces Old
-    /// in those uses with New.  Where those uses are constants, the
-    /// function generates new instructions to compute the result of the
-    /// new, non-constant expression and places them before
-    /// FirstEntryInstruction.  These instructions replace the constant
-    /// uses, so UnfoldConstant calls itself recursively for those.
-    ///
-    /// @param[in] llvm_function
-    ///     The function currently being processed.
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-
-    class FunctionValueCache {
-    public:
-        typedef std::function <llvm::Value *(llvm::Function *)> Maker;
-
-        FunctionValueCache (Maker const &maker);
-        ~FunctionValueCache ();
-        llvm::Value *GetValue (llvm::Function *function);
-    private:
-        Maker const m_maker;
-        typedef std::map<llvm::Function *, llvm::Value *> FunctionValueMap;
-        FunctionValueMap m_values;
-    };
-    
-    FunctionValueCache m_entry_instruction_finder;
-    
-    static bool
-    UnfoldConstant (llvm::Constant *old_constant,
-                    llvm::Function *llvm_function,
-                    FunctionValueCache &value_maker,
-                    FunctionValueCache &entry_instruction_finder,
-                    lldb_private::Stream &error_stream);
-    
-    //------------------------------------------------------------------
-    /// Construct a reference to m_reloc_placeholder with a given type
-    /// and offset.  This typically happens after inserting data into
-    /// m_data_allocator.
-    ///
-    /// @param[in] type
-    ///     The type of the value being loaded.
-    ///
-    /// @param[in] offset
-    ///     The offset of the value from the base of m_data_allocator.
-    ///
-    /// @return
-    ///     The Constant for the reference, usually a ConstantExpr.
-    //------------------------------------------------------------------
-    llvm::Constant *
-    BuildRelocation(llvm::Type *type, 
-                    uint64_t offset);
-    
-    //------------------------------------------------------------------
-    /// Commit the allocation in m_data_allocator and use its final
-    /// location to replace m_reloc_placeholder.
-    ///
-    /// @param[in] module
-    ///     The module that m_data_allocator resides in
-    ///
-    /// @return
-    ///     True on success; false otherwise
-    //------------------------------------------------------------------
-    bool 
-    CompleteDataAllocation ();
+  clang::NamedDecl *DeclForGlobal(llvm::GlobalValue *global);
 
+  //------------------------------------------------------------------
+  /// Set the constant result variable m_const_result to the provided
+  /// constant, assuming it can be evaluated.  The result variable
+  /// will be reset to NULL later if the expression has side effects.
+  ///
+  /// @param[in] initializer
+  ///     The constant initializer for the variable.
+  ///
+  /// @param[in] name
+  ///     The name of the result variable.
+  ///
+  /// @param[in] type
+  ///     The Clang type of the result variable.
+  //------------------------------------------------------------------
+  void MaybeSetConstantResult(llvm::Constant *initializer,
+                              const lldb_private::ConstString &name,
+                              lldb_private::TypeFromParser type);
+
+  //------------------------------------------------------------------
+  /// If the IR represents a cast of a variable, set m_const_result
+  /// to the result of the cast.  The result variable will be reset to
+  /// NULL latger if the expression has side effects.
+  ///
+  /// @param[in] type
+  ///     The Clang type of the result variable.
+  //------------------------------------------------------------------
+  void MaybeSetCastResult(lldb_private::TypeFromParser type);
+
+  //------------------------------------------------------------------
+  /// The top-level pass implementation
+  ///
+  /// @param[in] llvm_function
+  ///     The function currently being processed.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool CreateResultVariable(llvm::Function &llvm_function);
+
+  //------------------------------------------------------------------
+  /// A module-level pass to find Objective-C constant strings and
+  /// transform them to calls to CFStringCreateWithBytes.
+  //------------------------------------------------------------------
+
+  //------------------------------------------------------------------
+  /// Rewrite a single Objective-C constant string.
+  ///
+  /// @param[in] NSStr
+  ///     The constant NSString to be transformed
+  ///
+  /// @param[in] CStr
+  ///     The constant C string inside the NSString.  This will be
+  ///     passed as the bytes argument to CFStringCreateWithBytes.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool RewriteObjCConstString(llvm::GlobalVariable *NSStr,
+                              llvm::GlobalVariable *CStr);
+
+  //------------------------------------------------------------------
+  /// The top-level pass implementation
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool RewriteObjCConstStrings();
+
+  //------------------------------------------------------------------
+  /// A basic block-level pass to find all Objective-C method calls and
+  /// rewrite them to use sel_registerName instead of statically allocated
+  /// selectors.  The reason is that the selectors are created on the
+  /// assumption that the Objective-C runtime will scan the appropriate
+  /// section and prepare them.  This doesn't happen when code is copied
+  /// into the target, though, and there's no easy way to induce the
+  /// runtime to scan them.  So instead we get our selectors from
+  /// sel_registerName.
+  //------------------------------------------------------------------
+
+  //------------------------------------------------------------------
+  /// Replace a single selector reference
+  ///
+  /// @param[in] selector_load
+  ///     The load of the statically-allocated selector.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool RewriteObjCSelector(llvm::Instruction *selector_load);
+
+  //------------------------------------------------------------------
+  /// The top-level pass implementation
+  ///
+  /// @param[in] basic_block
+  ///     The basic block currently being processed.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool RewriteObjCSelectors(llvm::BasicBlock &basic_block);
+
+  //------------------------------------------------------------------
+  /// A basic block-level pass to find all newly-declared persistent
+  /// variables and register them with the ClangExprDeclMap.  This
+  /// allows them to be materialized and dematerialized like normal
+  /// external variables.  Before transformation, these persistent
+  /// variables look like normal locals, so they have an allocation.
+  /// This pass excises these allocations and makes references look
+  /// like external references where they will be resolved -- like all
+  /// other external references -- by ResolveExternals().
+  //------------------------------------------------------------------
+
+  //------------------------------------------------------------------
+  /// Handle a single allocation of a persistent variable
+  ///
+  /// @param[in] persistent_alloc
+  ///     The allocation of the persistent variable.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool RewritePersistentAlloc(llvm::Instruction *persistent_alloc);
+
+  //------------------------------------------------------------------
+  /// The top-level pass implementation
+  ///
+  /// @param[in] basic_block
+  ///     The basic block currently being processed.
+  //------------------------------------------------------------------
+  bool RewritePersistentAllocs(llvm::BasicBlock &basic_block);
+
+  //------------------------------------------------------------------
+  /// A function-level pass to find all external variables and functions
+  /// used in the IR.  Each found external variable is added to the
+  /// struct, and each external function is resolved in place, its call
+  /// replaced with a call to a function pointer whose value is the
+  /// address of the function in the target process.
+  //------------------------------------------------------------------
+
+  //------------------------------------------------------------------
+  /// Write an initializer to a memory array of assumed sufficient
+  /// size.
+  ///
+  /// @param[in] data
+  ///     A pointer to the data to write to.
+  ///
+  /// @param[in] initializer
+  ///     The initializer itself.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool MaterializeInitializer(uint8_t *data, llvm::Constant *initializer);
+
+  //------------------------------------------------------------------
+  /// Move an internal variable into the static allocation section.
+  ///
+  /// @param[in] global_variable
+  ///     The variable.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool MaterializeInternalVariable(llvm::GlobalVariable *global_variable);
+
+  //------------------------------------------------------------------
+  /// Handle a single externally-defined variable
+  ///
+  /// @param[in] value
+  ///     The variable.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool MaybeHandleVariable(llvm::Value *value);
+
+  //------------------------------------------------------------------
+  /// Handle a single externally-defined symbol
+  ///
+  /// @param[in] symbol
+  ///     The symbol.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool HandleSymbol(llvm::Value *symbol);
+
+  //------------------------------------------------------------------
+  /// Handle a single externally-defined Objective-C class
+  ///
+  /// @param[in] classlist_reference
+  ///     The reference, usually "01L_OBJC_CLASSLIST_REFERENCES_$_n"
+  ///     where n (if present) is an index.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool HandleObjCClass(llvm::Value *classlist_reference);
+
+  //------------------------------------------------------------------
+  /// Handle all the arguments to a function call
+  ///
+  /// @param[in] C
+  ///     The call instruction.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool MaybeHandleCallArguments(llvm::CallInst *call_inst);
+
+  //------------------------------------------------------------------
+  /// Resolve variable references in calls to external functions
+  ///
+  /// @param[in] basic_block
+  ///     The basic block currently being processed.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool ResolveCalls(llvm::BasicBlock &basic_block);
+
+  //------------------------------------------------------------------
+  /// Remove calls to __cxa_atexit, which should never be generated by
+  /// expressions.
+  ///
+  /// @param[in] call_inst
+  ///     The call instruction.
+  ///
+  /// @return
+  ///     True if the scan was successful; false if some operation
+  ///     failed
+  //------------------------------------------------------------------
+  bool RemoveCXAAtExit(llvm::BasicBlock &basic_block);
+
+  //------------------------------------------------------------------
+  /// The top-level pass implementation
+  ///
+  /// @param[in] basic_block
+  ///     The function currently being processed.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool ResolveExternals(llvm::Function &llvm_function);
+
+  //------------------------------------------------------------------
+  /// A basic block-level pass to excise guard variables from the code.
+  /// The result for the function is passed through Clang as a static
+  /// variable.  Static variables normally have guard variables to
+  /// ensure that they are only initialized once.
+  //------------------------------------------------------------------
+
+  //------------------------------------------------------------------
+  /// Rewrite a load to a guard variable to return constant 0.
+  ///
+  /// @param[in] guard_load
+  ///     The load instruction to zero out.
+  //------------------------------------------------------------------
+  void TurnGuardLoadIntoZero(llvm::Instruction *guard_load);
+
+  //------------------------------------------------------------------
+  /// The top-level pass implementation
+  ///
+  /// @param[in] basic_block
+  ///     The basic block currently being processed.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool RemoveGuards(llvm::BasicBlock &basic_block);
+
+  //------------------------------------------------------------------
+  /// A function-level pass to make all external variable references
+  /// point at the correct offsets from the void* passed into the
+  /// function.  ClangExpressionDeclMap::DoStructLayout() must be called
+  /// beforehand, so that the offsets are valid.
+  //------------------------------------------------------------------
+
+  //------------------------------------------------------------------
+  /// The top-level pass implementation
+  ///
+  /// @param[in] llvm_function
+  ///     The function currently being processed.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool ReplaceVariables(llvm::Function &llvm_function);
+
+  /// Flags
+  bool m_resolve_vars; ///< True if external variable references and persistent
+                       ///variable references should be resolved
+  lldb_private::ConstString
+      m_func_name; ///< The name of the function to translate
+  lldb_private::ConstString
+      m_result_name; ///< The name of the result variable ($0, $1, ...)
+  lldb_private::TypeFromParser
+      m_result_type;      ///< The type of the result variable.
+  llvm::Module *m_module; ///< The module being processed, or NULL if that has
+                          ///not been determined yet.
+  std::unique_ptr<llvm::DataLayout> m_target_data; ///< The target data for the
+                                                   ///module being processed, or
+                                                   ///NULL if there is no
+                                                   ///module.
+  lldb_private::ClangExpressionDeclMap
+      *m_decl_map; ///< The DeclMap containing the Decls
+  llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function
+                                             ///CFStringCreateWithBytes, cast to
+                                             ///the
+  /// appropriate function pointer type
+  llvm::Constant *m_sel_registerName; ///< The address of the function
+                                      ///sel_registerName, cast to the
+                                      ///appropriate
+                                      /// function pointer type
+  llvm::IntegerType
+      *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
+  lldb_private::Stream
+      &m_error_stream; ///< The stream on which errors should be printed
+  lldb_private::IRExecutionUnit &
+      m_execution_unit; ///< The execution unit containing the IR being created.
+
+  llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that
+                                   ///writes to the result variable.  If
+                                   /// m_has_side_effects is true, this is NULL.
+  bool m_result_is_pointer; ///< True if the function's result in the AST is a
+                            ///pointer (see comments in
+                            /// ASTResultSynthesizer::SynthesizeBodyResult)
+
+  llvm::GlobalVariable *m_reloc_placeholder; ///< A placeholder that will be
+                                             ///replaced by a pointer to the
+                                             ///final
+  /// location of the static allocation.
+
+  //------------------------------------------------------------------
+  /// UnfoldConstant operates on a constant [Old] which has just been
+  /// replaced with a value [New].  We assume that new_value has
+  /// been properly placed early in the function, in front of the
+  /// first instruction in the entry basic block
+  /// [FirstEntryInstruction].
+  ///
+  /// UnfoldConstant reads through the uses of Old and replaces Old
+  /// in those uses with New.  Where those uses are constants, the
+  /// function generates new instructions to compute the result of the
+  /// new, non-constant expression and places them before
+  /// FirstEntryInstruction.  These instructions replace the constant
+  /// uses, so UnfoldConstant calls itself recursively for those.
+  ///
+  /// @param[in] llvm_function
+  ///     The function currently being processed.
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+
+  class FunctionValueCache {
+  public:
+    typedef std::function<llvm::Value *(llvm::Function *)> Maker;
+
+    FunctionValueCache(Maker const &maker);
+    ~FunctionValueCache();
+    llvm::Value *GetValue(llvm::Function *function);
+
+  private:
+    Maker const m_maker;
+    typedef std::map<llvm::Function *, llvm::Value *> FunctionValueMap;
+    FunctionValueMap m_values;
+  };
+
+  FunctionValueCache m_entry_instruction_finder;
+
+  static bool UnfoldConstant(llvm::Constant *old_constant,
+                             llvm::Function *llvm_function,
+                             FunctionValueCache &value_maker,
+                             FunctionValueCache &entry_instruction_finder,
+                             lldb_private::Stream &error_stream);
+
+  //------------------------------------------------------------------
+  /// Construct a reference to m_reloc_placeholder with a given type
+  /// and offset.  This typically happens after inserting data into
+  /// m_data_allocator.
+  ///
+  /// @param[in] type
+  ///     The type of the value being loaded.
+  ///
+  /// @param[in] offset
+  ///     The offset of the value from the base of m_data_allocator.
+  ///
+  /// @return
+  ///     The Constant for the reference, usually a ConstantExpr.
+  //------------------------------------------------------------------
+  llvm::Constant *BuildRelocation(llvm::Type *type, uint64_t offset);
+
+  //------------------------------------------------------------------
+  /// Commit the allocation in m_data_allocator and use its final
+  /// location to replace m_reloc_placeholder.
+  ///
+  /// @param[in] module
+  ///     The module that m_data_allocator resides in
+  ///
+  /// @return
+  ///     True on success; false otherwise
+  //------------------------------------------------------------------
+  bool CompleteDataAllocation();
 };
 
 #endif // liblldb_IRForTarget_h_

Modified: lldb/trunk/source/Plugins/ExpressionParser/Go/GoAST.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Go/GoAST.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Go/GoAST.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Go/GoAST.h Tue Sep  6 15:57:50 2016
@@ -13,3214 +13,1965 @@
 #ifndef liblldb_GoAST_h
 #define liblldb_GoAST_h
 
+#include "Plugins/ExpressionParser/Go/GoLexer.h"
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-private.h"
 #include "llvm/Support/Casting.h"
-#include "Plugins/ExpressionParser/Go/GoLexer.h"
 
-namespace lldb_private
-{
+namespace lldb_private {
 
-class GoASTNode
-{
-  public:
-    typedef GoLexer::TokenType TokenType;
-    typedef GoLexer::Token Token;
-    enum ChanDir
-    {
-        eChanBidir,
-        eChanSend,
-        eChanRecv,
-    };
-    enum NodeKind
-    {
-        eBadDecl,
-        eFuncDecl,
-        eGenDecl,
-        eArrayType,
-        eBadExpr,
-        eBasicLit,
-        eBinaryExpr,
-        eIdent,
-        eCallExpr,
-        eChanType,
-        eCompositeLit,
-        eEllipsis,
-        eFuncType,
-        eFuncLit,
-        eIndexExpr,
-        eInterfaceType,
-        eKeyValueExpr,
-        eMapType,
-        eParenExpr,
-        eSelectorExpr,
-        eSliceExpr,
-        eStarExpr,
-        eStructType,
-        eTypeAssertExpr,
-        eUnaryExpr,
-        eImportSpec,
-        eTypeSpec,
-        eValueSpec,
-        eAssignStmt,
-        eBadStmt,
-        eBlockStmt,
-        eBranchStmt,
-        eCaseClause,
-        eCommClause,
-        eDeclStmt,
-        eDeferStmt,
-        eEmptyStmt,
-        eExprStmt,
-        eForStmt,
-        eGoStmt,
-        eIfStmt,
-        eIncDecStmt,
-        eLabeledStmt,
-        eRangeStmt,
-        eReturnStmt,
-        eSelectStmt,
-        eSendStmt,
-        eSwitchStmt,
-        eTypeSwitchStmt,
-        eField,
-        eFieldList,
-    };
-
-    virtual ~GoASTNode() = default;
-
-    NodeKind
-    GetKind() const
-    {
-        return m_kind;
-    }
+class GoASTNode {
+public:
+  typedef GoLexer::TokenType TokenType;
+  typedef GoLexer::Token Token;
+  enum ChanDir {
+    eChanBidir,
+    eChanSend,
+    eChanRecv,
+  };
+  enum NodeKind {
+    eBadDecl,
+    eFuncDecl,
+    eGenDecl,
+    eArrayType,
+    eBadExpr,
+    eBasicLit,
+    eBinaryExpr,
+    eIdent,
+    eCallExpr,
+    eChanType,
+    eCompositeLit,
+    eEllipsis,
+    eFuncType,
+    eFuncLit,
+    eIndexExpr,
+    eInterfaceType,
+    eKeyValueExpr,
+    eMapType,
+    eParenExpr,
+    eSelectorExpr,
+    eSliceExpr,
+    eStarExpr,
+    eStructType,
+    eTypeAssertExpr,
+    eUnaryExpr,
+    eImportSpec,
+    eTypeSpec,
+    eValueSpec,
+    eAssignStmt,
+    eBadStmt,
+    eBlockStmt,
+    eBranchStmt,
+    eCaseClause,
+    eCommClause,
+    eDeclStmt,
+    eDeferStmt,
+    eEmptyStmt,
+    eExprStmt,
+    eForStmt,
+    eGoStmt,
+    eIfStmt,
+    eIncDecStmt,
+    eLabeledStmt,
+    eRangeStmt,
+    eReturnStmt,
+    eSelectStmt,
+    eSendStmt,
+    eSwitchStmt,
+    eTypeSwitchStmt,
+    eField,
+    eFieldList,
+  };
+
+  virtual ~GoASTNode() = default;
 
-    virtual const char *GetKindName() const = 0;
+  NodeKind GetKind() const { return m_kind; }
 
-    template <typename V> void WalkChildren(V &v);
+  virtual const char *GetKindName() const = 0;
 
-  protected:
-    explicit GoASTNode(NodeKind kind) : m_kind(kind) { }
+  template <typename V> void WalkChildren(V &v);
 
-  private:
-    const NodeKind m_kind;
-    
-    GoASTNode(const GoASTNode &) = delete;
-    const GoASTNode &operator=(const GoASTNode &) = delete;
+protected:
+  explicit GoASTNode(NodeKind kind) : m_kind(kind) {}
+
+private:
+  const NodeKind m_kind;
+
+  GoASTNode(const GoASTNode &) = delete;
+  const GoASTNode &operator=(const GoASTNode &) = delete;
 };
 
+class GoASTDecl : public GoASTNode {
+public:
+  template <typename R, typename V> R Visit(V *v) const;
 
-class GoASTDecl : public GoASTNode
-{
-  public:
-    template <typename R, typename V> R Visit(V *v) const;
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() >= eBadDecl && n->GetKind() <= eGenDecl;
+  }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() >= eBadDecl && n->GetKind() <= eGenDecl;
-    }
+protected:
+  explicit GoASTDecl(NodeKind kind) : GoASTNode(kind) {}
 
-  protected:
-    explicit GoASTDecl(NodeKind kind) : GoASTNode(kind) { }
-  private:
-
-    GoASTDecl(const GoASTDecl &) = delete;
-    const GoASTDecl &operator=(const GoASTDecl &) = delete;
-};
-
-class GoASTExpr : public GoASTNode
-{
-  public:
-    template <typename R, typename V> R Visit(V *v) const;
-
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() >= eArrayType && n->GetKind() <= eUnaryExpr;
-    }
+private:
+  GoASTDecl(const GoASTDecl &) = delete;
+  const GoASTDecl &operator=(const GoASTDecl &) = delete;
+};
 
-  protected:
-    explicit GoASTExpr(NodeKind kind) : GoASTNode(kind) { }
-  private:
-
-    GoASTExpr(const GoASTExpr &) = delete;
-    const GoASTExpr &operator=(const GoASTExpr &) = delete;
-};
-
-class GoASTSpec : public GoASTNode
-{
-  public:
-    template <typename R, typename V> R Visit(V *v) const;
-
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() >= eImportSpec && n->GetKind() <= eValueSpec;
-    }
+class GoASTExpr : public GoASTNode {
+public:
+  template <typename R, typename V> R Visit(V *v) const;
 
-  protected:
-    explicit GoASTSpec(NodeKind kind) : GoASTNode(kind) { }
-  private:
-
-    GoASTSpec(const GoASTSpec &) = delete;
-    const GoASTSpec &operator=(const GoASTSpec &) = delete;
-};
-
-class GoASTStmt : public GoASTNode
-{
-  public:
-    template <typename R, typename V> R Visit(V *v) const;
-
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() >= eAssignStmt && n->GetKind() <= eTypeSwitchStmt;
-    }
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() >= eArrayType && n->GetKind() <= eUnaryExpr;
+  }
 
-  protected:
-    explicit GoASTStmt(NodeKind kind) : GoASTNode(kind) { }
-  private:
+protected:
+  explicit GoASTExpr(NodeKind kind) : GoASTNode(kind) {}
 
-    GoASTStmt(const GoASTStmt &) = delete;
-    const GoASTStmt &operator=(const GoASTStmt &) = delete;
+private:
+  GoASTExpr(const GoASTExpr &) = delete;
+  const GoASTExpr &operator=(const GoASTExpr &) = delete;
 };
 
+class GoASTSpec : public GoASTNode {
+public:
+  template <typename R, typename V> R Visit(V *v) const;
 
-class GoASTArrayType : public GoASTExpr
-{
-  public:
-    GoASTArrayType(GoASTExpr *len, GoASTExpr *elt) : GoASTExpr(eArrayType), m_len_up(len), m_elt_up(elt) {}
-    ~GoASTArrayType() override = default;
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() >= eImportSpec && n->GetKind() <= eValueSpec;
+  }
 
-    const char *
-    GetKindName() const override
-    {
-        return "ArrayType";
-    }
+protected:
+  explicit GoASTSpec(NodeKind kind) : GoASTNode(kind) {}
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eArrayType;
-    }
-    
-    const GoASTExpr *
-    GetLen() const
-    {
-        return m_len_up.get();
-    }
-    void
-    SetLen(GoASTExpr *len)
-    {
-        m_len_up.reset(len);
-    }
+private:
+  GoASTSpec(const GoASTSpec &) = delete;
+  const GoASTSpec &operator=(const GoASTSpec &) = delete;
+};
 
-    const GoASTExpr *
-    GetElt() const
-    {
-        return m_elt_up.get();
-    }
-    void
-    SetElt(GoASTExpr *elt)
-    {
-        m_elt_up.reset(elt);
-    }
+class GoASTStmt : public GoASTNode {
+public:
+  template <typename R, typename V> R Visit(V *v) const;
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_len_up;
-    std::unique_ptr<GoASTExpr> m_elt_up;
-
-    GoASTArrayType(const GoASTArrayType &) = delete;
-    const GoASTArrayType &operator=(const GoASTArrayType &) = delete;
-};
-
-class GoASTAssignStmt : public GoASTStmt
-{
-  public:
-    explicit GoASTAssignStmt(bool define) : GoASTStmt(eAssignStmt), m_define(define) {}
-    ~GoASTAssignStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "AssignStmt";
-    }
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() >= eAssignStmt && n->GetKind() <= eTypeSwitchStmt;
+  }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eAssignStmt;
-    }
-    
-    size_t
-    NumLhs() const
-    {
-        return m_lhs.size();
-    }
-    const GoASTExpr *
-    GetLhs(int i) const
-    {
-        return m_lhs[i].get();
-    }
-    void
-    AddLhs(GoASTExpr *lhs)
-    {
-        m_lhs.push_back(std::unique_ptr<GoASTExpr>(lhs));
-    }
+protected:
+  explicit GoASTStmt(NodeKind kind) : GoASTNode(kind) {}
 
-    size_t
-    NumRhs() const
-    {
-        return m_rhs.size();
-    }
-    const GoASTExpr *
-    GetRhs(int i) const
-    {
-        return m_rhs[i].get();
-    }
-    void
-    AddRhs(GoASTExpr *rhs)
-    {
-        m_rhs.push_back(std::unique_ptr<GoASTExpr>(rhs));
-    }
+private:
+  GoASTStmt(const GoASTStmt &) = delete;
+  const GoASTStmt &operator=(const GoASTStmt &) = delete;
+};
 
-    bool 
-    GetDefine() const
-    {
-        return m_define;
-    }
-    void
-    SetDefine(bool define)
-    {
-        m_define = define;
-    }
+class GoASTArrayType : public GoASTExpr {
+public:
+  GoASTArrayType(GoASTExpr *len, GoASTExpr *elt)
+      : GoASTExpr(eArrayType), m_len_up(len), m_elt_up(elt) {}
+  ~GoASTArrayType() override = default;
 
-  private:
-    friend class GoASTNode;
-    std::vector<std::unique_ptr<GoASTExpr> > m_lhs;
-    std::vector<std::unique_ptr<GoASTExpr> > m_rhs;
-    bool m_define;
-
-    GoASTAssignStmt(const GoASTAssignStmt &) = delete;
-    const GoASTAssignStmt &operator=(const GoASTAssignStmt &) = delete;
-};
-
-class GoASTBadDecl : public GoASTDecl
-{
-  public:
-    GoASTBadDecl() : GoASTDecl(eBadDecl) {}
-    ~GoASTBadDecl() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "BadDecl";
-    }
+  const char *GetKindName() const override { return "ArrayType"; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eBadDecl;
-    }
-    
-    GoASTBadDecl(const GoASTBadDecl &) = delete;
-    const GoASTBadDecl &operator=(const GoASTBadDecl &) = delete;
-};
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eArrayType; }
 
-class GoASTBadExpr : public GoASTExpr
-{
-  public:
-    GoASTBadExpr() : GoASTExpr(eBadExpr) {}
-    ~GoASTBadExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "BadExpr";
-    }
+  const GoASTExpr *GetLen() const { return m_len_up.get(); }
+  void SetLen(GoASTExpr *len) { m_len_up.reset(len); }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eBadExpr;
-    }
-    
-    GoASTBadExpr(const GoASTBadExpr &) = delete;
-    const GoASTBadExpr &operator=(const GoASTBadExpr &) = delete;
-};
+  const GoASTExpr *GetElt() const { return m_elt_up.get(); }
+  void SetElt(GoASTExpr *elt) { m_elt_up.reset(elt); }
 
-class GoASTBadStmt : public GoASTStmt
-{
-  public:
-    GoASTBadStmt() : GoASTStmt(eBadStmt) {}
-    ~GoASTBadStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "BadStmt";
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_len_up;
+  std::unique_ptr<GoASTExpr> m_elt_up;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eBadStmt;
-    }
-    
-    GoASTBadStmt(const GoASTBadStmt &) = delete;
-    const GoASTBadStmt &operator=(const GoASTBadStmt &) = delete;
+  GoASTArrayType(const GoASTArrayType &) = delete;
+  const GoASTArrayType &operator=(const GoASTArrayType &) = delete;
 };
 
-class GoASTBasicLit : public GoASTExpr
-{
-  public:
-    explicit GoASTBasicLit(Token value) : GoASTExpr(eBasicLit), m_value(value) {}
-    ~GoASTBasicLit() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "BasicLit";
-    }
+class GoASTAssignStmt : public GoASTStmt {
+public:
+  explicit GoASTAssignStmt(bool define)
+      : GoASTStmt(eAssignStmt), m_define(define) {}
+  ~GoASTAssignStmt() override = default;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eBasicLit;
-    }
-    
-    Token 
-    GetValue() const
-    {
-        return m_value;
-    }
-    void
-    SetValue(Token value)
-    {
-        m_value = value;
-    }
+  const char *GetKindName() const override { return "AssignStmt"; }
 
-  private:
-    friend class GoASTNode;
-    Token m_value;
-
-    GoASTBasicLit(const GoASTBasicLit &) = delete;
-    const GoASTBasicLit &operator=(const GoASTBasicLit &) = delete;
-};
-
-class GoASTBinaryExpr : public GoASTExpr
-{
-  public:
-    GoASTBinaryExpr(GoASTExpr *x, GoASTExpr *y, TokenType op) : GoASTExpr(eBinaryExpr), m_x_up(x), m_y_up(y), m_op(op) {}
-    ~GoASTBinaryExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "BinaryExpr";
-    }
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eAssignStmt;
+  }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eBinaryExpr;
-    }
-    
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+  size_t NumLhs() const { return m_lhs.size(); }
+  const GoASTExpr *GetLhs(int i) const { return m_lhs[i].get(); }
+  void AddLhs(GoASTExpr *lhs) {
+    m_lhs.push_back(std::unique_ptr<GoASTExpr>(lhs));
+  }
 
-    const GoASTExpr *
-    GetY() const
-    {
-        return m_y_up.get();
-    }
-    void
-    SetY(GoASTExpr *y)
-    {
-        m_y_up.reset(y);
-    }
+  size_t NumRhs() const { return m_rhs.size(); }
+  const GoASTExpr *GetRhs(int i) const { return m_rhs[i].get(); }
+  void AddRhs(GoASTExpr *rhs) {
+    m_rhs.push_back(std::unique_ptr<GoASTExpr>(rhs));
+  }
 
-    TokenType 
-    GetOp() const
-    {
-        return m_op;
-    }
-    void
-    SetOp(TokenType op)
-    {
-        m_op = op;
-    }
+  bool GetDefine() const { return m_define; }
+  void SetDefine(bool define) { m_define = define; }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_x_up;
-    std::unique_ptr<GoASTExpr> m_y_up;
-    TokenType m_op;
-
-    GoASTBinaryExpr(const GoASTBinaryExpr &) = delete;
-    const GoASTBinaryExpr &operator=(const GoASTBinaryExpr &) = delete;
-};
-
-class GoASTBlockStmt : public GoASTStmt
-{
-  public:
-    GoASTBlockStmt() : GoASTStmt(eBlockStmt) {}
-    ~GoASTBlockStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "BlockStmt";
-    }
+private:
+  friend class GoASTNode;
+  std::vector<std::unique_ptr<GoASTExpr>> m_lhs;
+  std::vector<std::unique_ptr<GoASTExpr>> m_rhs;
+  bool m_define;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eBlockStmt;
-    }
-    
-    size_t
-    NumList() const
-    {
-        return m_list.size();
-    }
-    const GoASTStmt *
-    GetList(int i) const
-    {
-        return m_list[i].get();
-    }
-    void
-    AddList(GoASTStmt *list)
-    {
-        m_list.push_back(std::unique_ptr<GoASTStmt>(list));
-    }
+  GoASTAssignStmt(const GoASTAssignStmt &) = delete;
+  const GoASTAssignStmt &operator=(const GoASTAssignStmt &) = delete;
+};
 
-  private:
-    friend class GoASTNode;
-    std::vector<std::unique_ptr<GoASTStmt> > m_list;
-
-    GoASTBlockStmt(const GoASTBlockStmt &) = delete;
-    const GoASTBlockStmt &operator=(const GoASTBlockStmt &) = delete;
-};
-
-class GoASTIdent : public GoASTExpr
-{
-  public:
-    explicit GoASTIdent(Token name) : GoASTExpr(eIdent), m_name(name) {}
-    ~GoASTIdent() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "Ident";
-    }
+class GoASTBadDecl : public GoASTDecl {
+public:
+  GoASTBadDecl() : GoASTDecl(eBadDecl) {}
+  ~GoASTBadDecl() override = default;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eIdent;
-    }
-    
-    Token 
-    GetName() const
-    {
-        return m_name;
-    }
-    void
-    SetName(Token name)
-    {
-        m_name = name;
-    }
+  const char *GetKindName() const override { return "BadDecl"; }
 
-  private:
-    friend class GoASTNode;
-    Token m_name;
-
-    GoASTIdent(const GoASTIdent &) = delete;
-    const GoASTIdent &operator=(const GoASTIdent &) = delete;
-};
-
-class GoASTBranchStmt : public GoASTStmt
-{
-  public:
-    GoASTBranchStmt(GoASTIdent *label, TokenType tok) : GoASTStmt(eBranchStmt), m_label_up(label), m_tok(tok) {}
-    ~GoASTBranchStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "BranchStmt";
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eBadDecl; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eBranchStmt;
-    }
-    
-    const GoASTIdent *
-    GetLabel() const
-    {
-        return m_label_up.get();
-    }
-    void
-    SetLabel(GoASTIdent *label)
-    {
-        m_label_up.reset(label);
-    }
+  GoASTBadDecl(const GoASTBadDecl &) = delete;
+  const GoASTBadDecl &operator=(const GoASTBadDecl &) = delete;
+};
 
-    TokenType 
-    GetTok() const
-    {
-        return m_tok;
-    }
-    void
-    SetTok(TokenType tok)
-    {
-        m_tok = tok;
-    }
+class GoASTBadExpr : public GoASTExpr {
+public:
+  GoASTBadExpr() : GoASTExpr(eBadExpr) {}
+  ~GoASTBadExpr() override = default;
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTIdent> m_label_up;
-    TokenType m_tok;
-
-    GoASTBranchStmt(const GoASTBranchStmt &) = delete;
-    const GoASTBranchStmt &operator=(const GoASTBranchStmt &) = delete;
-};
-
-class GoASTCallExpr : public GoASTExpr
-{
-  public:
-    explicit GoASTCallExpr(bool ellipsis) : GoASTExpr(eCallExpr), m_ellipsis(ellipsis) {}
-    ~GoASTCallExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "CallExpr";
-    }
+  const char *GetKindName() const override { return "BadExpr"; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eCallExpr;
-    }
-    
-    const GoASTExpr *
-    GetFun() const
-    {
-        return m_fun_up.get();
-    }
-    void
-    SetFun(GoASTExpr *fun)
-    {
-        m_fun_up.reset(fun);
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eBadExpr; }
 
-    size_t
-    NumArgs() const
-    {
-        return m_args.size();
-    }
-    const GoASTExpr *
-    GetArgs(int i) const
-    {
-        return m_args[i].get();
-    }
-    void
-    AddArgs(GoASTExpr *args)
-    {
-        m_args.push_back(std::unique_ptr<GoASTExpr>(args));
-    }
+  GoASTBadExpr(const GoASTBadExpr &) = delete;
+  const GoASTBadExpr &operator=(const GoASTBadExpr &) = delete;
+};
 
-    bool 
-    GetEllipsis() const
-    {
-        return m_ellipsis;
-    }
-    void
-    SetEllipsis(bool ellipsis)
-    {
-        m_ellipsis = ellipsis;
-    }
+class GoASTBadStmt : public GoASTStmt {
+public:
+  GoASTBadStmt() : GoASTStmt(eBadStmt) {}
+  ~GoASTBadStmt() override = default;
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_fun_up;
-    std::vector<std::unique_ptr<GoASTExpr> > m_args;
-    bool m_ellipsis;
-
-    GoASTCallExpr(const GoASTCallExpr &) = delete;
-    const GoASTCallExpr &operator=(const GoASTCallExpr &) = delete;
-};
-
-class GoASTCaseClause : public GoASTStmt
-{
-  public:
-    GoASTCaseClause() : GoASTStmt(eCaseClause) {}
-    ~GoASTCaseClause() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "CaseClause";
-    }
+  const char *GetKindName() const override { return "BadStmt"; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eCaseClause;
-    }
-    
-    size_t
-    NumList() const
-    {
-        return m_list.size();
-    }
-    const GoASTExpr *
-    GetList(int i) const
-    {
-        return m_list[i].get();
-    }
-    void
-    AddList(GoASTExpr *list)
-    {
-        m_list.push_back(std::unique_ptr<GoASTExpr>(list));
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eBadStmt; }
 
-    size_t
-    NumBody() const
-    {
-        return m_body.size();
-    }
-    const GoASTStmt *
-    GetBody(int i) const
-    {
-        return m_body[i].get();
-    }
-    void
-    AddBody(GoASTStmt *body)
-    {
-        m_body.push_back(std::unique_ptr<GoASTStmt>(body));
-    }
+  GoASTBadStmt(const GoASTBadStmt &) = delete;
+  const GoASTBadStmt &operator=(const GoASTBadStmt &) = delete;
+};
 
-  private:
-    friend class GoASTNode;
-    std::vector<std::unique_ptr<GoASTExpr> > m_list;
-    std::vector<std::unique_ptr<GoASTStmt> > m_body;
-
-    GoASTCaseClause(const GoASTCaseClause &) = delete;
-    const GoASTCaseClause &operator=(const GoASTCaseClause &) = delete;
-};
-
-class GoASTChanType : public GoASTExpr
-{
-  public:
-    GoASTChanType(ChanDir dir, GoASTExpr *value) : GoASTExpr(eChanType), m_dir(dir), m_value_up(value) {}
-    ~GoASTChanType() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "ChanType";
-    }
+class GoASTBasicLit : public GoASTExpr {
+public:
+  explicit GoASTBasicLit(Token value) : GoASTExpr(eBasicLit), m_value(value) {}
+  ~GoASTBasicLit() override = default;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eChanType;
-    }
-    
-    ChanDir 
-    GetDir() const
-    {
-        return m_dir;
-    }
-    void
-    SetDir(ChanDir dir)
-    {
-        m_dir = dir;
-    }
+  const char *GetKindName() const override { return "BasicLit"; }
 
-    const GoASTExpr *
-    GetValue() const
-    {
-        return m_value_up.get();
-    }
-    void
-    SetValue(GoASTExpr *value)
-    {
-        m_value_up.reset(value);
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eBasicLit; }
 
-  private:
-    friend class GoASTNode;
-    ChanDir m_dir;
-    std::unique_ptr<GoASTExpr> m_value_up;
-
-    GoASTChanType(const GoASTChanType &) = delete;
-    const GoASTChanType &operator=(const GoASTChanType &) = delete;
-};
-
-class GoASTCommClause : public GoASTStmt
-{
-  public:
-    GoASTCommClause() : GoASTStmt(eCommClause) {}
-    ~GoASTCommClause() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "CommClause";
-    }
+  Token GetValue() const { return m_value; }
+  void SetValue(Token value) { m_value = value; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eCommClause;
-    }
-    
-    const GoASTStmt *
-    GetComm() const
-    {
-        return m_comm_up.get();
-    }
-    void
-    SetComm(GoASTStmt *comm)
-    {
-        m_comm_up.reset(comm);
-    }
+private:
+  friend class GoASTNode;
+  Token m_value;
 
-    size_t
-    NumBody() const
-    {
-        return m_body.size();
-    }
-    const GoASTStmt *
-    GetBody(int i) const
-    {
-        return m_body[i].get();
-    }
-    void
-    AddBody(GoASTStmt *body)
-    {
-        m_body.push_back(std::unique_ptr<GoASTStmt>(body));
-    }
+  GoASTBasicLit(const GoASTBasicLit &) = delete;
+  const GoASTBasicLit &operator=(const GoASTBasicLit &) = delete;
+};
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTStmt> m_comm_up;
-    std::vector<std::unique_ptr<GoASTStmt> > m_body;
-
-    GoASTCommClause(const GoASTCommClause &) = delete;
-    const GoASTCommClause &operator=(const GoASTCommClause &) = delete;
-};
-
-class GoASTCompositeLit : public GoASTExpr
-{
-  public:
-    GoASTCompositeLit() : GoASTExpr(eCompositeLit) {}
-    ~GoASTCompositeLit() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "CompositeLit";
-    }
+class GoASTBinaryExpr : public GoASTExpr {
+public:
+  GoASTBinaryExpr(GoASTExpr *x, GoASTExpr *y, TokenType op)
+      : GoASTExpr(eBinaryExpr), m_x_up(x), m_y_up(y), m_op(op) {}
+  ~GoASTBinaryExpr() override = default;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eCompositeLit;
-    }
-    
-    const GoASTExpr *
-    GetType() const
-    {
-        return m_type_up.get();
-    }
-    void
-    SetType(GoASTExpr *type)
-    {
-        m_type_up.reset(type);
-    }
+  const char *GetKindName() const override { return "BinaryExpr"; }
 
-    size_t
-    NumElts() const
-    {
-        return m_elts.size();
-    }
-    const GoASTExpr *
-    GetElts(int i) const
-    {
-        return m_elts[i].get();
-    }
-    void
-    AddElts(GoASTExpr *elts)
-    {
-        m_elts.push_back(std::unique_ptr<GoASTExpr>(elts));
-    }
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eBinaryExpr;
+  }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_type_up;
-    std::vector<std::unique_ptr<GoASTExpr> > m_elts;
-
-    GoASTCompositeLit(const GoASTCompositeLit &) = delete;
-    const GoASTCompositeLit &operator=(const GoASTCompositeLit &) = delete;
-};
-
-class GoASTDeclStmt : public GoASTStmt
-{
-  public:
-    explicit GoASTDeclStmt(GoASTDecl *decl) : GoASTStmt(eDeclStmt), m_decl_up(decl) {}
-    ~GoASTDeclStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "DeclStmt";
-    }
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eDeclStmt;
-    }
-    
-    const GoASTDecl *
-    GetDecl() const
-    {
-        return m_decl_up.get();
-    }
-    void
-    SetDecl(GoASTDecl *decl)
-    {
-        m_decl_up.reset(decl);
-    }
+  const GoASTExpr *GetY() const { return m_y_up.get(); }
+  void SetY(GoASTExpr *y) { m_y_up.reset(y); }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTDecl> m_decl_up;
-
-    GoASTDeclStmt(const GoASTDeclStmt &) = delete;
-    const GoASTDeclStmt &operator=(const GoASTDeclStmt &) = delete;
-};
-
-class GoASTDeferStmt : public GoASTStmt
-{
-  public:
-    explicit GoASTDeferStmt(GoASTCallExpr *call) : GoASTStmt(eDeferStmt), m_call_up(call) {}
-    ~GoASTDeferStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "DeferStmt";
-    }
+  TokenType GetOp() const { return m_op; }
+  void SetOp(TokenType op) { m_op = op; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eDeferStmt;
-    }
-    
-    const GoASTCallExpr *
-    GetCall() const
-    {
-        return m_call_up.get();
-    }
-    void
-    SetCall(GoASTCallExpr *call)
-    {
-        m_call_up.reset(call);
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_x_up;
+  std::unique_ptr<GoASTExpr> m_y_up;
+  TokenType m_op;
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTCallExpr> m_call_up;
-
-    GoASTDeferStmt(const GoASTDeferStmt &) = delete;
-    const GoASTDeferStmt &operator=(const GoASTDeferStmt &) = delete;
-};
-
-class GoASTEllipsis : public GoASTExpr
-{
-  public:
-    explicit GoASTEllipsis(GoASTExpr *elt) : GoASTExpr(eEllipsis), m_elt_up(elt) {}
-    ~GoASTEllipsis() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "Ellipsis";
-    }
+  GoASTBinaryExpr(const GoASTBinaryExpr &) = delete;
+  const GoASTBinaryExpr &operator=(const GoASTBinaryExpr &) = delete;
+};
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eEllipsis;
-    }
-    
-    const GoASTExpr *
-    GetElt() const
-    {
-        return m_elt_up.get();
-    }
-    void
-    SetElt(GoASTExpr *elt)
-    {
-        m_elt_up.reset(elt);
-    }
+class GoASTBlockStmt : public GoASTStmt {
+public:
+  GoASTBlockStmt() : GoASTStmt(eBlockStmt) {}
+  ~GoASTBlockStmt() override = default;
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_elt_up;
-
-    GoASTEllipsis(const GoASTEllipsis &) = delete;
-    const GoASTEllipsis &operator=(const GoASTEllipsis &) = delete;
-};
-
-class GoASTEmptyStmt : public GoASTStmt
-{
-  public:
-    GoASTEmptyStmt() : GoASTStmt(eEmptyStmt) {}
-    ~GoASTEmptyStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "EmptyStmt";
-    }
+  const char *GetKindName() const override { return "BlockStmt"; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eEmptyStmt;
-    }
-    
-    GoASTEmptyStmt(const GoASTEmptyStmt &) = delete;
-    const GoASTEmptyStmt &operator=(const GoASTEmptyStmt &) = delete;
-};
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eBlockStmt; }
 
-class GoASTExprStmt : public GoASTStmt
-{
-  public:
-    explicit GoASTExprStmt(GoASTExpr *x) : GoASTStmt(eExprStmt), m_x_up(x) {}
-    ~GoASTExprStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "ExprStmt";
-    }
+  size_t NumList() const { return m_list.size(); }
+  const GoASTStmt *GetList(int i) const { return m_list[i].get(); }
+  void AddList(GoASTStmt *list) {
+    m_list.push_back(std::unique_ptr<GoASTStmt>(list));
+  }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eExprStmt;
-    }
-    
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+private:
+  friend class GoASTNode;
+  std::vector<std::unique_ptr<GoASTStmt>> m_list;
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_x_up;
-
-    GoASTExprStmt(const GoASTExprStmt &) = delete;
-    const GoASTExprStmt &operator=(const GoASTExprStmt &) = delete;
-};
-
-class GoASTField : public GoASTNode
-{
-  public:
-    GoASTField() : GoASTNode(eField) {}
-    ~GoASTField() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "Field";
-    }
+  GoASTBlockStmt(const GoASTBlockStmt &) = delete;
+  const GoASTBlockStmt &operator=(const GoASTBlockStmt &) = delete;
+};
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eField;
-    }
-    
-    size_t
-    NumNames() const
-    {
-        return m_names.size();
-    }
-    const GoASTIdent *
-    GetNames(int i) const
-    {
-        return m_names[i].get();
-    }
-    void
-    AddNames(GoASTIdent *names)
-    {
-        m_names.push_back(std::unique_ptr<GoASTIdent>(names));
-    }
+class GoASTIdent : public GoASTExpr {
+public:
+  explicit GoASTIdent(Token name) : GoASTExpr(eIdent), m_name(name) {}
+  ~GoASTIdent() override = default;
 
-    const GoASTExpr *
-    GetType() const
-    {
-        return m_type_up.get();
-    }
-    void
-    SetType(GoASTExpr *type)
-    {
-        m_type_up.reset(type);
-    }
+  const char *GetKindName() const override { return "Ident"; }
 
-    const GoASTBasicLit *
-    GetTag() const
-    {
-        return m_tag_up.get();
-    }
-    void
-    SetTag(GoASTBasicLit *tag)
-    {
-        m_tag_up.reset(tag);
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eIdent; }
 
-  private:
-    friend class GoASTNode;
-    std::vector<std::unique_ptr<GoASTIdent> > m_names;
-    std::unique_ptr<GoASTExpr> m_type_up;
-    std::unique_ptr<GoASTBasicLit> m_tag_up;
-
-    GoASTField(const GoASTField &) = delete;
-    const GoASTField &operator=(const GoASTField &) = delete;
-};
-
-class GoASTFieldList : public GoASTNode
-{
-  public:
-    GoASTFieldList() : GoASTNode(eFieldList) {}
-    ~GoASTFieldList() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "FieldList";
-    }
+  Token GetName() const { return m_name; }
+  void SetName(Token name) { m_name = name; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eFieldList;
-    }
-    
-    size_t
-    NumList() const
-    {
-        return m_list.size();
-    }
-    const GoASTField *
-    GetList(int i) const
-    {
-        return m_list[i].get();
-    }
-    void
-    AddList(GoASTField *list)
-    {
-        m_list.push_back(std::unique_ptr<GoASTField>(list));
-    }
+private:
+  friend class GoASTNode;
+  Token m_name;
 
-  private:
-    friend class GoASTNode;
-    std::vector<std::unique_ptr<GoASTField> > m_list;
-
-    GoASTFieldList(const GoASTFieldList &) = delete;
-    const GoASTFieldList &operator=(const GoASTFieldList &) = delete;
-};
-
-class GoASTForStmt : public GoASTStmt
-{
-  public:
-    GoASTForStmt(GoASTStmt *init, GoASTExpr *cond, GoASTStmt *post, GoASTBlockStmt *body) : GoASTStmt(eForStmt), m_init_up(init), m_cond_up(cond), m_post_up(post), m_body_up(body) {}
-    ~GoASTForStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "ForStmt";
-    }
+  GoASTIdent(const GoASTIdent &) = delete;
+  const GoASTIdent &operator=(const GoASTIdent &) = delete;
+};
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eForStmt;
-    }
-    
-    const GoASTStmt *
-    GetInit() const
-    {
-        return m_init_up.get();
-    }
-    void
-    SetInit(GoASTStmt *init)
-    {
-        m_init_up.reset(init);
-    }
+class GoASTBranchStmt : public GoASTStmt {
+public:
+  GoASTBranchStmt(GoASTIdent *label, TokenType tok)
+      : GoASTStmt(eBranchStmt), m_label_up(label), m_tok(tok) {}
+  ~GoASTBranchStmt() override = default;
 
-    const GoASTExpr *
-    GetCond() const
-    {
-        return m_cond_up.get();
-    }
-    void
-    SetCond(GoASTExpr *cond)
-    {
-        m_cond_up.reset(cond);
-    }
+  const char *GetKindName() const override { return "BranchStmt"; }
 
-    const GoASTStmt *
-    GetPost() const
-    {
-        return m_post_up.get();
-    }
-    void
-    SetPost(GoASTStmt *post)
-    {
-        m_post_up.reset(post);
-    }
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eBranchStmt;
+  }
 
-    const GoASTBlockStmt *
-    GetBody() const
-    {
-        return m_body_up.get();
-    }
-    void
-    SetBody(GoASTBlockStmt *body)
-    {
-        m_body_up.reset(body);
-    }
+  const GoASTIdent *GetLabel() const { return m_label_up.get(); }
+  void SetLabel(GoASTIdent *label) { m_label_up.reset(label); }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTStmt> m_init_up;
-    std::unique_ptr<GoASTExpr> m_cond_up;
-    std::unique_ptr<GoASTStmt> m_post_up;
-    std::unique_ptr<GoASTBlockStmt> m_body_up;
-
-    GoASTForStmt(const GoASTForStmt &) = delete;
-    const GoASTForStmt &operator=(const GoASTForStmt &) = delete;
-};
-
-class GoASTFuncType : public GoASTExpr
-{
-  public:
-    GoASTFuncType(GoASTFieldList *params, GoASTFieldList *results) : GoASTExpr(eFuncType), m_params_up(params), m_results_up(results) {}
-    ~GoASTFuncType() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "FuncType";
-    }
+  TokenType GetTok() const { return m_tok; }
+  void SetTok(TokenType tok) { m_tok = tok; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eFuncType;
-    }
-    
-    const GoASTFieldList *
-    GetParams() const
-    {
-        return m_params_up.get();
-    }
-    void
-    SetParams(GoASTFieldList *params)
-    {
-        m_params_up.reset(params);
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTIdent> m_label_up;
+  TokenType m_tok;
 
-    const GoASTFieldList *
-    GetResults() const
-    {
-        return m_results_up.get();
-    }
-    void
-    SetResults(GoASTFieldList *results)
-    {
-        m_results_up.reset(results);
-    }
+  GoASTBranchStmt(const GoASTBranchStmt &) = delete;
+  const GoASTBranchStmt &operator=(const GoASTBranchStmt &) = delete;
+};
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTFieldList> m_params_up;
-    std::unique_ptr<GoASTFieldList> m_results_up;
-
-    GoASTFuncType(const GoASTFuncType &) = delete;
-    const GoASTFuncType &operator=(const GoASTFuncType &) = delete;
-};
-
-class GoASTFuncDecl : public GoASTDecl
-{
-  public:
-    GoASTFuncDecl(GoASTFieldList *recv, GoASTIdent *name, GoASTFuncType *type, GoASTBlockStmt *body) : GoASTDecl(eFuncDecl), m_recv_up(recv), m_name_up(name), m_type_up(type), m_body_up(body) {}
-    ~GoASTFuncDecl() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "FuncDecl";
-    }
+class GoASTCallExpr : public GoASTExpr {
+public:
+  explicit GoASTCallExpr(bool ellipsis)
+      : GoASTExpr(eCallExpr), m_ellipsis(ellipsis) {}
+  ~GoASTCallExpr() override = default;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eFuncDecl;
-    }
-    
-    const GoASTFieldList *
-    GetRecv() const
-    {
-        return m_recv_up.get();
-    }
-    void
-    SetRecv(GoASTFieldList *recv)
-    {
-        m_recv_up.reset(recv);
-    }
+  const char *GetKindName() const override { return "CallExpr"; }
 
-    const GoASTIdent *
-    GetName() const
-    {
-        return m_name_up.get();
-    }
-    void
-    SetName(GoASTIdent *name)
-    {
-        m_name_up.reset(name);
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eCallExpr; }
 
-    const GoASTFuncType *
-    GetType() const
-    {
-        return m_type_up.get();
-    }
-    void
-    SetType(GoASTFuncType *type)
-    {
-        m_type_up.reset(type);
-    }
+  const GoASTExpr *GetFun() const { return m_fun_up.get(); }
+  void SetFun(GoASTExpr *fun) { m_fun_up.reset(fun); }
 
-    const GoASTBlockStmt *
-    GetBody() const
-    {
-        return m_body_up.get();
-    }
-    void
-    SetBody(GoASTBlockStmt *body)
-    {
-        m_body_up.reset(body);
-    }
+  size_t NumArgs() const { return m_args.size(); }
+  const GoASTExpr *GetArgs(int i) const { return m_args[i].get(); }
+  void AddArgs(GoASTExpr *args) {
+    m_args.push_back(std::unique_ptr<GoASTExpr>(args));
+  }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTFieldList> m_recv_up;
-    std::unique_ptr<GoASTIdent> m_name_up;
-    std::unique_ptr<GoASTFuncType> m_type_up;
-    std::unique_ptr<GoASTBlockStmt> m_body_up;
-
-    GoASTFuncDecl(const GoASTFuncDecl &) = delete;
-    const GoASTFuncDecl &operator=(const GoASTFuncDecl &) = delete;
-};
-
-class GoASTFuncLit : public GoASTExpr
-{
-  public:
-    GoASTFuncLit(GoASTFuncType *type, GoASTBlockStmt *body) : GoASTExpr(eFuncLit), m_type_up(type), m_body_up(body) {}
-    ~GoASTFuncLit() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "FuncLit";
-    }
+  bool GetEllipsis() const { return m_ellipsis; }
+  void SetEllipsis(bool ellipsis) { m_ellipsis = ellipsis; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eFuncLit;
-    }
-    
-    const GoASTFuncType *
-    GetType() const
-    {
-        return m_type_up.get();
-    }
-    void
-    SetType(GoASTFuncType *type)
-    {
-        m_type_up.reset(type);
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_fun_up;
+  std::vector<std::unique_ptr<GoASTExpr>> m_args;
+  bool m_ellipsis;
 
-    const GoASTBlockStmt *
-    GetBody() const
-    {
-        return m_body_up.get();
-    }
-    void
-    SetBody(GoASTBlockStmt *body)
-    {
-        m_body_up.reset(body);
-    }
+  GoASTCallExpr(const GoASTCallExpr &) = delete;
+  const GoASTCallExpr &operator=(const GoASTCallExpr &) = delete;
+};
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTFuncType> m_type_up;
-    std::unique_ptr<GoASTBlockStmt> m_body_up;
-
-    GoASTFuncLit(const GoASTFuncLit &) = delete;
-    const GoASTFuncLit &operator=(const GoASTFuncLit &) = delete;
-};
-
-class GoASTGenDecl : public GoASTDecl
-{
-  public:
-    explicit GoASTGenDecl(TokenType tok) : GoASTDecl(eGenDecl), m_tok(tok) {}
-    ~GoASTGenDecl() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "GenDecl";
-    }
+class GoASTCaseClause : public GoASTStmt {
+public:
+  GoASTCaseClause() : GoASTStmt(eCaseClause) {}
+  ~GoASTCaseClause() override = default;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eGenDecl;
-    }
-    
-    TokenType 
-    GetTok() const
-    {
-        return m_tok;
-    }
-    void
-    SetTok(TokenType tok)
-    {
-        m_tok = tok;
-    }
+  const char *GetKindName() const override { return "CaseClause"; }
 
-    size_t
-    NumSpecs() const
-    {
-        return m_specs.size();
-    }
-    const GoASTSpec *
-    GetSpecs(int i) const
-    {
-        return m_specs[i].get();
-    }
-    void
-    AddSpecs(GoASTSpec *specs)
-    {
-        m_specs.push_back(std::unique_ptr<GoASTSpec>(specs));
-    }
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eCaseClause;
+  }
 
-  private:
-    friend class GoASTNode;
-    TokenType m_tok;
-    std::vector<std::unique_ptr<GoASTSpec> > m_specs;
-
-    GoASTGenDecl(const GoASTGenDecl &) = delete;
-    const GoASTGenDecl &operator=(const GoASTGenDecl &) = delete;
-};
-
-class GoASTGoStmt : public GoASTStmt
-{
-  public:
-    explicit GoASTGoStmt(GoASTCallExpr *call) : GoASTStmt(eGoStmt), m_call_up(call) {}
-    ~GoASTGoStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "GoStmt";
-    }
+  size_t NumList() const { return m_list.size(); }
+  const GoASTExpr *GetList(int i) const { return m_list[i].get(); }
+  void AddList(GoASTExpr *list) {
+    m_list.push_back(std::unique_ptr<GoASTExpr>(list));
+  }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eGoStmt;
-    }
-    
-    const GoASTCallExpr *
-    GetCall() const
-    {
-        return m_call_up.get();
-    }
-    void
-    SetCall(GoASTCallExpr *call)
-    {
-        m_call_up.reset(call);
-    }
+  size_t NumBody() const { return m_body.size(); }
+  const GoASTStmt *GetBody(int i) const { return m_body[i].get(); }
+  void AddBody(GoASTStmt *body) {
+    m_body.push_back(std::unique_ptr<GoASTStmt>(body));
+  }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTCallExpr> m_call_up;
-
-    GoASTGoStmt(const GoASTGoStmt &) = delete;
-    const GoASTGoStmt &operator=(const GoASTGoStmt &) = delete;
-};
-
-class GoASTIfStmt : public GoASTStmt
-{
-  public:
-    GoASTIfStmt(GoASTStmt *init, GoASTExpr *cond, GoASTBlockStmt *body, GoASTStmt *els) : GoASTStmt(eIfStmt), m_init_up(init), m_cond_up(cond), m_body_up(body), m_els_up(els) {}
-    ~GoASTIfStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "IfStmt";
-    }
+private:
+  friend class GoASTNode;
+  std::vector<std::unique_ptr<GoASTExpr>> m_list;
+  std::vector<std::unique_ptr<GoASTStmt>> m_body;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eIfStmt;
-    }
-    
-    const GoASTStmt *
-    GetInit() const
-    {
-        return m_init_up.get();
-    }
-    void
-    SetInit(GoASTStmt *init)
-    {
-        m_init_up.reset(init);
-    }
+  GoASTCaseClause(const GoASTCaseClause &) = delete;
+  const GoASTCaseClause &operator=(const GoASTCaseClause &) = delete;
+};
 
-    const GoASTExpr *
-    GetCond() const
-    {
-        return m_cond_up.get();
-    }
-    void
-    SetCond(GoASTExpr *cond)
-    {
-        m_cond_up.reset(cond);
-    }
+class GoASTChanType : public GoASTExpr {
+public:
+  GoASTChanType(ChanDir dir, GoASTExpr *value)
+      : GoASTExpr(eChanType), m_dir(dir), m_value_up(value) {}
+  ~GoASTChanType() override = default;
 
-    const GoASTBlockStmt *
-    GetBody() const
-    {
-        return m_body_up.get();
-    }
-    void
-    SetBody(GoASTBlockStmt *body)
-    {
-        m_body_up.reset(body);
-    }
+  const char *GetKindName() const override { return "ChanType"; }
 
-    const GoASTStmt *
-    GetEls() const
-    {
-        return m_els_up.get();
-    }
-    void
-    SetEls(GoASTStmt *els)
-    {
-        m_els_up.reset(els);
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eChanType; }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTStmt> m_init_up;
-    std::unique_ptr<GoASTExpr> m_cond_up;
-    std::unique_ptr<GoASTBlockStmt> m_body_up;
-    std::unique_ptr<GoASTStmt> m_els_up;
-
-    GoASTIfStmt(const GoASTIfStmt &) = delete;
-    const GoASTIfStmt &operator=(const GoASTIfStmt &) = delete;
-};
-
-class GoASTImportSpec : public GoASTSpec
-{
-  public:
-    GoASTImportSpec(GoASTIdent *name, GoASTBasicLit *path) : GoASTSpec(eImportSpec), m_name_up(name), m_path_up(path) {}
-    ~GoASTImportSpec() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "ImportSpec";
-    }
+  ChanDir GetDir() const { return m_dir; }
+  void SetDir(ChanDir dir) { m_dir = dir; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eImportSpec;
-    }
-    
-    const GoASTIdent *
-    GetName() const
-    {
-        return m_name_up.get();
-    }
-    void
-    SetName(GoASTIdent *name)
-    {
-        m_name_up.reset(name);
-    }
+  const GoASTExpr *GetValue() const { return m_value_up.get(); }
+  void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
 
-    const GoASTBasicLit *
-    GetPath() const
-    {
-        return m_path_up.get();
-    }
-    void
-    SetPath(GoASTBasicLit *path)
-    {
-        m_path_up.reset(path);
-    }
+private:
+  friend class GoASTNode;
+  ChanDir m_dir;
+  std::unique_ptr<GoASTExpr> m_value_up;
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTIdent> m_name_up;
-    std::unique_ptr<GoASTBasicLit> m_path_up;
-
-    GoASTImportSpec(const GoASTImportSpec &) = delete;
-    const GoASTImportSpec &operator=(const GoASTImportSpec &) = delete;
-};
-
-class GoASTIncDecStmt : public GoASTStmt
-{
-  public:
-    GoASTIncDecStmt(GoASTExpr *x, TokenType tok) : GoASTStmt(eIncDecStmt), m_x_up(x), m_tok(tok) {}
-    ~GoASTIncDecStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "IncDecStmt";
-    }
+  GoASTChanType(const GoASTChanType &) = delete;
+  const GoASTChanType &operator=(const GoASTChanType &) = delete;
+};
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eIncDecStmt;
-    }
-    
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+class GoASTCommClause : public GoASTStmt {
+public:
+  GoASTCommClause() : GoASTStmt(eCommClause) {}
+  ~GoASTCommClause() override = default;
 
-    TokenType 
-    GetTok() const
-    {
-        return m_tok;
-    }
-    void
-    SetTok(TokenType tok)
-    {
-        m_tok = tok;
-    }
+  const char *GetKindName() const override { return "CommClause"; }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_x_up;
-    TokenType m_tok;
-
-    GoASTIncDecStmt(const GoASTIncDecStmt &) = delete;
-    const GoASTIncDecStmt &operator=(const GoASTIncDecStmt &) = delete;
-};
-
-class GoASTIndexExpr : public GoASTExpr
-{
-  public:
-    GoASTIndexExpr(GoASTExpr *x, GoASTExpr *index) : GoASTExpr(eIndexExpr), m_x_up(x), m_index_up(index) {}
-    ~GoASTIndexExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "IndexExpr";
-    }
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eCommClause;
+  }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eIndexExpr;
-    }
-    
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+  const GoASTStmt *GetComm() const { return m_comm_up.get(); }
+  void SetComm(GoASTStmt *comm) { m_comm_up.reset(comm); }
 
-    const GoASTExpr *
-    GetIndex() const
-    {
-        return m_index_up.get();
-    }
-    void
-    SetIndex(GoASTExpr *index)
-    {
-        m_index_up.reset(index);
-    }
+  size_t NumBody() const { return m_body.size(); }
+  const GoASTStmt *GetBody(int i) const { return m_body[i].get(); }
+  void AddBody(GoASTStmt *body) {
+    m_body.push_back(std::unique_ptr<GoASTStmt>(body));
+  }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_x_up;
-    std::unique_ptr<GoASTExpr> m_index_up;
-
-    GoASTIndexExpr(const GoASTIndexExpr &) = delete;
-    const GoASTIndexExpr &operator=(const GoASTIndexExpr &) = delete;
-};
-
-class GoASTInterfaceType : public GoASTExpr
-{
-  public:
-    explicit GoASTInterfaceType(GoASTFieldList *methods) : GoASTExpr(eInterfaceType), m_methods_up(methods) {}
-    ~GoASTInterfaceType() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "InterfaceType";
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTStmt> m_comm_up;
+  std::vector<std::unique_ptr<GoASTStmt>> m_body;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eInterfaceType;
-    }
-    
-    const GoASTFieldList *
-    GetMethods() const
-    {
-        return m_methods_up.get();
-    }
-    void
-    SetMethods(GoASTFieldList *methods)
-    {
-        m_methods_up.reset(methods);
-    }
+  GoASTCommClause(const GoASTCommClause &) = delete;
+  const GoASTCommClause &operator=(const GoASTCommClause &) = delete;
+};
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTFieldList> m_methods_up;
-
-    GoASTInterfaceType(const GoASTInterfaceType &) = delete;
-    const GoASTInterfaceType &operator=(const GoASTInterfaceType &) = delete;
-};
-
-class GoASTKeyValueExpr : public GoASTExpr
-{
-  public:
-    GoASTKeyValueExpr(GoASTExpr *key, GoASTExpr *value) : GoASTExpr(eKeyValueExpr), m_key_up(key), m_value_up(value) {}
-    ~GoASTKeyValueExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "KeyValueExpr";
-    }
+class GoASTCompositeLit : public GoASTExpr {
+public:
+  GoASTCompositeLit() : GoASTExpr(eCompositeLit) {}
+  ~GoASTCompositeLit() override = default;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eKeyValueExpr;
-    }
-    
-    const GoASTExpr *
-    GetKey() const
-    {
-        return m_key_up.get();
-    }
-    void
-    SetKey(GoASTExpr *key)
-    {
-        m_key_up.reset(key);
-    }
+  const char *GetKindName() const override { return "CompositeLit"; }
 
-    const GoASTExpr *
-    GetValue() const
-    {
-        return m_value_up.get();
-    }
-    void
-    SetValue(GoASTExpr *value)
-    {
-        m_value_up.reset(value);
-    }
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eCompositeLit;
+  }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_key_up;
-    std::unique_ptr<GoASTExpr> m_value_up;
-
-    GoASTKeyValueExpr(const GoASTKeyValueExpr &) = delete;
-    const GoASTKeyValueExpr &operator=(const GoASTKeyValueExpr &) = delete;
-};
-
-class GoASTLabeledStmt : public GoASTStmt
-{
-  public:
-    GoASTLabeledStmt(GoASTIdent *label, GoASTStmt *stmt) : GoASTStmt(eLabeledStmt), m_label_up(label), m_stmt_up(stmt) {}
-    ~GoASTLabeledStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "LabeledStmt";
-    }
+  const GoASTExpr *GetType() const { return m_type_up.get(); }
+  void SetType(GoASTExpr *type) { m_type_up.reset(type); }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eLabeledStmt;
-    }
-    
-    const GoASTIdent *
-    GetLabel() const
-    {
-        return m_label_up.get();
-    }
-    void
-    SetLabel(GoASTIdent *label)
-    {
-        m_label_up.reset(label);
-    }
+  size_t NumElts() const { return m_elts.size(); }
+  const GoASTExpr *GetElts(int i) const { return m_elts[i].get(); }
+  void AddElts(GoASTExpr *elts) {
+    m_elts.push_back(std::unique_ptr<GoASTExpr>(elts));
+  }
 
-    const GoASTStmt *
-    GetStmt() const
-    {
-        return m_stmt_up.get();
-    }
-    void
-    SetStmt(GoASTStmt *stmt)
-    {
-        m_stmt_up.reset(stmt);
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_type_up;
+  std::vector<std::unique_ptr<GoASTExpr>> m_elts;
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTIdent> m_label_up;
-    std::unique_ptr<GoASTStmt> m_stmt_up;
-
-    GoASTLabeledStmt(const GoASTLabeledStmt &) = delete;
-    const GoASTLabeledStmt &operator=(const GoASTLabeledStmt &) = delete;
-};
-
-class GoASTMapType : public GoASTExpr
-{
-  public:
-    GoASTMapType(GoASTExpr *key, GoASTExpr *value) : GoASTExpr(eMapType), m_key_up(key), m_value_up(value) {}
-    ~GoASTMapType() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "MapType";
-    }
+  GoASTCompositeLit(const GoASTCompositeLit &) = delete;
+  const GoASTCompositeLit &operator=(const GoASTCompositeLit &) = delete;
+};
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eMapType;
-    }
-    
-    const GoASTExpr *
-    GetKey() const
-    {
-        return m_key_up.get();
-    }
-    void
-    SetKey(GoASTExpr *key)
-    {
-        m_key_up.reset(key);
-    }
+class GoASTDeclStmt : public GoASTStmt {
+public:
+  explicit GoASTDeclStmt(GoASTDecl *decl)
+      : GoASTStmt(eDeclStmt), m_decl_up(decl) {}
+  ~GoASTDeclStmt() override = default;
 
-    const GoASTExpr *
-    GetValue() const
-    {
-        return m_value_up.get();
-    }
-    void
-    SetValue(GoASTExpr *value)
-    {
-        m_value_up.reset(value);
-    }
+  const char *GetKindName() const override { return "DeclStmt"; }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_key_up;
-    std::unique_ptr<GoASTExpr> m_value_up;
-
-    GoASTMapType(const GoASTMapType &) = delete;
-    const GoASTMapType &operator=(const GoASTMapType &) = delete;
-};
-
-class GoASTParenExpr : public GoASTExpr
-{
-  public:
-    explicit GoASTParenExpr(GoASTExpr *x) : GoASTExpr(eParenExpr), m_x_up(x) {}
-    ~GoASTParenExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "ParenExpr";
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eDeclStmt; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eParenExpr;
-    }
-    
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+  const GoASTDecl *GetDecl() const { return m_decl_up.get(); }
+  void SetDecl(GoASTDecl *decl) { m_decl_up.reset(decl); }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_x_up;
-
-    GoASTParenExpr(const GoASTParenExpr &) = delete;
-    const GoASTParenExpr &operator=(const GoASTParenExpr &) = delete;
-};
-
-class GoASTRangeStmt : public GoASTStmt
-{
-  public:
-    GoASTRangeStmt(GoASTExpr *key, GoASTExpr *value, bool define, GoASTExpr *x, GoASTBlockStmt *body) : GoASTStmt(eRangeStmt), m_key_up(key), m_value_up(value), m_define(define), m_x_up(x), m_body_up(body) {}
-    ~GoASTRangeStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "RangeStmt";
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTDecl> m_decl_up;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eRangeStmt;
-    }
-    
-    const GoASTExpr *
-    GetKey() const
-    {
-        return m_key_up.get();
-    }
-    void
-    SetKey(GoASTExpr *key)
-    {
-        m_key_up.reset(key);
-    }
+  GoASTDeclStmt(const GoASTDeclStmt &) = delete;
+  const GoASTDeclStmt &operator=(const GoASTDeclStmt &) = delete;
+};
 
-    const GoASTExpr *
-    GetValue() const
-    {
-        return m_value_up.get();
-    }
-    void
-    SetValue(GoASTExpr *value)
-    {
-        m_value_up.reset(value);
-    }
+class GoASTDeferStmt : public GoASTStmt {
+public:
+  explicit GoASTDeferStmt(GoASTCallExpr *call)
+      : GoASTStmt(eDeferStmt), m_call_up(call) {}
+  ~GoASTDeferStmt() override = default;
 
-    bool 
-    GetDefine() const
-    {
-        return m_define;
-    }
-    void
-    SetDefine(bool define)
-    {
-        m_define = define;
-    }
+  const char *GetKindName() const override { return "DeferStmt"; }
 
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eDeferStmt; }
 
-    const GoASTBlockStmt *
-    GetBody() const
-    {
-        return m_body_up.get();
-    }
-    void
-    SetBody(GoASTBlockStmt *body)
-    {
-        m_body_up.reset(body);
-    }
+  const GoASTCallExpr *GetCall() const { return m_call_up.get(); }
+  void SetCall(GoASTCallExpr *call) { m_call_up.reset(call); }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_key_up;
-    std::unique_ptr<GoASTExpr> m_value_up;
-    bool m_define;
-    std::unique_ptr<GoASTExpr> m_x_up;
-    std::unique_ptr<GoASTBlockStmt> m_body_up;
-
-    GoASTRangeStmt(const GoASTRangeStmt &) = delete;
-    const GoASTRangeStmt &operator=(const GoASTRangeStmt &) = delete;
-};
-
-class GoASTReturnStmt : public GoASTStmt
-{
-  public:
-    GoASTReturnStmt() : GoASTStmt(eReturnStmt) {}
-    ~GoASTReturnStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "ReturnStmt";
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTCallExpr> m_call_up;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eReturnStmt;
-    }
-    
-    size_t
-    NumResults() const
-    {
-        return m_results.size();
-    }
-    const GoASTExpr *
-    GetResults(int i) const
-    {
-        return m_results[i].get();
-    }
-    void
-    AddResults(GoASTExpr *results)
-    {
-        m_results.push_back(std::unique_ptr<GoASTExpr>(results));
-    }
+  GoASTDeferStmt(const GoASTDeferStmt &) = delete;
+  const GoASTDeferStmt &operator=(const GoASTDeferStmt &) = delete;
+};
 
-  private:
-    friend class GoASTNode;
-    std::vector<std::unique_ptr<GoASTExpr> > m_results;
-
-    GoASTReturnStmt(const GoASTReturnStmt &) = delete;
-    const GoASTReturnStmt &operator=(const GoASTReturnStmt &) = delete;
-};
-
-class GoASTSelectStmt : public GoASTStmt
-{
-  public:
-    explicit GoASTSelectStmt(GoASTBlockStmt *body) : GoASTStmt(eSelectStmt), m_body_up(body) {}
-    ~GoASTSelectStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "SelectStmt";
-    }
+class GoASTEllipsis : public GoASTExpr {
+public:
+  explicit GoASTEllipsis(GoASTExpr *elt)
+      : GoASTExpr(eEllipsis), m_elt_up(elt) {}
+  ~GoASTEllipsis() override = default;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eSelectStmt;
-    }
-    
-    const GoASTBlockStmt *
-    GetBody() const
-    {
-        return m_body_up.get();
-    }
-    void
-    SetBody(GoASTBlockStmt *body)
-    {
-        m_body_up.reset(body);
-    }
+  const char *GetKindName() const override { return "Ellipsis"; }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTBlockStmt> m_body_up;
-
-    GoASTSelectStmt(const GoASTSelectStmt &) = delete;
-    const GoASTSelectStmt &operator=(const GoASTSelectStmt &) = delete;
-};
-
-class GoASTSelectorExpr : public GoASTExpr
-{
-  public:
-    GoASTSelectorExpr(GoASTExpr *x, GoASTIdent *sel) : GoASTExpr(eSelectorExpr), m_x_up(x), m_sel_up(sel) {}
-    ~GoASTSelectorExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "SelectorExpr";
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eEllipsis; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eSelectorExpr;
-    }
-    
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+  const GoASTExpr *GetElt() const { return m_elt_up.get(); }
+  void SetElt(GoASTExpr *elt) { m_elt_up.reset(elt); }
 
-    const GoASTIdent *
-    GetSel() const
-    {
-        return m_sel_up.get();
-    }
-    void
-    SetSel(GoASTIdent *sel)
-    {
-        m_sel_up.reset(sel);
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_elt_up;
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_x_up;
-    std::unique_ptr<GoASTIdent> m_sel_up;
-
-    GoASTSelectorExpr(const GoASTSelectorExpr &) = delete;
-    const GoASTSelectorExpr &operator=(const GoASTSelectorExpr &) = delete;
-};
-
-class GoASTSendStmt : public GoASTStmt
-{
-  public:
-    GoASTSendStmt(GoASTExpr *chan, GoASTExpr *value) : GoASTStmt(eSendStmt), m_chan_up(chan), m_value_up(value) {}
-    ~GoASTSendStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "SendStmt";
-    }
+  GoASTEllipsis(const GoASTEllipsis &) = delete;
+  const GoASTEllipsis &operator=(const GoASTEllipsis &) = delete;
+};
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eSendStmt;
-    }
-    
-    const GoASTExpr *
-    GetChan() const
-    {
-        return m_chan_up.get();
-    }
-    void
-    SetChan(GoASTExpr *chan)
-    {
-        m_chan_up.reset(chan);
-    }
+class GoASTEmptyStmt : public GoASTStmt {
+public:
+  GoASTEmptyStmt() : GoASTStmt(eEmptyStmt) {}
+  ~GoASTEmptyStmt() override = default;
 
-    const GoASTExpr *
-    GetValue() const
-    {
-        return m_value_up.get();
-    }
-    void
-    SetValue(GoASTExpr *value)
-    {
-        m_value_up.reset(value);
-    }
+  const char *GetKindName() const override { return "EmptyStmt"; }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_chan_up;
-    std::unique_ptr<GoASTExpr> m_value_up;
-
-    GoASTSendStmt(const GoASTSendStmt &) = delete;
-    const GoASTSendStmt &operator=(const GoASTSendStmt &) = delete;
-};
-
-class GoASTSliceExpr : public GoASTExpr
-{
-  public:
-    GoASTSliceExpr(GoASTExpr *x, GoASTExpr *low, GoASTExpr *high, GoASTExpr *max, bool slice3) : GoASTExpr(eSliceExpr), m_x_up(x), m_low_up(low), m_high_up(high), m_max_up(max), m_slice3(slice3) {}
-    ~GoASTSliceExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "SliceExpr";
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eEmptyStmt; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eSliceExpr;
-    }
-    
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+  GoASTEmptyStmt(const GoASTEmptyStmt &) = delete;
+  const GoASTEmptyStmt &operator=(const GoASTEmptyStmt &) = delete;
+};
 
-    const GoASTExpr *
-    GetLow() const
-    {
-        return m_low_up.get();
-    }
-    void
-    SetLow(GoASTExpr *low)
-    {
-        m_low_up.reset(low);
-    }
+class GoASTExprStmt : public GoASTStmt {
+public:
+  explicit GoASTExprStmt(GoASTExpr *x) : GoASTStmt(eExprStmt), m_x_up(x) {}
+  ~GoASTExprStmt() override = default;
 
-    const GoASTExpr *
-    GetHigh() const
-    {
-        return m_high_up.get();
-    }
-    void
-    SetHigh(GoASTExpr *high)
-    {
-        m_high_up.reset(high);
-    }
+  const char *GetKindName() const override { return "ExprStmt"; }
 
-    const GoASTExpr *
-    GetMax() const
-    {
-        return m_max_up.get();
-    }
-    void
-    SetMax(GoASTExpr *max)
-    {
-        m_max_up.reset(max);
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eExprStmt; }
 
-    bool 
-    GetSlice3() const
-    {
-        return m_slice3;
-    }
-    void
-    SetSlice3(bool slice3)
-    {
-        m_slice3 = slice3;
-    }
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_x_up;
-    std::unique_ptr<GoASTExpr> m_low_up;
-    std::unique_ptr<GoASTExpr> m_high_up;
-    std::unique_ptr<GoASTExpr> m_max_up;
-    bool m_slice3;
-
-    GoASTSliceExpr(const GoASTSliceExpr &) = delete;
-    const GoASTSliceExpr &operator=(const GoASTSliceExpr &) = delete;
-};
-
-class GoASTStarExpr : public GoASTExpr
-{
-  public:
-    explicit GoASTStarExpr(GoASTExpr *x) : GoASTExpr(eStarExpr), m_x_up(x) {}
-    ~GoASTStarExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "StarExpr";
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_x_up;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eStarExpr;
-    }
-    
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+  GoASTExprStmt(const GoASTExprStmt &) = delete;
+  const GoASTExprStmt &operator=(const GoASTExprStmt &) = delete;
+};
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_x_up;
-
-    GoASTStarExpr(const GoASTStarExpr &) = delete;
-    const GoASTStarExpr &operator=(const GoASTStarExpr &) = delete;
-};
-
-class GoASTStructType : public GoASTExpr
-{
-  public:
-    explicit GoASTStructType(GoASTFieldList *fields) : GoASTExpr(eStructType), m_fields_up(fields) {}
-    ~GoASTStructType() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "StructType";
-    }
+class GoASTField : public GoASTNode {
+public:
+  GoASTField() : GoASTNode(eField) {}
+  ~GoASTField() override = default;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eStructType;
-    }
-    
-    const GoASTFieldList *
-    GetFields() const
-    {
-        return m_fields_up.get();
-    }
-    void
-    SetFields(GoASTFieldList *fields)
-    {
-        m_fields_up.reset(fields);
-    }
+  const char *GetKindName() const override { return "Field"; }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTFieldList> m_fields_up;
-
-    GoASTStructType(const GoASTStructType &) = delete;
-    const GoASTStructType &operator=(const GoASTStructType &) = delete;
-};
-
-class GoASTSwitchStmt : public GoASTStmt
-{
-  public:
-    GoASTSwitchStmt(GoASTStmt *init, GoASTExpr *tag, GoASTBlockStmt *body) : GoASTStmt(eSwitchStmt), m_init_up(init), m_tag_up(tag), m_body_up(body) {}
-    ~GoASTSwitchStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "SwitchStmt";
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eField; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eSwitchStmt;
-    }
-    
-    const GoASTStmt *
-    GetInit() const
-    {
-        return m_init_up.get();
-    }
-    void
-    SetInit(GoASTStmt *init)
-    {
-        m_init_up.reset(init);
-    }
+  size_t NumNames() const { return m_names.size(); }
+  const GoASTIdent *GetNames(int i) const { return m_names[i].get(); }
+  void AddNames(GoASTIdent *names) {
+    m_names.push_back(std::unique_ptr<GoASTIdent>(names));
+  }
 
-    const GoASTExpr *
-    GetTag() const
-    {
-        return m_tag_up.get();
-    }
-    void
-    SetTag(GoASTExpr *tag)
-    {
-        m_tag_up.reset(tag);
-    }
+  const GoASTExpr *GetType() const { return m_type_up.get(); }
+  void SetType(GoASTExpr *type) { m_type_up.reset(type); }
 
-    const GoASTBlockStmt *
-    GetBody() const
-    {
-        return m_body_up.get();
-    }
-    void
-    SetBody(GoASTBlockStmt *body)
-    {
-        m_body_up.reset(body);
-    }
+  const GoASTBasicLit *GetTag() const { return m_tag_up.get(); }
+  void SetTag(GoASTBasicLit *tag) { m_tag_up.reset(tag); }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTStmt> m_init_up;
-    std::unique_ptr<GoASTExpr> m_tag_up;
-    std::unique_ptr<GoASTBlockStmt> m_body_up;
-
-    GoASTSwitchStmt(const GoASTSwitchStmt &) = delete;
-    const GoASTSwitchStmt &operator=(const GoASTSwitchStmt &) = delete;
-};
-
-class GoASTTypeAssertExpr : public GoASTExpr
-{
-  public:
-    GoASTTypeAssertExpr(GoASTExpr *x, GoASTExpr *type) : GoASTExpr(eTypeAssertExpr), m_x_up(x), m_type_up(type) {}
-    ~GoASTTypeAssertExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "TypeAssertExpr";
-    }
+private:
+  friend class GoASTNode;
+  std::vector<std::unique_ptr<GoASTIdent>> m_names;
+  std::unique_ptr<GoASTExpr> m_type_up;
+  std::unique_ptr<GoASTBasicLit> m_tag_up;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eTypeAssertExpr;
-    }
-    
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+  GoASTField(const GoASTField &) = delete;
+  const GoASTField &operator=(const GoASTField &) = delete;
+};
 
-    const GoASTExpr *
-    GetType() const
-    {
-        return m_type_up.get();
-    }
-    void
-    SetType(GoASTExpr *type)
-    {
-        m_type_up.reset(type);
-    }
+class GoASTFieldList : public GoASTNode {
+public:
+  GoASTFieldList() : GoASTNode(eFieldList) {}
+  ~GoASTFieldList() override = default;
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTExpr> m_x_up;
-    std::unique_ptr<GoASTExpr> m_type_up;
-
-    GoASTTypeAssertExpr(const GoASTTypeAssertExpr &) = delete;
-    const GoASTTypeAssertExpr &operator=(const GoASTTypeAssertExpr &) = delete;
-};
-
-class GoASTTypeSpec : public GoASTSpec
-{
-  public:
-    GoASTTypeSpec(GoASTIdent *name, GoASTExpr *type) : GoASTSpec(eTypeSpec), m_name_up(name), m_type_up(type) {}
-    ~GoASTTypeSpec() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "TypeSpec";
-    }
+  const char *GetKindName() const override { return "FieldList"; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eTypeSpec;
-    }
-    
-    const GoASTIdent *
-    GetName() const
-    {
-        return m_name_up.get();
-    }
-    void
-    SetName(GoASTIdent *name)
-    {
-        m_name_up.reset(name);
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eFieldList; }
 
-    const GoASTExpr *
-    GetType() const
-    {
-        return m_type_up.get();
-    }
-    void
-    SetType(GoASTExpr *type)
-    {
-        m_type_up.reset(type);
-    }
+  size_t NumList() const { return m_list.size(); }
+  const GoASTField *GetList(int i) const { return m_list[i].get(); }
+  void AddList(GoASTField *list) {
+    m_list.push_back(std::unique_ptr<GoASTField>(list));
+  }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTIdent> m_name_up;
-    std::unique_ptr<GoASTExpr> m_type_up;
-
-    GoASTTypeSpec(const GoASTTypeSpec &) = delete;
-    const GoASTTypeSpec &operator=(const GoASTTypeSpec &) = delete;
-};
-
-class GoASTTypeSwitchStmt : public GoASTStmt
-{
-  public:
-    GoASTTypeSwitchStmt(GoASTStmt *init, GoASTStmt *assign, GoASTBlockStmt *body) : GoASTStmt(eTypeSwitchStmt), m_init_up(init), m_assign_up(assign), m_body_up(body) {}
-    ~GoASTTypeSwitchStmt() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "TypeSwitchStmt";
-    }
+private:
+  friend class GoASTNode;
+  std::vector<std::unique_ptr<GoASTField>> m_list;
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eTypeSwitchStmt;
-    }
-    
-    const GoASTStmt *
-    GetInit() const
-    {
-        return m_init_up.get();
-    }
-    void
-    SetInit(GoASTStmt *init)
-    {
-        m_init_up.reset(init);
-    }
+  GoASTFieldList(const GoASTFieldList &) = delete;
+  const GoASTFieldList &operator=(const GoASTFieldList &) = delete;
+};
 
-    const GoASTStmt *
-    GetAssign() const
-    {
-        return m_assign_up.get();
-    }
-    void
-    SetAssign(GoASTStmt *assign)
-    {
-        m_assign_up.reset(assign);
-    }
+class GoASTForStmt : public GoASTStmt {
+public:
+  GoASTForStmt(GoASTStmt *init, GoASTExpr *cond, GoASTStmt *post,
+               GoASTBlockStmt *body)
+      : GoASTStmt(eForStmt), m_init_up(init), m_cond_up(cond), m_post_up(post),
+        m_body_up(body) {}
+  ~GoASTForStmt() override = default;
 
-    const GoASTBlockStmt *
-    GetBody() const
-    {
-        return m_body_up.get();
-    }
-    void
-    SetBody(GoASTBlockStmt *body)
-    {
-        m_body_up.reset(body);
-    }
+  const char *GetKindName() const override { return "ForStmt"; }
 
-  private:
-    friend class GoASTNode;
-    std::unique_ptr<GoASTStmt> m_init_up;
-    std::unique_ptr<GoASTStmt> m_assign_up;
-    std::unique_ptr<GoASTBlockStmt> m_body_up;
-
-    GoASTTypeSwitchStmt(const GoASTTypeSwitchStmt &) = delete;
-    const GoASTTypeSwitchStmt &operator=(const GoASTTypeSwitchStmt &) = delete;
-};
-
-class GoASTUnaryExpr : public GoASTExpr
-{
-  public:
-    GoASTUnaryExpr(TokenType op, GoASTExpr *x) : GoASTExpr(eUnaryExpr), m_op(op), m_x_up(x) {}
-    ~GoASTUnaryExpr() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "UnaryExpr";
-    }
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eForStmt; }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eUnaryExpr;
-    }
-    
-    TokenType 
-    GetOp() const
-    {
-        return m_op;
-    }
-    void
-    SetOp(TokenType op)
-    {
-        m_op = op;
-    }
+  const GoASTStmt *GetInit() const { return m_init_up.get(); }
+  void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
 
-    const GoASTExpr *
-    GetX() const
-    {
-        return m_x_up.get();
-    }
-    void
-    SetX(GoASTExpr *x)
-    {
-        m_x_up.reset(x);
-    }
+  const GoASTExpr *GetCond() const { return m_cond_up.get(); }
+  void SetCond(GoASTExpr *cond) { m_cond_up.reset(cond); }
 
-  private:
-    friend class GoASTNode;
-    TokenType m_op;
-    std::unique_ptr<GoASTExpr> m_x_up;
-
-    GoASTUnaryExpr(const GoASTUnaryExpr &) = delete;
-    const GoASTUnaryExpr &operator=(const GoASTUnaryExpr &) = delete;
-};
-
-class GoASTValueSpec : public GoASTSpec
-{
-  public:
-    GoASTValueSpec() : GoASTSpec(eValueSpec) {}
-    ~GoASTValueSpec() override = default;
-
-    const char *
-    GetKindName() const override
-    {
-        return "ValueSpec";
-    }
+  const GoASTStmt *GetPost() const { return m_post_up.get(); }
+  void SetPost(GoASTStmt *post) { m_post_up.reset(post); }
 
-    static bool
-    classof(const GoASTNode *n)
-    {
-        return n->GetKind() == eValueSpec;
-    }
-    
-    size_t
-    NumNames() const
-    {
-        return m_names.size();
-    }
-    const GoASTIdent *
-    GetNames(int i) const
-    {
-        return m_names[i].get();
-    }
-    void
-    AddNames(GoASTIdent *names)
-    {
-        m_names.push_back(std::unique_ptr<GoASTIdent>(names));
-    }
+  const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+  void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
 
-    const GoASTExpr *
-    GetType() const
-    {
-        return m_type_up.get();
-    }
-    void
-    SetType(GoASTExpr *type)
-    {
-        m_type_up.reset(type);
-    }
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTStmt> m_init_up;
+  std::unique_ptr<GoASTExpr> m_cond_up;
+  std::unique_ptr<GoASTStmt> m_post_up;
+  std::unique_ptr<GoASTBlockStmt> m_body_up;
 
-    size_t
-    NumValues() const
-    {
-        return m_values.size();
-    }
-    const GoASTExpr *
-    GetValues(int i) const
-    {
-        return m_values[i].get();
-    }
-    void
-    AddValues(GoASTExpr *values)
-    {
-        m_values.push_back(std::unique_ptr<GoASTExpr>(values));
-    }
+  GoASTForStmt(const GoASTForStmt &) = delete;
+  const GoASTForStmt &operator=(const GoASTForStmt &) = delete;
+};
+
+class GoASTFuncType : public GoASTExpr {
+public:
+  GoASTFuncType(GoASTFieldList *params, GoASTFieldList *results)
+      : GoASTExpr(eFuncType), m_params_up(params), m_results_up(results) {}
+  ~GoASTFuncType() override = default;
+
+  const char *GetKindName() const override { return "FuncType"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncType; }
+
+  const GoASTFieldList *GetParams() const { return m_params_up.get(); }
+  void SetParams(GoASTFieldList *params) { m_params_up.reset(params); }
 
-  private:
-    friend class GoASTNode;
-    std::vector<std::unique_ptr<GoASTIdent> > m_names;
-    std::unique_ptr<GoASTExpr> m_type_up;
-    std::vector<std::unique_ptr<GoASTExpr> > m_values;
-
-    GoASTValueSpec(const GoASTValueSpec &) = delete;
-    const GoASTValueSpec &operator=(const GoASTValueSpec &) = delete;
+  const GoASTFieldList *GetResults() const { return m_results_up.get(); }
+  void SetResults(GoASTFieldList *results) { m_results_up.reset(results); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTFieldList> m_params_up;
+  std::unique_ptr<GoASTFieldList> m_results_up;
+
+  GoASTFuncType(const GoASTFuncType &) = delete;
+  const GoASTFuncType &operator=(const GoASTFuncType &) = delete;
 };
 
+class GoASTFuncDecl : public GoASTDecl {
+public:
+  GoASTFuncDecl(GoASTFieldList *recv, GoASTIdent *name, GoASTFuncType *type,
+                GoASTBlockStmt *body)
+      : GoASTDecl(eFuncDecl), m_recv_up(recv), m_name_up(name), m_type_up(type),
+        m_body_up(body) {}
+  ~GoASTFuncDecl() override = default;
 
-template <typename R, typename V>
-R GoASTDecl::Visit(V* v) const
-{
-    switch(GetKind())
-    {
-    case eBadDecl:
-        return v->VisitBadDecl(llvm::cast<const GoASTBadDecl>(this));
-    case eFuncDecl:
-        return v->VisitFuncDecl(llvm::cast<const GoASTFuncDecl>(this));
-    case eGenDecl:
-        return v->VisitGenDecl(llvm::cast<const GoASTGenDecl>(this));
-    default:
-        assert(false && "Invalid kind");
-    }
+  const char *GetKindName() const override { return "FuncDecl"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncDecl; }
+
+  const GoASTFieldList *GetRecv() const { return m_recv_up.get(); }
+  void SetRecv(GoASTFieldList *recv) { m_recv_up.reset(recv); }
+
+  const GoASTIdent *GetName() const { return m_name_up.get(); }
+  void SetName(GoASTIdent *name) { m_name_up.reset(name); }
+
+  const GoASTFuncType *GetType() const { return m_type_up.get(); }
+  void SetType(GoASTFuncType *type) { m_type_up.reset(type); }
+
+  const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+  void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTFieldList> m_recv_up;
+  std::unique_ptr<GoASTIdent> m_name_up;
+  std::unique_ptr<GoASTFuncType> m_type_up;
+  std::unique_ptr<GoASTBlockStmt> m_body_up;
+
+  GoASTFuncDecl(const GoASTFuncDecl &) = delete;
+  const GoASTFuncDecl &operator=(const GoASTFuncDecl &) = delete;
+};
+
+class GoASTFuncLit : public GoASTExpr {
+public:
+  GoASTFuncLit(GoASTFuncType *type, GoASTBlockStmt *body)
+      : GoASTExpr(eFuncLit), m_type_up(type), m_body_up(body) {}
+  ~GoASTFuncLit() override = default;
+
+  const char *GetKindName() const override { return "FuncLit"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncLit; }
+
+  const GoASTFuncType *GetType() const { return m_type_up.get(); }
+  void SetType(GoASTFuncType *type) { m_type_up.reset(type); }
+
+  const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+  void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTFuncType> m_type_up;
+  std::unique_ptr<GoASTBlockStmt> m_body_up;
+
+  GoASTFuncLit(const GoASTFuncLit &) = delete;
+  const GoASTFuncLit &operator=(const GoASTFuncLit &) = delete;
+};
+
+class GoASTGenDecl : public GoASTDecl {
+public:
+  explicit GoASTGenDecl(TokenType tok) : GoASTDecl(eGenDecl), m_tok(tok) {}
+  ~GoASTGenDecl() override = default;
+
+  const char *GetKindName() const override { return "GenDecl"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eGenDecl; }
+
+  TokenType GetTok() const { return m_tok; }
+  void SetTok(TokenType tok) { m_tok = tok; }
+
+  size_t NumSpecs() const { return m_specs.size(); }
+  const GoASTSpec *GetSpecs(int i) const { return m_specs[i].get(); }
+  void AddSpecs(GoASTSpec *specs) {
+    m_specs.push_back(std::unique_ptr<GoASTSpec>(specs));
+  }
+
+private:
+  friend class GoASTNode;
+  TokenType m_tok;
+  std::vector<std::unique_ptr<GoASTSpec>> m_specs;
+
+  GoASTGenDecl(const GoASTGenDecl &) = delete;
+  const GoASTGenDecl &operator=(const GoASTGenDecl &) = delete;
+};
+
+class GoASTGoStmt : public GoASTStmt {
+public:
+  explicit GoASTGoStmt(GoASTCallExpr *call)
+      : GoASTStmt(eGoStmt), m_call_up(call) {}
+  ~GoASTGoStmt() override = default;
+
+  const char *GetKindName() const override { return "GoStmt"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eGoStmt; }
+
+  const GoASTCallExpr *GetCall() const { return m_call_up.get(); }
+  void SetCall(GoASTCallExpr *call) { m_call_up.reset(call); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTCallExpr> m_call_up;
+
+  GoASTGoStmt(const GoASTGoStmt &) = delete;
+  const GoASTGoStmt &operator=(const GoASTGoStmt &) = delete;
+};
+
+class GoASTIfStmt : public GoASTStmt {
+public:
+  GoASTIfStmt(GoASTStmt *init, GoASTExpr *cond, GoASTBlockStmt *body,
+              GoASTStmt *els)
+      : GoASTStmt(eIfStmt), m_init_up(init), m_cond_up(cond), m_body_up(body),
+        m_els_up(els) {}
+  ~GoASTIfStmt() override = default;
+
+  const char *GetKindName() const override { return "IfStmt"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eIfStmt; }
+
+  const GoASTStmt *GetInit() const { return m_init_up.get(); }
+  void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
+
+  const GoASTExpr *GetCond() const { return m_cond_up.get(); }
+  void SetCond(GoASTExpr *cond) { m_cond_up.reset(cond); }
+
+  const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+  void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
+
+  const GoASTStmt *GetEls() const { return m_els_up.get(); }
+  void SetEls(GoASTStmt *els) { m_els_up.reset(els); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTStmt> m_init_up;
+  std::unique_ptr<GoASTExpr> m_cond_up;
+  std::unique_ptr<GoASTBlockStmt> m_body_up;
+  std::unique_ptr<GoASTStmt> m_els_up;
+
+  GoASTIfStmt(const GoASTIfStmt &) = delete;
+  const GoASTIfStmt &operator=(const GoASTIfStmt &) = delete;
+};
+
+class GoASTImportSpec : public GoASTSpec {
+public:
+  GoASTImportSpec(GoASTIdent *name, GoASTBasicLit *path)
+      : GoASTSpec(eImportSpec), m_name_up(name), m_path_up(path) {}
+  ~GoASTImportSpec() override = default;
+
+  const char *GetKindName() const override { return "ImportSpec"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eImportSpec;
+  }
+
+  const GoASTIdent *GetName() const { return m_name_up.get(); }
+  void SetName(GoASTIdent *name) { m_name_up.reset(name); }
+
+  const GoASTBasicLit *GetPath() const { return m_path_up.get(); }
+  void SetPath(GoASTBasicLit *path) { m_path_up.reset(path); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTIdent> m_name_up;
+  std::unique_ptr<GoASTBasicLit> m_path_up;
+
+  GoASTImportSpec(const GoASTImportSpec &) = delete;
+  const GoASTImportSpec &operator=(const GoASTImportSpec &) = delete;
+};
+
+class GoASTIncDecStmt : public GoASTStmt {
+public:
+  GoASTIncDecStmt(GoASTExpr *x, TokenType tok)
+      : GoASTStmt(eIncDecStmt), m_x_up(x), m_tok(tok) {}
+  ~GoASTIncDecStmt() override = default;
+
+  const char *GetKindName() const override { return "IncDecStmt"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eIncDecStmt;
+  }
+
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+  TokenType GetTok() const { return m_tok; }
+  void SetTok(TokenType tok) { m_tok = tok; }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_x_up;
+  TokenType m_tok;
+
+  GoASTIncDecStmt(const GoASTIncDecStmt &) = delete;
+  const GoASTIncDecStmt &operator=(const GoASTIncDecStmt &) = delete;
+};
+
+class GoASTIndexExpr : public GoASTExpr {
+public:
+  GoASTIndexExpr(GoASTExpr *x, GoASTExpr *index)
+      : GoASTExpr(eIndexExpr), m_x_up(x), m_index_up(index) {}
+  ~GoASTIndexExpr() override = default;
+
+  const char *GetKindName() const override { return "IndexExpr"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eIndexExpr; }
+
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+  const GoASTExpr *GetIndex() const { return m_index_up.get(); }
+  void SetIndex(GoASTExpr *index) { m_index_up.reset(index); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_x_up;
+  std::unique_ptr<GoASTExpr> m_index_up;
+
+  GoASTIndexExpr(const GoASTIndexExpr &) = delete;
+  const GoASTIndexExpr &operator=(const GoASTIndexExpr &) = delete;
+};
+
+class GoASTInterfaceType : public GoASTExpr {
+public:
+  explicit GoASTInterfaceType(GoASTFieldList *methods)
+      : GoASTExpr(eInterfaceType), m_methods_up(methods) {}
+  ~GoASTInterfaceType() override = default;
+
+  const char *GetKindName() const override { return "InterfaceType"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eInterfaceType;
+  }
+
+  const GoASTFieldList *GetMethods() const { return m_methods_up.get(); }
+  void SetMethods(GoASTFieldList *methods) { m_methods_up.reset(methods); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTFieldList> m_methods_up;
+
+  GoASTInterfaceType(const GoASTInterfaceType &) = delete;
+  const GoASTInterfaceType &operator=(const GoASTInterfaceType &) = delete;
+};
+
+class GoASTKeyValueExpr : public GoASTExpr {
+public:
+  GoASTKeyValueExpr(GoASTExpr *key, GoASTExpr *value)
+      : GoASTExpr(eKeyValueExpr), m_key_up(key), m_value_up(value) {}
+  ~GoASTKeyValueExpr() override = default;
+
+  const char *GetKindName() const override { return "KeyValueExpr"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eKeyValueExpr;
+  }
+
+  const GoASTExpr *GetKey() const { return m_key_up.get(); }
+  void SetKey(GoASTExpr *key) { m_key_up.reset(key); }
+
+  const GoASTExpr *GetValue() const { return m_value_up.get(); }
+  void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_key_up;
+  std::unique_ptr<GoASTExpr> m_value_up;
+
+  GoASTKeyValueExpr(const GoASTKeyValueExpr &) = delete;
+  const GoASTKeyValueExpr &operator=(const GoASTKeyValueExpr &) = delete;
+};
+
+class GoASTLabeledStmt : public GoASTStmt {
+public:
+  GoASTLabeledStmt(GoASTIdent *label, GoASTStmt *stmt)
+      : GoASTStmt(eLabeledStmt), m_label_up(label), m_stmt_up(stmt) {}
+  ~GoASTLabeledStmt() override = default;
+
+  const char *GetKindName() const override { return "LabeledStmt"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eLabeledStmt;
+  }
+
+  const GoASTIdent *GetLabel() const { return m_label_up.get(); }
+  void SetLabel(GoASTIdent *label) { m_label_up.reset(label); }
+
+  const GoASTStmt *GetStmt() const { return m_stmt_up.get(); }
+  void SetStmt(GoASTStmt *stmt) { m_stmt_up.reset(stmt); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTIdent> m_label_up;
+  std::unique_ptr<GoASTStmt> m_stmt_up;
+
+  GoASTLabeledStmt(const GoASTLabeledStmt &) = delete;
+  const GoASTLabeledStmt &operator=(const GoASTLabeledStmt &) = delete;
+};
+
+class GoASTMapType : public GoASTExpr {
+public:
+  GoASTMapType(GoASTExpr *key, GoASTExpr *value)
+      : GoASTExpr(eMapType), m_key_up(key), m_value_up(value) {}
+  ~GoASTMapType() override = default;
+
+  const char *GetKindName() const override { return "MapType"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eMapType; }
+
+  const GoASTExpr *GetKey() const { return m_key_up.get(); }
+  void SetKey(GoASTExpr *key) { m_key_up.reset(key); }
+
+  const GoASTExpr *GetValue() const { return m_value_up.get(); }
+  void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_key_up;
+  std::unique_ptr<GoASTExpr> m_value_up;
+
+  GoASTMapType(const GoASTMapType &) = delete;
+  const GoASTMapType &operator=(const GoASTMapType &) = delete;
+};
+
+class GoASTParenExpr : public GoASTExpr {
+public:
+  explicit GoASTParenExpr(GoASTExpr *x) : GoASTExpr(eParenExpr), m_x_up(x) {}
+  ~GoASTParenExpr() override = default;
+
+  const char *GetKindName() const override { return "ParenExpr"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eParenExpr; }
+
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_x_up;
+
+  GoASTParenExpr(const GoASTParenExpr &) = delete;
+  const GoASTParenExpr &operator=(const GoASTParenExpr &) = delete;
+};
+
+class GoASTRangeStmt : public GoASTStmt {
+public:
+  GoASTRangeStmt(GoASTExpr *key, GoASTExpr *value, bool define, GoASTExpr *x,
+                 GoASTBlockStmt *body)
+      : GoASTStmt(eRangeStmt), m_key_up(key), m_value_up(value),
+        m_define(define), m_x_up(x), m_body_up(body) {}
+  ~GoASTRangeStmt() override = default;
+
+  const char *GetKindName() const override { return "RangeStmt"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eRangeStmt; }
+
+  const GoASTExpr *GetKey() const { return m_key_up.get(); }
+  void SetKey(GoASTExpr *key) { m_key_up.reset(key); }
+
+  const GoASTExpr *GetValue() const { return m_value_up.get(); }
+  void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
+
+  bool GetDefine() const { return m_define; }
+  void SetDefine(bool define) { m_define = define; }
+
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+  const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+  void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_key_up;
+  std::unique_ptr<GoASTExpr> m_value_up;
+  bool m_define;
+  std::unique_ptr<GoASTExpr> m_x_up;
+  std::unique_ptr<GoASTBlockStmt> m_body_up;
+
+  GoASTRangeStmt(const GoASTRangeStmt &) = delete;
+  const GoASTRangeStmt &operator=(const GoASTRangeStmt &) = delete;
+};
+
+class GoASTReturnStmt : public GoASTStmt {
+public:
+  GoASTReturnStmt() : GoASTStmt(eReturnStmt) {}
+  ~GoASTReturnStmt() override = default;
+
+  const char *GetKindName() const override { return "ReturnStmt"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eReturnStmt;
+  }
+
+  size_t NumResults() const { return m_results.size(); }
+  const GoASTExpr *GetResults(int i) const { return m_results[i].get(); }
+  void AddResults(GoASTExpr *results) {
+    m_results.push_back(std::unique_ptr<GoASTExpr>(results));
+  }
+
+private:
+  friend class GoASTNode;
+  std::vector<std::unique_ptr<GoASTExpr>> m_results;
+
+  GoASTReturnStmt(const GoASTReturnStmt &) = delete;
+  const GoASTReturnStmt &operator=(const GoASTReturnStmt &) = delete;
+};
+
+class GoASTSelectStmt : public GoASTStmt {
+public:
+  explicit GoASTSelectStmt(GoASTBlockStmt *body)
+      : GoASTStmt(eSelectStmt), m_body_up(body) {}
+  ~GoASTSelectStmt() override = default;
+
+  const char *GetKindName() const override { return "SelectStmt"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eSelectStmt;
+  }
+
+  const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+  void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTBlockStmt> m_body_up;
+
+  GoASTSelectStmt(const GoASTSelectStmt &) = delete;
+  const GoASTSelectStmt &operator=(const GoASTSelectStmt &) = delete;
+};
+
+class GoASTSelectorExpr : public GoASTExpr {
+public:
+  GoASTSelectorExpr(GoASTExpr *x, GoASTIdent *sel)
+      : GoASTExpr(eSelectorExpr), m_x_up(x), m_sel_up(sel) {}
+  ~GoASTSelectorExpr() override = default;
+
+  const char *GetKindName() const override { return "SelectorExpr"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eSelectorExpr;
+  }
+
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+  const GoASTIdent *GetSel() const { return m_sel_up.get(); }
+  void SetSel(GoASTIdent *sel) { m_sel_up.reset(sel); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_x_up;
+  std::unique_ptr<GoASTIdent> m_sel_up;
+
+  GoASTSelectorExpr(const GoASTSelectorExpr &) = delete;
+  const GoASTSelectorExpr &operator=(const GoASTSelectorExpr &) = delete;
+};
+
+class GoASTSendStmt : public GoASTStmt {
+public:
+  GoASTSendStmt(GoASTExpr *chan, GoASTExpr *value)
+      : GoASTStmt(eSendStmt), m_chan_up(chan), m_value_up(value) {}
+  ~GoASTSendStmt() override = default;
+
+  const char *GetKindName() const override { return "SendStmt"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eSendStmt; }
+
+  const GoASTExpr *GetChan() const { return m_chan_up.get(); }
+  void SetChan(GoASTExpr *chan) { m_chan_up.reset(chan); }
+
+  const GoASTExpr *GetValue() const { return m_value_up.get(); }
+  void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_chan_up;
+  std::unique_ptr<GoASTExpr> m_value_up;
+
+  GoASTSendStmt(const GoASTSendStmt &) = delete;
+  const GoASTSendStmt &operator=(const GoASTSendStmt &) = delete;
+};
+
+class GoASTSliceExpr : public GoASTExpr {
+public:
+  GoASTSliceExpr(GoASTExpr *x, GoASTExpr *low, GoASTExpr *high, GoASTExpr *max,
+                 bool slice3)
+      : GoASTExpr(eSliceExpr), m_x_up(x), m_low_up(low), m_high_up(high),
+        m_max_up(max), m_slice3(slice3) {}
+  ~GoASTSliceExpr() override = default;
+
+  const char *GetKindName() const override { return "SliceExpr"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eSliceExpr; }
+
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+  const GoASTExpr *GetLow() const { return m_low_up.get(); }
+  void SetLow(GoASTExpr *low) { m_low_up.reset(low); }
+
+  const GoASTExpr *GetHigh() const { return m_high_up.get(); }
+  void SetHigh(GoASTExpr *high) { m_high_up.reset(high); }
+
+  const GoASTExpr *GetMax() const { return m_max_up.get(); }
+  void SetMax(GoASTExpr *max) { m_max_up.reset(max); }
+
+  bool GetSlice3() const { return m_slice3; }
+  void SetSlice3(bool slice3) { m_slice3 = slice3; }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_x_up;
+  std::unique_ptr<GoASTExpr> m_low_up;
+  std::unique_ptr<GoASTExpr> m_high_up;
+  std::unique_ptr<GoASTExpr> m_max_up;
+  bool m_slice3;
+
+  GoASTSliceExpr(const GoASTSliceExpr &) = delete;
+  const GoASTSliceExpr &operator=(const GoASTSliceExpr &) = delete;
+};
+
+class GoASTStarExpr : public GoASTExpr {
+public:
+  explicit GoASTStarExpr(GoASTExpr *x) : GoASTExpr(eStarExpr), m_x_up(x) {}
+  ~GoASTStarExpr() override = default;
+
+  const char *GetKindName() const override { return "StarExpr"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eStarExpr; }
+
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_x_up;
+
+  GoASTStarExpr(const GoASTStarExpr &) = delete;
+  const GoASTStarExpr &operator=(const GoASTStarExpr &) = delete;
+};
+
+class GoASTStructType : public GoASTExpr {
+public:
+  explicit GoASTStructType(GoASTFieldList *fields)
+      : GoASTExpr(eStructType), m_fields_up(fields) {}
+  ~GoASTStructType() override = default;
+
+  const char *GetKindName() const override { return "StructType"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eStructType;
+  }
+
+  const GoASTFieldList *GetFields() const { return m_fields_up.get(); }
+  void SetFields(GoASTFieldList *fields) { m_fields_up.reset(fields); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTFieldList> m_fields_up;
+
+  GoASTStructType(const GoASTStructType &) = delete;
+  const GoASTStructType &operator=(const GoASTStructType &) = delete;
+};
+
+class GoASTSwitchStmt : public GoASTStmt {
+public:
+  GoASTSwitchStmt(GoASTStmt *init, GoASTExpr *tag, GoASTBlockStmt *body)
+      : GoASTStmt(eSwitchStmt), m_init_up(init), m_tag_up(tag),
+        m_body_up(body) {}
+  ~GoASTSwitchStmt() override = default;
+
+  const char *GetKindName() const override { return "SwitchStmt"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eSwitchStmt;
+  }
+
+  const GoASTStmt *GetInit() const { return m_init_up.get(); }
+  void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
+
+  const GoASTExpr *GetTag() const { return m_tag_up.get(); }
+  void SetTag(GoASTExpr *tag) { m_tag_up.reset(tag); }
+
+  const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+  void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTStmt> m_init_up;
+  std::unique_ptr<GoASTExpr> m_tag_up;
+  std::unique_ptr<GoASTBlockStmt> m_body_up;
+
+  GoASTSwitchStmt(const GoASTSwitchStmt &) = delete;
+  const GoASTSwitchStmt &operator=(const GoASTSwitchStmt &) = delete;
+};
+
+class GoASTTypeAssertExpr : public GoASTExpr {
+public:
+  GoASTTypeAssertExpr(GoASTExpr *x, GoASTExpr *type)
+      : GoASTExpr(eTypeAssertExpr), m_x_up(x), m_type_up(type) {}
+  ~GoASTTypeAssertExpr() override = default;
+
+  const char *GetKindName() const override { return "TypeAssertExpr"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eTypeAssertExpr;
+  }
+
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+  const GoASTExpr *GetType() const { return m_type_up.get(); }
+  void SetType(GoASTExpr *type) { m_type_up.reset(type); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTExpr> m_x_up;
+  std::unique_ptr<GoASTExpr> m_type_up;
+
+  GoASTTypeAssertExpr(const GoASTTypeAssertExpr &) = delete;
+  const GoASTTypeAssertExpr &operator=(const GoASTTypeAssertExpr &) = delete;
+};
+
+class GoASTTypeSpec : public GoASTSpec {
+public:
+  GoASTTypeSpec(GoASTIdent *name, GoASTExpr *type)
+      : GoASTSpec(eTypeSpec), m_name_up(name), m_type_up(type) {}
+  ~GoASTTypeSpec() override = default;
+
+  const char *GetKindName() const override { return "TypeSpec"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eTypeSpec; }
+
+  const GoASTIdent *GetName() const { return m_name_up.get(); }
+  void SetName(GoASTIdent *name) { m_name_up.reset(name); }
+
+  const GoASTExpr *GetType() const { return m_type_up.get(); }
+  void SetType(GoASTExpr *type) { m_type_up.reset(type); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTIdent> m_name_up;
+  std::unique_ptr<GoASTExpr> m_type_up;
+
+  GoASTTypeSpec(const GoASTTypeSpec &) = delete;
+  const GoASTTypeSpec &operator=(const GoASTTypeSpec &) = delete;
+};
+
+class GoASTTypeSwitchStmt : public GoASTStmt {
+public:
+  GoASTTypeSwitchStmt(GoASTStmt *init, GoASTStmt *assign, GoASTBlockStmt *body)
+      : GoASTStmt(eTypeSwitchStmt), m_init_up(init), m_assign_up(assign),
+        m_body_up(body) {}
+  ~GoASTTypeSwitchStmt() override = default;
+
+  const char *GetKindName() const override { return "TypeSwitchStmt"; }
+
+  static bool classof(const GoASTNode *n) {
+    return n->GetKind() == eTypeSwitchStmt;
+  }
+
+  const GoASTStmt *GetInit() const { return m_init_up.get(); }
+  void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
+
+  const GoASTStmt *GetAssign() const { return m_assign_up.get(); }
+  void SetAssign(GoASTStmt *assign) { m_assign_up.reset(assign); }
+
+  const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
+  void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
+
+private:
+  friend class GoASTNode;
+  std::unique_ptr<GoASTStmt> m_init_up;
+  std::unique_ptr<GoASTStmt> m_assign_up;
+  std::unique_ptr<GoASTBlockStmt> m_body_up;
+
+  GoASTTypeSwitchStmt(const GoASTTypeSwitchStmt &) = delete;
+  const GoASTTypeSwitchStmt &operator=(const GoASTTypeSwitchStmt &) = delete;
+};
+
+class GoASTUnaryExpr : public GoASTExpr {
+public:
+  GoASTUnaryExpr(TokenType op, GoASTExpr *x)
+      : GoASTExpr(eUnaryExpr), m_op(op), m_x_up(x) {}
+  ~GoASTUnaryExpr() override = default;
+
+  const char *GetKindName() const override { return "UnaryExpr"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eUnaryExpr; }
+
+  TokenType GetOp() const { return m_op; }
+  void SetOp(TokenType op) { m_op = op; }
+
+  const GoASTExpr *GetX() const { return m_x_up.get(); }
+  void SetX(GoASTExpr *x) { m_x_up.reset(x); }
+
+private:
+  friend class GoASTNode;
+  TokenType m_op;
+  std::unique_ptr<GoASTExpr> m_x_up;
+
+  GoASTUnaryExpr(const GoASTUnaryExpr &) = delete;
+  const GoASTUnaryExpr &operator=(const GoASTUnaryExpr &) = delete;
+};
+
+class GoASTValueSpec : public GoASTSpec {
+public:
+  GoASTValueSpec() : GoASTSpec(eValueSpec) {}
+  ~GoASTValueSpec() override = default;
+
+  const char *GetKindName() const override { return "ValueSpec"; }
+
+  static bool classof(const GoASTNode *n) { return n->GetKind() == eValueSpec; }
+
+  size_t NumNames() const { return m_names.size(); }
+  const GoASTIdent *GetNames(int i) const { return m_names[i].get(); }
+  void AddNames(GoASTIdent *names) {
+    m_names.push_back(std::unique_ptr<GoASTIdent>(names));
+  }
+
+  const GoASTExpr *GetType() const { return m_type_up.get(); }
+  void SetType(GoASTExpr *type) { m_type_up.reset(type); }
+
+  size_t NumValues() const { return m_values.size(); }
+  const GoASTExpr *GetValues(int i) const { return m_values[i].get(); }
+  void AddValues(GoASTExpr *values) {
+    m_values.push_back(std::unique_ptr<GoASTExpr>(values));
+  }
+
+private:
+  friend class GoASTNode;
+  std::vector<std::unique_ptr<GoASTIdent>> m_names;
+  std::unique_ptr<GoASTExpr> m_type_up;
+  std::vector<std::unique_ptr<GoASTExpr>> m_values;
+
+  GoASTValueSpec(const GoASTValueSpec &) = delete;
+  const GoASTValueSpec &operator=(const GoASTValueSpec &) = delete;
+};
+
+template <typename R, typename V> R GoASTDecl::Visit(V *v) const {
+  switch (GetKind()) {
+  case eBadDecl:
+    return v->VisitBadDecl(llvm::cast<const GoASTBadDecl>(this));
+  case eFuncDecl:
+    return v->VisitFuncDecl(llvm::cast<const GoASTFuncDecl>(this));
+  case eGenDecl:
+    return v->VisitGenDecl(llvm::cast<const GoASTGenDecl>(this));
+  default:
+    assert(false && "Invalid kind");
+  }
 }
 
-template <typename R, typename V>
-R GoASTExpr::Visit(V* v) const
-{
-    switch(GetKind())
-    {
-    case eArrayType:
-        return v->VisitArrayType(llvm::cast<const GoASTArrayType>(this));
-    case eBadExpr:
-        return v->VisitBadExpr(llvm::cast<const GoASTBadExpr>(this));
-    case eBasicLit:
-        return v->VisitBasicLit(llvm::cast<const GoASTBasicLit>(this));
-    case eBinaryExpr:
-        return v->VisitBinaryExpr(llvm::cast<const GoASTBinaryExpr>(this));
-    case eIdent:
-        return v->VisitIdent(llvm::cast<const GoASTIdent>(this));
-    case eCallExpr:
-        return v->VisitCallExpr(llvm::cast<const GoASTCallExpr>(this));
-    case eChanType:
-        return v->VisitChanType(llvm::cast<const GoASTChanType>(this));
-    case eCompositeLit:
-        return v->VisitCompositeLit(llvm::cast<const GoASTCompositeLit>(this));
-    case eEllipsis:
-        return v->VisitEllipsis(llvm::cast<const GoASTEllipsis>(this));
-    case eFuncType:
-        return v->VisitFuncType(llvm::cast<const GoASTFuncType>(this));
-    case eFuncLit:
-        return v->VisitFuncLit(llvm::cast<const GoASTFuncLit>(this));
-    case eIndexExpr:
-        return v->VisitIndexExpr(llvm::cast<const GoASTIndexExpr>(this));
-    case eInterfaceType:
-        return v->VisitInterfaceType(llvm::cast<const GoASTInterfaceType>(this));
-    case eKeyValueExpr:
-        return v->VisitKeyValueExpr(llvm::cast<const GoASTKeyValueExpr>(this));
-    case eMapType:
-        return v->VisitMapType(llvm::cast<const GoASTMapType>(this));
-    case eParenExpr:
-        return v->VisitParenExpr(llvm::cast<const GoASTParenExpr>(this));
-    case eSelectorExpr:
-        return v->VisitSelectorExpr(llvm::cast<const GoASTSelectorExpr>(this));
-    case eSliceExpr:
-        return v->VisitSliceExpr(llvm::cast<const GoASTSliceExpr>(this));
-    case eStarExpr:
-        return v->VisitStarExpr(llvm::cast<const GoASTStarExpr>(this));
-    case eStructType:
-        return v->VisitStructType(llvm::cast<const GoASTStructType>(this));
-    case eTypeAssertExpr:
-        return v->VisitTypeAssertExpr(llvm::cast<const GoASTTypeAssertExpr>(this));
-    case eUnaryExpr:
-        return v->VisitUnaryExpr(llvm::cast<const GoASTUnaryExpr>(this));
-    default:
-        assert(false && "Invalid kind");
-        return R();
-    }
+template <typename R, typename V> R GoASTExpr::Visit(V *v) const {
+  switch (GetKind()) {
+  case eArrayType:
+    return v->VisitArrayType(llvm::cast<const GoASTArrayType>(this));
+  case eBadExpr:
+    return v->VisitBadExpr(llvm::cast<const GoASTBadExpr>(this));
+  case eBasicLit:
+    return v->VisitBasicLit(llvm::cast<const GoASTBasicLit>(this));
+  case eBinaryExpr:
+    return v->VisitBinaryExpr(llvm::cast<const GoASTBinaryExpr>(this));
+  case eIdent:
+    return v->VisitIdent(llvm::cast<const GoASTIdent>(this));
+  case eCallExpr:
+    return v->VisitCallExpr(llvm::cast<const GoASTCallExpr>(this));
+  case eChanType:
+    return v->VisitChanType(llvm::cast<const GoASTChanType>(this));
+  case eCompositeLit:
+    return v->VisitCompositeLit(llvm::cast<const GoASTCompositeLit>(this));
+  case eEllipsis:
+    return v->VisitEllipsis(llvm::cast<const GoASTEllipsis>(this));
+  case eFuncType:
+    return v->VisitFuncType(llvm::cast<const GoASTFuncType>(this));
+  case eFuncLit:
+    return v->VisitFuncLit(llvm::cast<const GoASTFuncLit>(this));
+  case eIndexExpr:
+    return v->VisitIndexExpr(llvm::cast<const GoASTIndexExpr>(this));
+  case eInterfaceType:
+    return v->VisitInterfaceType(llvm::cast<const GoASTInterfaceType>(this));
+  case eKeyValueExpr:
+    return v->VisitKeyValueExpr(llvm::cast<const GoASTKeyValueExpr>(this));
+  case eMapType:
+    return v->VisitMapType(llvm::cast<const GoASTMapType>(this));
+  case eParenExpr:
+    return v->VisitParenExpr(llvm::cast<const GoASTParenExpr>(this));
+  case eSelectorExpr:
+    return v->VisitSelectorExpr(llvm::cast<const GoASTSelectorExpr>(this));
+  case eSliceExpr:
+    return v->VisitSliceExpr(llvm::cast<const GoASTSliceExpr>(this));
+  case eStarExpr:
+    return v->VisitStarExpr(llvm::cast<const GoASTStarExpr>(this));
+  case eStructType:
+    return v->VisitStructType(llvm::cast<const GoASTStructType>(this));
+  case eTypeAssertExpr:
+    return v->VisitTypeAssertExpr(llvm::cast<const GoASTTypeAssertExpr>(this));
+  case eUnaryExpr:
+    return v->VisitUnaryExpr(llvm::cast<const GoASTUnaryExpr>(this));
+  default:
+    assert(false && "Invalid kind");
+    return R();
+  }
 }
 
-template <typename R, typename V>
-R GoASTSpec::Visit(V* v) const
-{
-    switch(GetKind())
-    {
-    case eImportSpec:
-        return v->VisitImportSpec(llvm::cast<const GoASTImportSpec>(this));
-    case eTypeSpec:
-        return v->VisitTypeSpec(llvm::cast<const GoASTTypeSpec>(this));
-    case eValueSpec:
-        return v->VisitValueSpec(llvm::cast<const GoASTValueSpec>(this));
-    default:
-        assert(false && "Invalid kind");
-    }
+template <typename R, typename V> R GoASTSpec::Visit(V *v) const {
+  switch (GetKind()) {
+  case eImportSpec:
+    return v->VisitImportSpec(llvm::cast<const GoASTImportSpec>(this));
+  case eTypeSpec:
+    return v->VisitTypeSpec(llvm::cast<const GoASTTypeSpec>(this));
+  case eValueSpec:
+    return v->VisitValueSpec(llvm::cast<const GoASTValueSpec>(this));
+  default:
+    assert(false && "Invalid kind");
+  }
 }
 
-template <typename R, typename V>
-R GoASTStmt::Visit(V* v) const
-{
-    switch(GetKind())
-    {
-    case eAssignStmt:
-        return v->VisitAssignStmt(llvm::cast<const GoASTAssignStmt>(this));
-    case eBadStmt:
-        return v->VisitBadStmt(llvm::cast<const GoASTBadStmt>(this));
-    case eBlockStmt:
-        return v->VisitBlockStmt(llvm::cast<const GoASTBlockStmt>(this));
-    case eBranchStmt:
-        return v->VisitBranchStmt(llvm::cast<const GoASTBranchStmt>(this));
-    case eCaseClause:
-        return v->VisitCaseClause(llvm::cast<const GoASTCaseClause>(this));
-    case eCommClause:
-        return v->VisitCommClause(llvm::cast<const GoASTCommClause>(this));
-    case eDeclStmt:
-        return v->VisitDeclStmt(llvm::cast<const GoASTDeclStmt>(this));
-    case eDeferStmt:
-        return v->VisitDeferStmt(llvm::cast<const GoASTDeferStmt>(this));
-    case eEmptyStmt:
-        return v->VisitEmptyStmt(llvm::cast<const GoASTEmptyStmt>(this));
-    case eExprStmt:
-        return v->VisitExprStmt(llvm::cast<const GoASTExprStmt>(this));
-    case eForStmt:
-        return v->VisitForStmt(llvm::cast<const GoASTForStmt>(this));
-    case eGoStmt:
-        return v->VisitGoStmt(llvm::cast<const GoASTGoStmt>(this));
-    case eIfStmt:
-        return v->VisitIfStmt(llvm::cast<const GoASTIfStmt>(this));
-    case eIncDecStmt:
-        return v->VisitIncDecStmt(llvm::cast<const GoASTIncDecStmt>(this));
-    case eLabeledStmt:
-        return v->VisitLabeledStmt(llvm::cast<const GoASTLabeledStmt>(this));
-    case eRangeStmt:
-        return v->VisitRangeStmt(llvm::cast<const GoASTRangeStmt>(this));
-    case eReturnStmt:
-        return v->VisitReturnStmt(llvm::cast<const GoASTReturnStmt>(this));
-    case eSelectStmt:
-        return v->VisitSelectStmt(llvm::cast<const GoASTSelectStmt>(this));
-    case eSendStmt:
-        return v->VisitSendStmt(llvm::cast<const GoASTSendStmt>(this));
-    case eSwitchStmt:
-        return v->VisitSwitchStmt(llvm::cast<const GoASTSwitchStmt>(this));
-    case eTypeSwitchStmt:
-        return v->VisitTypeSwitchStmt(llvm::cast<const GoASTTypeSwitchStmt>(this));
-    default:
-        assert(false && "Invalid kind");
-    }
+template <typename R, typename V> R GoASTStmt::Visit(V *v) const {
+  switch (GetKind()) {
+  case eAssignStmt:
+    return v->VisitAssignStmt(llvm::cast<const GoASTAssignStmt>(this));
+  case eBadStmt:
+    return v->VisitBadStmt(llvm::cast<const GoASTBadStmt>(this));
+  case eBlockStmt:
+    return v->VisitBlockStmt(llvm::cast<const GoASTBlockStmt>(this));
+  case eBranchStmt:
+    return v->VisitBranchStmt(llvm::cast<const GoASTBranchStmt>(this));
+  case eCaseClause:
+    return v->VisitCaseClause(llvm::cast<const GoASTCaseClause>(this));
+  case eCommClause:
+    return v->VisitCommClause(llvm::cast<const GoASTCommClause>(this));
+  case eDeclStmt:
+    return v->VisitDeclStmt(llvm::cast<const GoASTDeclStmt>(this));
+  case eDeferStmt:
+    return v->VisitDeferStmt(llvm::cast<const GoASTDeferStmt>(this));
+  case eEmptyStmt:
+    return v->VisitEmptyStmt(llvm::cast<const GoASTEmptyStmt>(this));
+  case eExprStmt:
+    return v->VisitExprStmt(llvm::cast<const GoASTExprStmt>(this));
+  case eForStmt:
+    return v->VisitForStmt(llvm::cast<const GoASTForStmt>(this));
+  case eGoStmt:
+    return v->VisitGoStmt(llvm::cast<const GoASTGoStmt>(this));
+  case eIfStmt:
+    return v->VisitIfStmt(llvm::cast<const GoASTIfStmt>(this));
+  case eIncDecStmt:
+    return v->VisitIncDecStmt(llvm::cast<const GoASTIncDecStmt>(this));
+  case eLabeledStmt:
+    return v->VisitLabeledStmt(llvm::cast<const GoASTLabeledStmt>(this));
+  case eRangeStmt:
+    return v->VisitRangeStmt(llvm::cast<const GoASTRangeStmt>(this));
+  case eReturnStmt:
+    return v->VisitReturnStmt(llvm::cast<const GoASTReturnStmt>(this));
+  case eSelectStmt:
+    return v->VisitSelectStmt(llvm::cast<const GoASTSelectStmt>(this));
+  case eSendStmt:
+    return v->VisitSendStmt(llvm::cast<const GoASTSendStmt>(this));
+  case eSwitchStmt:
+    return v->VisitSwitchStmt(llvm::cast<const GoASTSwitchStmt>(this));
+  case eTypeSwitchStmt:
+    return v->VisitTypeSwitchStmt(llvm::cast<const GoASTTypeSwitchStmt>(this));
+  default:
+    assert(false && "Invalid kind");
+  }
 }
 
-template <typename V>
-void GoASTNode::WalkChildren(V &v)
-{
-    switch (m_kind)
-    {
-
-
-    case eArrayType:
-        {
-            GoASTArrayType *n = llvm::cast<GoASTArrayType>(this);
-            (void)n;
-            v(n->m_len_up.get());
-            v(n->m_elt_up.get());
-            return;
-        }
-    case eAssignStmt:
-        {
-            GoASTAssignStmt *n = llvm::cast<GoASTAssignStmt>(this);
-            (void)n;
-            for (auto& e : n->m_lhs) { v(e.get()); }
-            for (auto& e : n->m_rhs) { v(e.get()); }
-            return;
-        }
-    case eBasicLit:
-        {
-            GoASTBasicLit *n = llvm::cast<GoASTBasicLit>(this);
-            (void)n;
-            return;
-        }
-    case eBinaryExpr:
-        {
-            GoASTBinaryExpr *n = llvm::cast<GoASTBinaryExpr>(this);
-            (void)n;
-            v(n->m_x_up.get());
-            v(n->m_y_up.get());
-            return;
-        }
-    case eBlockStmt:
-        {
-            GoASTBlockStmt *n = llvm::cast<GoASTBlockStmt>(this);
-            (void)n;
-            for (auto& e : n->m_list) { v(e.get()); }
-            return;
-        }
-    case eIdent:
-        {
-            GoASTIdent *n = llvm::cast<GoASTIdent>(this);
-            (void)n;
-            return;
-        }
-    case eBranchStmt:
-        {
-            GoASTBranchStmt *n = llvm::cast<GoASTBranchStmt>(this);
-            (void)n;
-            v(n->m_label_up.get());
-            return;
-        }
-    case eCallExpr:
-        {
-            GoASTCallExpr *n = llvm::cast<GoASTCallExpr>(this);
-            (void)n;
-            v(n->m_fun_up.get());
-            for (auto& e : n->m_args) { v(e.get()); }
-            return;
-        }
-    case eCaseClause:
-        {
-            GoASTCaseClause *n = llvm::cast<GoASTCaseClause>(this);
-            (void)n;
-            for (auto& e : n->m_list) { v(e.get()); }
-            for (auto& e : n->m_body) { v(e.get()); }
-            return;
-        }
-    case eChanType:
-        {
-            GoASTChanType *n = llvm::cast<GoASTChanType>(this);
-            (void)n;
-            v(n->m_value_up.get());
-            return;
-        }
-    case eCommClause:
-        {
-            GoASTCommClause *n = llvm::cast<GoASTCommClause>(this);
-            (void)n;
-            v(n->m_comm_up.get());
-            for (auto& e : n->m_body) { v(e.get()); }
-            return;
-        }
-    case eCompositeLit:
-        {
-            GoASTCompositeLit *n = llvm::cast<GoASTCompositeLit>(this);
-            (void)n;
-            v(n->m_type_up.get());
-            for (auto& e : n->m_elts) { v(e.get()); }
-            return;
-        }
-    case eDeclStmt:
-        {
-            GoASTDeclStmt *n = llvm::cast<GoASTDeclStmt>(this);
-            (void)n;
-            v(n->m_decl_up.get());
-            return;
-        }
-    case eDeferStmt:
-        {
-            GoASTDeferStmt *n = llvm::cast<GoASTDeferStmt>(this);
-            (void)n;
-            v(n->m_call_up.get());
-            return;
-        }
-    case eEllipsis:
-        {
-            GoASTEllipsis *n = llvm::cast<GoASTEllipsis>(this);
-            (void)n;
-            v(n->m_elt_up.get());
-            return;
-        }
-    case eExprStmt:
-        {
-            GoASTExprStmt *n = llvm::cast<GoASTExprStmt>(this);
-            (void)n;
-            v(n->m_x_up.get());
-            return;
-        }
-    case eField:
-        {
-            GoASTField *n = llvm::cast<GoASTField>(this);
-            (void)n;
-            for (auto& e : n->m_names) { v(e.get()); }
-            v(n->m_type_up.get());
-            v(n->m_tag_up.get());
-            return;
-        }
-    case eFieldList:
-        {
-            GoASTFieldList *n = llvm::cast<GoASTFieldList>(this);
-            (void)n;
-            for (auto& e : n->m_list) { v(e.get()); }
-            return;
-        }
-    case eForStmt:
-        {
-            GoASTForStmt *n = llvm::cast<GoASTForStmt>(this);
-            (void)n;
-            v(n->m_init_up.get());
-            v(n->m_cond_up.get());
-            v(n->m_post_up.get());
-            v(n->m_body_up.get());
-            return;
-        }
-    case eFuncType:
-        {
-            GoASTFuncType *n = llvm::cast<GoASTFuncType>(this);
-            (void)n;
-            v(n->m_params_up.get());
-            v(n->m_results_up.get());
-            return;
-        }
-    case eFuncDecl:
-        {
-            GoASTFuncDecl *n = llvm::cast<GoASTFuncDecl>(this);
-            (void)n;
-            v(n->m_recv_up.get());
-            v(n->m_name_up.get());
-            v(n->m_type_up.get());
-            v(n->m_body_up.get());
-            return;
-        }
-    case eFuncLit:
-        {
-            GoASTFuncLit *n = llvm::cast<GoASTFuncLit>(this);
-            (void)n;
-            v(n->m_type_up.get());
-            v(n->m_body_up.get());
-            return;
-        }
-    case eGenDecl:
-        {
-            GoASTGenDecl *n = llvm::cast<GoASTGenDecl>(this);
-            (void)n;
-            for (auto& e : n->m_specs) { v(e.get()); }
-            return;
-        }
-    case eGoStmt:
-        {
-            GoASTGoStmt *n = llvm::cast<GoASTGoStmt>(this);
-            (void)n;
-            v(n->m_call_up.get());
-            return;
-        }
-    case eIfStmt:
-        {
-            GoASTIfStmt *n = llvm::cast<GoASTIfStmt>(this);
-            (void)n;
-            v(n->m_init_up.get());
-            v(n->m_cond_up.get());
-            v(n->m_body_up.get());
-            v(n->m_els_up.get());
-            return;
-        }
-    case eImportSpec:
-        {
-            GoASTImportSpec *n = llvm::cast<GoASTImportSpec>(this);
-            (void)n;
-            v(n->m_name_up.get());
-            v(n->m_path_up.get());
-            return;
-        }
-    case eIncDecStmt:
-        {
-            GoASTIncDecStmt *n = llvm::cast<GoASTIncDecStmt>(this);
-            (void)n;
-            v(n->m_x_up.get());
-            return;
-        }
-    case eIndexExpr:
-        {
-            GoASTIndexExpr *n = llvm::cast<GoASTIndexExpr>(this);
-            (void)n;
-            v(n->m_x_up.get());
-            v(n->m_index_up.get());
-            return;
-        }
-    case eInterfaceType:
-        {
-            GoASTInterfaceType *n = llvm::cast<GoASTInterfaceType>(this);
-            (void)n;
-            v(n->m_methods_up.get());
-            return;
-        }
-    case eKeyValueExpr:
-        {
-            GoASTKeyValueExpr *n = llvm::cast<GoASTKeyValueExpr>(this);
-            (void)n;
-            v(n->m_key_up.get());
-            v(n->m_value_up.get());
-            return;
-        }
-    case eLabeledStmt:
-        {
-            GoASTLabeledStmt *n = llvm::cast<GoASTLabeledStmt>(this);
-            (void)n;
-            v(n->m_label_up.get());
-            v(n->m_stmt_up.get());
-            return;
-        }
-    case eMapType:
-        {
-            GoASTMapType *n = llvm::cast<GoASTMapType>(this);
-            (void)n;
-            v(n->m_key_up.get());
-            v(n->m_value_up.get());
-            return;
-        }
-    case eParenExpr:
-        {
-            GoASTParenExpr *n = llvm::cast<GoASTParenExpr>(this);
-            (void)n;
-            v(n->m_x_up.get());
-            return;
-        }
-    case eRangeStmt:
-        {
-            GoASTRangeStmt *n = llvm::cast<GoASTRangeStmt>(this);
-            (void)n;
-            v(n->m_key_up.get());
-            v(n->m_value_up.get());
-            v(n->m_x_up.get());
-            v(n->m_body_up.get());
-            return;
-        }
-    case eReturnStmt:
-        {
-            GoASTReturnStmt *n = llvm::cast<GoASTReturnStmt>(this);
-            (void)n;
-            for (auto& e : n->m_results) { v(e.get()); }
-            return;
-        }
-    case eSelectStmt:
-        {
-            GoASTSelectStmt *n = llvm::cast<GoASTSelectStmt>(this);
-            (void)n;
-            v(n->m_body_up.get());
-            return;
-        }
-    case eSelectorExpr:
-        {
-            GoASTSelectorExpr *n = llvm::cast<GoASTSelectorExpr>(this);
-            (void)n;
-            v(n->m_x_up.get());
-            v(n->m_sel_up.get());
-            return;
-        }
-    case eSendStmt:
-        {
-            GoASTSendStmt *n = llvm::cast<GoASTSendStmt>(this);
-            (void)n;
-            v(n->m_chan_up.get());
-            v(n->m_value_up.get());
-            return;
-        }
-    case eSliceExpr:
-        {
-            GoASTSliceExpr *n = llvm::cast<GoASTSliceExpr>(this);
-            (void)n;
-            v(n->m_x_up.get());
-            v(n->m_low_up.get());
-            v(n->m_high_up.get());
-            v(n->m_max_up.get());
-            return;
-        }
-    case eStarExpr:
-        {
-            GoASTStarExpr *n = llvm::cast<GoASTStarExpr>(this);
-            (void)n;
-            v(n->m_x_up.get());
-            return;
-        }
-    case eStructType:
-        {
-            GoASTStructType *n = llvm::cast<GoASTStructType>(this);
-            (void)n;
-            v(n->m_fields_up.get());
-            return;
-        }
-    case eSwitchStmt:
-        {
-            GoASTSwitchStmt *n = llvm::cast<GoASTSwitchStmt>(this);
-            (void)n;
-            v(n->m_init_up.get());
-            v(n->m_tag_up.get());
-            v(n->m_body_up.get());
-            return;
-        }
-    case eTypeAssertExpr:
-        {
-            GoASTTypeAssertExpr *n = llvm::cast<GoASTTypeAssertExpr>(this);
-            (void)n;
-            v(n->m_x_up.get());
-            v(n->m_type_up.get());
-            return;
-        }
-    case eTypeSpec:
-        {
-            GoASTTypeSpec *n = llvm::cast<GoASTTypeSpec>(this);
-            (void)n;
-            v(n->m_name_up.get());
-            v(n->m_type_up.get());
-            return;
-        }
-    case eTypeSwitchStmt:
-        {
-            GoASTTypeSwitchStmt *n = llvm::cast<GoASTTypeSwitchStmt>(this);
-            (void)n;
-            v(n->m_init_up.get());
-            v(n->m_assign_up.get());
-            v(n->m_body_up.get());
-            return;
-        }
-    case eUnaryExpr:
-        {
-            GoASTUnaryExpr *n = llvm::cast<GoASTUnaryExpr>(this);
-            (void)n;
-            v(n->m_x_up.get());
-            return;
-        }
-    case eValueSpec:
-        {
-            GoASTValueSpec *n = llvm::cast<GoASTValueSpec>(this);
-            (void)n;
-            for (auto& e : n->m_names) { v(e.get()); }
-            v(n->m_type_up.get());
-            for (auto& e : n->m_values) { v(e.get()); }
-            return;
-        }
-
-        case eEmptyStmt:
-        case eBadDecl:
-        case eBadExpr:
-        case eBadStmt:
-          break;
-    }
+template <typename V> void GoASTNode::WalkChildren(V &v) {
+  switch (m_kind) {
+
+  case eArrayType: {
+    GoASTArrayType *n = llvm::cast<GoASTArrayType>(this);
+    (void)n;
+    v(n->m_len_up.get());
+    v(n->m_elt_up.get());
+    return;
+  }
+  case eAssignStmt: {
+    GoASTAssignStmt *n = llvm::cast<GoASTAssignStmt>(this);
+    (void)n;
+    for (auto &e : n->m_lhs) {
+      v(e.get());
+    }
+    for (auto &e : n->m_rhs) {
+      v(e.get());
+    }
+    return;
+  }
+  case eBasicLit: {
+    GoASTBasicLit *n = llvm::cast<GoASTBasicLit>(this);
+    (void)n;
+    return;
+  }
+  case eBinaryExpr: {
+    GoASTBinaryExpr *n = llvm::cast<GoASTBinaryExpr>(this);
+    (void)n;
+    v(n->m_x_up.get());
+    v(n->m_y_up.get());
+    return;
+  }
+  case eBlockStmt: {
+    GoASTBlockStmt *n = llvm::cast<GoASTBlockStmt>(this);
+    (void)n;
+    for (auto &e : n->m_list) {
+      v(e.get());
+    }
+    return;
+  }
+  case eIdent: {
+    GoASTIdent *n = llvm::cast<GoASTIdent>(this);
+    (void)n;
+    return;
+  }
+  case eBranchStmt: {
+    GoASTBranchStmt *n = llvm::cast<GoASTBranchStmt>(this);
+    (void)n;
+    v(n->m_label_up.get());
+    return;
+  }
+  case eCallExpr: {
+    GoASTCallExpr *n = llvm::cast<GoASTCallExpr>(this);
+    (void)n;
+    v(n->m_fun_up.get());
+    for (auto &e : n->m_args) {
+      v(e.get());
+    }
+    return;
+  }
+  case eCaseClause: {
+    GoASTCaseClause *n = llvm::cast<GoASTCaseClause>(this);
+    (void)n;
+    for (auto &e : n->m_list) {
+      v(e.get());
+    }
+    for (auto &e : n->m_body) {
+      v(e.get());
+    }
+    return;
+  }
+  case eChanType: {
+    GoASTChanType *n = llvm::cast<GoASTChanType>(this);
+    (void)n;
+    v(n->m_value_up.get());
+    return;
+  }
+  case eCommClause: {
+    GoASTCommClause *n = llvm::cast<GoASTCommClause>(this);
+    (void)n;
+    v(n->m_comm_up.get());
+    for (auto &e : n->m_body) {
+      v(e.get());
+    }
+    return;
+  }
+  case eCompositeLit: {
+    GoASTCompositeLit *n = llvm::cast<GoASTCompositeLit>(this);
+    (void)n;
+    v(n->m_type_up.get());
+    for (auto &e : n->m_elts) {
+      v(e.get());
+    }
+    return;
+  }
+  case eDeclStmt: {
+    GoASTDeclStmt *n = llvm::cast<GoASTDeclStmt>(this);
+    (void)n;
+    v(n->m_decl_up.get());
+    return;
+  }
+  case eDeferStmt: {
+    GoASTDeferStmt *n = llvm::cast<GoASTDeferStmt>(this);
+    (void)n;
+    v(n->m_call_up.get());
+    return;
+  }
+  case eEllipsis: {
+    GoASTEllipsis *n = llvm::cast<GoASTEllipsis>(this);
+    (void)n;
+    v(n->m_elt_up.get());
+    return;
+  }
+  case eExprStmt: {
+    GoASTExprStmt *n = llvm::cast<GoASTExprStmt>(this);
+    (void)n;
+    v(n->m_x_up.get());
+    return;
+  }
+  case eField: {
+    GoASTField *n = llvm::cast<GoASTField>(this);
+    (void)n;
+    for (auto &e : n->m_names) {
+      v(e.get());
+    }
+    v(n->m_type_up.get());
+    v(n->m_tag_up.get());
+    return;
+  }
+  case eFieldList: {
+    GoASTFieldList *n = llvm::cast<GoASTFieldList>(this);
+    (void)n;
+    for (auto &e : n->m_list) {
+      v(e.get());
+    }
+    return;
+  }
+  case eForStmt: {
+    GoASTForStmt *n = llvm::cast<GoASTForStmt>(this);
+    (void)n;
+    v(n->m_init_up.get());
+    v(n->m_cond_up.get());
+    v(n->m_post_up.get());
+    v(n->m_body_up.get());
+    return;
+  }
+  case eFuncType: {
+    GoASTFuncType *n = llvm::cast<GoASTFuncType>(this);
+    (void)n;
+    v(n->m_params_up.get());
+    v(n->m_results_up.get());
+    return;
+  }
+  case eFuncDecl: {
+    GoASTFuncDecl *n = llvm::cast<GoASTFuncDecl>(this);
+    (void)n;
+    v(n->m_recv_up.get());
+    v(n->m_name_up.get());
+    v(n->m_type_up.get());
+    v(n->m_body_up.get());
+    return;
+  }
+  case eFuncLit: {
+    GoASTFuncLit *n = llvm::cast<GoASTFuncLit>(this);
+    (void)n;
+    v(n->m_type_up.get());
+    v(n->m_body_up.get());
+    return;
+  }
+  case eGenDecl: {
+    GoASTGenDecl *n = llvm::cast<GoASTGenDecl>(this);
+    (void)n;
+    for (auto &e : n->m_specs) {
+      v(e.get());
+    }
+    return;
+  }
+  case eGoStmt: {
+    GoASTGoStmt *n = llvm::cast<GoASTGoStmt>(this);
+    (void)n;
+    v(n->m_call_up.get());
+    return;
+  }
+  case eIfStmt: {
+    GoASTIfStmt *n = llvm::cast<GoASTIfStmt>(this);
+    (void)n;
+    v(n->m_init_up.get());
+    v(n->m_cond_up.get());
+    v(n->m_body_up.get());
+    v(n->m_els_up.get());
+    return;
+  }
+  case eImportSpec: {
+    GoASTImportSpec *n = llvm::cast<GoASTImportSpec>(this);
+    (void)n;
+    v(n->m_name_up.get());
+    v(n->m_path_up.get());
+    return;
+  }
+  case eIncDecStmt: {
+    GoASTIncDecStmt *n = llvm::cast<GoASTIncDecStmt>(this);
+    (void)n;
+    v(n->m_x_up.get());
+    return;
+  }
+  case eIndexExpr: {
+    GoASTIndexExpr *n = llvm::cast<GoASTIndexExpr>(this);
+    (void)n;
+    v(n->m_x_up.get());
+    v(n->m_index_up.get());
+    return;
+  }
+  case eInterfaceType: {
+    GoASTInterfaceType *n = llvm::cast<GoASTInterfaceType>(this);
+    (void)n;
+    v(n->m_methods_up.get());
+    return;
+  }
+  case eKeyValueExpr: {
+    GoASTKeyValueExpr *n = llvm::cast<GoASTKeyValueExpr>(this);
+    (void)n;
+    v(n->m_key_up.get());
+    v(n->m_value_up.get());
+    return;
+  }
+  case eLabeledStmt: {
+    GoASTLabeledStmt *n = llvm::cast<GoASTLabeledStmt>(this);
+    (void)n;
+    v(n->m_label_up.get());
+    v(n->m_stmt_up.get());
+    return;
+  }
+  case eMapType: {
+    GoASTMapType *n = llvm::cast<GoASTMapType>(this);
+    (void)n;
+    v(n->m_key_up.get());
+    v(n->m_value_up.get());
+    return;
+  }
+  case eParenExpr: {
+    GoASTParenExpr *n = llvm::cast<GoASTParenExpr>(this);
+    (void)n;
+    v(n->m_x_up.get());
+    return;
+  }
+  case eRangeStmt: {
+    GoASTRangeStmt *n = llvm::cast<GoASTRangeStmt>(this);
+    (void)n;
+    v(n->m_key_up.get());
+    v(n->m_value_up.get());
+    v(n->m_x_up.get());
+    v(n->m_body_up.get());
+    return;
+  }
+  case eReturnStmt: {
+    GoASTReturnStmt *n = llvm::cast<GoASTReturnStmt>(this);
+    (void)n;
+    for (auto &e : n->m_results) {
+      v(e.get());
+    }
+    return;
+  }
+  case eSelectStmt: {
+    GoASTSelectStmt *n = llvm::cast<GoASTSelectStmt>(this);
+    (void)n;
+    v(n->m_body_up.get());
+    return;
+  }
+  case eSelectorExpr: {
+    GoASTSelectorExpr *n = llvm::cast<GoASTSelectorExpr>(this);
+    (void)n;
+    v(n->m_x_up.get());
+    v(n->m_sel_up.get());
+    return;
+  }
+  case eSendStmt: {
+    GoASTSendStmt *n = llvm::cast<GoASTSendStmt>(this);
+    (void)n;
+    v(n->m_chan_up.get());
+    v(n->m_value_up.get());
+    return;
+  }
+  case eSliceExpr: {
+    GoASTSliceExpr *n = llvm::cast<GoASTSliceExpr>(this);
+    (void)n;
+    v(n->m_x_up.get());
+    v(n->m_low_up.get());
+    v(n->m_high_up.get());
+    v(n->m_max_up.get());
+    return;
+  }
+  case eStarExpr: {
+    GoASTStarExpr *n = llvm::cast<GoASTStarExpr>(this);
+    (void)n;
+    v(n->m_x_up.get());
+    return;
+  }
+  case eStructType: {
+    GoASTStructType *n = llvm::cast<GoASTStructType>(this);
+    (void)n;
+    v(n->m_fields_up.get());
+    return;
+  }
+  case eSwitchStmt: {
+    GoASTSwitchStmt *n = llvm::cast<GoASTSwitchStmt>(this);
+    (void)n;
+    v(n->m_init_up.get());
+    v(n->m_tag_up.get());
+    v(n->m_body_up.get());
+    return;
+  }
+  case eTypeAssertExpr: {
+    GoASTTypeAssertExpr *n = llvm::cast<GoASTTypeAssertExpr>(this);
+    (void)n;
+    v(n->m_x_up.get());
+    v(n->m_type_up.get());
+    return;
+  }
+  case eTypeSpec: {
+    GoASTTypeSpec *n = llvm::cast<GoASTTypeSpec>(this);
+    (void)n;
+    v(n->m_name_up.get());
+    v(n->m_type_up.get());
+    return;
+  }
+  case eTypeSwitchStmt: {
+    GoASTTypeSwitchStmt *n = llvm::cast<GoASTTypeSwitchStmt>(this);
+    (void)n;
+    v(n->m_init_up.get());
+    v(n->m_assign_up.get());
+    v(n->m_body_up.get());
+    return;
+  }
+  case eUnaryExpr: {
+    GoASTUnaryExpr *n = llvm::cast<GoASTUnaryExpr>(this);
+    (void)n;
+    v(n->m_x_up.get());
+    return;
+  }
+  case eValueSpec: {
+    GoASTValueSpec *n = llvm::cast<GoASTValueSpec>(this);
+    (void)n;
+    for (auto &e : n->m_names) {
+      v(e.get());
+    }
+    v(n->m_type_up.get());
+    for (auto &e : n->m_values) {
+      v(e.get());
+    }
+    return;
+  }
+
+  case eEmptyStmt:
+  case eBadDecl:
+  case eBadExpr:
+  case eBadStmt:
+    break;
+  }
 }
 
-}  // namespace lldb_private
+} // namespace lldb_private
 
 #endif
-

Modified: lldb/trunk/source/Plugins/ExpressionParser/Go/GoLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Go/GoLexer.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Go/GoLexer.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Go/GoLexer.cpp Tue Sep  6 15:57:50 2016
@@ -15,388 +15,336 @@ using namespace lldb_private;
 
 llvm::StringMap<GoLexer::TokenType> *GoLexer::m_keywords;
 
-GoLexer::GoLexer(const char *src) : m_src(src), m_end(src + strlen(src)), m_last_token(TOK_INVALID, "")
-{
-}
-
-bool
-GoLexer::SkipWhitespace()
-{
-    bool saw_newline = false;
-    for (; m_src < m_end; ++m_src)
-    {
-        if (*m_src == '\n')
-            saw_newline = true;
-        if (*m_src == '/' && !SkipComment())
-            return saw_newline;
-        else if (!IsWhitespace(*m_src))
-            return saw_newline;
-    }
-    return saw_newline;
-}
+GoLexer::GoLexer(const char *src)
+    : m_src(src), m_end(src + strlen(src)), m_last_token(TOK_INVALID, "") {}
 
-bool
-GoLexer::SkipComment()
-{
-    if (m_src[0] == '/' && m_src[1] == '/')
-    {
-        for (const char *c = m_src + 2; c < m_end; ++c)
-        {
-            if (*c == '\n')
-            {
-                m_src = c - 1;
-                return true;
-            }
-        }
+bool GoLexer::SkipWhitespace() {
+  bool saw_newline = false;
+  for (; m_src < m_end; ++m_src) {
+    if (*m_src == '\n')
+      saw_newline = true;
+    if (*m_src == '/' && !SkipComment())
+      return saw_newline;
+    else if (!IsWhitespace(*m_src))
+      return saw_newline;
+  }
+  return saw_newline;
+}
+
+bool GoLexer::SkipComment() {
+  if (m_src[0] == '/' && m_src[1] == '/') {
+    for (const char *c = m_src + 2; c < m_end; ++c) {
+      if (*c == '\n') {
+        m_src = c - 1;
         return true;
+      }
     }
-    else if (m_src[0] == '/' && m_src[1] == '*')
-    {
-        for (const char *c = m_src + 2; c < m_end; ++c)
-        {
-            if (c[0] == '*' && c[1] == '/')
-            {
-                m_src = c + 1;
-                return true;
-            }
-        }
+    return true;
+  } else if (m_src[0] == '/' && m_src[1] == '*') {
+    for (const char *c = m_src + 2; c < m_end; ++c) {
+      if (c[0] == '*' && c[1] == '/') {
+        m_src = c + 1;
+        return true;
+      }
     }
-    return false;
+  }
+  return false;
 }
 
-const GoLexer::Token &
-GoLexer::Lex()
-{
-    bool newline = SkipWhitespace();
-    const char *start = m_src;
-    m_last_token.m_type = InternalLex(newline);
-    m_last_token.m_value = llvm::StringRef(start, m_src - start);
-    return m_last_token;
-}
-
-GoLexer::TokenType
-GoLexer::InternalLex(bool newline)
-{
-    if (m_src >= m_end)
-    {
-        return TOK_EOF;
-    }
-    if (newline)
-    {
-        switch (m_last_token.m_type)
-        {
-            case TOK_IDENTIFIER:
-            case LIT_FLOAT:
-            case LIT_IMAGINARY:
-            case LIT_INTEGER:
-            case LIT_RUNE:
-            case LIT_STRING:
-            case KEYWORD_BREAK:
-            case KEYWORD_CONTINUE:
-            case KEYWORD_FALLTHROUGH:
-            case KEYWORD_RETURN:
-            case OP_PLUS_PLUS:
-            case OP_MINUS_MINUS:
-            case OP_RPAREN:
-            case OP_RBRACK:
-            case OP_RBRACE:
-                return OP_SEMICOLON;
-            default:
-                break;
-        }
-    }
-    char c = *m_src;
-    switch (c)
-    {
-        case '0':
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9':
-            return DoNumber();
-        case '+':
-        case '-':
-        case '*':
-        case '/':
-        case '%':
-        case '&':
-        case '|':
-        case '^':
-        case '<':
-        case '>':
-        case '!':
-        case ':':
-        case ';':
-        case '(':
-        case ')':
-        case '[':
-        case ']':
-        case '{':
-        case '}':
-        case ',':
-        case '=':
-            return DoOperator();
-        case '.':
-            if (IsDecimal(m_src[1]))
-                return DoNumber();
-            return DoOperator();
-        case '$':
-            // For lldb persistent vars.
-            return DoIdent();
-        case '"':
-        case '`':
-            return DoString();
-        case '\'':
-            return DoRune();
-        default:
-            break;
-    }
-    if (IsLetterOrDigit(c))
-        return DoIdent();
+const GoLexer::Token &GoLexer::Lex() {
+  bool newline = SkipWhitespace();
+  const char *start = m_src;
+  m_last_token.m_type = InternalLex(newline);
+  m_last_token.m_value = llvm::StringRef(start, m_src - start);
+  return m_last_token;
+}
+
+GoLexer::TokenType GoLexer::InternalLex(bool newline) {
+  if (m_src >= m_end) {
+    return TOK_EOF;
+  }
+  if (newline) {
+    switch (m_last_token.m_type) {
+    case TOK_IDENTIFIER:
+    case LIT_FLOAT:
+    case LIT_IMAGINARY:
+    case LIT_INTEGER:
+    case LIT_RUNE:
+    case LIT_STRING:
+    case KEYWORD_BREAK:
+    case KEYWORD_CONTINUE:
+    case KEYWORD_FALLTHROUGH:
+    case KEYWORD_RETURN:
+    case OP_PLUS_PLUS:
+    case OP_MINUS_MINUS:
+    case OP_RPAREN:
+    case OP_RBRACK:
+    case OP_RBRACE:
+      return OP_SEMICOLON;
+    default:
+      break;
+    }
+  }
+  char c = *m_src;
+  switch (c) {
+  case '0':
+  case '1':
+  case '2':
+  case '3':
+  case '4':
+  case '5':
+  case '6':
+  case '7':
+  case '8':
+  case '9':
+    return DoNumber();
+  case '+':
+  case '-':
+  case '*':
+  case '/':
+  case '%':
+  case '&':
+  case '|':
+  case '^':
+  case '<':
+  case '>':
+  case '!':
+  case ':':
+  case ';':
+  case '(':
+  case ')':
+  case '[':
+  case ']':
+  case '{':
+  case '}':
+  case ',':
+  case '=':
+    return DoOperator();
+  case '.':
+    if (IsDecimal(m_src[1]))
+      return DoNumber();
+    return DoOperator();
+  case '$':
+    // For lldb persistent vars.
+    return DoIdent();
+  case '"':
+  case '`':
+    return DoString();
+  case '\'':
+    return DoRune();
+  default:
+    break;
+  }
+  if (IsLetterOrDigit(c))
+    return DoIdent();
+  ++m_src;
+  return TOK_INVALID;
+}
+
+GoLexer::TokenType GoLexer::DoOperator() {
+  TokenType t = TOK_INVALID;
+  if (m_end - m_src > 2) {
+    t = LookupKeyword(llvm::StringRef(m_src, 3));
+    if (t != TOK_INVALID)
+      m_src += 3;
+  }
+  if (t == TOK_INVALID && m_end - m_src > 1) {
+    t = LookupKeyword(llvm::StringRef(m_src, 2));
+    if (t != TOK_INVALID)
+      m_src += 2;
+  }
+  if (t == TOK_INVALID) {
+    t = LookupKeyword(llvm::StringRef(m_src, 1));
     ++m_src;
-    return TOK_INVALID;
-}
-
-GoLexer::TokenType
-GoLexer::DoOperator()
-{
-    TokenType t = TOK_INVALID;
-    if (m_end - m_src > 2)
-    {
-        t = LookupKeyword(llvm::StringRef(m_src, 3));
-        if (t != TOK_INVALID)
-            m_src += 3;
-    }
-    if (t == TOK_INVALID && m_end - m_src > 1)
-    {
-        t = LookupKeyword(llvm::StringRef(m_src, 2));
-        if (t != TOK_INVALID)
-            m_src += 2;
-    }
-    if (t == TOK_INVALID)
-    {
-        t = LookupKeyword(llvm::StringRef(m_src, 1));
-        ++m_src;
-    }
-    return t;
+  }
+  return t;
 }
 
-GoLexer::TokenType
-GoLexer::DoIdent()
-{
-    const char *start = m_src++;
-    while (m_src < m_end && IsLetterOrDigit(*m_src))
-    {
+GoLexer::TokenType GoLexer::DoIdent() {
+  const char *start = m_src++;
+  while (m_src < m_end && IsLetterOrDigit(*m_src)) {
+    ++m_src;
+  }
+  TokenType kw = LookupKeyword(llvm::StringRef(start, m_src - start));
+  if (kw != TOK_INVALID)
+    return kw;
+  return TOK_IDENTIFIER;
+}
+
+GoLexer::TokenType GoLexer::DoNumber() {
+  if (m_src[0] == '0' && (m_src[1] == 'x' || m_src[1] == 'X')) {
+    m_src += 2;
+    while (IsHexChar(*m_src))
+      ++m_src;
+    return LIT_INTEGER;
+  }
+  bool dot_ok = true;
+  bool e_ok = true;
+  while (true) {
+    while (IsDecimal(*m_src))
+      ++m_src;
+    switch (*m_src) {
+    case 'i':
+      ++m_src;
+      return LIT_IMAGINARY;
+    case '.':
+      if (!dot_ok)
+        return LIT_FLOAT;
+      ++m_src;
+      dot_ok = false;
+      break;
+    case 'e':
+    case 'E':
+      if (!e_ok)
+        return LIT_FLOAT;
+      dot_ok = e_ok = false;
+      ++m_src;
+      if (*m_src == '+' || *m_src == '-')
         ++m_src;
-    }
-    TokenType kw = LookupKeyword(llvm::StringRef(start, m_src - start));
-    if (kw != TOK_INVALID)
-        return kw;
-    return TOK_IDENTIFIER;
-}
-
-GoLexer::TokenType
-GoLexer::DoNumber()
-{
-    if (m_src[0] == '0' && (m_src[1] == 'x' || m_src[1] == 'X'))
-    {
-        m_src += 2;
-        while (IsHexChar(*m_src))
-            ++m_src;
+      break;
+    default:
+      if (dot_ok)
         return LIT_INTEGER;
+      return LIT_FLOAT;
     }
-    bool dot_ok = true;
-    bool e_ok = true;
-    while (true)
-    {
-        while (IsDecimal(*m_src))
-            ++m_src;
-        switch (*m_src)
-        {
-            case 'i':
-                ++m_src;
-                return LIT_IMAGINARY;
-            case '.':
-                if (!dot_ok)
-                    return LIT_FLOAT;
-                ++m_src;
-                dot_ok = false;
-                break;
-            case 'e':
-            case 'E':
-                if (!e_ok)
-                    return LIT_FLOAT;
-                dot_ok = e_ok = false;
-                ++m_src;
-                if (*m_src == '+' || *m_src == '-')
-                    ++m_src;
-                break;
-            default:
-                if (dot_ok)
-                    return LIT_INTEGER;
-                return LIT_FLOAT;
-        }
-    }
+  }
 }
 
-GoLexer::TokenType
-GoLexer::DoRune()
-{
-    while (++m_src < m_end)
-    {
-        switch (*m_src)
-        {
-            case '\'':
-                ++m_src;
-                return LIT_RUNE;
-            case '\n':
-                return TOK_INVALID;
-            case '\\':
-                if (m_src[1] == '\n')
-                    return TOK_INVALID;
-                ++m_src;
-        }
+GoLexer::TokenType GoLexer::DoRune() {
+  while (++m_src < m_end) {
+    switch (*m_src) {
+    case '\'':
+      ++m_src;
+      return LIT_RUNE;
+    case '\n':
+      return TOK_INVALID;
+    case '\\':
+      if (m_src[1] == '\n')
+        return TOK_INVALID;
+      ++m_src;
     }
-    return TOK_INVALID;
+  }
+  return TOK_INVALID;
 }
 
-GoLexer::TokenType
-GoLexer::DoString()
-{
-    if (*m_src == '`')
-    {
-        while (++m_src < m_end)
-        {
-            if (*m_src == '`')
-            {
-                ++m_src;
-                return LIT_STRING;
-            }
-        }
-        return TOK_INVALID;
-    }
-    while (++m_src < m_end)
-    {
-        switch (*m_src)
-        {
-            case '"':
-                ++m_src;
-                return LIT_STRING;
-            case '\n':
-                return TOK_INVALID;
-            case '\\':
-                if (m_src[1] == '\n')
-                    return TOK_INVALID;
-                ++m_src;
-        }
+GoLexer::TokenType GoLexer::DoString() {
+  if (*m_src == '`') {
+    while (++m_src < m_end) {
+      if (*m_src == '`') {
+        ++m_src;
+        return LIT_STRING;
+      }
     }
     return TOK_INVALID;
-}
-
-GoLexer::TokenType
-GoLexer::LookupKeyword(llvm::StringRef id)
-{
-    if (m_keywords == nullptr)
-        m_keywords = InitKeywords();
-    const auto &it = m_keywords->find(id);
-    if (it == m_keywords->end())
+  }
+  while (++m_src < m_end) {
+    switch (*m_src) {
+    case '"':
+      ++m_src;
+      return LIT_STRING;
+    case '\n':
+      return TOK_INVALID;
+    case '\\':
+      if (m_src[1] == '\n')
         return TOK_INVALID;
-    return it->second;
+      ++m_src;
+    }
+  }
+  return TOK_INVALID;
 }
 
-llvm::StringRef
-GoLexer::LookupToken(TokenType t)
-{
-    if (m_keywords == nullptr)
-        m_keywords = InitKeywords();
-    for (const auto &e : *m_keywords)
-    {
-        if (e.getValue() == t)
-            return e.getKey();
-    }
-    return "";
+GoLexer::TokenType GoLexer::LookupKeyword(llvm::StringRef id) {
+  if (m_keywords == nullptr)
+    m_keywords = InitKeywords();
+  const auto &it = m_keywords->find(id);
+  if (it == m_keywords->end())
+    return TOK_INVALID;
+  return it->second;
 }
 
-llvm::StringMap<GoLexer::TokenType> *
-GoLexer::InitKeywords()
-{
-    auto &result = *new llvm::StringMap<TokenType>(128);
-    result["break"] = KEYWORD_BREAK;
-    result["default"] = KEYWORD_DEFAULT;
-    result["func"] = KEYWORD_FUNC;
-    result["interface"] = KEYWORD_INTERFACE;
-    result["select"] = KEYWORD_SELECT;
-    result["case"] = KEYWORD_CASE;
-    result["defer"] = KEYWORD_DEFER;
-    result["go"] = KEYWORD_GO;
-    result["map"] = KEYWORD_MAP;
-    result["struct"] = KEYWORD_STRUCT;
-    result["chan"] = KEYWORD_CHAN;
-    result["else"] = KEYWORD_ELSE;
-    result["goto"] = KEYWORD_GOTO;
-    result["package"] = KEYWORD_PACKAGE;
-    result["switch"] = KEYWORD_SWITCH;
-    result["const"] = KEYWORD_CONST;
-    result["fallthrough"] = KEYWORD_FALLTHROUGH;
-    result["if"] = KEYWORD_IF;
-    result["range"] = KEYWORD_RANGE;
-    result["type"] = KEYWORD_TYPE;
-    result["continue"] = KEYWORD_CONTINUE;
-    result["for"] = KEYWORD_FOR;
-    result["import"] = KEYWORD_IMPORT;
-    result["return"] = KEYWORD_RETURN;
-    result["var"] = KEYWORD_VAR;
-    result["+"] = OP_PLUS;
-    result["-"] = OP_MINUS;
-    result["*"] = OP_STAR;
-    result["/"] = OP_SLASH;
-    result["%"] = OP_PERCENT;
-    result["&"] = OP_AMP;
-    result["|"] = OP_PIPE;
-    result["^"] = OP_CARET;
-    result["<<"] = OP_LSHIFT;
-    result[">>"] = OP_RSHIFT;
-    result["&^"] = OP_AMP_CARET;
-    result["+="] = OP_PLUS_EQ;
-    result["-="] = OP_MINUS_EQ;
-    result["*="] = OP_STAR_EQ;
-    result["/="] = OP_SLASH_EQ;
-    result["%="] = OP_PERCENT_EQ;
-    result["&="] = OP_AMP_EQ;
-    result["|="] = OP_PIPE_EQ;
-    result["^="] = OP_CARET_EQ;
-    result["<<="] = OP_LSHIFT_EQ;
-    result[">>="] = OP_RSHIFT_EQ;
-    result["&^="] = OP_AMP_CARET_EQ;
-    result["&&"] = OP_AMP_AMP;
-    result["||"] = OP_PIPE_PIPE;
-    result["<-"] = OP_LT_MINUS;
-    result["++"] = OP_PLUS_PLUS;
-    result["--"] = OP_MINUS_MINUS;
-    result["=="] = OP_EQ_EQ;
-    result["<"] = OP_LT;
-    result[">"] = OP_GT;
-    result["="] = OP_EQ;
-    result["!"] = OP_BANG;
-    result["!="] = OP_BANG_EQ;
-    result["<="] = OP_LT_EQ;
-    result[">="] = OP_GT_EQ;
-    result[":="] = OP_COLON_EQ;
-    result["..."] = OP_DOTS;
-    result["("] = OP_LPAREN;
-    result["["] = OP_LBRACK;
-    result["{"] = OP_LBRACE;
-    result[","] = OP_COMMA;
-    result["."] = OP_DOT;
-    result[")"] = OP_RPAREN;
-    result["]"] = OP_RBRACK;
-    result["}"] = OP_RBRACE;
-    result[";"] = OP_SEMICOLON;
-    result[":"] = OP_COLON;
-    return &result;
+llvm::StringRef GoLexer::LookupToken(TokenType t) {
+  if (m_keywords == nullptr)
+    m_keywords = InitKeywords();
+  for (const auto &e : *m_keywords) {
+    if (e.getValue() == t)
+      return e.getKey();
+  }
+  return "";
+}
+
+llvm::StringMap<GoLexer::TokenType> *GoLexer::InitKeywords() {
+  auto &result = *new llvm::StringMap<TokenType>(128);
+  result["break"] = KEYWORD_BREAK;
+  result["default"] = KEYWORD_DEFAULT;
+  result["func"] = KEYWORD_FUNC;
+  result["interface"] = KEYWORD_INTERFACE;
+  result["select"] = KEYWORD_SELECT;
+  result["case"] = KEYWORD_CASE;
+  result["defer"] = KEYWORD_DEFER;
+  result["go"] = KEYWORD_GO;
+  result["map"] = KEYWORD_MAP;
+  result["struct"] = KEYWORD_STRUCT;
+  result["chan"] = KEYWORD_CHAN;
+  result["else"] = KEYWORD_ELSE;
+  result["goto"] = KEYWORD_GOTO;
+  result["package"] = KEYWORD_PACKAGE;
+  result["switch"] = KEYWORD_SWITCH;
+  result["const"] = KEYWORD_CONST;
+  result["fallthrough"] = KEYWORD_FALLTHROUGH;
+  result["if"] = KEYWORD_IF;
+  result["range"] = KEYWORD_RANGE;
+  result["type"] = KEYWORD_TYPE;
+  result["continue"] = KEYWORD_CONTINUE;
+  result["for"] = KEYWORD_FOR;
+  result["import"] = KEYWORD_IMPORT;
+  result["return"] = KEYWORD_RETURN;
+  result["var"] = KEYWORD_VAR;
+  result["+"] = OP_PLUS;
+  result["-"] = OP_MINUS;
+  result["*"] = OP_STAR;
+  result["/"] = OP_SLASH;
+  result["%"] = OP_PERCENT;
+  result["&"] = OP_AMP;
+  result["|"] = OP_PIPE;
+  result["^"] = OP_CARET;
+  result["<<"] = OP_LSHIFT;
+  result[">>"] = OP_RSHIFT;
+  result["&^"] = OP_AMP_CARET;
+  result["+="] = OP_PLUS_EQ;
+  result["-="] = OP_MINUS_EQ;
+  result["*="] = OP_STAR_EQ;
+  result["/="] = OP_SLASH_EQ;
+  result["%="] = OP_PERCENT_EQ;
+  result["&="] = OP_AMP_EQ;
+  result["|="] = OP_PIPE_EQ;
+  result["^="] = OP_CARET_EQ;
+  result["<<="] = OP_LSHIFT_EQ;
+  result[">>="] = OP_RSHIFT_EQ;
+  result["&^="] = OP_AMP_CARET_EQ;
+  result["&&"] = OP_AMP_AMP;
+  result["||"] = OP_PIPE_PIPE;
+  result["<-"] = OP_LT_MINUS;
+  result["++"] = OP_PLUS_PLUS;
+  result["--"] = OP_MINUS_MINUS;
+  result["=="] = OP_EQ_EQ;
+  result["<"] = OP_LT;
+  result[">"] = OP_GT;
+  result["="] = OP_EQ;
+  result["!"] = OP_BANG;
+  result["!="] = OP_BANG_EQ;
+  result["<="] = OP_LT_EQ;
+  result[">="] = OP_GT_EQ;
+  result[":="] = OP_COLON_EQ;
+  result["..."] = OP_DOTS;
+  result["("] = OP_LPAREN;
+  result["["] = OP_LBRACK;
+  result["{"] = OP_LBRACE;
+  result[","] = OP_COMMA;
+  result["."] = OP_DOT;
+  result[")"] = OP_RPAREN;
+  result["]"] = OP_RBRACK;
+  result["}"] = OP_RBRACE;
+  result[";"] = OP_SEMICOLON;
+  result[":"] = OP_COLON;
+  return &result;
 }

Modified: lldb/trunk/source/Plugins/ExpressionParser/Go/GoLexer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Go/GoLexer.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Go/GoLexer.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Go/GoLexer.h Tue Sep  6 15:57:50 2016
@@ -10,190 +10,170 @@
 #ifndef liblldb_GoLexer_h
 #define liblldb_GoLexer_h
 
-#include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
 
-namespace lldb_private
-{
-
-class GoLexer
-{
-  public:
-    explicit GoLexer(const char *src);
-
-    enum TokenType
-    {
-        TOK_EOF,
-        TOK_INVALID,
-        TOK_IDENTIFIER,
-        LIT_INTEGER,
-        LIT_FLOAT,
-        LIT_IMAGINARY,
-        LIT_RUNE,
-        LIT_STRING,
-        KEYWORD_BREAK,
-        KEYWORD_DEFAULT,
-        KEYWORD_FUNC,
-        KEYWORD_INTERFACE,
-        KEYWORD_SELECT,
-        KEYWORD_CASE,
-        KEYWORD_DEFER,
-        KEYWORD_GO,
-        KEYWORD_MAP,
-        KEYWORD_STRUCT,
-        KEYWORD_CHAN,
-        KEYWORD_ELSE,
-        KEYWORD_GOTO,
-        KEYWORD_PACKAGE,
-        KEYWORD_SWITCH,
-        KEYWORD_CONST,
-        KEYWORD_FALLTHROUGH,
-        KEYWORD_IF,
-        KEYWORD_RANGE,
-        KEYWORD_TYPE,
-        KEYWORD_CONTINUE,
-        KEYWORD_FOR,
-        KEYWORD_IMPORT,
-        KEYWORD_RETURN,
-        KEYWORD_VAR,
-        OP_PLUS,
-        OP_MINUS,
-        OP_STAR,
-        OP_SLASH,
-        OP_PERCENT,
-        OP_AMP,
-        OP_PIPE,
-        OP_CARET,
-        OP_LSHIFT,
-        OP_RSHIFT,
-        OP_AMP_CARET,
-        OP_PLUS_EQ,
-        OP_MINUS_EQ,
-        OP_STAR_EQ,
-        OP_SLASH_EQ,
-        OP_PERCENT_EQ,
-        OP_AMP_EQ,
-        OP_PIPE_EQ,
-        OP_CARET_EQ,
-        OP_LSHIFT_EQ,
-        OP_RSHIFT_EQ,
-        OP_AMP_CARET_EQ,
-        OP_AMP_AMP,
-        OP_PIPE_PIPE,
-        OP_LT_MINUS,
-        OP_PLUS_PLUS,
-        OP_MINUS_MINUS,
-        OP_EQ_EQ,
-        OP_LT,
-        OP_GT,
-        OP_EQ,
-        OP_BANG,
-        OP_BANG_EQ,
-        OP_LT_EQ,
-        OP_GT_EQ,
-        OP_COLON_EQ,
-        OP_DOTS,
-        OP_LPAREN,
-        OP_LBRACK,
-        OP_LBRACE,
-        OP_COMMA,
-        OP_DOT,
-        OP_RPAREN,
-        OP_RBRACK,
-        OP_RBRACE,
-        OP_SEMICOLON,
-        OP_COLON,
-    };
-
-    struct Token
-    {
-        explicit Token(TokenType t, llvm::StringRef text) : m_type(t), m_value(text) {}
-        TokenType m_type;
-        llvm::StringRef m_value;
-    };
-
-    const Token &Lex();
-
-    size_t
-    BytesRemaining() const
-    {
-        return m_end - m_src;
-    }
-    llvm::StringRef
-    GetString(int len) const
-    {
-        return llvm::StringRef(m_src, len);
-    }
-
-    static TokenType LookupKeyword(llvm::StringRef id);
-    static llvm::StringRef LookupToken(TokenType t);
-
-  private:
-    bool
-    IsDecimal(char c)
-    {
-        return c >= '0' && c <= '9';
-    }
-    bool
-    IsHexChar(char c)
-    {
-        if (c >= '0' && c <= '9')
-            return true;
-        if (c >= 'A' && c <= 'F')
-            return true;
-        if (c >= 'a' && c <= 'f')
-            return true;
-        return false;
-    }
-    bool
-    IsLetterOrDigit(char c)
-    {
-        if (c >= 'a' && c <= 'z')
-            return true;
-        if (c >= 'A' && c <= 'Z')
-            return true;
-        if (c == '_')
-            return true;
-        if (c >= '0' && c <= '9')
-            return true;
-        // Treat all non-ascii chars as letters for simplicity.
-        return 0 != (c & 0x80);
-    }
-    bool
-    IsWhitespace(char c)
-    {
-        switch (c)
-        {
-            case ' ':
-            case '\t':
-            case '\r':
-                return true;
-        }
-        return false;
-    }
-
-    bool SkipWhitespace();
-    bool SkipComment();
-
-    TokenType InternalLex(bool newline);
-
-    TokenType DoOperator();
-
-    TokenType DoIdent();
-
-    TokenType DoNumber();
-
-    TokenType DoRune();
-
-    TokenType DoString();
-
-    static llvm::StringMap<TokenType> *InitKeywords();
-
-    static llvm::StringMap<TokenType> *m_keywords;
+namespace lldb_private {
 
-    const char *m_src;
-    const char *m_end;
-    Token m_last_token;
+class GoLexer {
+public:
+  explicit GoLexer(const char *src);
+
+  enum TokenType {
+    TOK_EOF,
+    TOK_INVALID,
+    TOK_IDENTIFIER,
+    LIT_INTEGER,
+    LIT_FLOAT,
+    LIT_IMAGINARY,
+    LIT_RUNE,
+    LIT_STRING,
+    KEYWORD_BREAK,
+    KEYWORD_DEFAULT,
+    KEYWORD_FUNC,
+    KEYWORD_INTERFACE,
+    KEYWORD_SELECT,
+    KEYWORD_CASE,
+    KEYWORD_DEFER,
+    KEYWORD_GO,
+    KEYWORD_MAP,
+    KEYWORD_STRUCT,
+    KEYWORD_CHAN,
+    KEYWORD_ELSE,
+    KEYWORD_GOTO,
+    KEYWORD_PACKAGE,
+    KEYWORD_SWITCH,
+    KEYWORD_CONST,
+    KEYWORD_FALLTHROUGH,
+    KEYWORD_IF,
+    KEYWORD_RANGE,
+    KEYWORD_TYPE,
+    KEYWORD_CONTINUE,
+    KEYWORD_FOR,
+    KEYWORD_IMPORT,
+    KEYWORD_RETURN,
+    KEYWORD_VAR,
+    OP_PLUS,
+    OP_MINUS,
+    OP_STAR,
+    OP_SLASH,
+    OP_PERCENT,
+    OP_AMP,
+    OP_PIPE,
+    OP_CARET,
+    OP_LSHIFT,
+    OP_RSHIFT,
+    OP_AMP_CARET,
+    OP_PLUS_EQ,
+    OP_MINUS_EQ,
+    OP_STAR_EQ,
+    OP_SLASH_EQ,
+    OP_PERCENT_EQ,
+    OP_AMP_EQ,
+    OP_PIPE_EQ,
+    OP_CARET_EQ,
+    OP_LSHIFT_EQ,
+    OP_RSHIFT_EQ,
+    OP_AMP_CARET_EQ,
+    OP_AMP_AMP,
+    OP_PIPE_PIPE,
+    OP_LT_MINUS,
+    OP_PLUS_PLUS,
+    OP_MINUS_MINUS,
+    OP_EQ_EQ,
+    OP_LT,
+    OP_GT,
+    OP_EQ,
+    OP_BANG,
+    OP_BANG_EQ,
+    OP_LT_EQ,
+    OP_GT_EQ,
+    OP_COLON_EQ,
+    OP_DOTS,
+    OP_LPAREN,
+    OP_LBRACK,
+    OP_LBRACE,
+    OP_COMMA,
+    OP_DOT,
+    OP_RPAREN,
+    OP_RBRACK,
+    OP_RBRACE,
+    OP_SEMICOLON,
+    OP_COLON,
+  };
+
+  struct Token {
+    explicit Token(TokenType t, llvm::StringRef text)
+        : m_type(t), m_value(text) {}
+    TokenType m_type;
+    llvm::StringRef m_value;
+  };
+
+  const Token &Lex();
+
+  size_t BytesRemaining() const { return m_end - m_src; }
+  llvm::StringRef GetString(int len) const {
+    return llvm::StringRef(m_src, len);
+  }
+
+  static TokenType LookupKeyword(llvm::StringRef id);
+  static llvm::StringRef LookupToken(TokenType t);
+
+private:
+  bool IsDecimal(char c) { return c >= '0' && c <= '9'; }
+  bool IsHexChar(char c) {
+    if (c >= '0' && c <= '9')
+      return true;
+    if (c >= 'A' && c <= 'F')
+      return true;
+    if (c >= 'a' && c <= 'f')
+      return true;
+    return false;
+  }
+  bool IsLetterOrDigit(char c) {
+    if (c >= 'a' && c <= 'z')
+      return true;
+    if (c >= 'A' && c <= 'Z')
+      return true;
+    if (c == '_')
+      return true;
+    if (c >= '0' && c <= '9')
+      return true;
+    // Treat all non-ascii chars as letters for simplicity.
+    return 0 != (c & 0x80);
+  }
+  bool IsWhitespace(char c) {
+    switch (c) {
+    case ' ':
+    case '\t':
+    case '\r':
+      return true;
+    }
+    return false;
+  }
+
+  bool SkipWhitespace();
+  bool SkipComment();
+
+  TokenType InternalLex(bool newline);
+
+  TokenType DoOperator();
+
+  TokenType DoIdent();
+
+  TokenType DoNumber();
+
+  TokenType DoRune();
+
+  TokenType DoString();
+
+  static llvm::StringMap<TokenType> *InitKeywords();
+
+  static llvm::StringMap<TokenType> *m_keywords;
+
+  const char *m_src;
+  const char *m_end;
+  Token m_last_token;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/source/Plugins/ExpressionParser/Go/GoParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Go/GoParser.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Go/GoParser.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Go/GoParser.cpp Tue Sep  6 15:57:50 2016
@@ -11,1025 +11,870 @@
 
 #include "GoParser.h"
 
+#include "Plugins/ExpressionParser/Go/GoAST.h"
 #include "lldb/Core/Error.h"
 #include "llvm/ADT/SmallString.h"
-#include "Plugins/ExpressionParser/Go/GoAST.h"
 
 using namespace lldb_private;
 using namespace lldb;
 
-namespace
-{
-llvm::StringRef
-DescribeToken(GoLexer::TokenType t)
-{
-    switch (t)
-    {
-        case GoLexer::TOK_EOF:
-            return "<eof>";
-        case GoLexer::TOK_IDENTIFIER:
-            return "identifier";
-        case GoLexer::LIT_FLOAT:
-            return "float";
-        case GoLexer::LIT_IMAGINARY:
-            return "imaginary";
-        case GoLexer::LIT_INTEGER:
-            return "integer";
-        case GoLexer::LIT_RUNE:
-            return "rune";
-        case GoLexer::LIT_STRING:
-            return "string";
-        default:
-            return GoLexer::LookupToken(t);
-    }
+namespace {
+llvm::StringRef DescribeToken(GoLexer::TokenType t) {
+  switch (t) {
+  case GoLexer::TOK_EOF:
+    return "<eof>";
+  case GoLexer::TOK_IDENTIFIER:
+    return "identifier";
+  case GoLexer::LIT_FLOAT:
+    return "float";
+  case GoLexer::LIT_IMAGINARY:
+    return "imaginary";
+  case GoLexer::LIT_INTEGER:
+    return "integer";
+  case GoLexer::LIT_RUNE:
+    return "rune";
+  case GoLexer::LIT_STRING:
+    return "string";
+  default:
+    return GoLexer::LookupToken(t);
+  }
 }
 } // namespace
 
-class GoParser::Rule
-{
-  public:
-    Rule(llvm::StringRef name, GoParser *p) : m_name(name), m_parser(p), m_pos(p->m_pos) {}
-
-    std::nullptr_t
-    error()
-    {
-        if (!m_parser->m_failed)
-        {
-            // Set m_error in case this is the top level.
-            if (m_parser->m_last_tok == GoLexer::TOK_INVALID)
-                m_parser->m_error = m_parser->m_last;
-            else
-                m_parser->m_error = DescribeToken(m_parser->m_last_tok);
-            // And set m_last in case it isn't.
-            m_parser->m_last = m_name;
-            m_parser->m_last_tok = GoLexer::TOK_INVALID;
-            m_parser->m_pos = m_pos;
-        }
-        return nullptr;
-    }
-
-  private:
-    llvm::StringRef m_name;
-    GoParser *m_parser;
-    size_t m_pos;
+class GoParser::Rule {
+public:
+  Rule(llvm::StringRef name, GoParser *p)
+      : m_name(name), m_parser(p), m_pos(p->m_pos) {}
+
+  std::nullptr_t error() {
+    if (!m_parser->m_failed) {
+      // Set m_error in case this is the top level.
+      if (m_parser->m_last_tok == GoLexer::TOK_INVALID)
+        m_parser->m_error = m_parser->m_last;
+      else
+        m_parser->m_error = DescribeToken(m_parser->m_last_tok);
+      // And set m_last in case it isn't.
+      m_parser->m_last = m_name;
+      m_parser->m_last_tok = GoLexer::TOK_INVALID;
+      m_parser->m_pos = m_pos;
+    }
+    return nullptr;
+  }
+
+private:
+  llvm::StringRef m_name;
+  GoParser *m_parser;
+  size_t m_pos;
 };
 
-GoParser::GoParser(const char *src) : m_lexer(src), m_pos(0), m_failed(false)
-{
-}
+GoParser::GoParser(const char *src) : m_lexer(src), m_pos(0), m_failed(false) {}
 
-GoASTStmt *
-GoParser::Statement()
-{
-    Rule r("Statement", this);
-    GoLexer::TokenType t = peek();
-    GoASTStmt *ret = nullptr;
-    switch (t)
-    {
-        case GoLexer::TOK_EOF:
-        case GoLexer::OP_SEMICOLON:
-        case GoLexer::OP_RPAREN:
-        case GoLexer::OP_RBRACE:
-        case GoLexer::TOK_INVALID:
-            return EmptyStmt();
-        case GoLexer::OP_LBRACE:
-            return Block();
-
-        /*      TODO:
-    case GoLexer::KEYWORD_GO:
-        return GoStmt();
-    case GoLexer::KEYWORD_RETURN:
-        return ReturnStmt();
-    case GoLexer::KEYWORD_BREAK:
-    case GoLexer::KEYWORD_CONTINUE:
-    case GoLexer::KEYWORD_GOTO:
-    case GoLexer::KEYWORD_FALLTHROUGH:
-        return BranchStmt();
-    case GoLexer::KEYWORD_IF:
-        return IfStmt();
-    case GoLexer::KEYWORD_SWITCH:
-        return SwitchStmt();
-    case GoLexer::KEYWORD_SELECT:
-        return SelectStmt();
-    case GoLexer::KEYWORD_FOR:
-        return ForStmt();
-    case GoLexer::KEYWORD_DEFER:
-        return DeferStmt();
-    case GoLexer::KEYWORD_CONST:
-    case GoLexer::KEYWORD_TYPE:
-    case GoLexer::KEYWORD_VAR:
-        return DeclStmt();
-    case GoLexer::TOK_IDENTIFIER:
-        if ((ret = LabeledStmt()) ||
-            (ret = ShortVarDecl()))
-        {
-            return ret;
-        }
+GoASTStmt *GoParser::Statement() {
+  Rule r("Statement", this);
+  GoLexer::TokenType t = peek();
+  GoASTStmt *ret = nullptr;
+  switch (t) {
+  case GoLexer::TOK_EOF:
+  case GoLexer::OP_SEMICOLON:
+  case GoLexer::OP_RPAREN:
+  case GoLexer::OP_RBRACE:
+  case GoLexer::TOK_INVALID:
+    return EmptyStmt();
+  case GoLexer::OP_LBRACE:
+    return Block();
+
+  /*      TODO:
+case GoLexer::KEYWORD_GO:
+  return GoStmt();
+case GoLexer::KEYWORD_RETURN:
+  return ReturnStmt();
+case GoLexer::KEYWORD_BREAK:
+case GoLexer::KEYWORD_CONTINUE:
+case GoLexer::KEYWORD_GOTO:
+case GoLexer::KEYWORD_FALLTHROUGH:
+  return BranchStmt();
+case GoLexer::KEYWORD_IF:
+  return IfStmt();
+case GoLexer::KEYWORD_SWITCH:
+  return SwitchStmt();
+case GoLexer::KEYWORD_SELECT:
+  return SelectStmt();
+case GoLexer::KEYWORD_FOR:
+  return ForStmt();
+case GoLexer::KEYWORD_DEFER:
+  return DeferStmt();
+case GoLexer::KEYWORD_CONST:
+case GoLexer::KEYWORD_TYPE:
+case GoLexer::KEYWORD_VAR:
+  return DeclStmt();
+case GoLexer::TOK_IDENTIFIER:
+  if ((ret = LabeledStmt()) ||
+      (ret = ShortVarDecl()))
+  {
+      return ret;
+  }
 */
-        default:
-            break;
-    }
-    GoASTExpr *expr = Expression();
-    if (expr == nullptr)
-        return r.error();
-    if (/*(ret = SendStmt(expr)) ||*/
-        (ret = IncDecStmt(expr)) || (ret = Assignment(expr)) || (ret = ExpressionStmt(expr)))
-    {
-        return ret;
-    }
-    delete expr;
+  default:
+    break;
+  }
+  GoASTExpr *expr = Expression();
+  if (expr == nullptr)
     return r.error();
-}
-
-GoASTStmt *
-GoParser::ExpressionStmt(GoASTExpr *e)
-{
-    if (Semicolon())
-        return new GoASTExprStmt(e);
-    return nullptr;
-}
-
-GoASTStmt *
-GoParser::IncDecStmt(GoASTExpr *e)
-{
-    Rule r("IncDecStmt", this);
-    if (match(GoLexer::OP_PLUS_PLUS))
-        return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_PLUS_PLUS) : r.error();
-    if (match(GoLexer::OP_MINUS_MINUS))
-        return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_MINUS_MINUS) : r.error();
-    return nullptr;
-}
-
-GoASTStmt *
-GoParser::Assignment(lldb_private::GoASTExpr *e)
-{
-    Rule r("Assignment", this);
-    std::vector<std::unique_ptr<GoASTExpr>> lhs;
-    for (GoASTExpr *l = MoreExpressionList(); l; l = MoreExpressionList())
-        lhs.push_back(std::unique_ptr<GoASTExpr>(l));
-    switch (peek())
-    {
-        case GoLexer::OP_EQ:
-        case GoLexer::OP_PLUS_EQ:
-        case GoLexer::OP_MINUS_EQ:
-        case GoLexer::OP_PIPE_EQ:
-        case GoLexer::OP_CARET_EQ:
-        case GoLexer::OP_STAR_EQ:
-        case GoLexer::OP_SLASH_EQ:
-        case GoLexer::OP_PERCENT_EQ:
-        case GoLexer::OP_LSHIFT_EQ:
-        case GoLexer::OP_RSHIFT_EQ:
-        case GoLexer::OP_AMP_EQ:
-        case GoLexer::OP_AMP_CARET_EQ:
-            break;
-        default:
-            return r.error();
+  if (/*(ret = SendStmt(expr)) ||*/
+      (ret = IncDecStmt(expr)) || (ret = Assignment(expr)) ||
+      (ret = ExpressionStmt(expr))) {
+    return ret;
+  }
+  delete expr;
+  return r.error();
+}
+
+GoASTStmt *GoParser::ExpressionStmt(GoASTExpr *e) {
+  if (Semicolon())
+    return new GoASTExprStmt(e);
+  return nullptr;
+}
+
+GoASTStmt *GoParser::IncDecStmt(GoASTExpr *e) {
+  Rule r("IncDecStmt", this);
+  if (match(GoLexer::OP_PLUS_PLUS))
+    return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_PLUS_PLUS)
+                       : r.error();
+  if (match(GoLexer::OP_MINUS_MINUS))
+    return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_MINUS_MINUS)
+                       : r.error();
+  return nullptr;
+}
+
+GoASTStmt *GoParser::Assignment(lldb_private::GoASTExpr *e) {
+  Rule r("Assignment", this);
+  std::vector<std::unique_ptr<GoASTExpr>> lhs;
+  for (GoASTExpr *l = MoreExpressionList(); l; l = MoreExpressionList())
+    lhs.push_back(std::unique_ptr<GoASTExpr>(l));
+  switch (peek()) {
+  case GoLexer::OP_EQ:
+  case GoLexer::OP_PLUS_EQ:
+  case GoLexer::OP_MINUS_EQ:
+  case GoLexer::OP_PIPE_EQ:
+  case GoLexer::OP_CARET_EQ:
+  case GoLexer::OP_STAR_EQ:
+  case GoLexer::OP_SLASH_EQ:
+  case GoLexer::OP_PERCENT_EQ:
+  case GoLexer::OP_LSHIFT_EQ:
+  case GoLexer::OP_RSHIFT_EQ:
+  case GoLexer::OP_AMP_EQ:
+  case GoLexer::OP_AMP_CARET_EQ:
+    break;
+  default:
+    return r.error();
+  }
+  // We don't want to own e until we know this is an assignment.
+  std::unique_ptr<GoASTAssignStmt> stmt(new GoASTAssignStmt(false));
+  stmt->AddLhs(e);
+  for (auto &l : lhs)
+    stmt->AddLhs(l.release());
+  for (GoASTExpr *r = Expression(); r; r = MoreExpressionList())
+    stmt->AddRhs(r);
+  if (!Semicolon() || stmt->NumRhs() == 0)
+    return new GoASTBadStmt;
+  return stmt.release();
+}
+
+GoASTStmt *GoParser::EmptyStmt() {
+  if (match(GoLexer::TOK_EOF))
+    return nullptr;
+  if (Semicolon())
+    return new GoASTEmptyStmt;
+  return nullptr;
+}
+
+GoASTStmt *GoParser::GoStmt() {
+  if (match(GoLexer::KEYWORD_GO)) {
+    if (GoASTCallExpr *e =
+            llvm::dyn_cast_or_null<GoASTCallExpr>(Expression())) {
+      return FinishStmt(new GoASTGoStmt(e));
+    }
+    m_last = "call expression";
+    m_failed = true;
+    return new GoASTBadStmt();
+  }
+  return nullptr;
+}
+
+GoASTStmt *GoParser::ReturnStmt() {
+  if (match(GoLexer::KEYWORD_RETURN)) {
+    std::unique_ptr<GoASTReturnStmt> r(new GoASTReturnStmt());
+    for (GoASTExpr *e = Expression(); e; e = MoreExpressionList())
+      r->AddResults(e);
+    return FinishStmt(r.release());
+  }
+  return nullptr;
+}
+
+GoASTStmt *GoParser::BranchStmt() {
+  GoLexer::Token *tok;
+  if ((tok = match(GoLexer::KEYWORD_BREAK)) ||
+      (tok = match(GoLexer::KEYWORD_CONTINUE)) ||
+      (tok = match(GoLexer::KEYWORD_GOTO))) {
+    auto *e = Identifier();
+    if (tok->m_type == GoLexer::KEYWORD_GOTO && !e)
+      return syntaxerror();
+    return FinishStmt(new GoASTBranchStmt(e, tok->m_type));
+  }
+  if ((tok = match(GoLexer::KEYWORD_FALLTHROUGH)))
+    return FinishStmt(new GoASTBranchStmt(nullptr, tok->m_type));
+
+  return nullptr;
+}
+
+GoASTIdent *GoParser::Identifier() {
+  if (auto *tok = match(GoLexer::TOK_IDENTIFIER))
+    return new GoASTIdent(*tok);
+  return nullptr;
+}
+
+GoASTExpr *GoParser::MoreExpressionList() {
+  if (match(GoLexer::OP_COMMA)) {
+    auto *e = Expression();
+    if (!e)
+      return syntaxerror();
+    return e;
+  }
+  return nullptr;
+}
+
+GoASTIdent *GoParser::MoreIdentifierList() {
+  if (match(GoLexer::OP_COMMA)) {
+    auto *i = Identifier();
+    if (!i)
+      return syntaxerror();
+    return i;
+  }
+  return nullptr;
+}
+
+GoASTExpr *GoParser::Expression() {
+  Rule r("Expression", this);
+  if (GoASTExpr *ret = OrExpr())
+    return ret;
+  return r.error();
+}
+
+GoASTExpr *GoParser::UnaryExpr() {
+  switch (peek()) {
+  case GoLexer::OP_PLUS:
+  case GoLexer::OP_MINUS:
+  case GoLexer::OP_BANG:
+  case GoLexer::OP_CARET:
+  case GoLexer::OP_STAR:
+  case GoLexer::OP_AMP:
+  case GoLexer::OP_LT_MINUS: {
+    const GoLexer::Token t = next();
+    if (GoASTExpr *e = UnaryExpr()) {
+      if (t.m_type == GoLexer::OP_STAR)
+        return new GoASTStarExpr(e);
+      else
+        return new GoASTUnaryExpr(t.m_type, e);
     }
-    // We don't want to own e until we know this is an assignment.
-    std::unique_ptr<GoASTAssignStmt> stmt(new GoASTAssignStmt(false));
-    stmt->AddLhs(e);
-    for (auto &l : lhs)
-        stmt->AddLhs(l.release());
-    for (GoASTExpr *r = Expression(); r; r = MoreExpressionList())
-        stmt->AddRhs(r);
-    if (!Semicolon() || stmt->NumRhs() == 0)
-        return new GoASTBadStmt;
-    return stmt.release();
-}
-
-GoASTStmt *
-GoParser::EmptyStmt()
-{
-    if (match(GoLexer::TOK_EOF))
-        return nullptr;
-    if (Semicolon())
-        return new GoASTEmptyStmt;
-    return nullptr;
+    return syntaxerror();
+  }
+  default:
+    return PrimaryExpr();
+  }
 }
 
-GoASTStmt *
-GoParser::GoStmt()
-{
-    if (match(GoLexer::KEYWORD_GO))
-    {
-        if (GoASTCallExpr *e = llvm::dyn_cast_or_null<GoASTCallExpr>(Expression()))
-        {
-            return FinishStmt(new GoASTGoStmt(e));
-        }
-        m_last = "call expression";
-        m_failed = true;
-        return new GoASTBadStmt();
+GoASTExpr *GoParser::OrExpr() {
+  std::unique_ptr<GoASTExpr> l(AndExpr());
+  if (l) {
+    while (match(GoLexer::OP_PIPE_PIPE)) {
+      GoASTExpr *r = AndExpr();
+      if (r)
+        l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_PIPE_PIPE));
+      else
+        return syntaxerror();
     }
-    return nullptr;
+    return l.release();
+  }
+  return nullptr;
 }
 
-GoASTStmt *
-GoParser::ReturnStmt()
-{
-    if (match(GoLexer::KEYWORD_RETURN))
-    {
-        std::unique_ptr<GoASTReturnStmt> r(new GoASTReturnStmt());
-        for (GoASTExpr *e = Expression(); e; e = MoreExpressionList())
-            r->AddResults(e);
-        return FinishStmt(r.release());
+GoASTExpr *GoParser::AndExpr() {
+  std::unique_ptr<GoASTExpr> l(RelExpr());
+  if (l) {
+    while (match(GoLexer::OP_AMP_AMP)) {
+      GoASTExpr *r = RelExpr();
+      if (r)
+        l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_AMP_AMP));
+      else
+        return syntaxerror();
     }
-    return nullptr;
+    return l.release();
+  }
+  return nullptr;
 }
 
-GoASTStmt *
-GoParser::BranchStmt()
-{
-    GoLexer::Token *tok;
-    if ((tok = match(GoLexer::KEYWORD_BREAK)) || (tok = match(GoLexer::KEYWORD_CONTINUE)) ||
-        (tok = match(GoLexer::KEYWORD_GOTO)))
-    {
-        auto *e = Identifier();
-        if (tok->m_type == GoLexer::KEYWORD_GOTO && !e)
-            return syntaxerror();
-        return FinishStmt(new GoASTBranchStmt(e, tok->m_type));
+GoASTExpr *GoParser::RelExpr() {
+  std::unique_ptr<GoASTExpr> l(AddExpr());
+  if (l) {
+    for (GoLexer::Token *t;
+         (t = match(GoLexer::OP_EQ_EQ)) || (t = match(GoLexer::OP_BANG_EQ)) ||
+         (t = match(GoLexer::OP_LT)) || (t = match(GoLexer::OP_LT_EQ)) ||
+         (t = match(GoLexer::OP_GT)) || (t = match(GoLexer::OP_GT_EQ));) {
+      GoLexer::TokenType op = t->m_type;
+      GoASTExpr *r = AddExpr();
+      if (r)
+        l.reset(new GoASTBinaryExpr(l.release(), r, op));
+      else
+        return syntaxerror();
     }
-    if ((tok = match(GoLexer::KEYWORD_FALLTHROUGH)))
-        return FinishStmt(new GoASTBranchStmt(nullptr, tok->m_type));
-
-    return nullptr;
-}
-
-GoASTIdent *
-GoParser::Identifier()
-{
-    if (auto *tok = match(GoLexer::TOK_IDENTIFIER))
-        return new GoASTIdent(*tok);
-    return nullptr;
+    return l.release();
+  }
+  return nullptr;
 }
 
-GoASTExpr *
-GoParser::MoreExpressionList()
-{
-    if (match(GoLexer::OP_COMMA))
-    {
-        auto *e = Expression();
-        if (!e)
-            return syntaxerror();
-        return e;
+GoASTExpr *GoParser::AddExpr() {
+  std::unique_ptr<GoASTExpr> l(MulExpr());
+  if (l) {
+    for (GoLexer::Token *t;
+         (t = match(GoLexer::OP_PLUS)) || (t = match(GoLexer::OP_MINUS)) ||
+         (t = match(GoLexer::OP_PIPE)) || (t = match(GoLexer::OP_CARET));) {
+      GoLexer::TokenType op = t->m_type;
+      GoASTExpr *r = MulExpr();
+      if (r)
+        l.reset(new GoASTBinaryExpr(l.release(), r, op));
+      else
+        return syntaxerror();
     }
-    return nullptr;
+    return l.release();
+  }
+  return nullptr;
 }
 
-GoASTIdent *
-GoParser::MoreIdentifierList()
-{
-    if (match(GoLexer::OP_COMMA))
-    {
-        auto *i = Identifier();
-        if (!i)
-            return syntaxerror();
-        return i;
+GoASTExpr *GoParser::MulExpr() {
+  std::unique_ptr<GoASTExpr> l(UnaryExpr());
+  if (l) {
+    for (GoLexer::Token *t;
+         (t = match(GoLexer::OP_STAR)) || (t = match(GoLexer::OP_SLASH)) ||
+         (t = match(GoLexer::OP_PERCENT)) || (t = match(GoLexer::OP_LSHIFT)) ||
+         (t = match(GoLexer::OP_RSHIFT)) || (t = match(GoLexer::OP_AMP)) ||
+         (t = match(GoLexer::OP_AMP_CARET));) {
+      GoLexer::TokenType op = t->m_type;
+      GoASTExpr *r = UnaryExpr();
+      if (r)
+        l.reset(new GoASTBinaryExpr(l.release(), r, op));
+      else
+        return syntaxerror();
     }
-    return nullptr;
-}
-
-GoASTExpr *
-GoParser::Expression()
-{
-    Rule r("Expression", this);
-    if (GoASTExpr *ret = OrExpr())
-        return ret;
-    return r.error();
+    return l.release();
+  }
+  return nullptr;
 }
 
-GoASTExpr *
-GoParser::UnaryExpr()
-{
-    switch (peek())
-    {
-        case GoLexer::OP_PLUS:
-        case GoLexer::OP_MINUS:
-        case GoLexer::OP_BANG:
-        case GoLexer::OP_CARET:
-        case GoLexer::OP_STAR:
-        case GoLexer::OP_AMP:
-        case GoLexer::OP_LT_MINUS:
-        {
-            const GoLexer::Token t = next();
-            if (GoASTExpr *e = UnaryExpr())
-            {
-                if (t.m_type == GoLexer::OP_STAR)
-                    return new GoASTStarExpr(e);
-                else
-                    return new GoASTUnaryExpr(t.m_type, e);
-            }
-            return syntaxerror();
-        }
-        default:
-            return PrimaryExpr();
-    }
+GoASTExpr *GoParser::PrimaryExpr() {
+  GoASTExpr *l;
+  GoASTExpr *r;
+  (l = Conversion()) || (l = Operand());
+  if (!l)
+    return nullptr;
+  while ((r = Selector(l)) || (r = IndexOrSlice(l)) || (r = TypeAssertion(l)) ||
+         (r = Arguments(l))) {
+    l = r;
+  }
+  return l;
+}
+
+GoASTExpr *GoParser::Operand() {
+  GoLexer::Token *lit;
+  if ((lit = match(GoLexer::LIT_INTEGER)) ||
+      (lit = match(GoLexer::LIT_FLOAT)) ||
+      (lit = match(GoLexer::LIT_IMAGINARY)) ||
+      (lit = match(GoLexer::LIT_RUNE)) || (lit = match(GoLexer::LIT_STRING)))
+    return new GoASTBasicLit(*lit);
+  if (match(GoLexer::OP_LPAREN)) {
+    GoASTExpr *e;
+    if (!((e = Expression()) && match(GoLexer::OP_RPAREN)))
+      return syntaxerror();
+    return e;
+  }
+  // MethodExpr should be handled by Selector
+  if (GoASTExpr *e = CompositeLit())
+    return e;
+  if (GoASTExpr *n = Name())
+    return n;
+  return FunctionLit();
 }
 
-GoASTExpr *
-GoParser::OrExpr()
-{
-    std::unique_ptr<GoASTExpr> l(AndExpr());
-    if (l)
-    {
-        while (match(GoLexer::OP_PIPE_PIPE))
-        {
-            GoASTExpr *r = AndExpr();
-            if (r)
-                l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_PIPE_PIPE));
-            else
-                return syntaxerror();
-        }
-        return l.release();
-    }
+GoASTExpr *GoParser::FunctionLit() {
+  if (!match(GoLexer::KEYWORD_FUNC))
     return nullptr;
+  auto *sig = Signature();
+  if (!sig)
+    return syntaxerror();
+  auto *body = Block();
+  if (!body) {
+    delete sig;
+    return syntaxerror();
+  }
+  return new GoASTFuncLit(sig, body);
 }
 
-GoASTExpr *
-GoParser::AndExpr()
-{
-    std::unique_ptr<GoASTExpr> l(RelExpr());
-    if (l)
-    {
-        while (match(GoLexer::OP_AMP_AMP))
-        {
-            GoASTExpr *r = RelExpr();
-            if (r)
-                l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_AMP_AMP));
-            else
-                return syntaxerror();
-        }
-        return l.release();
-    }
+GoASTBlockStmt *GoParser::Block() {
+  if (!match(GoLexer::OP_LBRACE))
     return nullptr;
+  std::unique_ptr<GoASTBlockStmt> block(new GoASTBlockStmt);
+  for (auto *s = Statement(); s; s = Statement())
+    block->AddList(s);
+  if (!match(GoLexer::OP_RBRACE))
+    return syntaxerror();
+  return block.release();
 }
 
-GoASTExpr *
-GoParser::RelExpr()
-{
-    std::unique_ptr<GoASTExpr> l(AddExpr());
-    if (l)
-    {
-        for (GoLexer::Token *t; (t = match(GoLexer::OP_EQ_EQ)) || (t = match(GoLexer::OP_BANG_EQ)) ||
-                                (t = match(GoLexer::OP_LT)) || (t = match(GoLexer::OP_LT_EQ)) ||
-                                (t = match(GoLexer::OP_GT)) || (t = match(GoLexer::OP_GT_EQ));)
-        {
-            GoLexer::TokenType op = t->m_type;
-            GoASTExpr *r = AddExpr();
-            if (r)
-                l.reset(new GoASTBinaryExpr(l.release(), r, op));
-            else
-                return syntaxerror();
-        }
-        return l.release();
-    }
-    return nullptr;
+GoASTExpr *GoParser::CompositeLit() {
+  Rule r("CompositeLit", this);
+  GoASTExpr *type;
+  (type = StructType()) || (type = ArrayOrSliceType(true)) ||
+      (type = MapType()) || (type = Name());
+  if (!type)
+    return r.error();
+  GoASTCompositeLit *lit = LiteralValue();
+  if (!lit)
+    return r.error();
+  lit->SetType(type);
+  return lit;
 }
 
-GoASTExpr *
-GoParser::AddExpr()
-{
-    std::unique_ptr<GoASTExpr> l(MulExpr());
-    if (l)
-    {
-        for (GoLexer::Token *t; (t = match(GoLexer::OP_PLUS)) || (t = match(GoLexer::OP_MINUS)) ||
-                                (t = match(GoLexer::OP_PIPE)) || (t = match(GoLexer::OP_CARET));)
-        {
-            GoLexer::TokenType op = t->m_type;
-            GoASTExpr *r = MulExpr();
-            if (r)
-                l.reset(new GoASTBinaryExpr(l.release(), r, op));
-            else
-                return syntaxerror();
-        }
-        return l.release();
-    }
+GoASTCompositeLit *GoParser::LiteralValue() {
+  if (!match(GoLexer::OP_LBRACE))
     return nullptr;
-}
-
-GoASTExpr *
-GoParser::MulExpr()
-{
-    std::unique_ptr<GoASTExpr> l(UnaryExpr());
-    if (l)
-    {
-        for (GoLexer::Token *t; (t = match(GoLexer::OP_STAR)) || (t = match(GoLexer::OP_SLASH)) ||
-                                (t = match(GoLexer::OP_PERCENT)) || (t = match(GoLexer::OP_LSHIFT)) ||
-                                (t = match(GoLexer::OP_RSHIFT)) || (t = match(GoLexer::OP_AMP)) ||
-                                (t = match(GoLexer::OP_AMP_CARET));)
-        {
-            GoLexer::TokenType op = t->m_type;
-            GoASTExpr *r = UnaryExpr();
-            if (r)
-                l.reset(new GoASTBinaryExpr(l.release(), r, op));
-            else
-                return syntaxerror();
-        }
-        return l.release();
+  std::unique_ptr<GoASTCompositeLit> lit(new GoASTCompositeLit);
+  for (GoASTExpr *e = Element(); e; e = Element()) {
+    lit->AddElts(e);
+    if (!match(GoLexer::OP_COMMA))
+      break;
+  }
+  if (!mustMatch(GoLexer::OP_RBRACE))
+    return nullptr;
+  return lit.release();
+}
+
+GoASTExpr *GoParser::Element() {
+  GoASTExpr *key;
+  if (!((key = Expression()) || (key = LiteralValue())))
+    return nullptr;
+  if (!match(GoLexer::OP_COLON))
+    return key;
+  GoASTExpr *value;
+  if ((value = Expression()) || (value = LiteralValue()))
+    return new GoASTKeyValueExpr(key, value);
+  delete key;
+  return syntaxerror();
+}
+
+GoASTExpr *GoParser::Selector(GoASTExpr *e) {
+  Rule r("Selector", this);
+  if (match(GoLexer::OP_DOT)) {
+    if (auto *name = Identifier())
+      return new GoASTSelectorExpr(e, name);
+  }
+  return r.error();
+}
+
+GoASTExpr *GoParser::IndexOrSlice(GoASTExpr *e) {
+  Rule r("IndexOrSlice", this);
+  if (match(GoLexer::OP_LBRACK)) {
+    std::unique_ptr<GoASTExpr> i1(Expression()), i2, i3;
+    bool slice = false;
+    if (match(GoLexer::OP_COLON)) {
+      slice = true;
+      i2.reset(Expression());
+      if (i2 && match(GoLexer::OP_COLON)) {
+        i3.reset(Expression());
+        if (!i3)
+          return syntaxerror();
+      }
     }
-    return nullptr;
-}
-
-GoASTExpr *
-GoParser::PrimaryExpr()
-{
-    GoASTExpr *l;
-    GoASTExpr *r;
-    (l = Conversion()) || (l = Operand());
-    if (!l)
+    if (!(slice || i1))
+      return syntaxerror();
+    if (!mustMatch(GoLexer::OP_RBRACK))
+      return nullptr;
+    if (slice) {
+      bool slice3 = i3.get();
+      return new GoASTSliceExpr(e, i1.release(), i2.release(), i3.release(),
+                                slice3);
+    }
+    return new GoASTIndexExpr(e, i1.release());
+  }
+  return r.error();
+}
+
+GoASTExpr *GoParser::TypeAssertion(GoASTExpr *e) {
+  Rule r("TypeAssertion", this);
+  if (match(GoLexer::OP_DOT) && match(GoLexer::OP_LPAREN)) {
+    if (auto *t = Type()) {
+      if (!mustMatch(GoLexer::OP_RPAREN))
         return nullptr;
-    while ((r = Selector(l)) || (r = IndexOrSlice(l)) || (r = TypeAssertion(l)) || (r = Arguments(l)))
-    {
-        l = r;
+      return new GoASTTypeAssertExpr(e, t);
     }
-    return l;
+    return syntaxerror();
+  }
+  return r.error();
 }
 
-GoASTExpr *
-GoParser::Operand()
-{
-    GoLexer::Token *lit;
-    if ((lit = match(GoLexer::LIT_INTEGER)) || (lit = match(GoLexer::LIT_FLOAT)) ||
-        (lit = match(GoLexer::LIT_IMAGINARY)) || (lit = match(GoLexer::LIT_RUNE)) || (lit = match(GoLexer::LIT_STRING)))
-        return new GoASTBasicLit(*lit);
-    if (match(GoLexer::OP_LPAREN))
-    {
-        GoASTExpr *e;
-        if (!((e = Expression()) && match(GoLexer::OP_RPAREN)))
-            return syntaxerror();
-        return e;
+GoASTExpr *GoParser::Arguments(GoASTExpr *e) {
+  if (match(GoLexer::OP_LPAREN)) {
+    std::unique_ptr<GoASTCallExpr> call(new GoASTCallExpr(false));
+    GoASTExpr *arg;
+    // ( ExpressionList | Type [ "," ExpressionList ] )
+    for ((arg = Expression()) || (arg = Type()); arg;
+         arg = MoreExpressionList()) {
+      call->AddArgs(arg);
     }
-    // MethodExpr should be handled by Selector
-    if (GoASTExpr *e = CompositeLit())
-        return e;
-    if (GoASTExpr *n = Name())
-        return n;
-    return FunctionLit();
-}
+    if (match(GoLexer::OP_DOTS))
+      call->SetEllipsis(true);
 
-GoASTExpr *
-GoParser::FunctionLit()
-{
-    if (!match(GoLexer::KEYWORD_FUNC))
-        return nullptr;
-    auto *sig = Signature();
-    if (!sig)
-        return syntaxerror();
-    auto *body = Block();
-    if (!body)
-    {
-        delete sig;
-        return syntaxerror();
-    }
-    return new GoASTFuncLit(sig, body);
-}
+    // Eat trailing comma
+    match(GoLexer::OP_COMMA);
 
-GoASTBlockStmt *
-GoParser::Block()
-{
-    if (!match(GoLexer::OP_LBRACE))
-        return nullptr;
-    std::unique_ptr<GoASTBlockStmt> block(new GoASTBlockStmt);
-    for (auto *s = Statement(); s; s = Statement())
-        block->AddList(s);
-    if (!match(GoLexer::OP_RBRACE))
-        return syntaxerror();
-    return block.release();
+    if (!mustMatch(GoLexer::OP_RPAREN))
+      return nullptr;
+    call->SetFun(e);
+    return call.release();
+  }
+  return nullptr;
 }
 
-GoASTExpr *
-GoParser::CompositeLit()
-{
-    Rule r("CompositeLit", this);
-    GoASTExpr *type;
-    (type = StructType()) || (type = ArrayOrSliceType(true)) || (type = MapType()) || (type = Name());
-    if (!type)
-        return r.error();
-    GoASTCompositeLit *lit = LiteralValue();
-    if (!lit)
+GoASTExpr *GoParser::Conversion() {
+  Rule r("Conversion", this);
+  if (GoASTExpr *t = Type2()) {
+    if (match(GoLexer::OP_LPAREN)) {
+      GoASTExpr *v = Expression();
+      if (!v)
+        return syntaxerror();
+      match(GoLexer::OP_COMMA);
+      if (!mustMatch(GoLexer::OP_RPAREN))
         return r.error();
-    lit->SetType(type);
-    return lit;
-}
-
-GoASTCompositeLit *
-GoParser::LiteralValue()
-{
-    if (!match(GoLexer::OP_LBRACE))
-        return nullptr;
-    std::unique_ptr<GoASTCompositeLit> lit(new GoASTCompositeLit);
-    for (GoASTExpr *e = Element(); e; e = Element())
-    {
-        lit->AddElts(e);
-        if (!match(GoLexer::OP_COMMA))
-            break;
-    }
-    if (!mustMatch(GoLexer::OP_RBRACE))
-        return nullptr;
-    return lit.release();
-}
-
-GoASTExpr *
-GoParser::Element()
-{
-    GoASTExpr *key;
-    if (!((key = Expression()) || (key = LiteralValue())))
-        return nullptr;
-    if (!match(GoLexer::OP_COLON))
-        return key;
-    GoASTExpr *value;
-    if ((value = Expression()) || (value = LiteralValue()))
-        return new GoASTKeyValueExpr(key, value);
-    delete key;
-    return syntaxerror();
-}
-
-GoASTExpr *
-GoParser::Selector(GoASTExpr *e)
-{
-    Rule r("Selector", this);
-    if (match(GoLexer::OP_DOT))
-    {
-        if (auto *name = Identifier())
-            return new GoASTSelectorExpr(e, name);
-    }
-    return r.error();
+      GoASTCallExpr *call = new GoASTCallExpr(false);
+      call->SetFun(t);
+      call->AddArgs(v);
+      return call;
+    }
+  }
+  return r.error();
+}
+
+GoASTExpr *GoParser::Type2() {
+  switch (peek()) {
+  case GoLexer::OP_LBRACK:
+    return ArrayOrSliceType(false);
+  case GoLexer::KEYWORD_STRUCT:
+    return StructType();
+  case GoLexer::KEYWORD_FUNC:
+    return FunctionType();
+  case GoLexer::KEYWORD_INTERFACE:
+    return InterfaceType();
+  case GoLexer::KEYWORD_MAP:
+    return MapType();
+  case GoLexer::KEYWORD_CHAN:
+    return ChanType2();
+  default:
+    return nullptr;
+  }
 }
 
-GoASTExpr *
-GoParser::IndexOrSlice(GoASTExpr *e)
-{
-    Rule r("IndexOrSlice", this);
-    if (match(GoLexer::OP_LBRACK))
-    {
-        std::unique_ptr<GoASTExpr> i1(Expression()), i2, i3;
-        bool slice = false;
-        if (match(GoLexer::OP_COLON))
-        {
-            slice = true;
-            i2.reset(Expression());
-            if (i2 && match(GoLexer::OP_COLON))
-            {
-                i3.reset(Expression());
-                if (!i3)
-                    return syntaxerror();
-            }
-        }
-        if (!(slice || i1))
-            return syntaxerror();
-        if (!mustMatch(GoLexer::OP_RBRACK))
-            return nullptr;
-        if (slice)
-        {
-            bool slice3 = i3.get();
-            return new GoASTSliceExpr(e, i1.release(), i2.release(), i3.release(), slice3);
-        }
-        return new GoASTIndexExpr(e, i1.release());
+GoASTExpr *GoParser::ArrayOrSliceType(bool allowEllipsis) {
+  Rule r("ArrayType", this);
+  if (match(GoLexer::OP_LBRACK)) {
+    std::unique_ptr<GoASTExpr> len;
+    if (allowEllipsis && match(GoLexer::OP_DOTS)) {
+      len.reset(new GoASTEllipsis(nullptr));
+    } else {
+      len.reset(Expression());
     }
-    return r.error();
-}
 
-GoASTExpr *
-GoParser::TypeAssertion(GoASTExpr *e)
-{
-    Rule r("TypeAssertion", this);
-    if (match(GoLexer::OP_DOT) && match(GoLexer::OP_LPAREN))
-    {
-        if (auto *t = Type())
-        {
-            if (!mustMatch(GoLexer::OP_RPAREN))
-                return nullptr;
-            return new GoASTTypeAssertExpr(e, t);
-        }
-        return syntaxerror();
-    }
-    return r.error();
+    if (!match(GoLexer::OP_RBRACK))
+      return r.error();
+    GoASTExpr *elem = Type();
+    if (!elem)
+      return syntaxerror();
+    return new GoASTArrayType(len.release(), elem);
+  }
+  return r.error();
 }
 
-GoASTExpr *
-GoParser::Arguments(GoASTExpr *e)
-{
-    if (match(GoLexer::OP_LPAREN))
-    {
-        std::unique_ptr<GoASTCallExpr> call(new GoASTCallExpr(false));
-        GoASTExpr *arg;
-        // ( ExpressionList | Type [ "," ExpressionList ] )
-        for ((arg = Expression()) || (arg = Type()); arg; arg = MoreExpressionList())
-        {
-            call->AddArgs(arg);
-        }
-        if (match(GoLexer::OP_DOTS))
-            call->SetEllipsis(true);
-
-        // Eat trailing comma
-        match(GoLexer::OP_COMMA);
-
-        if (!mustMatch(GoLexer::OP_RPAREN))
-            return nullptr;
-        call->SetFun(e);
-        return call.release();
-    }
+GoASTExpr *GoParser::StructType() {
+  if (!(match(GoLexer::KEYWORD_STRUCT) && mustMatch(GoLexer::OP_LBRACE)))
     return nullptr;
+  std::unique_ptr<GoASTFieldList> fields(new GoASTFieldList);
+  while (auto *field = FieldDecl())
+    fields->AddList(field);
+  if (!mustMatch(GoLexer::OP_RBRACE))
+    return nullptr;
+  return new GoASTStructType(fields.release());
 }
 
-GoASTExpr *
-GoParser::Conversion()
-{
-    Rule r("Conversion", this);
-    if (GoASTExpr *t = Type2())
-    {
-        if (match(GoLexer::OP_LPAREN))
-        {
-            GoASTExpr *v = Expression();
-            if (!v)
-                return syntaxerror();
-            match(GoLexer::OP_COMMA);
-            if (!mustMatch(GoLexer::OP_RPAREN))
-                return r.error();
-            GoASTCallExpr *call = new GoASTCallExpr(false);
-            call->SetFun(t);
-            call->AddArgs(v);
-            return call;
-        }
-    }
-    return r.error();
-}
-
-GoASTExpr *
-GoParser::Type2()
-{
-    switch (peek())
-    {
-        case GoLexer::OP_LBRACK:
-            return ArrayOrSliceType(false);
-        case GoLexer::KEYWORD_STRUCT:
-            return StructType();
-        case GoLexer::KEYWORD_FUNC:
-            return FunctionType();
-        case GoLexer::KEYWORD_INTERFACE:
-            return InterfaceType();
-        case GoLexer::KEYWORD_MAP:
-            return MapType();
-        case GoLexer::KEYWORD_CHAN:
-            return ChanType2();
-        default:
-            return nullptr;
-    }
-}
+GoASTField *GoParser::FieldDecl() {
+  std::unique_ptr<GoASTField> f(new GoASTField);
+  GoASTExpr *t = FieldNamesAndType(f.get());
+  if (!t)
+    t = AnonymousFieldType();
+  if (!t)
+    return nullptr;
 
-GoASTExpr *
-GoParser::ArrayOrSliceType(bool allowEllipsis)
-{
-    Rule r("ArrayType", this);
-    if (match(GoLexer::OP_LBRACK))
-    {
-        std::unique_ptr<GoASTExpr> len;
-        if (allowEllipsis && match(GoLexer::OP_DOTS))
-        {
-            len.reset(new GoASTEllipsis(nullptr));
-        }
-        else
-        {
-            len.reset(Expression());
-        }
-
-        if (!match(GoLexer::OP_RBRACK))
-            return r.error();
-        GoASTExpr *elem = Type();
-        if (!elem)
-            return syntaxerror();
-        return new GoASTArrayType(len.release(), elem);
-    }
-    return r.error();
+  if (auto *tok = match(GoLexer::LIT_STRING))
+    f->SetTag(new GoASTBasicLit(*tok));
+  if (!Semicolon())
+    return syntaxerror();
+  return f.release();
 }
 
-GoASTExpr *
-GoParser::StructType()
-{
-    if (!(match(GoLexer::KEYWORD_STRUCT) && mustMatch(GoLexer::OP_LBRACE)))
-        return nullptr;
-    std::unique_ptr<GoASTFieldList> fields(new GoASTFieldList);
-    while (auto *field = FieldDecl())
-        fields->AddList(field);
-    if (!mustMatch(GoLexer::OP_RBRACE))
-        return nullptr;
-    return new GoASTStructType(fields.release());
+GoASTExpr *GoParser::FieldNamesAndType(GoASTField *field) {
+  Rule r("FieldNames", this);
+  for (auto *id = Identifier(); id; id = MoreIdentifierList())
+    field->AddNames(id);
+  if (m_failed)
+    return nullptr;
+  GoASTExpr *t = Type();
+  if (t)
+    return t;
+  return r.error();
 }
 
-GoASTField *
-GoParser::FieldDecl()
-{
-    std::unique_ptr<GoASTField> f(new GoASTField);
-    GoASTExpr *t = FieldNamesAndType(f.get());
-    if (!t)
-        t = AnonymousFieldType();
-    if (!t)
-        return nullptr;
-
-    if (auto *tok = match(GoLexer::LIT_STRING))
-        f->SetTag(new GoASTBasicLit(*tok));
-    if (!Semicolon())
-        return syntaxerror();
-    return f.release();
+GoASTExpr *GoParser::AnonymousFieldType() {
+  bool pointer = match(GoLexer::OP_STAR);
+  GoASTExpr *t = Type();
+  if (!t)
+    return nullptr;
+  if (pointer)
+    return new GoASTStarExpr(t);
+  return t;
 }
 
-GoASTExpr *
-GoParser::FieldNamesAndType(GoASTField *field)
-{
-    Rule r("FieldNames", this);
-    for (auto *id = Identifier(); id; id = MoreIdentifierList())
-        field->AddNames(id);
-    if (m_failed)
-        return nullptr;
-    GoASTExpr *t = Type();
-    if (t)
-        return t;
-    return r.error();
+GoASTExpr *GoParser::FunctionType() {
+  if (!match(GoLexer::KEYWORD_FUNC))
+    return nullptr;
+  return Signature();
 }
 
-GoASTExpr *
-GoParser::AnonymousFieldType()
-{
-    bool pointer = match(GoLexer::OP_STAR);
-    GoASTExpr *t = Type();
-    if (!t)
-        return nullptr;
-    if (pointer)
-        return new GoASTStarExpr(t);
+GoASTFuncType *GoParser::Signature() {
+  auto *params = Params();
+  if (!params)
+    return syntaxerror();
+  auto *result = Params();
+  if (!result) {
+    if (auto *t = Type()) {
+      result = new GoASTFieldList;
+      auto *f = new GoASTField;
+      f->SetType(t);
+      result->AddList(f);
+    }
+  }
+  return new GoASTFuncType(params, result);
+}
+
+GoASTFieldList *GoParser::Params() {
+  if (!match(GoLexer::OP_LPAREN))
+    return nullptr;
+  std::unique_ptr<GoASTFieldList> l(new GoASTFieldList);
+  while (GoASTField *p = ParamDecl()) {
+    l->AddList(p);
+    if (!match(GoLexer::OP_COMMA))
+      break;
+  }
+  if (!mustMatch(GoLexer::OP_RPAREN))
+    return nullptr;
+  return l.release();
+}
+
+GoASTField *GoParser::ParamDecl() {
+  std::unique_ptr<GoASTField> field(new GoASTField);
+  GoASTIdent *id = Identifier();
+  if (id) {
+    // Try `IdentifierList [ "..." ] Type`.
+    // If that fails, backtrack and try `[ "..." ] Type`.
+    Rule r("NamedParam", this);
+    for (; id; id = MoreIdentifierList())
+      field->AddNames(id);
+    GoASTExpr *t = ParamType();
+    if (t) {
+      field->SetType(t);
+      return field.release();
+    }
+    field.reset(new GoASTField);
+    r.error();
+  }
+  GoASTExpr *t = ParamType();
+  if (t) {
+    field->SetType(t);
+    return field.release();
+  }
+  return nullptr;
+}
+
+GoASTExpr *GoParser::ParamType() {
+  bool dots = match(GoLexer::OP_DOTS);
+  GoASTExpr *t = Type();
+  if (!dots)
     return t;
+  if (!t)
+    return syntaxerror();
+  return new GoASTEllipsis(t);
 }
 
-GoASTExpr *
-GoParser::FunctionType()
-{
-    if (!match(GoLexer::KEYWORD_FUNC))
-        return nullptr;
-    return Signature();
-}
-
-GoASTFuncType *
-GoParser::Signature()
-{
-    auto *params = Params();
-    if (!params)
-        return syntaxerror();
-    auto *result = Params();
-    if (!result)
-    {
-        if (auto *t = Type())
-        {
-            result = new GoASTFieldList;
-            auto *f = new GoASTField;
-            f->SetType(t);
-            result->AddList(f);
-        }
-    }
-    return new GoASTFuncType(params, result);
-}
-
-GoASTFieldList *
-GoParser::Params()
-{
-    if (!match(GoLexer::OP_LPAREN))
-        return nullptr;
-    std::unique_ptr<GoASTFieldList> l(new GoASTFieldList);
-    while (GoASTField *p = ParamDecl())
-    {
-        l->AddList(p);
-        if (!match(GoLexer::OP_COMMA))
-            break;
+GoASTExpr *GoParser::InterfaceType() {
+  if (!match(GoLexer::KEYWORD_INTERFACE) || !mustMatch(GoLexer::OP_LBRACE))
+    return nullptr;
+  std::unique_ptr<GoASTFieldList> methods(new GoASTFieldList);
+  while (true) {
+    Rule r("MethodSpec", this);
+    // ( identifier Signature | TypeName ) ;
+    std::unique_ptr<GoASTIdent> id(Identifier());
+    if (!id)
+      break;
+    GoASTExpr *type = Signature();
+    if (!type) {
+      r.error();
+      id.reset();
+      type = Name();
     }
-    if (!mustMatch(GoLexer::OP_RPAREN))
-        return nullptr;
-    return l.release();
-}
-
-GoASTField *
-GoParser::ParamDecl()
-{
-    std::unique_ptr<GoASTField> field(new GoASTField);
-    GoASTIdent *id = Identifier();
+    if (!Semicolon())
+      return syntaxerror();
+    auto *f = new GoASTField;
     if (id)
-    {
-        // Try `IdentifierList [ "..." ] Type`.
-        // If that fails, backtrack and try `[ "..." ] Type`.
-        Rule r("NamedParam", this);
-        for (; id; id = MoreIdentifierList())
-            field->AddNames(id);
-        GoASTExpr *t = ParamType();
-        if (t)
-        {
-            field->SetType(t);
-            return field.release();
-        }
-        field.reset(new GoASTField);
-        r.error();
-    }
-    GoASTExpr *t = ParamType();
-    if (t)
-    {
-        field->SetType(t);
-        return field.release();
-    }
+      f->AddNames(id.release());
+    f->SetType(type);
+    methods->AddList(f);
+  }
+  if (!mustMatch(GoLexer::OP_RBRACE))
     return nullptr;
+  return new GoASTInterfaceType(methods.release());
 }
 
-GoASTExpr *
-GoParser::ParamType()
-{
-    bool dots = match(GoLexer::OP_DOTS);
-    GoASTExpr *t = Type();
-    if (!dots)
-        return t;
-    if (!t)
-        return syntaxerror();
-    return new GoASTEllipsis(t);
-}
-
-GoASTExpr *
-GoParser::InterfaceType()
-{
-    if (!match(GoLexer::KEYWORD_INTERFACE) || !mustMatch(GoLexer::OP_LBRACE))
-        return nullptr;
-    std::unique_ptr<GoASTFieldList> methods(new GoASTFieldList);
-    while (true)
-    {
-        Rule r("MethodSpec", this);
-        // ( identifier Signature | TypeName ) ;
-        std::unique_ptr<GoASTIdent> id(Identifier());
-        if (!id)
-            break;
-        GoASTExpr *type = Signature();
-        if (!type)
-        {
-            r.error();
-            id.reset();
-            type = Name();
-        }
-        if (!Semicolon())
-            return syntaxerror();
-        auto *f = new GoASTField;
-        if (id)
-            f->AddNames(id.release());
-        f->SetType(type);
-        methods->AddList(f);
-    }
-    if (!mustMatch(GoLexer::OP_RBRACE))
-        return nullptr;
-    return new GoASTInterfaceType(methods.release());
-}
-
-GoASTExpr *
-GoParser::MapType()
-{
-    if (!(match(GoLexer::KEYWORD_MAP) && mustMatch(GoLexer::OP_LBRACK)))
-        return nullptr;
-    std::unique_ptr<GoASTExpr> key(Type());
-    if (!key)
-        return syntaxerror();
-    if (!mustMatch(GoLexer::OP_RBRACK))
-        return nullptr;
-    auto *elem = Type();
-    if (!elem)
-        return syntaxerror();
-    return new GoASTMapType(key.release(), elem);
-}
-
-GoASTExpr *
-GoParser::ChanType()
-{
-    Rule r("chan", this);
-    if (match(GoLexer::OP_LT_MINUS))
-    {
-        if (match(GoLexer::KEYWORD_CHAN))
-        {
-            auto *elem = Type();
-            if (!elem)
-                return syntaxerror();
-            return new GoASTChanType(GoASTNode::eChanRecv, elem);
-        }
-        return r.error();
-    }
-    return ChanType2();
-}
-
-GoASTExpr *
-GoParser::ChanType2()
-{
-    if (!match(GoLexer::KEYWORD_CHAN))
-        return nullptr;
-    auto dir = GoASTNode::eChanBidir;
-    if (match(GoLexer::OP_LT_MINUS))
-        dir = GoASTNode::eChanSend;
-    auto *elem = Type();
-    if (!elem)
-        return syntaxerror();
-    return new GoASTChanType(dir, elem);
-}
-
-GoASTExpr *
-GoParser::Type()
-{
-    if (GoASTExpr *t = Type2())
-        return t;
-    if (GoASTExpr *t = Name())
-        return t;
-    if (GoASTExpr *t = ChanType())
-        return t;
-    if (match(GoLexer::OP_STAR))
-    {
-        GoASTExpr *t = Type();
-        if (!t)
-            return syntaxerror();
-        return new GoASTStarExpr(t);
-    }
-    if (match(GoLexer::OP_LPAREN))
-    {
-        std::unique_ptr<GoASTExpr> t(Type());
-        if (!t || !match(GoLexer::OP_RPAREN))
-            return syntaxerror();
-        return t.release();
-    }
+GoASTExpr *GoParser::MapType() {
+  if (!(match(GoLexer::KEYWORD_MAP) && mustMatch(GoLexer::OP_LBRACK)))
+    return nullptr;
+  std::unique_ptr<GoASTExpr> key(Type());
+  if (!key)
+    return syntaxerror();
+  if (!mustMatch(GoLexer::OP_RBRACK))
     return nullptr;
+  auto *elem = Type();
+  if (!elem)
+    return syntaxerror();
+  return new GoASTMapType(key.release(), elem);
 }
 
-bool
-GoParser::Semicolon()
-{
-    if (match(GoLexer::OP_SEMICOLON))
-        return true;
-    switch (peek())
-    {
-        case GoLexer::OP_RPAREN:
-        case GoLexer::OP_RBRACE:
-        case GoLexer::TOK_EOF:
-            return true;
-        default:
-            return false;
+GoASTExpr *GoParser::ChanType() {
+  Rule r("chan", this);
+  if (match(GoLexer::OP_LT_MINUS)) {
+    if (match(GoLexer::KEYWORD_CHAN)) {
+      auto *elem = Type();
+      if (!elem)
+        return syntaxerror();
+      return new GoASTChanType(GoASTNode::eChanRecv, elem);
     }
+    return r.error();
+  }
+  return ChanType2();
 }
 
-GoASTExpr *
-GoParser::Name()
-{
-    if (auto *id = Identifier())
-    {
-        if (GoASTExpr *qual = QualifiedIdent(id))
-            return qual;
-        return id;
-    }
+GoASTExpr *GoParser::ChanType2() {
+  if (!match(GoLexer::KEYWORD_CHAN))
     return nullptr;
+  auto dir = GoASTNode::eChanBidir;
+  if (match(GoLexer::OP_LT_MINUS))
+    dir = GoASTNode::eChanSend;
+  auto *elem = Type();
+  if (!elem)
+    return syntaxerror();
+  return new GoASTChanType(dir, elem);
 }
 
-GoASTExpr *
-GoParser::QualifiedIdent(lldb_private::GoASTIdent *p)
-{
-    Rule r("QualifiedIdent", this);
-    llvm::SmallString<32> path(p->GetName().m_value);
-    GoLexer::Token *next;
-    bool have_slashes = false;
-    // LLDB extension: support full/package/path.name
-    while (match(GoLexer::OP_SLASH) && (next = match(GoLexer::TOK_IDENTIFIER)))
-    {
-        have_slashes = true;
-        path.append("/");
-        path.append(next->m_value);
-    }
-    if (match(GoLexer::OP_DOT))
-    {
-        auto *name = Identifier();
-        if (name)
-        {
-            if (have_slashes)
-            {
-                p->SetName(GoLexer::Token(GoLexer::TOK_IDENTIFIER, CopyString(path)));
-            }
-            return new GoASTSelectorExpr(p, name);
-        }
-    }
-    return r.error();
-}
-
-llvm::StringRef
-GoParser::CopyString(llvm::StringRef s)
-{
-    return m_strings.insert(std::make_pair(s, 'x')).first->getKey();
-}
-
-void
-GoParser::GetError(Error &error)
-{
-    llvm::StringRef want;
-    if (m_failed)
-        want = m_last_tok == GoLexer::TOK_INVALID ? DescribeToken(m_last_tok) : m_last;
-    else
-        want = m_error;
-    size_t len = m_lexer.BytesRemaining();
-    if (len > 10)
-        len = 10;
-    llvm::StringRef got;
-    if (len == 0)
-        got = "<eof>";
-    else
-        got = m_lexer.GetString(len);
-    error.SetErrorStringWithFormat("Syntax error: expected %s before '%s'.", want.str().c_str(), got.str().c_str());
+GoASTExpr *GoParser::Type() {
+  if (GoASTExpr *t = Type2())
+    return t;
+  if (GoASTExpr *t = Name())
+    return t;
+  if (GoASTExpr *t = ChanType())
+    return t;
+  if (match(GoLexer::OP_STAR)) {
+    GoASTExpr *t = Type();
+    if (!t)
+      return syntaxerror();
+    return new GoASTStarExpr(t);
+  }
+  if (match(GoLexer::OP_LPAREN)) {
+    std::unique_ptr<GoASTExpr> t(Type());
+    if (!t || !match(GoLexer::OP_RPAREN))
+      return syntaxerror();
+    return t.release();
+  }
+  return nullptr;
+}
+
+bool GoParser::Semicolon() {
+  if (match(GoLexer::OP_SEMICOLON))
+    return true;
+  switch (peek()) {
+  case GoLexer::OP_RPAREN:
+  case GoLexer::OP_RBRACE:
+  case GoLexer::TOK_EOF:
+    return true;
+  default:
+    return false;
+  }
+}
+
+GoASTExpr *GoParser::Name() {
+  if (auto *id = Identifier()) {
+    if (GoASTExpr *qual = QualifiedIdent(id))
+      return qual;
+    return id;
+  }
+  return nullptr;
+}
+
+GoASTExpr *GoParser::QualifiedIdent(lldb_private::GoASTIdent *p) {
+  Rule r("QualifiedIdent", this);
+  llvm::SmallString<32> path(p->GetName().m_value);
+  GoLexer::Token *next;
+  bool have_slashes = false;
+  // LLDB extension: support full/package/path.name
+  while (match(GoLexer::OP_SLASH) && (next = match(GoLexer::TOK_IDENTIFIER))) {
+    have_slashes = true;
+    path.append("/");
+    path.append(next->m_value);
+  }
+  if (match(GoLexer::OP_DOT)) {
+    auto *name = Identifier();
+    if (name) {
+      if (have_slashes) {
+        p->SetName(GoLexer::Token(GoLexer::TOK_IDENTIFIER, CopyString(path)));
+      }
+      return new GoASTSelectorExpr(p, name);
+    }
+  }
+  return r.error();
+}
+
+llvm::StringRef GoParser::CopyString(llvm::StringRef s) {
+  return m_strings.insert(std::make_pair(s, 'x')).first->getKey();
+}
+
+void GoParser::GetError(Error &error) {
+  llvm::StringRef want;
+  if (m_failed)
+    want =
+        m_last_tok == GoLexer::TOK_INVALID ? DescribeToken(m_last_tok) : m_last;
+  else
+    want = m_error;
+  size_t len = m_lexer.BytesRemaining();
+  if (len > 10)
+    len = 10;
+  llvm::StringRef got;
+  if (len == 0)
+    got = "<eof>";
+  else
+    got = m_lexer.GetString(len);
+  error.SetErrorStringWithFormat("Syntax error: expected %s before '%s'.",
+                                 want.str().c_str(), got.str().c_str());
 }

Modified: lldb/trunk/source/Plugins/ExpressionParser/Go/GoParser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Go/GoParser.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Go/GoParser.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Go/GoParser.h Tue Sep  6 15:57:50 2016
@@ -1,4 +1,5 @@
-//===-- GoParser.h -----------------------------------------------*- C++ -*-===//
+//===-- GoParser.h -----------------------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -10,155 +11,134 @@
 #ifndef liblldb_GoParser_h
 #define liblldb_GoParser_h
 
-#include "lldb/lldb-private.h"
 #include "Plugins/ExpressionParser/Go/GoAST.h"
 #include "Plugins/ExpressionParser/Go/GoLexer.h"
+#include "lldb/lldb-private.h"
 
-namespace lldb_private
-{
-class GoParser
-{
-  public:
-    explicit GoParser(const char *src);
-
-    GoASTStmt *Statement();
-
-    GoASTStmt *GoStmt();
-    GoASTStmt *ReturnStmt();
-    GoASTStmt *BranchStmt();
-    GoASTStmt *EmptyStmt();
-    GoASTStmt *ExpressionStmt(GoASTExpr *e);
-    GoASTStmt *IncDecStmt(GoASTExpr *e);
-    GoASTStmt *Assignment(GoASTExpr *e);
-    GoASTBlockStmt *Block();
-
-    GoASTExpr *MoreExpressionList();  // ["," Expression]
-    GoASTIdent *MoreIdentifierList(); // ["," Identifier]
-
-    GoASTExpr *Expression();
-    GoASTExpr *UnaryExpr();
-    GoASTExpr *OrExpr();
-    GoASTExpr *AndExpr();
-    GoASTExpr *RelExpr();
-    GoASTExpr *AddExpr();
-    GoASTExpr *MulExpr();
-    GoASTExpr *PrimaryExpr();
-    GoASTExpr *Operand();
-    GoASTExpr *Conversion();
-
-    GoASTExpr *Selector(GoASTExpr *e);
-    GoASTExpr *IndexOrSlice(GoASTExpr *e);
-    GoASTExpr *TypeAssertion(GoASTExpr *e);
-    GoASTExpr *Arguments(GoASTExpr *e);
-
-    GoASTExpr *Type();
-    GoASTExpr *Type2();
-    GoASTExpr *ArrayOrSliceType(bool allowEllipsis);
-    GoASTExpr *StructType();
-    GoASTExpr *FunctionType();
-    GoASTExpr *InterfaceType();
-    GoASTExpr *MapType();
-    GoASTExpr *ChanType();
-    GoASTExpr *ChanType2();
-
-    GoASTExpr *Name();
-    GoASTExpr *QualifiedIdent(GoASTIdent *p);
-    GoASTIdent *Identifier();
-
-    GoASTField *FieldDecl();
-    GoASTExpr *AnonymousFieldType();
-    GoASTExpr *FieldNamesAndType(GoASTField *f);
-
-    GoASTFieldList *Params();
-    GoASTField *ParamDecl();
-    GoASTExpr *ParamType();
-    GoASTFuncType *Signature();
-    GoASTExpr *CompositeLit();
-    GoASTExpr *FunctionLit();
-    GoASTExpr *Element();
-    GoASTCompositeLit *LiteralValue();
-
-    bool
-    Failed() const
-    {
-        return m_failed;
-    }
-    bool
-    AtEOF() const
-    {
-        return m_lexer.BytesRemaining() == 0 && m_pos == m_tokens.size();
-    }
-
-    void GetError(Error &error);
-
-  private:
-    class Rule;
-    friend class Rule;
-
-    std::nullptr_t
-    syntaxerror()
-    {
-        m_failed = true;
-        return nullptr;
-    }
-    GoLexer::Token &
-    next()
-    {
-        if (m_pos >= m_tokens.size())
-        {
-            if (m_pos != 0 &&
-                (m_tokens.back().m_type == GoLexer::TOK_EOF || m_tokens.back().m_type == GoLexer::TOK_INVALID))
-                return m_tokens.back();
-            m_pos = m_tokens.size();
-            m_tokens.push_back(m_lexer.Lex());
-        }
-        return m_tokens[m_pos++];
-    }
-    GoLexer::TokenType
-    peek()
-    {
-        GoLexer::Token &tok = next();
-        --m_pos;
-        return tok.m_type;
-    }
-    GoLexer::Token *
-    match(GoLexer::TokenType t)
-    {
-        GoLexer::Token &tok = next();
-        if (tok.m_type == t)
-            return &tok;
-        --m_pos;
-        m_last_tok = t;
-        return nullptr;
-    }
-    GoLexer::Token *
-    mustMatch(GoLexer::TokenType t)
-    {
-        GoLexer::Token *tok = match(t);
-        if (tok)
-            return tok;
-        return syntaxerror();
-    }
-    bool Semicolon();
-
-    GoASTStmt *
-    FinishStmt(GoASTStmt *s)
-    {
-        if (!Semicolon())
-            m_failed = true;
-        return s;
-    }
-
-    llvm::StringRef CopyString(llvm::StringRef s);
-
-    GoLexer m_lexer;
-    std::vector<GoLexer::Token> m_tokens;
-    size_t m_pos;
-    llvm::StringRef m_error;
-    llvm::StringRef m_last;
-    GoLexer::TokenType m_last_tok;
-    llvm::StringMap<uint8_t> m_strings;
-    bool m_failed;
+namespace lldb_private {
+class GoParser {
+public:
+  explicit GoParser(const char *src);
+
+  GoASTStmt *Statement();
+
+  GoASTStmt *GoStmt();
+  GoASTStmt *ReturnStmt();
+  GoASTStmt *BranchStmt();
+  GoASTStmt *EmptyStmt();
+  GoASTStmt *ExpressionStmt(GoASTExpr *e);
+  GoASTStmt *IncDecStmt(GoASTExpr *e);
+  GoASTStmt *Assignment(GoASTExpr *e);
+  GoASTBlockStmt *Block();
+
+  GoASTExpr *MoreExpressionList();  // ["," Expression]
+  GoASTIdent *MoreIdentifierList(); // ["," Identifier]
+
+  GoASTExpr *Expression();
+  GoASTExpr *UnaryExpr();
+  GoASTExpr *OrExpr();
+  GoASTExpr *AndExpr();
+  GoASTExpr *RelExpr();
+  GoASTExpr *AddExpr();
+  GoASTExpr *MulExpr();
+  GoASTExpr *PrimaryExpr();
+  GoASTExpr *Operand();
+  GoASTExpr *Conversion();
+
+  GoASTExpr *Selector(GoASTExpr *e);
+  GoASTExpr *IndexOrSlice(GoASTExpr *e);
+  GoASTExpr *TypeAssertion(GoASTExpr *e);
+  GoASTExpr *Arguments(GoASTExpr *e);
+
+  GoASTExpr *Type();
+  GoASTExpr *Type2();
+  GoASTExpr *ArrayOrSliceType(bool allowEllipsis);
+  GoASTExpr *StructType();
+  GoASTExpr *FunctionType();
+  GoASTExpr *InterfaceType();
+  GoASTExpr *MapType();
+  GoASTExpr *ChanType();
+  GoASTExpr *ChanType2();
+
+  GoASTExpr *Name();
+  GoASTExpr *QualifiedIdent(GoASTIdent *p);
+  GoASTIdent *Identifier();
+
+  GoASTField *FieldDecl();
+  GoASTExpr *AnonymousFieldType();
+  GoASTExpr *FieldNamesAndType(GoASTField *f);
+
+  GoASTFieldList *Params();
+  GoASTField *ParamDecl();
+  GoASTExpr *ParamType();
+  GoASTFuncType *Signature();
+  GoASTExpr *CompositeLit();
+  GoASTExpr *FunctionLit();
+  GoASTExpr *Element();
+  GoASTCompositeLit *LiteralValue();
+
+  bool Failed() const { return m_failed; }
+  bool AtEOF() const {
+    return m_lexer.BytesRemaining() == 0 && m_pos == m_tokens.size();
+  }
+
+  void GetError(Error &error);
+
+private:
+  class Rule;
+  friend class Rule;
+
+  std::nullptr_t syntaxerror() {
+    m_failed = true;
+    return nullptr;
+  }
+  GoLexer::Token &next() {
+    if (m_pos >= m_tokens.size()) {
+      if (m_pos != 0 && (m_tokens.back().m_type == GoLexer::TOK_EOF ||
+                         m_tokens.back().m_type == GoLexer::TOK_INVALID))
+        return m_tokens.back();
+      m_pos = m_tokens.size();
+      m_tokens.push_back(m_lexer.Lex());
+    }
+    return m_tokens[m_pos++];
+  }
+  GoLexer::TokenType peek() {
+    GoLexer::Token &tok = next();
+    --m_pos;
+    return tok.m_type;
+  }
+  GoLexer::Token *match(GoLexer::TokenType t) {
+    GoLexer::Token &tok = next();
+    if (tok.m_type == t)
+      return &tok;
+    --m_pos;
+    m_last_tok = t;
+    return nullptr;
+  }
+  GoLexer::Token *mustMatch(GoLexer::TokenType t) {
+    GoLexer::Token *tok = match(t);
+    if (tok)
+      return tok;
+    return syntaxerror();
+  }
+  bool Semicolon();
+
+  GoASTStmt *FinishStmt(GoASTStmt *s) {
+    if (!Semicolon())
+      m_failed = true;
+    return s;
+  }
+
+  llvm::StringRef CopyString(llvm::StringRef s);
+
+  GoLexer m_lexer;
+  std::vector<GoLexer::Token> m_tokens;
+  size_t m_pos;
+  llvm::StringRef m_error;
+  llvm::StringRef m_last;
+  GoLexer::TokenType m_last_tok;
+  llvm::StringMap<uint8_t> m_strings;
+  bool m_failed;
 };
 }
 

Modified: lldb/trunk/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp Tue Sep  6 15:57:50 2016
@@ -20,8 +20,8 @@
 #include <vector>
 
 // Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
 
 // Project includes
 #include "GoUserExpression.h"
@@ -57,705 +57,621 @@
 using namespace lldb_private;
 using namespace lldb;
 
-class GoUserExpression::GoInterpreter
-{
-  public:
-    GoInterpreter(ExecutionContext &exe_ctx, const char *expr)
-        : m_exe_ctx(exe_ctx), m_frame(exe_ctx.GetFrameSP()), m_parser(expr)
-    {
-        if (m_frame)
-        {
-            const SymbolContext &ctx = m_frame->GetSymbolContext(eSymbolContextFunction);
-            ConstString fname = ctx.GetFunctionName();
-            if (fname.GetLength() > 0)
-            {
-                size_t dot = fname.GetStringRef().find('.');
-                if (dot != llvm::StringRef::npos)
-                    m_package = llvm::StringRef(fname.AsCString(), dot);
-            }
-        }
-    }
-
-    void
-    set_use_dynamic(DynamicValueType use_dynamic)
-    {
-        m_use_dynamic = use_dynamic;
-    }
-
-    bool Parse();
-    lldb::ValueObjectSP Evaluate(ExecutionContext &exe_ctx);
-    lldb::ValueObjectSP EvaluateStatement(const GoASTStmt *s);
-    lldb::ValueObjectSP EvaluateExpr(const GoASTExpr *e);
-
-    ValueObjectSP
-    VisitBadExpr(const GoASTBadExpr *e)
-    {
-        m_parser.GetError(m_error);
-        return nullptr;
-    }
-
-    ValueObjectSP VisitParenExpr(const GoASTParenExpr *e);
-    ValueObjectSP VisitIdent(const GoASTIdent *e);
-    ValueObjectSP VisitStarExpr(const GoASTStarExpr *e);
-    ValueObjectSP VisitSelectorExpr(const GoASTSelectorExpr *e);
-    ValueObjectSP VisitBasicLit(const GoASTBasicLit *e);
-    ValueObjectSP VisitIndexExpr(const GoASTIndexExpr *e);
-    ValueObjectSP VisitUnaryExpr(const GoASTUnaryExpr *e);
-    ValueObjectSP VisitCallExpr(const GoASTCallExpr *e);
-
-    ValueObjectSP
-    VisitTypeAssertExpr(const GoASTTypeAssertExpr *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitBinaryExpr(const GoASTBinaryExpr *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitArrayType(const GoASTArrayType *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitChanType(const GoASTChanType *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitCompositeLit(const GoASTCompositeLit *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitEllipsis(const GoASTEllipsis *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitFuncType(const GoASTFuncType *e)
-    {
-        return NotImplemented(e);
-    }
+class GoUserExpression::GoInterpreter {
+public:
+  GoInterpreter(ExecutionContext &exe_ctx, const char *expr)
+      : m_exe_ctx(exe_ctx), m_frame(exe_ctx.GetFrameSP()), m_parser(expr) {
+    if (m_frame) {
+      const SymbolContext &ctx =
+          m_frame->GetSymbolContext(eSymbolContextFunction);
+      ConstString fname = ctx.GetFunctionName();
+      if (fname.GetLength() > 0) {
+        size_t dot = fname.GetStringRef().find('.');
+        if (dot != llvm::StringRef::npos)
+          m_package = llvm::StringRef(fname.AsCString(), dot);
+      }
+    }
+  }
+
+  void set_use_dynamic(DynamicValueType use_dynamic) {
+    m_use_dynamic = use_dynamic;
+  }
+
+  bool Parse();
+  lldb::ValueObjectSP Evaluate(ExecutionContext &exe_ctx);
+  lldb::ValueObjectSP EvaluateStatement(const GoASTStmt *s);
+  lldb::ValueObjectSP EvaluateExpr(const GoASTExpr *e);
 
-    ValueObjectSP
-    VisitFuncLit(const GoASTFuncLit *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitInterfaceType(const GoASTInterfaceType *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitKeyValueExpr(const GoASTKeyValueExpr *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitMapType(const GoASTMapType *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitSliceExpr(const GoASTSliceExpr *e)
-    {
-        return NotImplemented(e);
-    }
-
-    ValueObjectSP
-    VisitStructType(const GoASTStructType *e)
-    {
-        return NotImplemented(e);
-    }
-
-    CompilerType EvaluateType(const GoASTExpr *e);
-
-    Error &
-    error()
-    {
-        return m_error;
-    }
+  ValueObjectSP VisitBadExpr(const GoASTBadExpr *e) {
+    m_parser.GetError(m_error);
+    return nullptr;
+  }
 
-  private:
-    std::nullptr_t
-    NotImplemented(const GoASTExpr *e)
-    {
-        m_error.SetErrorStringWithFormat("%s node not implemented", e->GetKindName());
-        return nullptr;
-    }
+  ValueObjectSP VisitParenExpr(const GoASTParenExpr *e);
+  ValueObjectSP VisitIdent(const GoASTIdent *e);
+  ValueObjectSP VisitStarExpr(const GoASTStarExpr *e);
+  ValueObjectSP VisitSelectorExpr(const GoASTSelectorExpr *e);
+  ValueObjectSP VisitBasicLit(const GoASTBasicLit *e);
+  ValueObjectSP VisitIndexExpr(const GoASTIndexExpr *e);
+  ValueObjectSP VisitUnaryExpr(const GoASTUnaryExpr *e);
+  ValueObjectSP VisitCallExpr(const GoASTCallExpr *e);
+
+  ValueObjectSP VisitTypeAssertExpr(const GoASTTypeAssertExpr *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitBinaryExpr(const GoASTBinaryExpr *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitArrayType(const GoASTArrayType *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitChanType(const GoASTChanType *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitCompositeLit(const GoASTCompositeLit *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitEllipsis(const GoASTEllipsis *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitFuncType(const GoASTFuncType *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitFuncLit(const GoASTFuncLit *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitInterfaceType(const GoASTInterfaceType *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitKeyValueExpr(const GoASTKeyValueExpr *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitMapType(const GoASTMapType *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitSliceExpr(const GoASTSliceExpr *e) {
+    return NotImplemented(e);
+  }
+
+  ValueObjectSP VisitStructType(const GoASTStructType *e) {
+    return NotImplemented(e);
+  }
+
+  CompilerType EvaluateType(const GoASTExpr *e);
+
+  Error &error() { return m_error; }
+
+private:
+  std::nullptr_t NotImplemented(const GoASTExpr *e) {
+    m_error.SetErrorStringWithFormat("%s node not implemented",
+                                     e->GetKindName());
+    return nullptr;
+  }
 
-    ExecutionContext m_exe_ctx;
-    lldb::StackFrameSP m_frame;
-    GoParser m_parser;
-    DynamicValueType m_use_dynamic;
-    Error m_error;
-    llvm::StringRef m_package;
-    std::vector<std::unique_ptr<GoASTStmt>> m_statements;
+  ExecutionContext m_exe_ctx;
+  lldb::StackFrameSP m_frame;
+  GoParser m_parser;
+  DynamicValueType m_use_dynamic;
+  Error m_error;
+  llvm::StringRef m_package;
+  std::vector<std::unique_ptr<GoASTStmt>> m_statements;
 };
 
-VariableSP
-FindGlobalVariable(TargetSP target, llvm::Twine name)
-{
-    ConstString fullname(name.str());
-    VariableList variable_list;
-    const bool append = true;
-    if (!target)
-    {
-        return nullptr;
-    }
-    const uint32_t match_count = target->GetImages().FindGlobalVariables(fullname, append, 1, variable_list);
-    if (match_count == 1)
-    {
-        return variable_list.GetVariableAtIndex(0);
-    }
+VariableSP FindGlobalVariable(TargetSP target, llvm::Twine name) {
+  ConstString fullname(name.str());
+  VariableList variable_list;
+  const bool append = true;
+  if (!target) {
     return nullptr;
+  }
+  const uint32_t match_count = target->GetImages().FindGlobalVariables(
+      fullname, append, 1, variable_list);
+  if (match_count == 1) {
+    return variable_list.GetVariableAtIndex(0);
+  }
+  return nullptr;
 }
 
-CompilerType
-LookupType(TargetSP target, ConstString name)
-{
-    if (!target)
-        return CompilerType();
-    SymbolContext sc;
-    TypeList type_list;
-    llvm::DenseSet<SymbolFile *> searched_symbol_files;
-    uint32_t num_matches = target->GetImages().FindTypes(sc, name, false, 2, searched_symbol_files, type_list);
-    if (num_matches > 0)
-    {
-        return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
-    }
+CompilerType LookupType(TargetSP target, ConstString name) {
+  if (!target)
     return CompilerType();
+  SymbolContext sc;
+  TypeList type_list;
+  llvm::DenseSet<SymbolFile *> searched_symbol_files;
+  uint32_t num_matches = target->GetImages().FindTypes(
+      sc, name, false, 2, searched_symbol_files, type_list);
+  if (num_matches > 0) {
+    return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
+  }
+  return CompilerType();
 }
 
-GoUserExpression::GoUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
-                                   lldb::LanguageType language, ResultType desired_type,
+GoUserExpression::GoUserExpression(ExecutionContextScope &exe_scope,
+                                   const char *expr, const char *expr_prefix,
+                                   lldb::LanguageType language,
+                                   ResultType desired_type,
                                    const EvaluateExpressionOptions &options)
-    : UserExpression(exe_scope, expr, expr_prefix, language, desired_type, options)
-{
-}
+    : UserExpression(exe_scope, expr, expr_prefix, language, desired_type,
+                     options) {}
 
-bool
-GoUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
-                        lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
-                        bool generate_debug_info)
-{
-    InstallContext(exe_ctx);
-    m_interpreter.reset(new GoInterpreter(exe_ctx, GetUserText()));
-    if (m_interpreter->Parse())
-        return true;
-    const char *error_cstr = m_interpreter->error().AsCString();
-    if (error_cstr && error_cstr[0])
-        diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
-    else
-        diagnostic_manager.Printf(eDiagnosticSeverityError, "expression can't be interpreted or run");
-    return false;
+bool GoUserExpression::Parse(DiagnosticManager &diagnostic_manager,
+                             ExecutionContext &exe_ctx,
+                             lldb_private::ExecutionPolicy execution_policy,
+                             bool keep_result_in_memory,
+                             bool generate_debug_info) {
+  InstallContext(exe_ctx);
+  m_interpreter.reset(new GoInterpreter(exe_ctx, GetUserText()));
+  if (m_interpreter->Parse())
+    return true;
+  const char *error_cstr = m_interpreter->error().AsCString();
+  if (error_cstr && error_cstr[0])
+    diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
+  else
+    diagnostic_manager.Printf(eDiagnosticSeverityError,
+                              "expression can't be interpreted or run");
+  return false;
 }
 
 lldb::ExpressionResults
-GoUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
-                            const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me,
-                            lldb::ExpressionVariableSP &result)
-{
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-
-    lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
-    lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
-
-    Process *process = exe_ctx.GetProcessPtr();
-    Target *target = exe_ctx.GetTargetPtr();
-
-    if (target == nullptr || process == nullptr || process->GetState() != lldb::eStateStopped)
-    {
-        if (execution_policy == eExecutionPolicyAlways)
-        {
-            if (log)
-                log->Printf("== [GoUserExpression::Evaluate] Expression may not run, but is not constant ==");
-
-            diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression needed to run but couldn't");
-
-            return execution_results;
-        }
-    }
-
-    m_interpreter->set_use_dynamic(options.GetUseDynamic());
-    ValueObjectSP result_val_sp = m_interpreter->Evaluate(exe_ctx);
-    Error err = m_interpreter->error();
-    m_interpreter.reset();
-
-    if (!result_val_sp)
-    {
-        const char *error_cstr = err.AsCString();
-        if (error_cstr && error_cstr[0])
-            diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
-        else
-            diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
-        return lldb::eExpressionDiscarded;
-    }
-    result.reset(new ExpressionVariable(ExpressionVariable::eKindGo));
-    result->m_live_sp = result->m_frozen_sp = result_val_sp;
-    result->m_flags |= ExpressionVariable::EVIsProgramReference;
-    PersistentExpressionState *pv = target->GetPersistentExpressionStateForLanguage(eLanguageTypeGo);
-    if (pv != nullptr)
-    {
-        result->SetName(pv->GetNextPersistentVariableName());
-        pv->AddVariable(result);
-    }
-    return lldb::eExpressionCompleted;
-}
-
-bool
-GoUserExpression::GoInterpreter::Parse()
-{
-    for (std::unique_ptr<GoASTStmt> stmt(m_parser.Statement()); stmt; stmt.reset(m_parser.Statement()))
-    {
-        if (m_parser.Failed())
-            break;
-        m_statements.emplace_back(std::move(stmt));
-    }
-    if (m_parser.Failed() || !m_parser.AtEOF())
-        m_parser.GetError(m_error);
+GoUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
+                            ExecutionContext &exe_ctx,
+                            const EvaluateExpressionOptions &options,
+                            lldb::UserExpressionSP &shared_ptr_to_me,
+                            lldb::ExpressionVariableSP &result) {
+  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
+                                                  LIBLLDB_LOG_STEP));
+
+  lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
+  lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
+
+  Process *process = exe_ctx.GetProcessPtr();
+  Target *target = exe_ctx.GetTargetPtr();
+
+  if (target == nullptr || process == nullptr ||
+      process->GetState() != lldb::eStateStopped) {
+    if (execution_policy == eExecutionPolicyAlways) {
+      if (log)
+        log->Printf("== [GoUserExpression::Evaluate] Expression may not run, "
+                    "but is not constant ==");
+
+      diagnostic_manager.PutCString(eDiagnosticSeverityError,
+                                    "expression needed to run but couldn't");
+
+      return execution_results;
+    }
+  }
+
+  m_interpreter->set_use_dynamic(options.GetUseDynamic());
+  ValueObjectSP result_val_sp = m_interpreter->Evaluate(exe_ctx);
+  Error err = m_interpreter->error();
+  m_interpreter.reset();
 
-    return m_error.Success();
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::Evaluate(ExecutionContext &exe_ctx)
-{
-    m_exe_ctx = exe_ctx;
-    ValueObjectSP result;
-    for (const std::unique_ptr<GoASTStmt> &stmt : m_statements)
-    {
-        result = EvaluateStatement(stmt.get());
-        if (m_error.Fail())
-            return nullptr;
-    }
-    return result;
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::EvaluateStatement(const lldb_private::GoASTStmt *stmt)
-{
-    ValueObjectSP result;
-    switch (stmt->GetKind())
-    {
-        case GoASTNode::eBlockStmt:
-        {
-            const GoASTBlockStmt *block = llvm::cast<GoASTBlockStmt>(stmt);
-            for (size_t i = 0; i < block->NumList(); ++i)
-                result = EvaluateStatement(block->GetList(i));
-            break;
-        }
-        case GoASTNode::eBadStmt:
-            m_parser.GetError(m_error);
-            break;
-        case GoASTNode::eExprStmt:
-        {
-            const GoASTExprStmt *expr = llvm::cast<GoASTExprStmt>(stmt);
-            return EvaluateExpr(expr->GetX());
-        }
+  if (!result_val_sp) {
+    const char *error_cstr = err.AsCString();
+    if (error_cstr && error_cstr[0])
+      diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
+    else
+      diagnostic_manager.PutCString(eDiagnosticSeverityError,
+                                    "expression can't be interpreted or run");
+    return lldb::eExpressionDiscarded;
+  }
+  result.reset(new ExpressionVariable(ExpressionVariable::eKindGo));
+  result->m_live_sp = result->m_frozen_sp = result_val_sp;
+  result->m_flags |= ExpressionVariable::EVIsProgramReference;
+  PersistentExpressionState *pv =
+      target->GetPersistentExpressionStateForLanguage(eLanguageTypeGo);
+  if (pv != nullptr) {
+    result->SetName(pv->GetNextPersistentVariableName());
+    pv->AddVariable(result);
+  }
+  return lldb::eExpressionCompleted;
+}
+
+bool GoUserExpression::GoInterpreter::Parse() {
+  for (std::unique_ptr<GoASTStmt> stmt(m_parser.Statement()); stmt;
+       stmt.reset(m_parser.Statement())) {
+    if (m_parser.Failed())
+      break;
+    m_statements.emplace_back(std::move(stmt));
+  }
+  if (m_parser.Failed() || !m_parser.AtEOF())
+    m_parser.GetError(m_error);
+
+  return m_error.Success();
+}
+
+ValueObjectSP
+GoUserExpression::GoInterpreter::Evaluate(ExecutionContext &exe_ctx) {
+  m_exe_ctx = exe_ctx;
+  ValueObjectSP result;
+  for (const std::unique_ptr<GoASTStmt> &stmt : m_statements) {
+    result = EvaluateStatement(stmt.get());
+    if (m_error.Fail())
+      return nullptr;
+  }
+  return result;
+}
+
+ValueObjectSP GoUserExpression::GoInterpreter::EvaluateStatement(
+    const lldb_private::GoASTStmt *stmt) {
+  ValueObjectSP result;
+  switch (stmt->GetKind()) {
+  case GoASTNode::eBlockStmt: {
+    const GoASTBlockStmt *block = llvm::cast<GoASTBlockStmt>(stmt);
+    for (size_t i = 0; i < block->NumList(); ++i)
+      result = EvaluateStatement(block->GetList(i));
+    break;
+  }
+  case GoASTNode::eBadStmt:
+    m_parser.GetError(m_error);
+    break;
+  case GoASTNode::eExprStmt: {
+    const GoASTExprStmt *expr = llvm::cast<GoASTExprStmt>(stmt);
+    return EvaluateExpr(expr->GetX());
+  }
+  default:
+    m_error.SetErrorStringWithFormat("%s node not supported",
+                                     stmt->GetKindName());
+  }
+  return result;
+}
+
+ValueObjectSP GoUserExpression::GoInterpreter::EvaluateExpr(
+    const lldb_private::GoASTExpr *e) {
+  if (e)
+    return e->Visit<ValueObjectSP>(this);
+  return ValueObjectSP();
+}
+
+ValueObjectSP GoUserExpression::GoInterpreter::VisitParenExpr(
+    const lldb_private::GoASTParenExpr *e) {
+  return EvaluateExpr(e->GetX());
+}
+
+ValueObjectSP GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e) {
+  ValueObjectSP val;
+  if (m_frame) {
+    VariableSP var_sp;
+    std::string varname = e->GetName().m_value.str();
+    if (varname.size() > 1 && varname[0] == '$') {
+      RegisterContextSP reg_ctx_sp = m_frame->GetRegisterContext();
+      const RegisterInfo *reg =
+          reg_ctx_sp->GetRegisterInfoByName(varname.c_str() + 1);
+      if (reg) {
+        std::string type;
+        switch (reg->encoding) {
+        case lldb::eEncodingSint:
+          type.append("int");
+          break;
+        case lldb::eEncodingUint:
+          type.append("uint");
+          break;
+        case lldb::eEncodingIEEE754:
+          type.append("float");
+          break;
         default:
-            m_error.SetErrorStringWithFormat("%s node not supported", stmt->GetKindName());
-    }
-    return result;
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::EvaluateExpr(const lldb_private::GoASTExpr *e)
-{
-    if (e)
-        return e->Visit<ValueObjectSP>(this);
-    return ValueObjectSP();
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitParenExpr(const lldb_private::GoASTParenExpr *e)
-{
-    return EvaluateExpr(e->GetX());
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e)
-{
-    ValueObjectSP val;
-    if (m_frame)
-    {
-        VariableSP var_sp;
-        std::string varname = e->GetName().m_value.str();
-        if (varname.size() > 1 && varname[0] == '$')
-        {
-            RegisterContextSP reg_ctx_sp = m_frame->GetRegisterContext();
-            const RegisterInfo *reg = reg_ctx_sp->GetRegisterInfoByName(varname.c_str() + 1);
-            if (reg)
-            {
-                std::string type;
-                switch (reg->encoding)
-                {
-                    case lldb::eEncodingSint:
-                        type.append("int");
-                        break;
-                    case lldb::eEncodingUint:
-                        type.append("uint");
-                        break;
-                    case lldb::eEncodingIEEE754:
-                        type.append("float");
-                        break;
-                    default:
-                        m_error.SetErrorString("Invalid register encoding");
-                        return nullptr;
-                }
-                switch (reg->byte_size)
-                {
-                    case 8:
-                        type.append("64");
-                        break;
-                    case 4:
-                        type.append("32");
-                        break;
-                    case 2:
-                        type.append("16");
-                        break;
-                    case 1:
-                        type.append("8");
-                        break;
-                    default:
-                        m_error.SetErrorString("Invalid register size");
-                        return nullptr;
-                }
-                ValueObjectSP regVal =
-                    ValueObjectRegister::Create(m_frame.get(), reg_ctx_sp, reg->kinds[eRegisterKindLLDB]);
-                CompilerType goType = LookupType(m_frame->CalculateTarget(), ConstString(type));
-                if (regVal)
-                {
-                    regVal = regVal->Cast(goType);
-                    return regVal;
-                }
-            }
-            m_error.SetErrorString("Invalid register name");
-            return nullptr;
-        }
-        VariableListSP var_list_sp(m_frame->GetInScopeVariableList(false));
-        if (var_list_sp)
-        {
-            var_sp = var_list_sp->FindVariable(ConstString(varname));
-            if (var_sp)
-                val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
-            else
-            {
-                // When a variable is on the heap instead of the stack, go records a variable
-                // '&x' instead of 'x'.
-                var_sp = var_list_sp->FindVariable(ConstString("&" + varname));
-                if (var_sp)
-                {
-                    val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
-                    if (val)
-                        val = val->Dereference(m_error);
-                    if (m_error.Fail())
-                        return nullptr;
-                }
-            }
-        }
-        if (!val)
-        {
-            m_error.Clear();
-            TargetSP target = m_frame->CalculateTarget();
-            if (!target)
-            {
-                m_error.SetErrorString("No target");
-                return nullptr;
-            }
-            var_sp = FindGlobalVariable(target, m_package + "." + e->GetName().m_value);
-            if (var_sp)
-                return m_frame->TrackGlobalVariable(var_sp, m_use_dynamic);
-        }
-    }
-    if (!val)
-        m_error.SetErrorStringWithFormat("Unknown variable %s", e->GetName().m_value.str().c_str());
-    return val;
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitStarExpr(const GoASTStarExpr *e)
-{
-    ValueObjectSP target = EvaluateExpr(e->GetX());
-    if (!target)
-        return nullptr;
-    return target->Dereference(m_error);
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitSelectorExpr(const lldb_private::GoASTSelectorExpr *e)
-{
-    ValueObjectSP target = EvaluateExpr(e->GetX());
-    if (target)
-    {
-        if (target->GetCompilerType().IsPointerType())
-        {
-            target = target->Dereference(m_error);
-            if (m_error.Fail())
-                return nullptr;
+          m_error.SetErrorString("Invalid register encoding");
+          return nullptr;
         }
-        ConstString field(e->GetSel()->GetName().m_value);
-        ValueObjectSP result = target->GetChildMemberWithName(field, true);
-        if (!result)
-            m_error.SetErrorStringWithFormat("Unknown child %s", field.AsCString());
-        return result;
-    }
-    if (const GoASTIdent *package = llvm::dyn_cast<GoASTIdent>(e->GetX()))
-    {
-        if (VariableSP global = FindGlobalVariable(m_exe_ctx.GetTargetSP(),
-                                                   package->GetName().m_value + "." + e->GetSel()->GetName().m_value))
-        {
-            if (m_frame)
-            {
-                m_error.Clear();
-                return m_frame->GetValueObjectForFrameVariable(global, m_use_dynamic);
-            }
+        switch (reg->byte_size) {
+        case 8:
+          type.append("64");
+          break;
+        case 4:
+          type.append("32");
+          break;
+        case 2:
+          type.append("16");
+          break;
+        case 1:
+          type.append("8");
+          break;
+        default:
+          m_error.SetErrorString("Invalid register size");
+          return nullptr;
         }
-    }
-    if (const GoASTBasicLit *packageLit = llvm::dyn_cast<GoASTBasicLit>(e->GetX()))
-    {
-        if (packageLit->GetValue().m_type == GoLexer::LIT_STRING)
-        {
-            std::string value = packageLit->GetValue().m_value.str();
-            value = value.substr(1, value.size() - 2);
-            if (VariableSP global =
-                    FindGlobalVariable(m_exe_ctx.GetTargetSP(), value + "." + e->GetSel()->GetName().m_value))
-            {
-                if (m_frame)
-                {
-                    m_error.Clear();
-                    return m_frame->TrackGlobalVariable(global, m_use_dynamic);
-                }
-            }
+        ValueObjectSP regVal = ValueObjectRegister::Create(
+            m_frame.get(), reg_ctx_sp, reg->kinds[eRegisterKindLLDB]);
+        CompilerType goType =
+            LookupType(m_frame->CalculateTarget(), ConstString(type));
+        if (regVal) {
+          regVal = regVal->Cast(goType);
+          return regVal;
+        }
+      }
+      m_error.SetErrorString("Invalid register name");
+      return nullptr;
+    }
+    VariableListSP var_list_sp(m_frame->GetInScopeVariableList(false));
+    if (var_list_sp) {
+      var_sp = var_list_sp->FindVariable(ConstString(varname));
+      if (var_sp)
+        val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
+      else {
+        // When a variable is on the heap instead of the stack, go records a
+        // variable
+        // '&x' instead of 'x'.
+        var_sp = var_list_sp->FindVariable(ConstString("&" + varname));
+        if (var_sp) {
+          val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
+          if (val)
+            val = val->Dereference(m_error);
+          if (m_error.Fail())
+            return nullptr;
         }
+      }
     }
-    // EvaluateExpr should have already set m_error.
-    return target;
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitBasicLit(const lldb_private::GoASTBasicLit *e)
-{
-    std::string value = e->GetValue().m_value.str();
-    if (e->GetValue().m_type != GoLexer::LIT_INTEGER)
-    {
-        m_error.SetErrorStringWithFormat("Unsupported literal %s", value.c_str());
-        return nullptr;
-    }
-    errno = 0;
-    int64_t intvalue = strtol(value.c_str(), nullptr, 0);
-    if (errno != 0)
-    {
-        m_error.SetErrorToErrno();
-        return nullptr;
-    }
-    DataBufferSP buf(new DataBufferHeap(sizeof(intvalue), 0));
-    TargetSP target = m_exe_ctx.GetTargetSP();
-    if (!target)
-    {
+    if (!val) {
+      m_error.Clear();
+      TargetSP target = m_frame->CalculateTarget();
+      if (!target) {
         m_error.SetErrorString("No target");
         return nullptr;
-    }
-    ByteOrder order = target->GetArchitecture().GetByteOrder();
-    uint8_t addr_size = target->GetArchitecture().GetAddressByteSize();
-    DataEncoder enc(buf, order, addr_size);
-    enc.PutU64(0, static_cast<uint64_t>(intvalue));
-    DataExtractor data(buf, order, addr_size);
-
-    CompilerType type = LookupType(target, ConstString("int64"));
-    return ValueObject::CreateValueObjectFromData(nullptr, data, m_exe_ctx, type);
+      }
+      var_sp =
+          FindGlobalVariable(target, m_package + "." + e->GetName().m_value);
+      if (var_sp)
+        return m_frame->TrackGlobalVariable(var_sp, m_use_dynamic);
+    }
+  }
+  if (!val)
+    m_error.SetErrorStringWithFormat("Unknown variable %s",
+                                     e->GetName().m_value.str().c_str());
+  return val;
 }
 
 ValueObjectSP
-GoUserExpression::GoInterpreter::VisitIndexExpr(const lldb_private::GoASTIndexExpr *e)
-{
-    ValueObjectSP target = EvaluateExpr(e->GetX());
-    if (!target)
-        return nullptr;
-    ValueObjectSP index = EvaluateExpr(e->GetIndex());
-    if (!index)
-        return nullptr;
-    bool is_signed;
-    if (!index->GetCompilerType().IsIntegerType(is_signed))
-    {
-        m_error.SetErrorString("Unsupported index");
-        return nullptr;
-    }
-    size_t idx;
-    if (is_signed)
-        idx = index->GetValueAsSigned(0);
-    else
-        idx = index->GetValueAsUnsigned(0);
-    if (GoASTContext::IsGoSlice(target->GetCompilerType()))
-    {
-        target = target->GetStaticValue();
-        ValueObjectSP cap = target->GetChildMemberWithName(ConstString("cap"), true);
-        if (cap)
-        {
-            uint64_t capval = cap->GetValueAsUnsigned(0);
-            if (idx >= capval)
-            {
-                m_error.SetErrorStringWithFormat("Invalid index %" PRIu64 " , cap = %" PRIu64, uint64_t(idx), capval);
-                return nullptr;
-            }
-        }
-        target = target->GetChildMemberWithName(ConstString("array"), true);
-        if (target && m_use_dynamic != eNoDynamicValues)
-        {
-            ValueObjectSP dynamic = target->GetDynamicValue(m_use_dynamic);
-            if (dynamic)
-                target = dynamic;
-        }
-        if (!target)
-            return nullptr;
-        return target->GetSyntheticArrayMember(idx, true);
-    }
-    return target->GetChildAtIndex(idx, true);
+GoUserExpression::GoInterpreter::VisitStarExpr(const GoASTStarExpr *e) {
+  ValueObjectSP target = EvaluateExpr(e->GetX());
+  if (!target)
+    return nullptr;
+  return target->Dereference(m_error);
 }
 
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitUnaryExpr(const GoASTUnaryExpr *e)
-{
-    ValueObjectSP x = EvaluateExpr(e->GetX());
-    if (!x)
-        return nullptr;
-    switch (e->GetOp())
-    {
-        case GoLexer::OP_AMP:
-        {
-            CompilerType type = x->GetCompilerType().GetPointerType();
-            uint64_t address = x->GetAddressOf();
-            return ValueObject::CreateValueObjectFromAddress(nullptr, address, m_exe_ctx, type);
-        }
-        case GoLexer::OP_PLUS:
-            return x;
-        default:
-            m_error.SetErrorStringWithFormat("Operator %s not supported",
-                                             GoLexer::LookupToken(e->GetOp()).str().c_str());
-            return nullptr;
-    }
+ValueObjectSP GoUserExpression::GoInterpreter::VisitSelectorExpr(
+    const lldb_private::GoASTSelectorExpr *e) {
+  ValueObjectSP target = EvaluateExpr(e->GetX());
+  if (target) {
+    if (target->GetCompilerType().IsPointerType()) {
+      target = target->Dereference(m_error);
+      if (m_error.Fail())
+        return nullptr;
+    }
+    ConstString field(e->GetSel()->GetName().m_value);
+    ValueObjectSP result = target->GetChildMemberWithName(field, true);
+    if (!result)
+      m_error.SetErrorStringWithFormat("Unknown child %s", field.AsCString());
+    return result;
+  }
+  if (const GoASTIdent *package = llvm::dyn_cast<GoASTIdent>(e->GetX())) {
+    if (VariableSP global = FindGlobalVariable(
+            m_exe_ctx.GetTargetSP(), package->GetName().m_value + "." +
+                                         e->GetSel()->GetName().m_value)) {
+      if (m_frame) {
+        m_error.Clear();
+        return m_frame->GetValueObjectForFrameVariable(global, m_use_dynamic);
+      }
+    }
+  }
+  if (const GoASTBasicLit *packageLit =
+          llvm::dyn_cast<GoASTBasicLit>(e->GetX())) {
+    if (packageLit->GetValue().m_type == GoLexer::LIT_STRING) {
+      std::string value = packageLit->GetValue().m_value.str();
+      value = value.substr(1, value.size() - 2);
+      if (VariableSP global = FindGlobalVariable(
+              m_exe_ctx.GetTargetSP(),
+              value + "." + e->GetSel()->GetName().m_value)) {
+        if (m_frame) {
+          m_error.Clear();
+          return m_frame->TrackGlobalVariable(global, m_use_dynamic);
+        }
+      }
+    }
+  }
+  // EvaluateExpr should have already set m_error.
+  return target;
+}
+
+ValueObjectSP GoUserExpression::GoInterpreter::VisitBasicLit(
+    const lldb_private::GoASTBasicLit *e) {
+  std::string value = e->GetValue().m_value.str();
+  if (e->GetValue().m_type != GoLexer::LIT_INTEGER) {
+    m_error.SetErrorStringWithFormat("Unsupported literal %s", value.c_str());
+    return nullptr;
+  }
+  errno = 0;
+  int64_t intvalue = strtol(value.c_str(), nullptr, 0);
+  if (errno != 0) {
+    m_error.SetErrorToErrno();
+    return nullptr;
+  }
+  DataBufferSP buf(new DataBufferHeap(sizeof(intvalue), 0));
+  TargetSP target = m_exe_ctx.GetTargetSP();
+  if (!target) {
+    m_error.SetErrorString("No target");
+    return nullptr;
+  }
+  ByteOrder order = target->GetArchitecture().GetByteOrder();
+  uint8_t addr_size = target->GetArchitecture().GetAddressByteSize();
+  DataEncoder enc(buf, order, addr_size);
+  enc.PutU64(0, static_cast<uint64_t>(intvalue));
+  DataExtractor data(buf, order, addr_size);
+
+  CompilerType type = LookupType(target, ConstString("int64"));
+  return ValueObject::CreateValueObjectFromData(nullptr, data, m_exe_ctx, type);
 }
 
-CompilerType
-GoUserExpression::GoInterpreter::EvaluateType(const GoASTExpr *e)
-{
-    TargetSP target = m_exe_ctx.GetTargetSP();
-    if (auto *id = llvm::dyn_cast<GoASTIdent>(e))
-    {
-        CompilerType result = LookupType(target, ConstString(id->GetName().m_value));
-        if (result.IsValid())
-            return result;
-        std::string fullname = (m_package + "." + id->GetName().m_value).str();
-        result = LookupType(target, ConstString(fullname));
-        if (!result)
-            m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
-        return result;
-    }
-    if (auto *sel = llvm::dyn_cast<GoASTSelectorExpr>(e))
-    {
-        std::string package;
-        if (auto *pkg_node = llvm::dyn_cast<GoASTIdent>(sel->GetX()))
-        {
-            package = pkg_node->GetName().m_value.str();
-        }
-        else if (auto *str_node = llvm::dyn_cast<GoASTBasicLit>(sel->GetX()))
-        {
-            if (str_node->GetValue().m_type == GoLexer::LIT_STRING)
-            {
-                package = str_node->GetValue().m_value.substr(1).str();
-                package.resize(package.length() - 1);
-            }
-        }
-        if (package.empty())
-        {
-            m_error.SetErrorStringWithFormat("Invalid %s in type expression", sel->GetX()->GetKindName());
-            return CompilerType();
-        }
-        std::string fullname = (package + "." + sel->GetSel()->GetName().m_value).str();
-        CompilerType result = LookupType(target, ConstString(fullname));
-        if (!result)
-            m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
-        return result;
-    }
-    if (auto *star = llvm::dyn_cast<GoASTStarExpr>(e))
-    {
-        CompilerType elem = EvaluateType(star->GetX());
-        return elem.GetPointerType();
-    }
-    if (auto *paren = llvm::dyn_cast<GoASTParenExpr>(e))
-        return EvaluateType(paren->GetX());
-    if (auto *array = llvm::dyn_cast<GoASTArrayType>(e))
-    {
-        CompilerType elem = EvaluateType(array->GetElt());
+ValueObjectSP GoUserExpression::GoInterpreter::VisitIndexExpr(
+    const lldb_private::GoASTIndexExpr *e) {
+  ValueObjectSP target = EvaluateExpr(e->GetX());
+  if (!target)
+    return nullptr;
+  ValueObjectSP index = EvaluateExpr(e->GetIndex());
+  if (!index)
+    return nullptr;
+  bool is_signed;
+  if (!index->GetCompilerType().IsIntegerType(is_signed)) {
+    m_error.SetErrorString("Unsupported index");
+    return nullptr;
+  }
+  size_t idx;
+  if (is_signed)
+    idx = index->GetValueAsSigned(0);
+  else
+    idx = index->GetValueAsUnsigned(0);
+  if (GoASTContext::IsGoSlice(target->GetCompilerType())) {
+    target = target->GetStaticValue();
+    ValueObjectSP cap =
+        target->GetChildMemberWithName(ConstString("cap"), true);
+    if (cap) {
+      uint64_t capval = cap->GetValueAsUnsigned(0);
+      if (idx >= capval) {
+        m_error.SetErrorStringWithFormat("Invalid index %" PRIu64
+                                         " , cap = %" PRIu64,
+                                         uint64_t(idx), capval);
+        return nullptr;
+      }
+    }
+    target = target->GetChildMemberWithName(ConstString("array"), true);
+    if (target && m_use_dynamic != eNoDynamicValues) {
+      ValueObjectSP dynamic = target->GetDynamicValue(m_use_dynamic);
+      if (dynamic)
+        target = dynamic;
     }
-
-    m_error.SetErrorStringWithFormat("Invalid %s in type expression", e->GetKindName());
-    return CompilerType();
+    if (!target)
+      return nullptr;
+    return target->GetSyntheticArrayMember(idx, true);
+  }
+  return target->GetChildAtIndex(idx, true);
 }
 
 ValueObjectSP
-GoUserExpression::GoInterpreter::VisitCallExpr(const lldb_private::GoASTCallExpr *e)
-{
-    ValueObjectSP x = EvaluateExpr(e->GetFun());
-    if (x || e->NumArgs() != 1)
-    {
-        m_error.SetErrorStringWithFormat("Code execution not supported");
-        return nullptr;
-    }
-    m_error.Clear();
-    CompilerType type = EvaluateType(e->GetFun());
-    if (!type)
-    {
-        return nullptr;
-    }
-    ValueObjectSP value = EvaluateExpr(e->GetArgs(0));
-    if (!value)
-        return nullptr;
-    // TODO: Handle special conversions
-    return value->Cast(type);
+GoUserExpression::GoInterpreter::VisitUnaryExpr(const GoASTUnaryExpr *e) {
+  ValueObjectSP x = EvaluateExpr(e->GetX());
+  if (!x)
+    return nullptr;
+  switch (e->GetOp()) {
+  case GoLexer::OP_AMP: {
+    CompilerType type = x->GetCompilerType().GetPointerType();
+    uint64_t address = x->GetAddressOf();
+    return ValueObject::CreateValueObjectFromAddress(nullptr, address,
+                                                     m_exe_ctx, type);
+  }
+  case GoLexer::OP_PLUS:
+    return x;
+  default:
+    m_error.SetErrorStringWithFormat(
+        "Operator %s not supported",
+        GoLexer::LookupToken(e->GetOp()).str().c_str());
+    return nullptr;
+  }
 }
 
-GoPersistentExpressionState::GoPersistentExpressionState() : PersistentExpressionState(eKindGo)
-{
+CompilerType GoUserExpression::GoInterpreter::EvaluateType(const GoASTExpr *e) {
+  TargetSP target = m_exe_ctx.GetTargetSP();
+  if (auto *id = llvm::dyn_cast<GoASTIdent>(e)) {
+    CompilerType result =
+        LookupType(target, ConstString(id->GetName().m_value));
+    if (result.IsValid())
+      return result;
+    std::string fullname = (m_package + "." + id->GetName().m_value).str();
+    result = LookupType(target, ConstString(fullname));
+    if (!result)
+      m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
+    return result;
+  }
+  if (auto *sel = llvm::dyn_cast<GoASTSelectorExpr>(e)) {
+    std::string package;
+    if (auto *pkg_node = llvm::dyn_cast<GoASTIdent>(sel->GetX())) {
+      package = pkg_node->GetName().m_value.str();
+    } else if (auto *str_node = llvm::dyn_cast<GoASTBasicLit>(sel->GetX())) {
+      if (str_node->GetValue().m_type == GoLexer::LIT_STRING) {
+        package = str_node->GetValue().m_value.substr(1).str();
+        package.resize(package.length() - 1);
+      }
+    }
+    if (package.empty()) {
+      m_error.SetErrorStringWithFormat("Invalid %s in type expression",
+                                       sel->GetX()->GetKindName());
+      return CompilerType();
+    }
+    std::string fullname =
+        (package + "." + sel->GetSel()->GetName().m_value).str();
+    CompilerType result = LookupType(target, ConstString(fullname));
+    if (!result)
+      m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
+    return result;
+  }
+  if (auto *star = llvm::dyn_cast<GoASTStarExpr>(e)) {
+    CompilerType elem = EvaluateType(star->GetX());
+    return elem.GetPointerType();
+  }
+  if (auto *paren = llvm::dyn_cast<GoASTParenExpr>(e))
+    return EvaluateType(paren->GetX());
+  if (auto *array = llvm::dyn_cast<GoASTArrayType>(e)) {
+    CompilerType elem = EvaluateType(array->GetElt());
+  }
+
+  m_error.SetErrorStringWithFormat("Invalid %s in type expression",
+                                   e->GetKindName());
+  return CompilerType();
+}
+
+ValueObjectSP GoUserExpression::GoInterpreter::VisitCallExpr(
+    const lldb_private::GoASTCallExpr *e) {
+  ValueObjectSP x = EvaluateExpr(e->GetFun());
+  if (x || e->NumArgs() != 1) {
+    m_error.SetErrorStringWithFormat("Code execution not supported");
+    return nullptr;
+  }
+  m_error.Clear();
+  CompilerType type = EvaluateType(e->GetFun());
+  if (!type) {
+    return nullptr;
+  }
+  ValueObjectSP value = EvaluateExpr(e->GetArgs(0));
+  if (!value)
+    return nullptr;
+  // TODO: Handle special conversions
+  return value->Cast(type);
 }
 
-ConstString
-GoPersistentExpressionState::GetNextPersistentVariableName()
-{
-    char name_cstr[256];
-    // We can't use the same variable format as clang.
-    ::snprintf(name_cstr, sizeof(name_cstr), "$go%u", m_next_persistent_variable_id++);
-    ConstString name(name_cstr);
-    return name;
+GoPersistentExpressionState::GoPersistentExpressionState()
+    : PersistentExpressionState(eKindGo) {}
+
+ConstString GoPersistentExpressionState::GetNextPersistentVariableName() {
+  char name_cstr[256];
+  // We can't use the same variable format as clang.
+  ::snprintf(name_cstr, sizeof(name_cstr), "$go%u",
+             m_next_persistent_variable_id++);
+  ConstString name(name_cstr);
+  return name;
 }
 
-void
-GoPersistentExpressionState::RemovePersistentVariable(lldb::ExpressionVariableSP variable)
-{
-    RemoveVariable(variable);
+void GoPersistentExpressionState::RemovePersistentVariable(
+    lldb::ExpressionVariableSP variable) {
+  RemoveVariable(variable);
 
-    const char *name = variable->GetName().AsCString();
+  const char *name = variable->GetName().AsCString();
 
-    if (*(name++) != '$')
-        return;
-    if (*(name++) != 'g')
-        return;
-    if (*(name++) != 'o')
-        return;
+  if (*(name++) != '$')
+    return;
+  if (*(name++) != 'g')
+    return;
+  if (*(name++) != 'o')
+    return;
 
-    if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1)
-        m_next_persistent_variable_id--;
+  if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1)
+    m_next_persistent_variable_id--;
 }

Modified: lldb/trunk/source/Plugins/ExpressionParser/Go/GoUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Go/GoUserExpression.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Go/GoUserExpression.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Go/GoUserExpression.h Tue Sep  6 15:57:50 2016
@@ -16,83 +16,75 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
-#include "lldb/Expression/UserExpression.h"
 #include "lldb/Expression/ExpressionVariable.h"
+#include "lldb/Expression/UserExpression.h"
 #include "lldb/Target/ExecutionContext.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
 
-namespace lldb_private
-{
+namespace lldb_private {
 class GoParser;
 
-class GoPersistentExpressionState : public PersistentExpressionState
-{
-  public:
-    GoPersistentExpressionState();
-
-    ConstString GetNextPersistentVariableName() override;
-
-    void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
-
-    lldb::addr_t
-    LookupSymbol(const ConstString &name) override
-    {
-        return LLDB_INVALID_ADDRESS;
-    }
-
-    static bool
-    classof(const PersistentExpressionState *pv)
-    {
-        return pv->getKind() == PersistentExpressionState::eKindGo;
-    }
+class GoPersistentExpressionState : public PersistentExpressionState {
+public:
+  GoPersistentExpressionState();
+
+  ConstString GetNextPersistentVariableName() override;
+
+  void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
+
+  lldb::addr_t LookupSymbol(const ConstString &name) override {
+    return LLDB_INVALID_ADDRESS;
+  }
+
+  static bool classof(const PersistentExpressionState *pv) {
+    return pv->getKind() == PersistentExpressionState::eKindGo;
+  }
 
-  private:
-    uint32_t m_next_persistent_variable_id; ///< The counter used by GetNextResultName().
+private:
+  uint32_t m_next_persistent_variable_id; ///< The counter used by
+                                          ///GetNextResultName().
 };
 
 //----------------------------------------------------------------------
-/// @class GoUserExpression GoUserExpression.h "lldb/Expression/GoUserExpression.h"
+/// @class GoUserExpression GoUserExpression.h
+/// "lldb/Expression/GoUserExpression.h"
 /// @brief Encapsulates a single expression for use with Go
 ///
 /// LLDB uses expressions for various purposes, notably to call functions
 /// and as a backend for the expr command.  GoUserExpression encapsulates
 /// the objects needed to parse and interpret an expression.
 //----------------------------------------------------------------------
-class GoUserExpression : public UserExpression
-{
-  public:
-      GoUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
-                       lldb::LanguageType language, ResultType desired_type, const EvaluateExpressionOptions &options);
-
-      bool
-      Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
-            lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
-            bool generate_debug_info) override;
-
-      bool
-      CanInterpret() override
-      {
-          return true;
-      }
-      bool
-      FinalizeJITExecution(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
-                           lldb::ExpressionVariableSP &result,
-                           lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
-                           lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override
-      {
-          return true;
-    }
-
-  protected:
-      lldb::ExpressionResults
-      DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
-                const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me,
-                lldb::ExpressionVariableSP &result) override;
-
-  private:
-    class GoInterpreter;
-    std::unique_ptr<GoInterpreter> m_interpreter;
+class GoUserExpression : public UserExpression {
+public:
+  GoUserExpression(ExecutionContextScope &exe_scope, const char *expr,
+                   const char *expr_prefix, lldb::LanguageType language,
+                   ResultType desired_type,
+                   const EvaluateExpressionOptions &options);
+
+  bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+             lldb_private::ExecutionPolicy execution_policy,
+             bool keep_result_in_memory, bool generate_debug_info) override;
+
+  bool CanInterpret() override { return true; }
+  bool FinalizeJITExecution(
+      DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+      lldb::ExpressionVariableSP &result,
+      lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
+      lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override {
+    return true;
+  }
+
+protected:
+  lldb::ExpressionResults
+  DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
+            const EvaluateExpressionOptions &options,
+            lldb::UserExpressionSP &shared_ptr_to_me,
+            lldb::ExpressionVariableSP &result) override;
+
+private:
+  class GoInterpreter;
+  std::unique_ptr<GoInterpreter> m_interpreter;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/source/Plugins/ExpressionParser/Go/gen_go_ast.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Go/gen_go_ast.py?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Go/gen_go_ast.py (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Go/gen_go_ast.py Tue Sep  6 15:57:50 2016
@@ -1,8 +1,17 @@
 import StringIO
 
+
 def addNodes():
     addNode("ArrayType", "Expr", "len", "Expr", "elt", "Expr")
-    addNode("AssignStmt", "Stmt", "lhs", "[]Expr", "rhs", "[]Expr", "define", "bool")
+    addNode(
+        "AssignStmt",
+        "Stmt",
+        "lhs",
+        "[]Expr",
+        "rhs",
+        "[]Expr",
+        "define",
+        "bool")
     addNode("BadDecl", "Decl")
     addNode("BadExpr", "Expr")
     addNode("BadStmt", "Stmt")
@@ -11,7 +20,15 @@ def addNodes():
     addNode("BlockStmt", "Stmt", "list", "[]Stmt")
     addNode("Ident", "Expr", "name", "Token")
     addNode("BranchStmt", "Stmt", "label", "Ident", "tok", "TokenType")
-    addNode("CallExpr", "Expr", "fun", "Expr", "args", "[]Expr", "ellipsis", "bool")
+    addNode(
+        "CallExpr",
+        "Expr",
+        "fun",
+        "Expr",
+        "args",
+        "[]Expr",
+        "ellipsis",
+        "bool")
     addNode("CaseClause", "Stmt", "list", "[]Expr", "body", "[]Stmt")
     addNode("ChanType", "Expr", "dir", "ChanDir", "value", "Expr")
     addNode("CommClause", "Stmt", "comm", "Stmt", "body", "[]Stmt")
@@ -21,15 +38,53 @@ def addNodes():
     addNode("Ellipsis", "Expr", "elt", "Expr")
     addNode("EmptyStmt", "Stmt")
     addNode("ExprStmt", "Stmt", "x", "Expr")
-    addNode("Field", "Node", "names", "[]Ident", "type", "Expr", "tag", "BasicLit")
+    addNode(
+        "Field",
+        "Node",
+        "names",
+        "[]Ident",
+        "type",
+        "Expr",
+        "tag",
+        "BasicLit")
     addNode("FieldList", "Node", "list", "[]Field")
-    addNode("ForStmt", "Stmt", "init", "Stmt", "cond", "Expr", "post", "Stmt", "body", "BlockStmt")
+    addNode(
+        "ForStmt",
+        "Stmt",
+        "init",
+        "Stmt",
+        "cond",
+        "Expr",
+        "post",
+        "Stmt",
+        "body",
+        "BlockStmt")
     addNode("FuncType", "Expr", "params", "FieldList", "results", "FieldList")
-    addNode("FuncDecl", "Decl", "recv", "FieldList", "name", "Ident", "type", "FuncType", "body", "BlockStmt")
+    addNode(
+        "FuncDecl",
+        "Decl",
+        "recv",
+        "FieldList",
+        "name",
+        "Ident",
+        "type",
+        "FuncType",
+        "body",
+        "BlockStmt")
     addNode("FuncLit", "Expr", "type", "FuncType", "body", "BlockStmt")
     addNode("GenDecl", "Decl", "tok", "TokenType", "specs", "[]Spec")
     addNode("GoStmt", "Stmt", "call", "CallExpr")
-    addNode("IfStmt", "Stmt", "init", "Stmt", "cond", "Expr", "body", "BlockStmt", "els", "Stmt")
+    addNode(
+        "IfStmt",
+        "Stmt",
+        "init",
+        "Stmt",
+        "cond",
+        "Expr",
+        "body",
+        "BlockStmt",
+        "els",
+        "Stmt")
     addNode("ImportSpec", "Spec", "name", "Ident", "path", "BasicLit")
     addNode("IncDecStmt", "Stmt", "x", "Expr", "tok", "TokenType")
     addNode("IndexExpr", "Expr", "x", "Expr", "index", "Expr")
@@ -38,20 +93,68 @@ def addNodes():
     addNode("LabeledStmt", "Stmt", "label", "Ident", "stmt", "Stmt")
     addNode("MapType", "Expr", "key", "Expr", "value", "Expr")
     addNode("ParenExpr", "Expr", "x", "Expr")
-    addNode("RangeStmt", "Stmt", "key", "Expr", "value", "Expr", "define", "bool", "x", "Expr", "body", "BlockStmt")
+    addNode(
+        "RangeStmt",
+        "Stmt",
+        "key",
+        "Expr",
+        "value",
+        "Expr",
+        "define",
+        "bool",
+        "x",
+        "Expr",
+        "body",
+        "BlockStmt")
     addNode("ReturnStmt", "Stmt", "results", "[]Expr")
     addNode("SelectStmt", "Stmt", "body", "BlockStmt")
     addNode("SelectorExpr", "Expr", "x", "Expr", "sel", "Ident")
     addNode("SendStmt", "Stmt", "chan", "Expr", "value", "Expr")
-    addNode("SliceExpr", "Expr", "x", "Expr", "low", "Expr", "high", "Expr", "max", "Expr", "slice3", "bool")
+    addNode(
+        "SliceExpr",
+        "Expr",
+        "x",
+        "Expr",
+        "low",
+        "Expr",
+        "high",
+        "Expr",
+        "max",
+        "Expr",
+        "slice3",
+        "bool")
     addNode("StarExpr", "Expr", "x", "Expr")
     addNode("StructType", "Expr", "fields", "FieldList")
-    addNode("SwitchStmt", "Stmt", "init", "Stmt", "tag", "Expr", "body", "BlockStmt")
+    addNode(
+        "SwitchStmt",
+        "Stmt",
+        "init",
+        "Stmt",
+        "tag",
+        "Expr",
+        "body",
+        "BlockStmt")
     addNode("TypeAssertExpr", "Expr", "x", "Expr", "type", "Expr")
     addNode("TypeSpec", "Spec", "name", "Ident", "type", "Expr")
-    addNode("TypeSwitchStmt", "Stmt", "init", "Stmt", "assign", "Stmt", "body", "BlockStmt")
+    addNode(
+        "TypeSwitchStmt",
+        "Stmt",
+        "init",
+        "Stmt",
+        "assign",
+        "Stmt",
+        "body",
+        "BlockStmt")
     addNode("UnaryExpr", "Expr", "op", "TokenType", "x", "Expr")
-    addNode("ValueSpec", "Spec", "names", "[]Ident", "type", "Expr", "values", "[]Expr")
+    addNode(
+        "ValueSpec",
+        "Spec",
+        "names",
+        "[]Ident",
+        "type",
+        "Expr",
+        "values",
+        "[]Expr")
     addParent("Decl", "Node")
     addParent("Expr", "Node")
     addParent("Spec", "Node")
@@ -59,6 +162,7 @@ def addNodes():
 
 
 class Member(object):
+
     def __init__(self, name, typename):
         self.title = name.title()
         self.sname = name
@@ -75,13 +179,14 @@ class Member(object):
             self.argtype = 'GoAST' + typename
             self.mtype = 'std::unique_ptr<%s>' % self.argtype
             self.mname = self.mname + '_up'
-    
+
 
 kinds = {}
 parentClasses = StringIO.StringIO()
 childClasses = StringIO.StringIO()
 walker = StringIO.StringIO()
 
+
 def startClass(name, parent, out):
     out.write("""
 class GoAST%s : public GoAST%s
@@ -89,6 +194,7 @@ class GoAST%s : public GoAST%s
   public:
 """ % (name, parent))
 
+
 def endClass(name, out):
     out.write("""
     %(name)s(const %(name)s &) = delete;
@@ -96,6 +202,7 @@ def endClass(name, out):
 };
 """ % {'name': 'GoAST' + name})
 
+
 def addNode(name, parent, *children):
     startClass(name, parent, childClasses)
     l = kinds.setdefault(parent, [])
@@ -114,10 +221,11 @@ def addNode(name, parent, *children):
     {
         return n->GetKind() == e%(name)s;
     }
-    """ % {'name':name})
+    """ % {'name': name})
     addChildren(name, children)
     endClass(name, childClasses)
 
+
 def isValueType(typename):
     if typename[0].islower():
         return True
@@ -161,7 +269,7 @@ def addConstructor(name, parent, childre
     ~GoAST%s() override = default;
 """ % name)
 
-    
+
 def addChildren(name, children):
     if len(children) == 0:
         return
@@ -169,7 +277,7 @@ def addChildren(name, children):
     case e%(n)s:
         {
             GoAST%(n)s *n = llvm::cast<GoAST%(n)s>(this);
-            (void)n;""" % {'n':name})
+            (void)n;""" % {'n': name})
     for c in children:
         if c.is_list:
             childClasses.write("""
@@ -217,14 +325,14 @@ def addChildren(name, children):
     {
         %(set)s;
     }
-""" % {'const':const, 'title': c.title, 'sname': c.sname, 'get': get, 'set': set, 'type': t, 'mname': c.mname})
+""" % {'const': const, 'title': c.title, 'sname': c.sname, 'get': get, 'set': set, 'type': t, 'mname': c.mname})
     childClasses.write('\n  private:\n    friend class GoASTNode;\n')
     walker.write("""
             return;
         }""")
     for c in children:
-        childClasses.write('    %s %s;\n' %(c.mtype, c.mname))
-    
+        childClasses.write('    %s %s;\n' % (c.mtype, c.mname))
+
 
 def addParent(name, parent):
     startClass(name, parent, parentClasses)
@@ -244,7 +352,7 @@ def addParent(name, parent):
   private:
 """ % (minName, maxName, name))
     endClass(name, parentClasses)
-    
+
 addNodes()
 
 print """//===-- GoAST.h -------------------------------------------------*- C++ -*-===//
@@ -305,7 +413,7 @@ print """    };
 
   private:
     const NodeKind m_kind;
-    
+
     GoASTNode(const GoASTNode &) = delete;
     const GoASTNode &operator=(const GoASTNode &) = delete;
 };
@@ -326,7 +434,7 @@ R GoAST%s::Visit(V* v) const
     {""" % k
     for subtype in l:
         print """    case e%(n)s:
-        return v->Visit%(n)s(llvm::cast<const GoAST%(n)s>(this));""" % {'n':subtype}
+        return v->Visit%(n)s(llvm::cast<const GoAST%(n)s>(this));""" % {'n': subtype}
 
     print """    default:
         assert(false && "Invalid kind");




More information about the lldb-commits mailing list