[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