summaryrefslogtreecommitdiff
path: root/include/lldb/Expression
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:55:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:55:28 +0000
commite81d9d49145e432d917eea3a70d2ae74dcad1d89 (patch)
tree9ed5e1a91f242e2cb5911577356e487a55c01b78 /include/lldb/Expression
parent85d8ef8f1f0e0e063a8571944302be2d2026f823 (diff)
Notes
Diffstat (limited to 'include/lldb/Expression')
-rw-r--r--include/lldb/Expression/ASTDumper.h43
-rw-r--r--include/lldb/Expression/ASTResultSynthesizer.h184
-rw-r--r--include/lldb/Expression/ASTStructExtractor.h156
-rw-r--r--include/lldb/Expression/ClangASTSource.h525
-rw-r--r--include/lldb/Expression/ClangExpressionDeclMap.h705
-rw-r--r--include/lldb/Expression/ClangExpressionVariable.h456
-rw-r--r--include/lldb/Expression/ClangModulesDeclVendor.h129
-rw-r--r--include/lldb/Expression/ClangPersistentVariables.h91
-rw-r--r--include/lldb/Expression/DWARFExpression.h45
-rw-r--r--include/lldb/Expression/Expression.h (renamed from include/lldb/Expression/ClangExpression.h)64
-rw-r--r--include/lldb/Expression/ExpressionParser.h (renamed from include/lldb/Expression/ClangExpressionParser.h)89
-rw-r--r--include/lldb/Expression/ExpressionTypeSystemHelper.h54
-rw-r--r--include/lldb/Expression/ExpressionVariable.h320
-rw-r--r--include/lldb/Expression/FunctionCaller.h (renamed from include/lldb/Expression/ClangFunction.h)138
-rw-r--r--include/lldb/Expression/IRDynamicChecks.h20
-rw-r--r--include/lldb/Expression/IRExecutionUnit.h74
-rw-r--r--include/lldb/Expression/IRForTarget.h745
-rw-r--r--include/lldb/Expression/IRInterpreter.h1
-rw-r--r--include/lldb/Expression/IRMemoryMap.h9
-rw-r--r--include/lldb/Expression/IRToDWARF.h111
-rw-r--r--include/lldb/Expression/LLVMUserExpression.h118
-rw-r--r--include/lldb/Expression/Materializer.h73
-rw-r--r--include/lldb/Expression/REPL.h211
-rw-r--r--include/lldb/Expression/UserExpression.h (renamed from include/lldb/Expression/ClangUserExpression.h)220
-rw-r--r--include/lldb/Expression/UtilityFunction.h (renamed from include/lldb/Expression/ClangUtilityFunction.h)93
25 files changed, 1065 insertions, 3609 deletions
diff --git a/include/lldb/Expression/ASTDumper.h b/include/lldb/Expression/ASTDumper.h
deleted file mode 100644
index 47f7ea460b87..000000000000
--- a/include/lldb/Expression/ASTDumper.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- ASTDumper.h ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ASTDumper_h_
-#define liblldb_ASTDumper_h_
-
-#include "clang/AST/DeclVisitor.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/TypeVisitor.h"
-
-#include "lldb/Core/Stream.h"
-#include "llvm/ADT/DenseSet.h"
-
-namespace lldb_private
-{
-
-class ASTDumper
-{
-public:
- ASTDumper (clang::Decl *decl);
- ASTDumper (clang::DeclContext *decl_ctx);
- ASTDumper (const clang::Type *type);
- ASTDumper (clang::QualType type);
- ASTDumper (lldb::clang_type_t type);
- ASTDumper (const ClangASTType &clang_type);
-
- const char *GetCString();
- void ToSTDERR();
- void ToLog(Log *log, const char *prefix);
- void ToStream(lldb::StreamSP &stream);
-private:
- std::string m_dump;
-};
-
-} // namespace lldb_private
-
-#endif
diff --git a/include/lldb/Expression/ASTResultSynthesizer.h b/include/lldb/Expression/ASTResultSynthesizer.h
deleted file mode 100644
index 410a862fc12a..000000000000
--- a/include/lldb/Expression/ASTResultSynthesizer.h
+++ /dev/null
@@ -1,184 +0,0 @@
-//===-- ASTResultSynthesizer.h ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ASTResultSynthesizer_h_
-#define liblldb_ASTResultSynthesizer_h_
-
-#include "clang/Sema/SemaConsumer.h"
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Symbol/TaggedASTType.h"
-
-namespace lldb_private {
-
-//----------------------------------------------------------------------
-/// @class ASTResultSynthesizer ASTResultSynthesizer.h "lldb/Expression/ASTResultSynthesizer.h"
-/// @brief Adds a result variable declaration to the ASTs for an expression.
-///
-/// Users expect the expression "i + 3" to return a result, even if a result
-/// variable wasn't specifically declared. To fulfil this requirement, LLDB adds
-/// a result variable to the expression, transforming it to
-/// "int $__lldb_expr_result = i + 3." The IR transformers ensure that the
-/// resulting variable is mapped to the right piece of memory.
-/// ASTResultSynthesizer's job is to add the variable and its initialization to
-/// the ASTs for the expression, and it does so by acting as a SemaConsumer for
-/// Clang.
-//----------------------------------------------------------------------
-class ASTResultSynthesizer : public clang::SemaConsumer
-{
-public:
- //----------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] passthrough
- /// Since the ASTs must typically go through to the Clang code generator
- /// in order to produce LLVM IR, this SemaConsumer must allow them to
- /// pass to the next step in the chain after processing. Passthrough is
- /// the next ASTConsumer, or NULL if none is required.
- ///
- /// @param[in] target
- /// The target, which contains the persistent variable store and the
- /// AST importer.
- //----------------------------------------------------------------------
- ASTResultSynthesizer(clang::ASTConsumer *passthrough,
- Target &target);
-
- //----------------------------------------------------------------------
- /// Destructor
- //----------------------------------------------------------------------
- ~ASTResultSynthesizer();
-
- //----------------------------------------------------------------------
- /// Link this consumer with a particular AST context
- ///
- /// @param[in] Context
- /// This AST context will be used for types and identifiers, and also
- /// forwarded to the passthrough consumer, if one exists.
- //----------------------------------------------------------------------
- void Initialize(clang::ASTContext &Context);
-
- //----------------------------------------------------------------------
- /// Examine a list of Decls to find the function $__lldb_expr and
- /// transform its code
- ///
- /// @param[in] D
- /// The list of Decls to search. These may contain LinkageSpecDecls,
- /// which need to be searched recursively. That job falls to
- /// TransformTopLevelDecl.
- //----------------------------------------------------------------------
- bool HandleTopLevelDecl(clang::DeclGroupRef D);
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTranslationUnit(clang::ASTContext &Ctx);
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTagDeclDefinition(clang::TagDecl *D);
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void CompleteTentativeDefinition(clang::VarDecl *D);
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleVTable(clang::CXXRecordDecl *RD);
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void PrintStats();
-
- //----------------------------------------------------------------------
- /// Set the Sema object to use when performing transforms, and pass it on
- ///
- /// @param[in] S
- /// The Sema to use. Because Sema isn't externally visible, this class
- /// casts it to an Action for actual use.
- //----------------------------------------------------------------------
- void InitializeSema(clang::Sema &S);
-
- //----------------------------------------------------------------------
- /// Reset the Sema to NULL now that transformations are done
- //----------------------------------------------------------------------
- void ForgetSema();
-private:
- //----------------------------------------------------------------------
- /// Hunt the given Decl for FunctionDecls named $__lldb_expr, recursing
- /// as necessary through LinkageSpecDecls, and calling SynthesizeResult on
- /// anything that was found
- ///
- /// @param[in] D
- /// The Decl to hunt.
- //----------------------------------------------------------------------
- void TransformTopLevelDecl(clang::Decl *D);
-
- //----------------------------------------------------------------------
- /// Process an Objective-C method and produce the result variable and
- /// initialization
- ///
- /// @param[in] MethodDecl
- /// The method to process.
- //----------------------------------------------------------------------
- bool SynthesizeObjCMethodResult(clang::ObjCMethodDecl *MethodDecl);
-
- //----------------------------------------------------------------------
- /// Process a function and produce the result variable and initialization
- ///
- /// @param[in] FunDecl
- /// The function to process.
- //----------------------------------------------------------------------
- bool SynthesizeFunctionResult(clang::FunctionDecl *FunDecl);
-
- //----------------------------------------------------------------------
- /// Process a function body and produce the result variable and
- /// initialization
- ///
- /// @param[in] Body
- /// The body of the function.
- ///
- /// @param[in] DC
- /// The DeclContext of the function, into which the result variable
- /// is inserted.
- //----------------------------------------------------------------------
- bool SynthesizeBodyResult(clang::CompoundStmt *Body,
- clang::DeclContext *DC);
-
- //----------------------------------------------------------------------
- /// Given a DeclContext for a function or method, find all types
- /// declared in the context and record any persistent types found.
- ///
- /// @param[in] FunDeclCtx
- /// The context for the function to process.
- //----------------------------------------------------------------------
- void RecordPersistentTypes(clang::DeclContext *FunDeclCtx);
-
- //----------------------------------------------------------------------
- /// Given a TypeDecl, if it declares a type whose name starts with a
- /// dollar sign, register it as a pointer type in the target's scratch
- /// AST context.
- ///
- /// @param[in] Body
- /// The body of the function.
- //----------------------------------------------------------------------
- void MaybeRecordPersistentType(clang::TypeDecl *D);
-
- clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
- clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
- clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
- Target &m_target; ///< The target, which contains the persistent variable store and the
- clang::Sema *m_sema; ///< The Sema to use.
-};
-
-}
-
-#endif
diff --git a/include/lldb/Expression/ASTStructExtractor.h b/include/lldb/Expression/ASTStructExtractor.h
deleted file mode 100644
index 25193744c9e0..000000000000
--- a/include/lldb/Expression/ASTStructExtractor.h
+++ /dev/null
@@ -1,156 +0,0 @@
-//===-- ASTStructExtractor.h ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ASTStructExtractor_h_
-#define liblldb_ASTStructExtractor_h_
-
-#include "clang/Sema/SemaConsumer.h"
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Expression/ClangExpressionVariable.h"
-#include "lldb/Expression/ClangFunction.h"
-
-namespace lldb_private {
-
-//----------------------------------------------------------------------
-/// @class ASTStructExtractor ASTStructExtractor.h "lldb/Expression/ASTStructExtractor.h"
-/// @brief Extracts and describes the argument structure for a wrapped function.
-///
-/// This pass integrates with ClangFunction, which calls functions with custom
-/// sets of arguments. To avoid having to implement the full calling convention
-/// for the target's architecture, ClangFunction writes a simple wrapper
-/// function that takes a pointer to an argument structure that contains room
-/// for the address of the function to be called, the values of all its
-/// arguments, and room for the function's return value.
-///
-/// The definition of this struct is itself in the body of the wrapper function,
-/// so Clang does the structure layout itself. ASTStructExtractor reads through
-/// the AST for the wrapper function and finds the struct.
-//----------------------------------------------------------------------
-class ASTStructExtractor : public clang::SemaConsumer
-{
-public:
- //----------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] passthrough
- /// Since the ASTs must typically go through to the Clang code generator
- /// in order to produce LLVM IR, this SemaConsumer must allow them to
- /// pass to the next step in the chain after processing. Passthrough is
- /// the next ASTConsumer, or NULL if none is required.
- ///
- /// @param[in] struct_name
- /// The name of the structure to extract from the wrapper function.
- ///
- /// @param[in] function
- /// The caller object whose members should be populated with information
- /// about the argument struct. ClangFunction friends ASTStructExtractor
- /// for this purpose.
- //----------------------------------------------------------------------
- ASTStructExtractor(clang::ASTConsumer *passthrough,
- const char *struct_name,
- ClangFunction &function);
-
- //----------------------------------------------------------------------
- /// Destructor
- //----------------------------------------------------------------------
- virtual ~ASTStructExtractor();
-
- //----------------------------------------------------------------------
- /// Link this consumer with a particular AST context
- ///
- /// @param[in] Context
- /// This AST context will be used for types and identifiers, and also
- /// forwarded to the passthrough consumer, if one exists.
- //----------------------------------------------------------------------
- void Initialize(clang::ASTContext &Context);
-
- //----------------------------------------------------------------------
- /// Examine a list of Decls to find the function $__lldb_expr and
- /// transform its code
- ///
- /// @param[in] D
- /// The list of Decls to search. These may contain LinkageSpecDecls,
- /// which need to be searched recursively. That job falls to
- /// TransformTopLevelDecl.
- //----------------------------------------------------------------------
- bool HandleTopLevelDecl(clang::DeclGroupRef D);
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTranslationUnit(clang::ASTContext &Ctx);
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleTagDeclDefinition(clang::TagDecl *D);
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void CompleteTentativeDefinition(clang::VarDecl *D);
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void HandleVTable(clang::CXXRecordDecl *RD);
-
- //----------------------------------------------------------------------
- /// Passthrough stub
- //----------------------------------------------------------------------
- void PrintStats();
-
- //----------------------------------------------------------------------
- /// Set the Sema object to use when performing transforms, and pass it on
- ///
- /// @param[in] S
- /// The Sema to use. Because Sema isn't externally visible, this class
- /// casts it to an Action for actual use.
- //----------------------------------------------------------------------
- void InitializeSema(clang::Sema &S);
-
- //----------------------------------------------------------------------
- /// Reset the Sema to NULL now that transformations are done
- //----------------------------------------------------------------------
- void ForgetSema();
-private:
- //----------------------------------------------------------------------
- /// Hunt the given FunctionDecl for the argument struct and place
- /// information about it into m_function
- ///
- /// @param[in] F
- /// The FunctionDecl to hunt.
- //----------------------------------------------------------------------
- void
- ExtractFromFunctionDecl(clang::FunctionDecl* F);
-
- //----------------------------------------------------------------------
- /// Hunt the given Decl for FunctionDecls named the same as the wrapper
- /// function name, recursing as necessary through LinkageSpecDecls, and
- /// calling ExtractFromFunctionDecl on anything that was found
- ///
- /// @param[in] D
- /// The Decl to hunt.
- //----------------------------------------------------------------------
- void
- ExtractFromTopLevelDecl(clang::Decl* D);
-
- clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types.
- clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer.
- clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
- clang::Sema *m_sema; ///< The Sema to use.
- clang::Action *m_action; ///< The Sema to use, cast to an Action so it's usable.
-
- ClangFunction &m_function; ///< The function to populate with information about the argument structure.
- std::string m_struct_name; ///< The name of the structure to extract.
-};
-
-}
-
-#endif
diff --git a/include/lldb/Expression/ClangASTSource.h b/include/lldb/Expression/ClangASTSource.h
deleted file mode 100644
index 46140d2f2e64..000000000000
--- a/include/lldb/Expression/ClangASTSource.h
+++ /dev/null
@@ -1,525 +0,0 @@
-//===-- ClangASTSource.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ClangASTSource_h_
-#define liblldb_ClangASTSource_h_
-
-#include <set>
-
-#include "clang/Basic/IdentifierTable.h"
-#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
-#include "lldb/Symbol/ClangASTImporter.h"
-#include "lldb/Symbol/ClangASTType.h"
-#include "lldb/Target/Target.h"
-
-#include "llvm/ADT/SmallSet.h"
-
-namespace lldb_private {
-
-//----------------------------------------------------------------------
-/// @class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
-/// @brief Provider for named objects defined in the debug info for Clang
-///
-/// As Clang parses an expression, it may encounter names that are not
-/// defined inside the expression, including variables, functions, and
-/// types. Clang knows the name it is looking for, but nothing else.
-/// The ExternalSemaSource class provides Decls (VarDecl, FunDecl, TypeDecl)
-/// to Clang for these names, consulting the ClangExpressionDeclMap to do
-/// the actual lookups.
-//----------------------------------------------------------------------
-class ClangASTSource :
- public ClangExternalASTSourceCommon,
- public ClangASTImporter::MapCompleter
-{
-public:
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] declMap
- /// A reference to the LLDB object that handles entity lookup.
- //------------------------------------------------------------------
- ClangASTSource (const lldb::TargetSP &target) :
- m_import_in_progress (false),
- m_lookups_enabled (false),
- m_target (target),
- m_ast_context (NULL),
- m_active_lexical_decls (),
- m_active_lookups ()
- {
- m_ast_importer = m_target->GetClangASTImporter();
- }
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- ~ClangASTSource();
-
- //------------------------------------------------------------------
- /// Interface stubs.
- //------------------------------------------------------------------
- clang::Decl *GetExternalDecl (uint32_t) override { return NULL; }
- clang::Stmt *GetExternalDeclStmt (uint64_t) override { return NULL; }
- clang::Selector GetExternalSelector (uint32_t) override { return clang::Selector(); }
- uint32_t GetNumExternalSelectors () override { return 0; }
- clang::CXXBaseSpecifier *GetExternalCXXBaseSpecifiers (uint64_t Offset) override
- { return NULL; }
- void MaterializeVisibleDecls (const clang::DeclContext *DC)
- { return; }
-
- void InstallASTContext (clang::ASTContext *ast_context)
- {
- m_ast_context = ast_context;
- m_ast_importer->InstallMapCompleter(ast_context, *this);
- }
-
- //
- // APIs for ExternalASTSource
- //
-
- //------------------------------------------------------------------
- /// Look up all Decls that match a particular name. Only handles
- /// Identifiers and DeclContexts that are either NamespaceDecls or
- /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with
- /// the result.
- ///
- /// The work for this function is done by
- /// void FindExternalVisibleDecls (NameSearchContext &);
- ///
- /// @param[in] DC
- /// The DeclContext to register the found Decls in.
- ///
- /// @param[in] Name
- /// The name to find entries for.
- ///
- /// @return
- /// Whatever SetExternalVisibleDeclsForName returns.
- //------------------------------------------------------------------
- bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override;
-
- //------------------------------------------------------------------
- /// Enumerate all Decls in a given lexical context.
- ///
- /// @param[in] DC
- /// The DeclContext being searched.
- ///
- /// @param[in] isKindWeWant
- /// If non-NULL, a callback function that returns true given the
- /// DeclKinds of desired Decls, and false otherwise.
- ///
- /// @param[in] Decls
- /// A vector that is filled in with matching Decls.
- //------------------------------------------------------------------
- clang::ExternalLoadResult FindExternalLexicalDecls(const clang::DeclContext *DC,
- bool (*isKindWeWant)(clang::Decl::Kind),
- llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
-
- //------------------------------------------------------------------
- /// Specify the layout of the contents of a RecordDecl.
- ///
- /// @param[in] Record
- /// The record (in the parser's AST context) that needs to be
- /// laid out.
- ///
- /// @param[out] Size
- /// The total size of the record in bits.
- ///
- /// @param[out] Alignment
- /// The alignment of the record in bits.
- ///
- /// @param[in] FieldOffsets
- /// A map that must be populated with pairs of the record's
- /// fields (in the parser's AST context) and their offsets
- /// (measured in bits).
- ///
- /// @param[in] BaseOffsets
- /// A map that must be populated with pairs of the record's
- /// C++ concrete base classes (in the parser's AST context,
- /// and only if the record is a CXXRecordDecl and has base
- /// classes) and their offsets (measured in bytes).
- ///
- /// @param[in] VirtualBaseOffsets
- /// A map that must be populated with pairs of the record's
- /// C++ virtual base classes (in the parser's AST context,
- /// and only if the record is a CXXRecordDecl and has base
- /// classes) and their offsets (measured in bytes).
- ///
- /// @return
- /// True <=> the layout is valid.
- //-----------------------------------------------------------------
- bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override;
-
- //------------------------------------------------------------------
- /// Complete a TagDecl.
- ///
- /// @param[in] Tag
- /// The Decl to be completed in place.
- //------------------------------------------------------------------
- void CompleteType(clang::TagDecl *Tag) override;
-
- //------------------------------------------------------------------
- /// Complete an ObjCInterfaceDecl.
- ///
- /// @param[in] Class
- /// The Decl to be completed in place.
- //------------------------------------------------------------------
- void CompleteType(clang::ObjCInterfaceDecl *Class) override;
-
- //------------------------------------------------------------------
- /// Called on entering a translation unit. Tells Clang by calling
- /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage()
- /// that this object has something to say about undefined names.
- ///
- /// @param[in] ASTConsumer
- /// Unused.
- //------------------------------------------------------------------
- void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
-
- //
- // APIs for NamespaceMapCompleter
- //
-
- //------------------------------------------------------------------
- /// Look up the modules containing a given namespace and put the
- /// appropriate entries in the namespace map.
- ///
- /// @param[in] namespace_map
- /// The map to be completed.
- ///
- /// @param[in] name
- /// The name of the namespace to be found.
- ///
- /// @param[in] parent_map
- /// The map for the namespace's parent namespace, if there is
- /// one.
- //------------------------------------------------------------------
- void CompleteNamespaceMap(ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name,
- ClangASTImporter::NamespaceMapSP &parent_map) const override;
-
- //
- // Helper APIs
- //
-
- clang::NamespaceDecl *
- AddNamespace (NameSearchContext &context,
- ClangASTImporter::NamespaceMapSP &namespace_decls);
-
- //------------------------------------------------------------------
- /// The worker function for FindExternalVisibleDeclsByName.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when filing results.
- //------------------------------------------------------------------
- virtual void FindExternalVisibleDecls (NameSearchContext &context);
-
- void SetImportInProgress (bool import_in_progress) { m_import_in_progress = import_in_progress; }
- bool GetImportInProgress () { return m_import_in_progress; }
-
- void SetLookupsEnabled (bool lookups_enabled) { m_lookups_enabled = lookups_enabled; }
- bool GetLookupsEnabled () { return m_lookups_enabled; }
-
- //----------------------------------------------------------------------
- /// @class ClangASTSourceProxy ClangASTSource.h "lldb/Expression/ClangASTSource.h"
- /// @brief Proxy for ClangASTSource
- ///
- /// Clang AST contexts like to own their AST sources, so this is a
- /// state-free proxy object.
- //----------------------------------------------------------------------
- class ClangASTSourceProxy : public ClangExternalASTSourceCommon
- {
- public:
- ClangASTSourceProxy (ClangASTSource &original) :
- m_original(original)
- {
- }
-
- bool
- FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name) override
- {
- return m_original.FindExternalVisibleDeclsByName(DC, Name);
- }
-
- clang::ExternalLoadResult
- FindExternalLexicalDecls(const clang::DeclContext *DC, bool (*isKindWeWant)(clang::Decl::Kind),
- llvm::SmallVectorImpl<clang::Decl *> &Decls) override
- {
- return m_original.FindExternalLexicalDecls(DC, isKindWeWant, Decls);
- }
-
- void
- CompleteType(clang::TagDecl *Tag) override
- {
- return m_original.CompleteType(Tag);
- }
-
- void
- CompleteType(clang::ObjCInterfaceDecl *Class) override
- {
- return m_original.CompleteType(Class);
- }
-
- bool
- layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
- llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override
- {
- return m_original.layoutRecordType(Record,
- Size,
- Alignment,
- FieldOffsets,
- BaseOffsets,
- VirtualBaseOffsets);
- }
-
- void
- StartTranslationUnit(clang::ASTConsumer *Consumer) override
- {
- return m_original.StartTranslationUnit(Consumer);
- }
-
- ClangASTMetadata *
- GetMetadata(const void * object)
- {
- return m_original.GetMetadata(object);
- }
-
- void
- SetMetadata(const void * object, ClangASTMetadata &metadata)
- {
- return m_original.SetMetadata(object, metadata);
- }
-
- bool
- HasMetadata(const void * object)
- {
- return m_original.HasMetadata(object);
- }
- private:
- ClangASTSource &m_original;
- };
-
- clang::ExternalASTSource *CreateProxy()
- {
- return new ClangASTSourceProxy(*this);
- }
-
-protected:
- //------------------------------------------------------------------
- /// Look for the complete version of an Objective-C interface, and
- /// return it if found.
- ///
- /// @param[in] interface_decl
- /// An ObjCInterfaceDecl that may not be the complete one.
- ///
- /// @return
- /// NULL if the complete interface couldn't be found;
- /// the complete interface otherwise.
- //------------------------------------------------------------------
- clang::ObjCInterfaceDecl *
- GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl);
-
- //------------------------------------------------------------------
- /// Find all entities matching a given name in a given module,
- /// using a NameSearchContext to make Decls for them.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- ///
- /// @param[in] module
- /// If non-NULL, the module to query.
- ///
- /// @param[in] namespace_decl
- /// If valid and module is non-NULL, the parent namespace.
- ///
- /// @param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- void
- FindExternalVisibleDecls (NameSearchContext &context,
- lldb::ModuleSP module,
- ClangNamespaceDecl &namespace_decl,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Find all Objective-C methods matching a given selector.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- /// Its m_decl_name contains the selector and its m_decl_context
- /// is the containing object.
- //------------------------------------------------------------------
- void
- FindObjCMethodDecls (NameSearchContext &context);
-
- //------------------------------------------------------------------
- /// Find all Objective-C properties and ivars with a given name.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- /// Its m_decl_name contains the name and its m_decl_context
- /// is the containing object.
- //------------------------------------------------------------------
- void
- FindObjCPropertyAndIvarDecls (NameSearchContext &context);
-
- //------------------------------------------------------------------
- /// A wrapper for ClangASTContext::CopyType that sets a flag that
- /// indicates that we should not respond to queries during import.
- ///
- /// @param[in] dest_context
- /// The target AST context, typically the parser's AST context.
- ///
- /// @param[in] source_context
- /// The source AST context, typically the AST context of whatever
- /// symbol file the type was found in.
- ///
- /// @param[in] clang_type
- /// The source type.
- ///
- /// @return
- /// The imported type.
- //------------------------------------------------------------------
- ClangASTType
- GuardedCopyType (const ClangASTType &src_type);
-
- friend struct NameSearchContext;
-
- bool m_import_in_progress;
- bool m_lookups_enabled;
-
- const lldb::TargetSP m_target; ///< The target to use in finding variables and types.
- clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for.
- ClangASTImporter *m_ast_importer; ///< The target's AST importer.
- std::set<const clang::Decl *> m_active_lexical_decls;
- std::set<const char *> m_active_lookups;
-};
-
-//----------------------------------------------------------------------
-/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h"
-/// @brief Container for all objects relevant to a single name lookup
-///
-/// LLDB needs to create Decls for entities it finds. This class communicates
-/// what name is being searched for and provides helper functions to construct
-/// Decls given appropriate type information.
-//----------------------------------------------------------------------
-struct NameSearchContext {
- ClangASTSource &m_ast_source; ///< The AST source making the request
- llvm::SmallVectorImpl<clang::NamedDecl*> &m_decls; ///< The list of declarations already constructed
- ClangASTImporter::NamespaceMapSP m_namespace_map; ///< The mapping of all namespaces found for this request back to their modules
- const clang::DeclarationName &m_decl_name; ///< The name being looked for
- const clang::DeclContext *m_decl_context; ///< The DeclContext to put declarations into
- llvm::SmallSet <ClangASTType, 5> m_function_types; ///< All the types of functions that have been reported, so we don't report conflicts
-
- struct {
- bool variable : 1;
- bool function_with_type_info : 1;
- bool function : 1;
- } m_found;
-
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] astSource
- /// A reference to the AST source making a request.
- ///
- /// @param[in] decls
- /// A reference to a list into which new Decls will be placed. This
- /// list is typically empty when the function is called.
- ///
- /// @param[in] name
- /// The name being searched for (always an Identifier).
- ///
- /// @param[in] dc
- /// The DeclContext to register Decls in.
- //------------------------------------------------------------------
- NameSearchContext (ClangASTSource &astSource,
- llvm::SmallVectorImpl<clang::NamedDecl*> &decls,
- clang::DeclarationName &name,
- const clang::DeclContext *dc) :
- m_ast_source(astSource),
- m_decls(decls),
- m_decl_name(name),
- m_decl_context(dc)
- {
- memset(&m_found, 0, sizeof(m_found));
- }
-
- //------------------------------------------------------------------
- /// Create a VarDecl with the name being searched for and the provided
- /// type and register it in the right places.
- ///
- /// @param[in] type
- /// The opaque QualType for the VarDecl being registered.
- //------------------------------------------------------------------
- clang::NamedDecl *AddVarDecl(const ClangASTType &type);
-
- //------------------------------------------------------------------
- /// Create a FunDecl with the name being searched for and the provided
- /// type and register it in the right places.
- ///
- /// @param[in] type
- /// The opaque QualType for the FunDecl being registered.
- ///
- /// @param[in] extern_c
- /// If true, build an extern "C" linkage specification for this.
- //------------------------------------------------------------------
- clang::NamedDecl *AddFunDecl(const ClangASTType &type,
- bool extern_c = false);
-
- //------------------------------------------------------------------
- /// Create a FunDecl with the name being searched for and generic
- /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the
- /// right places.
- //------------------------------------------------------------------
- clang::NamedDecl *AddGenericFunDecl();
-
- //------------------------------------------------------------------
- /// Create a TypeDecl with the name being searched for and the provided
- /// type and register it in the right places.
- ///
- /// @param[in] type
- /// The opaque QualType for the TypeDecl being registered.
- //------------------------------------------------------------------
- clang::NamedDecl *AddTypeDecl(const ClangASTType &clang_type);
-
-
- //------------------------------------------------------------------
- /// Add Decls from the provided DeclContextLookupResult to the list
- /// of results.
- ///
- /// @param[in] result
- /// The DeclContextLookupResult, usually returned as the result
- /// of querying a DeclContext.
- //------------------------------------------------------------------
- void AddLookupResult (clang::DeclContextLookupResult result);
-
- //------------------------------------------------------------------
- /// Add a NamedDecl to the list of results.
- ///
- /// @param[in] decl
- /// The NamedDecl, usually returned as the result
- /// of querying a DeclContext.
- //------------------------------------------------------------------
- void AddNamedDecl (clang::NamedDecl *decl);
-};
-
-}
-
-#endif
diff --git a/include/lldb/Expression/ClangExpressionDeclMap.h b/include/lldb/Expression/ClangExpressionDeclMap.h
deleted file mode 100644
index f24500ab5237..000000000000
--- a/include/lldb/Expression/ClangExpressionDeclMap.h
+++ /dev/null
@@ -1,705 +0,0 @@
-//===-- ClangExpressionDeclMap.h --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ClangExpressionDeclMap_h_
-#define liblldb_ClangExpressionDeclMap_h_
-
-// C Includes
-#include <signal.h>
-#include <stdint.h>
-
-// C++ Includes
-#include <vector>
-
-// Other libraries and framework includes
-// Project includes
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/DenseMap.h"
-#include "clang/AST/Decl.h"
-#include "lldb/lldb-public.h"
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangASTSource.h"
-#include "lldb/Expression/ClangExpressionVariable.h"
-#include "lldb/Expression/Materializer.h"
-#include "lldb/Symbol/TaggedASTType.h"
-#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Target/ExecutionContext.h"
-
-namespace lldb_private {
-
-//----------------------------------------------------------------------
-/// @class ClangExpressionDeclMap ClangExpressionDeclMap.h "lldb/Expression/ClangExpressionDeclMap.h"
-/// @brief Manages named entities that are defined in LLDB's debug information.
-///
-/// The Clang parser uses the ClangASTSource as an interface to request named
-/// entities from outside an expression. The ClangASTSource reports back, listing
-/// all possible objects corresponding to a particular name. But it in turn
-/// relies on ClangExpressionDeclMap, which performs several important functions.
-///
-/// First, it records what variables and functions were looked up and what Decls
-/// were returned for them.
-///
-/// Second, it constructs a struct on behalf of IRForTarget, recording which
-/// variables should be placed where and relaying this information back so that
-/// IRForTarget can generate context-independent code.
-///
-/// Third, it "materializes" this struct on behalf of the expression command,
-/// finding the current values of each variable and placing them into the
-/// struct so that it can be passed to the JITted version of the IR.
-///
-/// Fourth and finally, it "dematerializes" the struct after the JITted code has
-/// has executed, placing the new values back where it found the old ones.
-//----------------------------------------------------------------------
-class ClangExpressionDeclMap :
- public ClangASTSource
-{
-public:
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// Initializes class variables.
- ///
- /// @param[in] keep_result_in_memory
- /// If true, inhibits the normal deallocation of the memory for
- /// the result persistent variable, and instead marks the variable
- /// as persisting.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use when parsing.
- //------------------------------------------------------------------
- ClangExpressionDeclMap (bool keep_result_in_memory,
- ExecutionContext &exe_ctx);
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- ~ClangExpressionDeclMap ();
-
- //------------------------------------------------------------------
- /// Enable the state needed for parsing and IR transformation.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use when finding types for variables.
- /// Also used to find a "scratch" AST context to store result types.
- ///
- /// @param[in] materializer
- /// If non-NULL, the materializer to populate with information about
- /// the variables to use
- ///
- /// @return
- /// True if parsing is possible; false if it is unsafe to continue.
- //------------------------------------------------------------------
- bool
- WillParse (ExecutionContext &exe_ctx,
- Materializer *materializer);
-
- void
- InstallCodeGenerator (clang::ASTConsumer *code_gen);
-
- //------------------------------------------------------------------
- /// [Used by ClangExpressionParser] For each variable that had an unknown
- /// type at the beginning of parsing, determine its final type now.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- ResolveUnknownTypes();
-
- //------------------------------------------------------------------
- /// Disable the state needed for parsing and IR transformation.
- //------------------------------------------------------------------
- void
- DidParse ();
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Add a variable to the list of persistent
- /// variables for the process.
- ///
- /// @param[in] decl
- /// The Clang declaration for the persistent variable, used for
- /// lookup during parsing.
- ///
- /// @param[in] name
- /// The name of the persistent variable, usually $something.
- ///
- /// @param[in] type
- /// The type of the variable, in the Clang parser's context.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- AddPersistentVariable (const clang::NamedDecl *decl,
- const ConstString &name,
- TypeFromParser type,
- bool is_result,
- bool is_lvalue);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Add a variable to the struct that needs to
- /// be materialized each time the expression runs.
- ///
- /// @param[in] decl
- /// The Clang declaration for the variable.
- ///
- /// @param[in] name
- /// The name of the variable.
- ///
- /// @param[in] value
- /// The LLVM IR value for this variable.
- ///
- /// @param[in] size
- /// The size of the variable in bytes.
- ///
- /// @param[in] alignment
- /// The required alignment of the variable in bytes.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- AddValueToStruct (const clang::NamedDecl *decl,
- const ConstString &name,
- llvm::Value *value,
- size_t size,
- lldb::offset_t alignment);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Finalize the struct, laying out the position
- /// of each object in it.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- bool
- DoStructLayout ();
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get general information about the laid-out
- /// struct after DoStructLayout() has been called.
- ///
- /// @param[out] num_elements
- /// The number of elements in the struct.
- ///
- /// @param[out] size
- /// The size of the struct, in bytes.
- ///
- /// @param[out] alignment
- /// The alignment of the struct, in bytes.
- ///
- /// @return
- /// True if the information could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetStructInfo (uint32_t &num_elements,
- size_t &size,
- lldb::offset_t &alignment);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get specific information about one field
- /// of the laid-out struct after DoStructLayout() has been called.
- ///
- /// @param[out] decl
- /// The parsed Decl for the field, as generated by ClangASTSource
- /// on ClangExpressionDeclMap's behalf. In the case of the result
- /// value, this will have the name $__lldb_result even if the
- /// result value ends up having the name $1. This is an
- /// implementation detail of IRForTarget.
- ///
- /// @param[out] value
- /// The IR value for the field (usually a GlobalVariable). In
- /// the case of the result value, this will have the correct
- /// name ($1, for instance). This is an implementation detail
- /// of IRForTarget.
- ///
- /// @param[out] offset
- /// The offset of the field from the beginning of the struct.
- /// As long as the struct is aligned according to its required
- /// alignment, this offset will align the field correctly.
- ///
- /// @param[out] name
- /// The name of the field as used in materialization.
- ///
- /// @param[in] index
- /// The index of the field about which information is requested.
- ///
- /// @return
- /// True if the information could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetStructElement (const clang::NamedDecl *&decl,
- llvm::Value *&value,
- lldb::offset_t &offset,
- ConstString &name,
- uint32_t index);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get information about a function given its
- /// Decl.
- ///
- /// @param[in] decl
- /// The parsed Decl for the Function, as generated by ClangASTSource
- /// on ClangExpressionDeclMap's behalf.
- ///
- /// @param[out] ptr
- /// The absolute address of the function in the target.
- ///
- /// @return
- /// True if the information could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetFunctionInfo (const clang::NamedDecl *decl,
- uint64_t &ptr);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get the address of a function given nothing
- /// but its name. Some functions are needed but didn't get Decls made
- /// during parsing -- specifically, sel_registerName is never called
- /// in the generated IR but we need to call it nonetheless.
- ///
- /// @param[in] name
- /// The name of the function.
- ///
- /// @param[out] ptr
- /// The absolute address of the function in the target.
- ///
- /// @return
- /// True if the address could be retrieved; false otherwise.
- //------------------------------------------------------------------
- bool
- GetFunctionAddress (const ConstString &name,
- uint64_t &ptr);
-
- //------------------------------------------------------------------
- /// [Used by IRForTarget] Get the address of a symbol given nothing
- /// but its name.
- ///
- /// @param[in] target
- /// The target to find the symbol in. If not provided,
- /// then the current parsing context's Target.
- ///
- /// @param[in] process
- /// The process to use. For Objective-C symbols, the process's
- /// Objective-C language runtime may be queried if the process
- /// is non-NULL.
- ///
- /// @param[in] name
- /// The name of the symbol.
- ///
- /// @param[in] module
- /// The module to limit the search to. This can be NULL
- ///
- /// @return
- /// Valid load address for the symbol
- //------------------------------------------------------------------
- lldb::addr_t
- GetSymbolAddress (Target &target,
- Process *process,
- const ConstString &name,
- lldb::SymbolType symbol_type,
- Module *module = NULL);
-
- lldb::addr_t
- GetSymbolAddress (const ConstString &name,
- lldb::SymbolType symbol_type);
-
- //------------------------------------------------------------------
- /// [Used by IRInterpreter] Get basic target information.
- ///
- /// @param[out] byte_order
- /// The byte order of the target.
- ///
- /// @param[out] address_byte_size
- /// The size of a pointer in bytes.
- ///
- /// @return
- /// True if the information could be determined; false
- /// otherwise.
- //------------------------------------------------------------------
- struct TargetInfo
- {
- lldb::ByteOrder byte_order;
- size_t address_byte_size;
-
- TargetInfo() :
- byte_order(lldb::eByteOrderInvalid),
- address_byte_size(0)
- {
- }
-
- bool IsValid()
- {
- return (byte_order != lldb::eByteOrderInvalid &&
- address_byte_size != 0);
- }
- };
- TargetInfo GetTargetInfo();
-
- //------------------------------------------------------------------
- /// [Used by ClangASTSource] Find all entities matching a given name,
- /// using a NameSearchContext to make Decls for them.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- void
- FindExternalVisibleDecls (NameSearchContext &context);
-
- //------------------------------------------------------------------
- /// Find all entities matching a given name in a given module/namespace,
- /// using a NameSearchContext to make Decls for them.
- ///
- /// @param[in] context
- /// The NameSearchContext that can construct Decls for this name.
- ///
- /// @param[in] module
- /// If non-NULL, the module to query.
- ///
- /// @param[in] namespace_decl
- /// If valid and module is non-NULL, the parent namespace.
- ///
- /// @param[in] name
- /// The name as a plain C string. The NameSearchContext contains
- /// a DeclarationName for the name so at first the name may seem
- /// redundant, but ClangExpressionDeclMap operates in RTTI land so
- /// it can't access DeclarationName.
- ///
- /// @param[in] current_id
- /// The ID for the current FindExternalVisibleDecls invocation,
- /// for logging purposes.
- ///
- /// @return
- /// True on success; false otherwise.
- //------------------------------------------------------------------
- void
- FindExternalVisibleDecls (NameSearchContext &context,
- lldb::ModuleSP module,
- ClangNamespaceDecl &namespace_decl,
- unsigned int current_id);
-private:
- ClangExpressionVariableList m_found_entities; ///< All entities that were looked up for the parser.
- ClangExpressionVariableList m_struct_members; ///< All entities that need to be placed in the struct.
- bool m_keep_result_in_memory; ///< True if result persistent variables generated by this expression should stay in memory.
-
- //----------------------------------------------------------------------
- /// The following values should not live beyond parsing
- //----------------------------------------------------------------------
- class ParserVars
- {
- public:
- ParserVars(ClangExpressionDeclMap &decl_map) :
- m_decl_map(decl_map)
- {
- }
-
- Target *
- GetTarget()
- {
- if (m_exe_ctx.GetTargetPtr())
- return m_exe_ctx.GetTargetPtr();
- else if (m_sym_ctx.target_sp)
- m_sym_ctx.target_sp.get();
- return NULL;
- }
-
- ExecutionContext m_exe_ctx; ///< The execution context to use when parsing.
- SymbolContext m_sym_ctx; ///< The symbol context to use in finding variables and types.
- ClangPersistentVariables *m_persistent_vars = nullptr; ///< The persistent variables for the process.
- bool m_enable_lookups = false; ///< Set to true during parsing if we have found the first "$__lldb" name.
- TargetInfo m_target_info; ///< Basic information about the target.
- Materializer *m_materializer = nullptr; ///< If non-NULL, the materializer to use when reporting used variables.
- clang::ASTConsumer *m_code_gen = nullptr; ///< If non-NULL, a code generator that receives new top-level functions.
- private:
- ClangExpressionDeclMap &m_decl_map;
- DISALLOW_COPY_AND_ASSIGN (ParserVars);
- };
-
- std::unique_ptr<ParserVars> m_parser_vars;
-
- //----------------------------------------------------------------------
- /// Activate parser-specific variables
- //----------------------------------------------------------------------
- void
- EnableParserVars()
- {
- if (!m_parser_vars.get())
- m_parser_vars.reset(new ParserVars(*this));
- }
-
- //----------------------------------------------------------------------
- /// Deallocate parser-specific variables
- //----------------------------------------------------------------------
- void
- DisableParserVars()
- {
- m_parser_vars.reset();
- }
-
- //----------------------------------------------------------------------
- /// The following values contain layout information for the materialized
- /// struct, but are not specific to a single materialization
- //----------------------------------------------------------------------
- struct StructVars {
- StructVars() :
- m_struct_alignment(0),
- m_struct_size(0),
- m_struct_laid_out(false),
- m_result_name(),
- m_object_pointer_type(NULL, NULL)
- {
- }
-
- lldb::offset_t m_struct_alignment; ///< The alignment of the struct in bytes.
- size_t m_struct_size; ///< The size of the struct in bytes.
- bool m_struct_laid_out; ///< True if the struct has been laid out and the layout is valid (that is, no new fields have been added since).
- ConstString m_result_name; ///< The name of the result variable ($1, for example)
- TypeFromUser m_object_pointer_type; ///< The type of the "this" variable, if one exists
- };
-
- std::unique_ptr<StructVars> m_struct_vars;
-
- //----------------------------------------------------------------------
- /// Activate struct variables
- //----------------------------------------------------------------------
- void
- EnableStructVars()
- {
- if (!m_struct_vars.get())
- m_struct_vars.reset(new struct StructVars);
- }
-
- //----------------------------------------------------------------------
- /// Deallocate struct variables
- //----------------------------------------------------------------------
- void
- DisableStructVars()
- {
- m_struct_vars.reset();
- }
-
- //----------------------------------------------------------------------
- /// Get this parser's ID for use in extracting parser- and JIT-specific
- /// data from persistent variables.
- //----------------------------------------------------------------------
- uint64_t
- GetParserID()
- {
- return (uint64_t)this;
- }
-
- //------------------------------------------------------------------
- /// Given a target, find a data symbol that has the given name.
- ///
- /// @param[in] target
- /// The target to use as the basis for the search.
- ///
- /// @param[in] name
- /// The name as a plain C string.
- ///
- /// @param[in] module
- /// The module to limit the search to. This can be NULL
- ///
- /// @return
- /// The LLDB Symbol found, or NULL if none was found.
- //------------------------------------------------------------------
- const Symbol *
- FindGlobalDataSymbol (Target &target,
- const ConstString &name,
- Module *module = NULL);
-
- //------------------------------------------------------------------
- /// Given a target, find a variable that matches the given name and
- /// type.
- ///
- /// @param[in] target
- /// The target to use as a basis for finding the variable.
- ///
- /// @param[in] module
- /// If non-NULL, the module to search.
- ///
- /// @param[in] name
- /// The name as a plain C string.
- ///
- /// @param[in] namespace_decl
- /// If non-NULL and module is non-NULL, the parent namespace.
- ///
- /// @param[in] type
- /// The required type for the variable. This function may be called
- /// during parsing, in which case we don't know its type; hence the
- /// default.
- ///
- /// @return
- /// The LLDB Variable found, or NULL if none was found.
- //------------------------------------------------------------------
- lldb::VariableSP
- FindGlobalVariable (Target &target,
- lldb::ModuleSP &module,
- const ConstString &name,
- ClangNamespaceDecl *namespace_decl,
- TypeFromUser *type = NULL);
-
- //------------------------------------------------------------------
- /// Get the value of a variable in a given execution context and return
- /// the associated Types if needed.
- ///
- /// @param[in] var
- /// The variable to evaluate.
- ///
- /// @param[out] var_location
- /// The variable location value to fill in
- ///
- /// @param[out] found_type
- /// The type of the found value, as it was found in the user process.
- /// This is only useful when the variable is being inspected on behalf
- /// of the parser, hence the default.
- ///
- /// @param[out] parser_type
- /// The type of the found value, as it was copied into the parser's
- /// AST context. This is only useful when the variable is being
- /// inspected on behalf of the parser, hence the default.
- ///
- /// @param[in] decl
- /// The Decl to be looked up.
- ///
- /// @return
- /// Return true if the value was successfully filled in.
- //------------------------------------------------------------------
- bool
- GetVariableValue (lldb::VariableSP &var,
- lldb_private::Value &var_location,
- TypeFromUser *found_type = NULL,
- TypeFromParser *parser_type = NULL);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given LLDB
- /// Variable, and put it in the Tuple list.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] var
- /// The LLDB Variable that needs a Decl.
- ///
- /// @param[in] valobj
- /// The LLDB ValueObject for that variable.
- //------------------------------------------------------------------
- void
- AddOneVariable (NameSearchContext &context,
- lldb::VariableSP var,
- lldb::ValueObjectSP valobj,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// persistent variable, and put it in the list of found entities.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] pvar
- /// The persistent variable that needs a Decl.
- ///
- /// @param[in] current_id
- /// The ID of the current invocation of FindExternalVisibleDecls
- /// for logging purposes.
- //------------------------------------------------------------------
- void
- AddOneVariable (NameSearchContext &context,
- lldb::ClangExpressionVariableSP &pvar_sp,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given LLDB
- /// symbol (treated as a variable), and put it in the list of found
- /// entities.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] var
- /// The LLDB Variable that needs a Decl.
- //------------------------------------------------------------------
- void
- AddOneGenericVariable (NameSearchContext &context,
- const Symbol &symbol,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// function. (Functions are not placed in the Tuple list.) Can
- /// handle both fully typed functions and generic functions.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] fun
- /// The Function that needs to be created. If non-NULL, this is
- /// a fully-typed function.
- ///
- /// @param[in] sym
- /// The Symbol that corresponds to a function that needs to be
- /// created with generic type (unitptr_t foo(...)).
- //------------------------------------------------------------------
- void
- AddOneFunction (NameSearchContext &context,
- Function *fun,
- Symbol *sym,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// register.
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] reg_info
- /// The information corresponding to that register.
- //------------------------------------------------------------------
- void
- AddOneRegister (NameSearchContext &context,
- const RegisterInfo *reg_info,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Use the NameSearchContext to generate a Decl for the given
- /// type. (Types are not placed in the Tuple list.)
- ///
- /// @param[in] context
- /// The NameSearchContext to use when constructing the Decl.
- ///
- /// @param[in] type
- /// The type that needs to be created.
- //------------------------------------------------------------------
- void
- AddOneType (NameSearchContext &context,
- TypeFromUser &type,
- unsigned int current_id);
-
- //------------------------------------------------------------------
- /// Copy a C++ class type into the parser's AST context and add a
- /// member function declaration to it for the expression.
- ///
- /// @param[in] type
- /// The type that needs to be created.
- //------------------------------------------------------------------
-
- TypeFromParser
- CopyClassType(TypeFromUser &type,
- unsigned int current_id);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_ClangExpressionDeclMap_h_
diff --git a/include/lldb/Expression/ClangExpressionVariable.h b/include/lldb/Expression/ClangExpressionVariable.h
deleted file mode 100644
index 6c210106d51e..000000000000
--- a/include/lldb/Expression/ClangExpressionVariable.h
+++ /dev/null
@@ -1,456 +0,0 @@
-//===-- ClangExpressionVariable.h -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ClangExpressionVariable_h_
-#define liblldb_ClangExpressionVariable_h_
-
-// C Includes
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
-
-// C++ Includes
-#include <map>
-#include <string>
-#include <vector>
-
-// Other libraries and framework includes
-// Project includes
-#include "lldb/lldb-public.h"
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Core/ConstString.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Symbol/TaggedASTType.h"
-
-namespace llvm {
- class Value;
-}
-
-namespace lldb_private {
-
-class ClangExpressionVariableList;
-class ValueObjectConstResult;
-
-//----------------------------------------------------------------------
-/// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
-/// @brief Encapsulates one variable for the expression parser.
-///
-/// The expression parser uses variables in three different contexts:
-///
-/// First, it stores persistent variables along with the process for use
-/// in expressions. These persistent variables contain their own data
-/// and are typed.
-///
-/// Second, in an interpreted expression, it stores the local variables
-/// for the expression along with the expression. These variables
-/// contain their own data and are typed.
-///
-/// Third, in a JIT-compiled expression, it stores the variables that
-/// the expression needs to have materialized and dematerialized at each
-/// execution. These do not contain their own data but are named and
-/// typed.
-///
-/// This class supports all of these use cases using simple type
-/// polymorphism, and provides necessary support methods. Its interface
-/// is RTTI-neutral.
-//----------------------------------------------------------------------
-class ClangExpressionVariable
-{
-public:
- ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size);
-
- ClangExpressionVariable (ExecutionContextScope *exe_scope,
- Value &value,
- const ConstString &name,
- uint16_t flags = EVNone);
-
- ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);
-
- //----------------------------------------------------------------------
- /// If the variable contains its own data, make a Value point at it.
- /// If \a exe_ctx in not NULL, the value will be resolved in with
- /// that execution context.
- ///
- /// @param[in] value
- /// The value to point at the data.
- ///
- /// @param[in] exe_ctx
- /// The execution context to use to resolve \a value.
- ///
- /// @return
- /// True on success; false otherwise (in particular, if this variable
- /// does not contain its own data).
- //----------------------------------------------------------------------
- bool
- PointValueAtData(Value &value, ExecutionContext *exe_ctx);
-
- lldb::ValueObjectSP
- GetValueObject();
-
- //----------------------------------------------------------------------
- /// The following values should not live beyond parsing
- //----------------------------------------------------------------------
- class ParserVars
- {
- public:
-
- ParserVars() :
- m_parser_type(),
- m_named_decl (NULL),
- m_llvm_value (NULL),
- m_lldb_value (),
- m_lldb_var (),
- m_lldb_sym (NULL)
- {
- }
-
- TypeFromParser m_parser_type; ///< The type of the variable according to the parser
- const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable
- llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue
- lldb_private::Value m_lldb_value; ///< The value found in LLDB for this variable
- lldb::VariableSP m_lldb_var; ///< The original variable for this variable
- const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol
- };
-
-private:
- typedef std::map <uint64_t, ParserVars> ParserVarMap;
- ParserVarMap m_parser_vars;
-
-public:
- //----------------------------------------------------------------------
- /// Make this variable usable by the parser by allocating space for
- /// parser-specific variables
- //----------------------------------------------------------------------
- void
- EnableParserVars(uint64_t parser_id)
- {
- m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
- }
-
- //----------------------------------------------------------------------
- /// Deallocate parser-specific variables
- //----------------------------------------------------------------------
- void
- DisableParserVars(uint64_t parser_id)
- {
- m_parser_vars.erase(parser_id);
- }
-
- //----------------------------------------------------------------------
- /// Access parser-specific variables
- //----------------------------------------------------------------------
- ParserVars *
- GetParserVars(uint64_t parser_id)
- {
- ParserVarMap::iterator i = m_parser_vars.find(parser_id);
-
- if (i == m_parser_vars.end())
- return NULL;
- else
- return &i->second;
- }
-
- //----------------------------------------------------------------------
- /// The following values are valid if the variable is used by JIT code
- //----------------------------------------------------------------------
- struct JITVars {
- JITVars () :
- m_alignment (0),
- m_size (0),
- m_offset (0)
- {
- }
-
- lldb::offset_t m_alignment; ///< The required alignment of the variable, in bytes
- size_t m_size; ///< The space required for the variable, in bytes
- lldb::offset_t m_offset; ///< The offset of the variable in the struct, in bytes
- };
-
-private:
- typedef std::map <uint64_t, JITVars> JITVarMap;
- JITVarMap m_jit_vars;
-
-public:
- //----------------------------------------------------------------------
- /// Make this variable usable for materializing for the JIT by allocating
- /// space for JIT-specific variables
- //----------------------------------------------------------------------
- void
- EnableJITVars(uint64_t parser_id)
- {
- m_jit_vars.insert(std::make_pair(parser_id, JITVars()));
- }
-
- //----------------------------------------------------------------------
- /// Deallocate JIT-specific variables
- //----------------------------------------------------------------------
- void
- DisableJITVars(uint64_t parser_id)
- {
- m_jit_vars.erase(parser_id);
- }
-
- JITVars *GetJITVars(uint64_t parser_id)
- {
- JITVarMap::iterator i = m_jit_vars.find(parser_id);
-
- if (i == m_jit_vars.end())
- return NULL;
- else
- return &i->second;
- }
-
- //----------------------------------------------------------------------
- /// Return the variable's size in bytes
- //----------------------------------------------------------------------
- size_t
- GetByteSize ();
-
- const ConstString &
- GetName();
-
- RegisterInfo *
- GetRegisterInfo();
-
- void
- SetRegisterInfo (const RegisterInfo *reg_info);
-
- ClangASTType
- GetClangType ();
-
- void
- SetClangType (const ClangASTType &clang_type);
-
- TypeFromUser
- GetTypeFromUser ();
-
- uint8_t *
- GetValueBytes ();
-
- void
- SetName (const ConstString &name);
-
- void
- ValueUpdated ();
-
- // this function is used to copy the address-of m_live_sp into m_frozen_sp
- // this is necessary because the results of certain cast and pointer-arithmetic
- // operations (such as those described in bugzilla issues 11588 and 11618) generate
- // frozen objects that do not have a valid address-of, which can be troublesome when
- // using synthetic children providers. Transferring the address-of the live object
- // solves these issues and provides the expected user-level behavior
- void
- TransferAddress (bool force = false);
-
- typedef std::shared_ptr<ValueObjectConstResult> ValueObjectConstResultSP;
-
- //----------------------------------------------------------------------
- /// Members
- //----------------------------------------------------------------------
- enum Flags
- {
- EVNone = 0,
- EVIsLLDBAllocated = 1 << 0, ///< This variable is resident in a location specifically allocated for it by LLDB in the target process
- EVIsProgramReference = 1 << 1, ///< This variable is a reference to a (possibly invalid) area managed by the target program
- EVNeedsAllocation = 1 << 2, ///< Space for this variable has yet to be allocated in the target process
- EVIsFreezeDried = 1 << 3, ///< This variable's authoritative version is in m_frozen_sp (for example, for statically-computed results)
- EVNeedsFreezeDry = 1 << 4, ///< Copy from m_live_sp to m_frozen_sp during dematerialization
- EVKeepInTarget = 1 << 5, ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it
- EVTypeIsReference = 1 << 6, ///< The original type of this variable is a reference, so materialize the value rather than the location
- EVUnknownType = 1 << 7, ///< This is a symbol of unknown type, and the type must be resolved after parsing is complete
- EVBareRegister = 1 << 8 ///< This variable is a direct reference to $pc or some other entity.
- };
-
- typedef uint16_t FlagType;
-
- FlagType m_flags; // takes elements of Flags
-
- lldb::ValueObjectSP m_frozen_sp;
- lldb::ValueObjectSP m_live_sp;
-
- DISALLOW_COPY_AND_ASSIGN (ClangExpressionVariable);
-};
-
-//----------------------------------------------------------------------
-/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
-/// @brief A list of variable references.
-///
-/// This class stores variables internally, acting as the permanent store.
-//----------------------------------------------------------------------
-class ClangExpressionVariableList
-{
-public:
- //----------------------------------------------------------------------
- /// Implementation of methods in ClangExpressionVariableListBase
- //----------------------------------------------------------------------
- size_t
- GetSize()
- {
- return m_variables.size();
- }
-
- lldb::ClangExpressionVariableSP
- GetVariableAtIndex(size_t index)
- {
- lldb::ClangExpressionVariableSP var_sp;
- if (index < m_variables.size())
- var_sp = m_variables[index];
- return var_sp;
- }
-
- size_t
- AddVariable (const lldb::ClangExpressionVariableSP &var_sp)
- {
- m_variables.push_back(var_sp);
- return m_variables.size() - 1;
- }
-
- bool
- ContainsVariable (const lldb::ClangExpressionVariableSP &var_sp)
- {
- const size_t size = m_variables.size();
- for (size_t index = 0; index < size; ++index)
- {
- if (m_variables[index].get() == var_sp.get())
- return true;
- }
- return false;
- }
-
- //----------------------------------------------------------------------
- /// Finds a variable by name in the list.
- ///
- /// @param[in] name
- /// The name of the requested variable.
- ///
- /// @return
- /// The variable requested, or NULL if that variable is not in the list.
- //----------------------------------------------------------------------
- lldb::ClangExpressionVariableSP
- GetVariable (const ConstString &name)
- {
- lldb::ClangExpressionVariableSP var_sp;
- for (size_t index = 0, size = GetSize(); index < size; ++index)
- {
- var_sp = GetVariableAtIndex(index);
- if (var_sp->GetName() == name)
- return var_sp;
- }
- var_sp.reset();
- return var_sp;
- }
-
- lldb::ClangExpressionVariableSP
- GetVariable (const char *name)
- {
- lldb::ClangExpressionVariableSP var_sp;
- if (name && name[0])
- {
- for (size_t index = 0, size = GetSize(); index < size; ++index)
- {
- var_sp = GetVariableAtIndex(index);
- const char *var_name_cstr = var_sp->GetName().GetCString();
- if (!var_name_cstr || !name)
- continue;
- if (::strcmp (var_name_cstr, name) == 0)
- return var_sp;
- }
- var_sp.reset();
- }
- return var_sp;
- }
-
- //----------------------------------------------------------------------
- /// Finds a variable by NamedDecl in the list.
- ///
- /// @param[in] name
- /// The name of the requested variable.
- ///
- /// @return
- /// The variable requested, or NULL if that variable is not in the list.
- //----------------------------------------------------------------------
- lldb::ClangExpressionVariableSP
- GetVariable (const clang::NamedDecl *decl, uint64_t parser_id)
- {
- lldb::ClangExpressionVariableSP var_sp;
- for (size_t index = 0, size = GetSize(); index < size; ++index)
- {
- var_sp = GetVariableAtIndex(index);
-
- ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(parser_id);
-
- if (parser_vars && parser_vars->m_named_decl == decl)
- return var_sp;
- }
- var_sp.reset();
- return var_sp;
- }
-
- //----------------------------------------------------------------------
- /// Create a new variable in the list and return its index
- //----------------------------------------------------------------------
- lldb::ClangExpressionVariableSP
- CreateVariable (ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size)
- {
- lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
- m_variables.push_back(var_sp);
- return var_sp;
- }
-
- lldb::ClangExpressionVariableSP
- CreateVariable(const lldb::ValueObjectSP &valobj_sp)
- {
- lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(valobj_sp));
- m_variables.push_back(var_sp);
- return var_sp;
- }
-
- lldb::ClangExpressionVariableSP
- CreateVariable (ExecutionContextScope *exe_scope,
- const ConstString &name,
- const TypeFromUser& user_type,
- lldb::ByteOrder byte_order,
- uint32_t addr_byte_size)
- {
- lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
- var_sp->SetName (name);
- var_sp->SetClangType (user_type);
- m_variables.push_back(var_sp);
- return var_sp;
- }
-
- void
- RemoveVariable (lldb::ClangExpressionVariableSP var_sp)
- {
- for (std::vector<lldb::ClangExpressionVariableSP>::iterator vi = m_variables.begin(), ve = m_variables.end();
- vi != ve;
- ++vi)
- {
- if (vi->get() == var_sp.get())
- {
- m_variables.erase(vi);
- return;
- }
- }
- }
-
- void
- Clear()
- {
- m_variables.clear();
- }
-
-private:
- std::vector <lldb::ClangExpressionVariableSP> m_variables;
-};
-
-
-} // namespace lldb_private
-
-#endif // liblldb_ClangExpressionVariable_h_
diff --git a/include/lldb/Expression/ClangModulesDeclVendor.h b/include/lldb/Expression/ClangModulesDeclVendor.h
deleted file mode 100644
index a8297c8fa331..000000000000
--- a/include/lldb/Expression/ClangModulesDeclVendor.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===-- ClangModulesDeclVendor.h --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _liblldb_ClangModulesDeclVendor_
-#define _liblldb_ClangModulesDeclVendor_
-
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Symbol/DeclVendor.h"
-#include "lldb/Target/Platform.h"
-
-#include <set>
-#include <vector>
-
-namespace lldb_private
-{
-
-class ClangModulesDeclVendor : public DeclVendor
-{
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- ClangModulesDeclVendor();
-
- virtual
- ~ClangModulesDeclVendor();
-
- static ClangModulesDeclVendor *
- Create(Target &target);
-
- typedef std::vector<ConstString> ModulePath;
- typedef uintptr_t ModuleID;
- typedef std::vector<ModuleID> ModuleVector;
-
- //------------------------------------------------------------------
- /// Add a module to the list of modules to search.
- ///
- /// @param[in] path
- /// The path to the exact module to be loaded. E.g., if the desired
- /// module is std.io, then this should be { "std", "io" }.
- ///
- /// @param[in] exported_modules
- /// If non-NULL, a pointer to a vector to populate with the ID of every
- /// module that is re-exported by the specified module.
- ///
- /// @param[in] error_stream
- /// A stream to populate with the output of the Clang parser when
- /// it tries to load the module.
- ///
- /// @return
- /// True if the module could be loaded; false if not. If the
- /// compiler encountered a fatal error during a previous module
- /// load, then this will always return false for this ModuleImporter.
- //------------------------------------------------------------------
- virtual bool
- AddModule(ModulePath &path,
- ModuleVector *exported_modules,
- Stream &error_stream) = 0;
-
- //------------------------------------------------------------------
- /// Add all modules referred to in a given compilation unit to the list
- /// of modules to search.
- ///
- /// @param[in] cu
- /// The compilation unit to scan for imported modules.
- ///
- /// @param[in] exported_modules
- /// A vector to populate with the ID of each module loaded (directly
- /// and via re-exports) in this way.
- ///
- /// @param[in] error_stream
- /// A stream to populate with the output of the Clang parser when
- /// it tries to load the modules.
- ///
- /// @return
- /// True if all modules referred to by the compilation unit could be
- /// loaded; false if one could not be loaded. If the compiler
- /// encountered a fatal error during a previous module
- /// load, then this will always return false for this ModuleImporter.
- //------------------------------------------------------------------
- virtual bool
- AddModulesForCompileUnit(CompileUnit &cu,
- ModuleVector &exported_modules,
- Stream &error_stream) = 0;
-
- //------------------------------------------------------------------
- /// Enumerate all the macros that are defined by a given set of modules
- /// that are already imported.
- ///
- /// @param[in] modules
- /// The unique IDs for all modules to query. Later modules have higher
- /// priority, just as if you @imported them in that order. This matters
- /// if module A #defines a macro and module B #undefs it.
- ///
- /// @param[in] handler
- /// A function to call with the text of each #define (including the
- /// #define directive). #undef directives are not included; we simply
- /// elide any corresponding #define. If this function returns true,
- /// we stop the iteration immediately.
- //------------------------------------------------------------------
- virtual void
- ForEachMacro(const ModuleVector &modules,
- std::function<bool (const std::string &)> handler) = 0;
-
- //------------------------------------------------------------------
- /// Query whether Clang supports modules for a particular language.
- /// LLDB uses this to decide whether to try to find the modules loaded
- /// by a gaiven compile unit.
- ///
- /// @param[in] language
- /// The language to query for.
- ///
- /// @return
- /// True if Clang has modules for the given language.
- //------------------------------------------------------------------
- static bool
- LanguageSupportsClangModules (lldb::LanguageType language);
-
-};
-
-}
-#endif /* defined(_lldb_ClangModulesDeclVendor_) */
diff --git a/include/lldb/Expression/ClangPersistentVariables.h b/include/lldb/Expression/ClangPersistentVariables.h
deleted file mode 100644
index 247f87fae41b..000000000000
--- a/include/lldb/Expression/ClangPersistentVariables.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//===-- ClangPersistentVariables.h ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ClangPersistentVariables_h_
-#define liblldb_ClangPersistentVariables_h_
-
-#include "lldb/Expression/ClangExpressionVariable.h"
-#include "lldb/Expression/ClangModulesDeclVendor.h"
-
-#include "llvm/ADT/DenseMap.h"
-
-namespace lldb_private
-{
-
-//----------------------------------------------------------------------
-/// @class ClangPersistentVariables ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h"
-/// @brief Manages persistent values that need to be preserved between expression invocations.
-///
-/// A list of variables that can be accessed and updated by any expression. See
-/// ClangPersistentVariable for more discussion. Also provides an increasing,
-/// 0-based counter for naming result variables.
-//----------------------------------------------------------------------
-class ClangPersistentVariables : public ClangExpressionVariableList
-{
-public:
-
- //----------------------------------------------------------------------
- /// Constructor
- //----------------------------------------------------------------------
- ClangPersistentVariables ();
-
- lldb::ClangExpressionVariableSP
- CreatePersistentVariable (const lldb::ValueObjectSP &valobj_sp);
-
- lldb::ClangExpressionVariableSP
- CreatePersistentVariable (ExecutionContextScope *exe_scope,
- const ConstString &name,
- const TypeFromUser& user_type,
- lldb::ByteOrder byte_order,
- uint32_t addr_byte_size);
-
- //----------------------------------------------------------------------
- /// Return the next entry in the sequence of strings "$0", "$1", ... for
- /// use naming persistent expression convenience variables.
- ///
- /// @return
- /// A string that contains the next persistent variable name.
- //----------------------------------------------------------------------
- ConstString
- GetNextPersistentVariableName ();
-
- void
- RemovePersistentVariable (lldb::ClangExpressionVariableSP variable);
-
- void
- RegisterPersistentType (const ConstString &name,
- clang::TypeDecl *tag_decl);
-
- clang::TypeDecl *
- GetPersistentType (const ConstString &name);
-
- void
- AddHandLoadedClangModule(ClangModulesDeclVendor::ModuleID module)
- {
- m_hand_loaded_clang_modules.push_back(module);
- }
-
- const ClangModulesDeclVendor::ModuleVector &GetHandLoadedClangModules()
- {
- return m_hand_loaded_clang_modules;
- }
-
-private:
- uint32_t m_next_persistent_variable_id; ///< The counter used by GetNextResultName().
-
- typedef llvm::DenseMap<const char *, clang::TypeDecl *> PersistentTypeMap;
- PersistentTypeMap m_persistent_types; ///< The persistent types declared by the user.
-
- ClangModulesDeclVendor::ModuleVector m_hand_loaded_clang_modules; ///< These are Clang modules we hand-loaded; these are the highest-
- ///< priority source for macros.
-};
-
-}
-
-#endif
diff --git a/include/lldb/Expression/DWARFExpression.h b/include/lldb/Expression/DWARFExpression.h
index 9ddecc053e00..3527c3b4b153 100644
--- a/include/lldb/Expression/DWARFExpression.h
+++ b/include/lldb/Expression/DWARFExpression.h
@@ -11,18 +11,19 @@
#define liblldb_DWARFExpression_h_
#include "lldb/lldb-private.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Scalar.h"
+class DWARFCompileUnit;
+
namespace lldb_private {
+class ClangExpressionDeclMap;
class ClangExpressionVariable;
class ClangExpressionVariableList;
-class ClangExpressionDeclMap;
//----------------------------------------------------------------------
/// @class DWARFExpression DWARFExpression.h "lldb/Expression/DWARFExpression.h"
@@ -40,10 +41,17 @@ class ClangExpressionDeclMap;
class DWARFExpression
{
public:
+ enum LocationListFormat : uint8_t
+ {
+ NonLocationList, // Not a location list
+ RegularLocationList, // Location list format used in non-split dwarf files
+ SplitDwarfLocationList, // Location list format used in split dwarf files
+ };
+
//------------------------------------------------------------------
/// Constructor
//------------------------------------------------------------------
- DWARFExpression();
+ explicit DWARFExpression(DWARFCompileUnit* dwarf_cu);
//------------------------------------------------------------------
/// Constructor
@@ -60,6 +68,7 @@ public:
//------------------------------------------------------------------
DWARFExpression(lldb::ModuleSP module,
const DataExtractor& data,
+ DWARFCompileUnit* dwarf_cu,
lldb::offset_t data_offset,
lldb::offset_t data_length);
@@ -356,6 +365,7 @@ public:
RegisterContext *reg_ctx,
lldb::ModuleSP opcode_ctx,
const DataExtractor& opcodes,
+ DWARFCompileUnit* dwarf_cu,
const lldb::offset_t offset,
const lldb::offset_t length,
const lldb::RegisterKind reg_set,
@@ -397,6 +407,24 @@ public:
lldb::addr_t address,
ABI *abi);
+ static size_t
+ LocationListSize(const DWARFCompileUnit* dwarf_cu,
+ const DataExtractor& debug_loc_data,
+ lldb::offset_t offset);
+
+ static bool
+ PrintDWARFExpression(Stream &s,
+ const DataExtractor& data,
+ int address_size,
+ int dwarf_ref_size,
+ bool location_expression);
+
+ static void
+ PrintDWARFLocationList(Stream &s,
+ const DWARFCompileUnit* cu,
+ const DataExtractor& debug_loc_data,
+ lldb::offset_t offset);
+
protected:
//------------------------------------------------------------------
/// Pretty-prints the location expression to a stream
@@ -430,17 +458,26 @@ protected:
lldb::offset_t &offset,
lldb::offset_t &len);
+ static bool
+ AddressRangeForLocationListEntry(const DWARFCompileUnit* dwarf_cu,
+ const DataExtractor& debug_loc_data,
+ lldb::offset_t* offset_ptr,
+ lldb::addr_t& low_pc,
+ lldb::addr_t& high_pc);
+
//------------------------------------------------------------------
/// Classes that inherit from DWARFExpression can see and modify these
//------------------------------------------------------------------
lldb::ModuleWP m_module_wp; ///< Module which defined this expression.
DataExtractor m_data; ///< A data extractor capable of reading opcode bytes
+ DWARFCompileUnit* m_dwarf_cu; ///< The DWARF compile unit this expression belongs to. It is used
+ ///< to evaluate values indexing into the .debug_addr section (e.g.
+ ///< DW_OP_GNU_addr_index, DW_OP_GNU_const_index)
lldb::RegisterKind m_reg_kind; ///< One of the defines that starts with LLDB_REGKIND_
lldb::addr_t m_loclist_slide; ///< A value used to slide the location list offsets so that
///< they are relative to the object that owns the location list
///< (the function for frame base and variable location lists)
-
};
} // namespace lldb_private
diff --git a/include/lldb/Expression/ClangExpression.h b/include/lldb/Expression/Expression.h
index 6e831e4471e8..b5c2d575ae04 100644
--- a/include/lldb/Expression/ClangExpression.h
+++ b/include/lldb/Expression/Expression.h
@@ -1,4 +1,4 @@
-//===-- ClangExpression.h ---------------------------------------*- C++ -*-===//
+//===-- Expression.h --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpression_h_
-#define liblldb_ClangExpression_h_
+#ifndef liblldb_Expression_h_
+#define liblldb_Expression_h_
// C Includes
// C++ Includes
@@ -21,23 +21,23 @@
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Target/Process.h"
+#include "lldb/Expression/ExpressionTypeSystemHelper.h"
namespace lldb_private {
class RecordingMemoryManager;
//----------------------------------------------------------------------
-/// @class ClangExpression ClangExpression.h "lldb/Expression/ClangExpression.h"
-/// @brief Encapsulates a single expression for use with Clang
+/// @class Expression Expression.h "lldb/Expression/Expression.h"
+/// @brief Encapsulates a single expression for use in lldb
///
/// LLDB uses expressions for various purposes, notably to call functions
-/// and as a backend for the expr command. ClangExpression encapsulates
+/// and as a backend for the expr command. Expression encapsulates
/// the objects needed to parse and interpret or JIT an expression. It
-/// uses the Clang parser to produce LLVM IR from the expression.
+/// uses the expression parser appropriate to the language of the expression
+/// to produce LLVM IR from the expression.
//----------------------------------------------------------------------
-class ClangExpression
+class Expression
{
public:
enum ResultType {
@@ -45,17 +45,14 @@ public:
eResultTypeId
};
- ClangExpression () :
- m_jit_process_wp(),
- m_jit_start_addr (LLDB_INVALID_ADDRESS),
- m_jit_end_addr (LLDB_INVALID_ADDRESS)
- {
- }
-
+ Expression (Target &target);
+
+ Expression (ExecutionContextScope &exe_scope);
+
//------------------------------------------------------------------
/// Destructor
//------------------------------------------------------------------
- virtual ~ClangExpression ()
+ virtual ~Expression ()
{
}
@@ -85,24 +82,6 @@ public:
}
//------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- virtual ClangExpressionDeclMap *
- DeclMap () = 0;
-
- //------------------------------------------------------------------
- /// 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.
- //------------------------------------------------------------------
- virtual clang::ASTConsumer *
- ASTTransformer (clang::ASTConsumer *passthrough) = 0;
-
- //------------------------------------------------------------------
/// Return the desired result type of the function, or
/// eResultTypeAny if indifferent.
//------------------------------------------------------------------
@@ -130,6 +109,8 @@ public:
virtual bool
NeedsVariableResolution () = 0;
+ virtual EvaluateExpressionOptions *GetOptions() { return nullptr; };
+
//------------------------------------------------------------------
/// Return the address of the function's JIT-compiled code, or
/// LLDB_INVALID_ADDRESS if the function is not JIT compiled
@@ -139,10 +120,17 @@ public:
{
return m_jit_start_addr;
}
+
+ virtual ExpressionTypeSystemHelper *
+ GetTypeSystemHelper ()
+ {
+ return nullptr;
+ }
protected:
- lldb::ProcessWP m_jit_process_wp;
+ lldb::TargetWP m_target_wp; /// Expression's always have to have a target...
+ lldb::ProcessWP m_jit_process_wp; /// An expression might have a process, but it doesn't need to (e.g. calculator mode.)
lldb::addr_t m_jit_start_addr; ///< The address of the JITted function within the JIT allocation. LLDB_INVALID_ADDRESS if invalid.
lldb::addr_t m_jit_end_addr; ///< The address of the JITted function within the JIT allocation. LLDB_INVALID_ADDRESS if invalid.
@@ -150,4 +138,4 @@ protected:
} // namespace lldb_private
-#endif // liblldb_ClangExpression_h_
+#endif // liblldb_Expression_h_
diff --git a/include/lldb/Expression/ClangExpressionParser.h b/include/lldb/Expression/ExpressionParser.h
index 21a27a489bcd..49333e79bf5e 100644
--- a/include/lldb/Expression/ClangExpressionParser.h
+++ b/include/lldb/Expression/ExpressionParser.h
@@ -1,4 +1,4 @@
-//===-- ClangExpressionParser.h ---------------------------------*- C++ -*-===//
+//===-- ExpressionParser.h --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,17 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangExpressionParser_h_
-#define liblldb_ClangExpressionParser_h_
+#ifndef liblldb_ExpressionParser_h_
+#define liblldb_ExpressionParser_h_
#include "lldb/lldb-public.h"
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Error.h"
-#include "lldb/Expression/IRForTarget.h"
-
-#include <string>
-#include <vector>
namespace lldb_private
{
@@ -25,16 +19,12 @@ namespace lldb_private
class IRExecutionUnit;
//----------------------------------------------------------------------
-/// @class ClangExpressionParser ClangExpressionParser.h "lldb/Expression/ClangExpressionParser.h"
-/// @brief Encapsulates an instance of Clang that can parse expressions.
+/// @class ExpressionParser ExpressionParser.h "lldb/Expression/ExpressionParser.h"
+/// @brief Encapsulates an instance of a compiler that can parse expressions.
///
-/// ClangExpressionParser is responsible for preparing an instance of
-/// ClangExpression for execution. ClangExpressionParser uses ClangExpression
-/// as a glorified parameter list, performing the required parsing and
-/// conversion to formats (DWARF bytecode, or JIT compiled machine code)
-/// that can be executed.
+/// ExpressionParser is the base class for llvm based Expression parsers.
//----------------------------------------------------------------------
-class ClangExpressionParser
+class ExpressionParser
{
public:
//------------------------------------------------------------------
@@ -50,14 +40,18 @@ public:
/// @param[in] expr
/// The expression to be parsed.
//------------------------------------------------------------------
- ClangExpressionParser (ExecutionContextScope *exe_scope,
- ClangExpression &expr,
- bool generate_debug_info);
+ ExpressionParser (ExecutionContextScope *exe_scope,
+ Expression &expr,
+ bool generate_debug_info) :
+ m_expr(expr),
+ m_generate_debug_info(generate_debug_info)
+ {
+ }
//------------------------------------------------------------------
/// Destructor
//------------------------------------------------------------------
- ~ClangExpressionParser ();
+ virtual ~ExpressionParser () {};
//------------------------------------------------------------------
/// Parse a single expression and convert it to IR using Clang. Don't
@@ -70,8 +64,8 @@ public:
/// The number of errors encountered during parsing. 0 means
/// success.
//------------------------------------------------------------------
- unsigned
- Parse (Stream &stream);
+ virtual unsigned
+ Parse (Stream &stream) = 0;
//------------------------------------------------------------------
/// Ready an already-parsed expression for execution, possibly
@@ -92,15 +86,10 @@ public:
/// @param[in] exe_ctx
/// The execution context to write the function into.
///
- /// @param[out] evaluated_statically
+ /// @param[out] can_interpret
/// Set to true if the expression could be interpreted statically;
/// untouched otherwise.
///
- /// @param[out] const_result
- /// If the result of the expression is constant, and the
- /// expression has no side effects, this is set to the result of the
- /// expression.
- ///
/// @param[in] execution_policy
/// Determines whether the expression must be JIT-compiled, must be
/// evaluated statically, or whether this decision may be made
@@ -110,47 +99,25 @@ public:
/// An error code indicating the success or failure of the operation.
/// Test with Success().
//------------------------------------------------------------------
- Error
+ virtual Error
PrepareForExecution (lldb::addr_t &func_addr,
lldb::addr_t &func_end,
std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
ExecutionContext &exe_ctx,
bool &can_interpret,
- lldb_private::ExecutionPolicy execution_policy);
+ lldb_private::ExecutionPolicy execution_policy) = 0;
- //------------------------------------------------------------------
- /// Disassemble the machine code for a JITted function from the target
- /// process's memory and print the result to a stream.
- ///
- /// @param[in] stream
- /// The stream to print disassembly to.
- ///
- /// @param[in] exc_context
- /// The execution context to get the machine code from.
- ///
- /// @return
- /// The error generated. If .Success() is true, disassembly succeeded.
- //------------------------------------------------------------------
- Error
- DisassembleFunction (Stream &stream,
- ExecutionContext &exe_ctx);
-
bool
- GetGenerateDebugInfo () const;
-
-private:
- ClangExpression & m_expr; ///< The expression to be parsed
- std::unique_ptr<llvm::LLVMContext> m_llvm_context; ///< The LLVM context to generate IR into
- std::unique_ptr<clang::FileManager> m_file_manager; ///< The Clang file manager object used by the compiler
- std::unique_ptr<clang::CompilerInstance> m_compiler; ///< The Clang compiler used to parse expressions into IR
- std::unique_ptr<clang::Builtin::Context> m_builtin_context; ///< Context for Clang built-ins
- std::unique_ptr<clang::SelectorTable> m_selector_table; ///< Selector table for Objective-C methods
- std::unique_ptr<clang::CodeGenerator> m_code_generator; ///< The Clang object that generates IR
+ GetGenerateDebugInfo () const
+ {
+ return m_generate_debug_info;
+ }
- class LLDBPreprocessorCallbacks;
- LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor encounters module imports
+protected:
+ Expression & m_expr; ///< The expression to be parsed
+ bool m_generate_debug_info;
};
}
-#endif // liblldb_ClangExpressionParser_h_
+#endif // liblldb_ExpressionParser_h_
diff --git a/include/lldb/Expression/ExpressionTypeSystemHelper.h b/include/lldb/Expression/ExpressionTypeSystemHelper.h
new file mode 100644
index 000000000000..cb560c9b5a42
--- /dev/null
+++ b/include/lldb/Expression/ExpressionTypeSystemHelper.h
@@ -0,0 +1,54 @@
+//===-- ExpressionTypeSystemHelper.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ExpressionTypeSystemHelper_h
+#define ExpressionTypeSystemHelper_h
+
+#include "llvm/Support/Casting.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class ExpressionTypeSystemHelper ExpressionTypeSystemHelper.h "lldb/Expression/ExpressionTypeSystemHelper.h"
+/// @brief A helper object that the Expression can pass to its ExpressionParser to provide generic information that
+/// any type of expression will need to supply. It's only job is to support dyn_cast so that the expression parser
+/// can cast it back to the requisite specific type.
+///
+//----------------------------------------------------------------------
+
+class ExpressionTypeSystemHelper
+{
+public:
+ enum LLVMCastKind {
+ eKindClangHelper,
+ eKindSwiftHelper,
+ eKindGoHelper,
+ kNumKinds
+ };
+
+ LLVMCastKind getKind() const { return m_kind; }
+
+ ExpressionTypeSystemHelper (LLVMCastKind kind) :
+ m_kind(kind)
+ {
+ }
+
+ ~ExpressionTypeSystemHelper () {}
+
+protected:
+ LLVMCastKind m_kind;
+};
+
+
+
+
+} // namespace lldb_private
+
+#endif /* ExpressionTypeSystemHelper_h */
diff --git a/include/lldb/Expression/ExpressionVariable.h b/include/lldb/Expression/ExpressionVariable.h
new file mode 100644
index 000000000000..d8030ba1c257
--- /dev/null
+++ b/include/lldb/Expression/ExpressionVariable.h
@@ -0,0 +1,320 @@
+//===-- ExpressionVariable.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ExpressionVariable_h_
+#define liblldb_ExpressionVariable_h_
+
+// C Includes
+// C++ Includes
+#include <memory>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/ValueObject.h"
+
+namespace lldb_private
+{
+
+class ClangExpressionVariable;
+
+class ExpressionVariable :
+ public std::enable_shared_from_this<ExpressionVariable>
+{
+public:
+ //----------------------------------------------------------------------
+ // See TypeSystem.h for how to add subclasses to this.
+ //----------------------------------------------------------------------
+ enum LLVMCastKind {
+ eKindClang,
+ eKindSwift,
+ eKindGo,
+ kNumKinds
+ };
+
+ LLVMCastKind getKind() const { return m_kind; }
+
+ ExpressionVariable(LLVMCastKind kind) :
+ m_flags(0),
+ m_kind(kind)
+ {
+ }
+
+ virtual ~ExpressionVariable();
+
+ size_t
+ GetByteSize ()
+ {
+ return m_frozen_sp->GetByteSize();
+ }
+
+ const ConstString &
+ GetName ()
+ {
+ return m_frozen_sp->GetName();
+ }
+
+ lldb::ValueObjectSP
+ GetValueObject()
+ {
+ return m_frozen_sp;
+ }
+
+ uint8_t *GetValueBytes();
+
+ void
+ ValueUpdated ()
+ {
+ m_frozen_sp->ValueUpdated ();
+ }
+
+ RegisterInfo *
+ GetRegisterInfo()
+ {
+ return m_frozen_sp->GetValue().GetRegisterInfo();
+ }
+
+ void
+ SetRegisterInfo (const RegisterInfo *reg_info)
+ {
+ return m_frozen_sp->GetValue().SetContext (Value::eContextTypeRegisterInfo, const_cast<RegisterInfo *>(reg_info));
+ }
+
+ CompilerType
+ GetCompilerType()
+ {
+ return m_frozen_sp->GetCompilerType();
+ }
+
+ void
+ SetCompilerType(const CompilerType &compiler_type)
+ {
+ m_frozen_sp->GetValue().SetCompilerType(compiler_type);
+ }
+
+ void
+ SetName (const ConstString &name)
+ {
+ m_frozen_sp->SetName (name);
+ }
+
+ // this function is used to copy the address-of m_live_sp into m_frozen_sp
+ // this is necessary because the results of certain cast and pointer-arithmetic
+ // operations (such as those described in bugzilla issues 11588 and 11618) generate
+ // frozen objects that do not have a valid address-of, which can be troublesome when
+ // using synthetic children providers. Transferring the address-of the live object
+ // solves these issues and provides the expected user-level behavior
+ void
+ TransferAddress (bool force = false)
+ {
+ if (m_live_sp.get() == nullptr)
+ return;
+
+ if (m_frozen_sp.get() == nullptr)
+ return;
+
+ if (force || (m_frozen_sp->GetLiveAddress() == LLDB_INVALID_ADDRESS))
+ m_frozen_sp->SetLiveAddress(m_live_sp->GetLiveAddress());
+ }
+
+ enum Flags
+ {
+ EVNone = 0,
+ EVIsLLDBAllocated = 1 << 0, ///< This variable is resident in a location specifically allocated for it by LLDB in the target process
+ EVIsProgramReference = 1 << 1, ///< This variable is a reference to a (possibly invalid) area managed by the target program
+ EVNeedsAllocation = 1 << 2, ///< Space for this variable has yet to be allocated in the target process
+ EVIsFreezeDried = 1 << 3, ///< This variable's authoritative version is in m_frozen_sp (for example, for statically-computed results)
+ EVNeedsFreezeDry = 1 << 4, ///< Copy from m_live_sp to m_frozen_sp during dematerialization
+ EVKeepInTarget = 1 << 5, ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it
+ EVTypeIsReference = 1 << 6, ///< The original type of this variable is a reference, so materialize the value rather than the location
+ EVUnknownType = 1 << 7, ///< This is a symbol of unknown type, and the type must be resolved after parsing is complete
+ EVBareRegister = 1 << 8 ///< This variable is a direct reference to $pc or some other entity.
+ };
+
+ typedef uint16_t FlagType;
+
+ FlagType m_flags; // takes elements of Flags
+
+ // these should be private
+ lldb::ValueObjectSP m_frozen_sp;
+ lldb::ValueObjectSP m_live_sp;
+ LLVMCastKind m_kind;
+};
+
+//----------------------------------------------------------------------
+/// @class ExpressionVariableList ExpressionVariable.h "lldb/Expression/ExpressionVariable.h"
+/// @brief A list of variable references.
+///
+/// This class stores variables internally, acting as the permanent store.
+//----------------------------------------------------------------------
+class ExpressionVariableList
+{
+public:
+ //----------------------------------------------------------------------
+ /// Implementation of methods in ExpressionVariableListBase
+ //----------------------------------------------------------------------
+ size_t
+ GetSize()
+ {
+ return m_variables.size();
+ }
+
+ lldb::ExpressionVariableSP
+ GetVariableAtIndex(size_t index)
+ {
+ lldb::ExpressionVariableSP var_sp;
+ if (index < m_variables.size())
+ var_sp = m_variables[index];
+ return var_sp;
+ }
+
+ size_t
+ AddVariable (const lldb::ExpressionVariableSP &var_sp)
+ {
+ m_variables.push_back(var_sp);
+ return m_variables.size() - 1;
+ }
+
+ lldb::ExpressionVariableSP
+ AddNewlyConstructedVariable (ExpressionVariable *var)
+ {
+ lldb::ExpressionVariableSP var_sp(var);
+ m_variables.push_back(var_sp);
+ return m_variables.back();
+ }
+
+ bool
+ ContainsVariable (const lldb::ExpressionVariableSP &var_sp)
+ {
+ const size_t size = m_variables.size();
+ for (size_t index = 0; index < size; ++index)
+ {
+ if (m_variables[index].get() == var_sp.get())
+ return true;
+ }
+ return false;
+ }
+
+ //----------------------------------------------------------------------
+ /// Finds a variable by name in the list.
+ ///
+ /// @param[in] name
+ /// The name of the requested variable.
+ ///
+ /// @return
+ /// The variable requested, or nullptr if that variable is not in the list.
+ //----------------------------------------------------------------------
+ lldb::ExpressionVariableSP
+ GetVariable (const ConstString &name)
+ {
+ lldb::ExpressionVariableSP var_sp;
+ for (size_t index = 0, size = GetSize(); index < size; ++index)
+ {
+ var_sp = GetVariableAtIndex(index);
+ if (var_sp->GetName() == name)
+ return var_sp;
+ }
+ var_sp.reset();
+ return var_sp;
+ }
+
+ lldb::ExpressionVariableSP
+ GetVariable (const char *name)
+ {
+ lldb::ExpressionVariableSP var_sp;
+ if (name && name[0])
+ {
+ for (size_t index = 0, size = GetSize(); index < size; ++index)
+ {
+ var_sp = GetVariableAtIndex(index);
+ const char *var_name_cstr = var_sp->GetName().GetCString();
+ if (!var_name_cstr || !name)
+ continue;
+ if (::strcmp (var_name_cstr, name) == 0)
+ return var_sp;
+ }
+ var_sp.reset();
+ }
+ return var_sp;
+ }
+
+ void
+ RemoveVariable (lldb::ExpressionVariableSP var_sp)
+ {
+ for (std::vector<lldb::ExpressionVariableSP>::iterator vi = m_variables.begin(), ve = m_variables.end();
+ vi != ve;
+ ++vi)
+ {
+ if (vi->get() == var_sp.get())
+ {
+ m_variables.erase(vi);
+ return;
+ }
+ }
+ }
+
+ void
+ Clear()
+ {
+ m_variables.clear();
+ }
+
+private:
+ std::vector <lldb::ExpressionVariableSP> m_variables;
+};
+
+class PersistentExpressionState : public ExpressionVariableList {
+public:
+ //----------------------------------------------------------------------
+ // See TypeSystem.h for how to add subclasses to this.
+ //----------------------------------------------------------------------
+ enum LLVMCastKind {
+ eKindClang,
+ eKindSwift,
+ eKindGo,
+ kNumKinds
+ };
+
+ LLVMCastKind getKind() const { return m_kind; }
+
+ PersistentExpressionState(LLVMCastKind kind) :
+ m_kind(kind)
+ {
+ }
+
+ virtual ~PersistentExpressionState();
+
+ virtual lldb::ExpressionVariableSP
+ CreatePersistentVariable (const lldb::ValueObjectSP &valobj_sp) = 0;
+
+ virtual lldb::ExpressionVariableSP
+ CreatePersistentVariable (ExecutionContextScope *exe_scope,
+ const ConstString &name,
+ const CompilerType &type,
+ lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size) = 0;
+
+ virtual ConstString
+ GetNextPersistentVariableName () = 0;
+
+ virtual void
+ RemovePersistentVariable (lldb::ExpressionVariableSP variable) = 0;
+
+ virtual lldb::addr_t
+ LookupSymbol (const ConstString &name) = 0;
+
+private:
+ LLVMCastKind m_kind;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ExpressionVariable_h_
diff --git a/include/lldb/Expression/ClangFunction.h b/include/lldb/Expression/FunctionCaller.h
index cf7e2592021f..c9a45811670f 100644
--- a/include/lldb/Expression/ClangFunction.h
+++ b/include/lldb/Expression/FunctionCaller.h
@@ -1,4 +1,4 @@
-//===-- ClangFunction.h -----------------------------------------*- C++ -*-===//
+//===-- FunctionCaller.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,35 +7,32 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_ClangFunction_h_
-#define lldb_ClangFunction_h_
+#ifndef liblldb_FunctionCaller_h_
+#define liblldb_FunctionCaller_h_
// C Includes
// C++ Includes
-#include <vector>
#include <list>
+#include <memory>
+#include <string>
+#include <vector>
+
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Value.h"
-#include "lldb/Core/ValueObjectList.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Symbol/ClangASTType.h"
-#include "lldb/Target/Process.h"
+#include "lldb/Expression/Expression.h"
+#include "lldb/Expression/ExpressionParser.h"
+#include "lldb/Symbol/CompilerType.h"
namespace lldb_private
{
-class ASTStructExtractor;
-class ClangExpressionParser;
-
//----------------------------------------------------------------------
-/// @class ClangFunction ClangFunction.h "lldb/Expression/ClangFunction.h"
+/// @class FunctionCaller FunctionCaller.h "lldb/Expression/FunctionCaller.h"
/// @brief Encapsulates a function that can be called.
///
-/// A given ClangFunction object can handle a single function signature.
+/// A given FunctionCaller object can handle a single function signature.
/// Once constructed, it can set up any number of concurrent calls to
/// functions with that signature.
///
@@ -46,7 +43,7 @@ class ClangExpressionParser;
/// struct with the written arguments. This method lets Clang handle the
/// vagaries of function calling conventions.
///
-/// The simplest use of the ClangFunction is to construct it with a
+/// The simplest use of the FunctionCaller is to construct it with a
/// function representative of the signature you want to use, then call
/// ExecuteFunction(ExecutionContext &, Stream &, Value &).
///
@@ -61,12 +58,11 @@ class ClangExpressionParser;
/// a pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated
/// and its address returned in that variable.
///
-/// Any of the methods that take arg_addr_ptr can be passed NULL, and the
+/// Any of the methods that take arg_addr_ptr can be passed nullptr, and the
/// argument space will be managed for you.
//----------------------------------------------------------------------
-class ClangFunction : public ClangExpression
+class FunctionCaller : public Expression
{
- friend class ASTStructExtractor;
public:
//------------------------------------------------------------------
/// Constructor
@@ -75,30 +71,6 @@ public:
/// An execution context scope that gets us at least a target and
/// process.
///
- /// @param[in] function_ptr
- /// The default function to be called. Can be overridden using
- /// WriteFunctionArguments().
- ///
- /// @param[in] ast_context
- /// The AST context to evaluate argument types in.
- ///
- /// @param[in] arg_value_list
- /// The default values to use when calling this function. Can
- /// be overridden using WriteFunctionArguments().
- //------------------------------------------------------------------
- ClangFunction (ExecutionContextScope &exe_scope,
- Function &function_ptr,
- ClangASTContext *ast_context,
- const ValueList &arg_value_list,
- const char *name);
-
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] exe_scope
- /// An execution context scope that gets us at least a target and
- /// process.
- ///
/// @param[in] ast_context
/// The AST context to evaluate argument types in.
///
@@ -113,8 +85,8 @@ public:
/// The default values to use when calling this function. Can
/// be overridden using WriteFunctionArguments().
//------------------------------------------------------------------
- ClangFunction (ExecutionContextScope &exe_scope,
- const ClangASTType &return_type,
+ FunctionCaller (ExecutionContextScope &exe_scope,
+ const CompilerType &return_type,
const Address& function_address,
const ValueList &arg_value_list,
const char *name);
@@ -122,8 +94,7 @@ public:
//------------------------------------------------------------------
/// Destructor
//------------------------------------------------------------------
- virtual
- ~ClangFunction();
+ ~FunctionCaller() override;
//------------------------------------------------------------------
/// Compile the wrapper function
@@ -134,8 +105,8 @@ public:
/// @return
/// The number of errors.
//------------------------------------------------------------------
- unsigned
- CompileFunction (Stream &errors);
+ virtual unsigned
+ CompileFunction (Stream &errors) = 0;
//------------------------------------------------------------------
/// Insert the default function wrapper and its default argument struct
@@ -209,10 +180,7 @@ public:
/// @param[in,out] args_addr_ref
/// The address of the structure to write the arguments into. May
/// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
- /// and args_addr_ref is pointed to it.
- ///
- /// @param[in] function_address
- /// The address of the function to call.
+ /// and args_addr_ref is pointed at it.
///
/// @param[in] arg_values
/// The values of the function's arguments.
@@ -225,12 +193,11 @@ public:
//------------------------------------------------------------------
bool WriteFunctionArguments (ExecutionContext &exe_ctx,
lldb::addr_t &args_addr_ref,
- Address function_address,
- ValueList &arg_values,
+ ValueList &arg_values,
Stream &errors);
//------------------------------------------------------------------
- /// Run the function this ClangFunction was created with.
+ /// Run the function this FunctionCaller was created with.
///
/// This is the full version.
///
@@ -238,7 +205,7 @@ public:
/// The thread & process in which this function will run.
///
/// @param[in] args_addr_ptr
- /// If NULL, the function will take care of allocating & deallocating the wrapper
+ /// If nullptr, the function will take care of allocating & deallocating the wrapper
/// args structure. Otherwise, if set to LLDB_INVALID_ADDRESS, a new structure
/// will be allocated, filled and the address returned to you. You are responsible
/// for deallocating it. And if passed in with a value other than LLDB_INVALID_ADDRESS,
@@ -264,7 +231,7 @@ public:
Value &results);
//------------------------------------------------------------------
- /// Get a thread plan to run the function this ClangFunction was created with.
+ /// Get a thread plan to run the function this FunctionCaller was created with.
///
/// @param[in] exe_ctx
/// The execution context to insert the function and its arguments
@@ -335,7 +302,7 @@ public:
/// translation unit.
//------------------------------------------------------------------
const char *
- Text ()
+ Text() override
{
return m_wrapper_function_text.c_str();
}
@@ -346,48 +313,27 @@ public:
/// function.
//------------------------------------------------------------------
const char *
- FunctionName ()
+ FunctionName() override
{
return m_wrapper_function_name.c_str();
}
//------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- ClangExpressionDeclMap *
- DeclMap ()
- {
- return NULL;
- }
-
- //------------------------------------------------------------------
/// Return the object that the parser should use when registering
- /// local variables. May be NULL if the Expression doesn't care.
+ /// local variables. May be nullptr if the Expression doesn't care.
//------------------------------------------------------------------
- ClangExpressionVariableList *
+ ExpressionVariableList *
LocalVariables ()
{
- return NULL;
+ return nullptr;
}
//------------------------------------------------------------------
- /// 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);
-
- //------------------------------------------------------------------
/// Return true if validation code should be inserted into the
/// expression.
//------------------------------------------------------------------
bool
- NeedsValidation ()
+ NeedsValidation() override
{
return false;
}
@@ -397,7 +343,7 @@ public:
/// resolved.
//------------------------------------------------------------------
bool
- NeedsVariableResolution ()
+ NeedsVariableResolution() override
{
return false;
}
@@ -407,29 +353,27 @@ public:
{
return m_arg_values;
}
-private:
- //------------------------------------------------------------------
- // For ClangFunction only
- //------------------------------------------------------------------
+protected:
// Note: the parser needs to be destructed before the execution unit, so
// declare the execution unit first.
std::shared_ptr<IRExecutionUnit> m_execution_unit_sp;
- std::unique_ptr<ClangExpressionParser> m_parser; ///< The parser responsible for compiling the function.
+ std::unique_ptr<ExpressionParser> m_parser; ///< The parser responsible for compiling the function.
+ ///< This will get made in CompileFunction, so it is
+ ///< safe to access it after that.
+
lldb::ModuleWP m_jit_module_wp;
std::string m_name; ///< The name of this clang function - for debugging purposes.
- Function *m_function_ptr; ///< The function we're going to call. May be NULL if we don't have debug info for the function.
+ Function *m_function_ptr; ///< The function we're going to call. May be nullptr if we don't have debug info for the function.
Address m_function_addr; ///< If we don't have the FunctionSP, we at least need the address & return type.
- ClangASTType m_function_return_type; ///< The opaque clang qual type for the function return type.
+ CompilerType m_function_return_type; ///< The opaque clang qual type for the function return type.
std::string m_wrapper_function_name; ///< The name of the wrapper function.
std::string m_wrapper_function_text; ///< The contents of the wrapper function.
std::string m_wrapper_struct_name; ///< The name of the struct that contains the target function address, arguments, and result.
std::list<lldb::addr_t> m_wrapper_args_addrs; ///< The addresses of the arguments to the wrapper function.
- std::unique_ptr<ASTStructExtractor> m_struct_extractor; ///< The class that generates the argument struct below.
-
bool m_struct_valid; ///< True if the ASTStructExtractor has populated the variables below.
//------------------------------------------------------------------
@@ -446,6 +390,6 @@ private:
bool m_JITted; ///< True if the wrapper function has already been JIT-compiled.
};
-} // Namespace lldb_private
+} // namespace lldb_private
-#endif // lldb_ClangFunction_h_
+#endif // liblldb_FunctionCaller_h_
diff --git a/include/lldb/Expression/IRDynamicChecks.h b/include/lldb/Expression/IRDynamicChecks.h
index 226f5c94e98c..ef77d55f4b34 100644
--- a/include/lldb/Expression/IRDynamicChecks.h
+++ b/include/lldb/Expression/IRDynamicChecks.h
@@ -24,11 +24,10 @@ namespace llvm {
class Value;
}
-namespace lldb_private
+namespace lldb_private
{
class ClangExpressionDeclMap;
-class ClangUtilityFunction;
class ExecutionContext;
class Stream;
@@ -77,8 +76,8 @@ public:
bool DoCheckersExplainStop (lldb::addr_t addr, Stream &message);
- std::unique_ptr<ClangUtilityFunction> m_valid_pointer_check;
- std::unique_ptr<ClangUtilityFunction> m_objc_object_check;
+ std::unique_ptr<UtilityFunction> m_valid_pointer_check;
+ std::unique_ptr<UtilityFunction> m_objc_object_check;
};
//----------------------------------------------------------------------
@@ -114,7 +113,7 @@ public:
//------------------------------------------------------------------
/// Destructor
//------------------------------------------------------------------
- virtual ~IRDynamicChecks();
+ ~IRDynamicChecks() override;
//------------------------------------------------------------------
/// Run this IR transformer on a single module
@@ -127,18 +126,19 @@ public:
/// @return
/// True on success; false otherwise
//------------------------------------------------------------------
- bool runOnModule(llvm::Module &M);
+ bool runOnModule(llvm::Module &M) override;
//------------------------------------------------------------------
/// Interface stub
//------------------------------------------------------------------
void assignPassManager(llvm::PMStack &PMS,
- llvm::PassManagerType T = llvm::PMT_ModulePassManager);
+ llvm::PassManagerType T = llvm::PMT_ModulePassManager) override;
//------------------------------------------------------------------
/// Returns PMT_ModulePassManager
//------------------------------------------------------------------
- llvm::PassManagerType getPotentialPassManagerType() const;
+ llvm::PassManagerType getPotentialPassManagerType() const override;
+
private:
//------------------------------------------------------------------
/// A basic block-level pass to find all pointer dereferences and
@@ -164,6 +164,6 @@ private:
DynamicCheckerFunctions &m_checker_functions; ///< The checker functions for the process
};
-}
+} // namespace lldb_private
-#endif
+#endif // liblldb_IRDynamicChecks_h_
diff --git a/include/lldb/Expression/IRExecutionUnit.h b/include/lldb/Expression/IRExecutionUnit.h
index bd1a795a158e..86744b7b9726 100644
--- a/include/lldb/Expression/IRExecutionUnit.h
+++ b/include/lldb/Expression/IRExecutionUnit.h
@@ -7,27 +7,24 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_IRExecutionUnit_h_
-#define lldb_IRExecutionUnit_h_
+#ifndef liblldb_IRExecutionUnit_h_
+#define liblldb_IRExecutionUnit_h_
// C Includes
// C++ Includes
#include <atomic>
+#include <memory>
#include <string>
#include <vector>
-#include <map>
// Other libraries and framework includes
#include "llvm/IR/Module.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
// Project includes
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
-#include "lldb/Core/ClangForward.h"
#include "lldb/Core/DataBufferHeap.h"
-#include "llvm/ExecutionEngine/SectionMemoryManager.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangExpressionParser.h"
#include "lldb/Expression/IRMemoryMap.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -37,7 +34,7 @@ namespace llvm {
class Module;
class ExecutionEngine;
-}
+} // namespace llvm
namespace lldb_private {
@@ -79,7 +76,7 @@ public:
//------------------------------------------------------------------
/// Destructor
//------------------------------------------------------------------
- ~IRExecutionUnit();
+ ~IRExecutionUnit() override;
llvm::Module *
GetModule()
@@ -90,10 +87,7 @@ public:
llvm::Function *
GetFunction()
{
- if (m_module)
- return m_module->getFunction (m_name.AsCString());
- else
- return NULL;
+ return ((m_module != nullptr) ? m_module->getFunction(m_name.AsCString()) : nullptr);
}
void
@@ -118,22 +112,22 @@ public:
//------------------------------------------------------------------
/// ObjectFileJITDelegate overrides
//------------------------------------------------------------------
- virtual lldb::ByteOrder
- GetByteOrder () const;
+ lldb::ByteOrder
+ GetByteOrder() const override;
- virtual uint32_t
- GetAddressByteSize () const;
+ uint32_t
+ GetAddressByteSize() const override;
- virtual void
- PopulateSymtab (lldb_private::ObjectFile *obj_file,
- lldb_private::Symtab &symtab);
+ void
+ PopulateSymtab(lldb_private::ObjectFile *obj_file,
+ lldb_private::Symtab &symtab) override;
- virtual void
- PopulateSectionList (lldb_private::ObjectFile *obj_file,
- lldb_private::SectionList &section_list);
+ void
+ PopulateSectionList(lldb_private::ObjectFile *obj_file,
+ lldb_private::SectionList &section_list) override;
- virtual bool
- GetArchitecture (lldb_private::ArchSpec &arch);
+ bool
+ GetArchitecture(lldb_private::ArchSpec &arch) override;
lldb::ModuleSP
GetJITModule ();
@@ -215,7 +209,7 @@ private:
public:
MemoryManager (IRExecutionUnit &parent);
- virtual ~MemoryManager();
+ ~MemoryManager() override;
//------------------------------------------------------------------
/// Allocate space for executable code, and add it to the
@@ -233,9 +227,9 @@ private:
/// @return
/// Allocated space.
//------------------------------------------------------------------
- virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID,
- llvm::StringRef SectionName);
+ uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ llvm::StringRef SectionName) override;
//------------------------------------------------------------------
/// Allocate space for data, and add it to the m_spaceBlocks map
@@ -255,10 +249,10 @@ private:
/// @return
/// Allocated space.
//------------------------------------------------------------------
- virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID,
- llvm::StringRef SectionName,
- bool IsReadOnly);
+ uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ llvm::StringRef SectionName,
+ bool IsReadOnly) override;
//------------------------------------------------------------------
/// Called when object loading is complete and section page
@@ -270,7 +264,7 @@ private:
/// @return
/// True in case of failure, false in case of success.
//------------------------------------------------------------------
- virtual bool finalizeMemory(std::string *ErrMsg) {
+ bool finalizeMemory(std::string *ErrMsg) override {
// TODO: Ensure that the instruction cache is flushed because
// relocations are updated by dy-load. See:
// sys::Memory::InvalidateInstructionCache
@@ -278,17 +272,17 @@ private:
return false;
}
- virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
- return;
+ void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
}
//------------------------------------------------------------------
/// Passthrough interface stub
//------------------------------------------------------------------
- virtual uint64_t getSymbolAddress(const std::string &Name);
+ uint64_t getSymbolAddress(const std::string &Name) override;
+
+ void *getPointerToNamedFunction(const std::string &Name,
+ bool AbortOnFailure = true) override;
- virtual void *getPointerToNamedFunction(const std::string &Name,
- bool AbortOnFailure = true);
private:
std::unique_ptr<SectionMemoryManager> m_default_mm_ap; ///< The memory allocator to use in actually creating space. All calls are passed through to it.
IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
@@ -403,4 +397,4 @@ private:
} // namespace lldb_private
-#endif // lldb_IRExecutionUnit_h_
+#endif // liblldb_IRExecutionUnit_h_
diff --git a/include/lldb/Expression/IRForTarget.h b/include/lldb/Expression/IRForTarget.h
deleted file mode 100644
index b81fab7a8a83..000000000000
--- a/include/lldb/Expression/IRForTarget.h
+++ /dev/null
@@ -1,745 +0,0 @@
-//===-- IRForTarget.h ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#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 "llvm/Pass.h"
-
-#include <map>
-#include <functional>
-
-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;
-}
-
-namespace lldb_private {
- class ClangExpressionDeclMap;
- class IRExecutionUnit;
- class IRMemoryMap;
-}
-
-//----------------------------------------------------------------------
-/// @class IRForTarget IRForTarget.h "lldb/Expression/IRForTarget.h"
-/// @brief Transforms the IR for a function to run in the target
-///
-/// Once an expression has been parsed and converted to IR, it can run
-/// in two contexts: interpreted by LLDB as a DWARF location expression,
-/// or compiled by the JIT and inserted into the target process for
-/// execution.
-///
-/// IRForTarget makes the second possible, by applying a series of
-/// transformations to the IR which make it relocatable. These
-/// transformations are discussed in more detail next to their relevant
-/// functions.
-//----------------------------------------------------------------------
-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
- //------------------------------------------------------------------
- virtual ~IRForTarget();
-
- //------------------------------------------------------------------
- /// 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
- //------------------------------------------------------------------
- virtual bool
- runOnModule (llvm::Module &llvm_module);
-
- //------------------------------------------------------------------
- /// Interface stub
- ///
- /// Implementation of the llvm::ModulePass::assignPassManager()
- /// function.
- //------------------------------------------------------------------
- virtual void
- assignPassManager (llvm::PMStack &pass_mgr_stack,
- llvm::PassManagerType pass_mgr_type = llvm::PMT_ModulePassManager);
-
- //------------------------------------------------------------------
- /// Returns PMT_ModulePassManager
- ///
- /// Implementation of the llvm::ModulePass::getPotentialPassManagerType()
- /// function.
- //------------------------------------------------------------------
- virtual llvm::PassManagerType
- getPotentialPassManagerType() const;
-
-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);
-
- //------------------------------------------------------------------
- /// Build a function pointer given a type and a raw pointer.
- ///
- /// @param[in] type
- /// The type of the function pointer to be built.
- ///
- /// @param[in] ptr
- /// The value of the pointer.
- ///
- /// @return
- /// The pointer.
- //------------------------------------------------------------------
- llvm::Constant *
- BuildFunctionPointer (llvm::Type *type,
- uint64_t ptr);
-
- void
- RegisterFunctionMetadata (llvm::LLVMContext &context,
- llvm::Value *function_ptr,
- const char *name);
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] llvm_function
- /// The function currently being processed.
- ///
- /// @return
- /// True if the function has side effects (or if this cannot
- /// be determined); false otherwise.
- //------------------------------------------------------------------
- bool
- ResolveFunctionPointers (llvm::Module &llvm_module);
-
- //------------------------------------------------------------------
- /// 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);
-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 module-level pass to allocate all string literals in a separate
- /// allocation and redirect references to them.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- ReplaceStrings ();
-
- //------------------------------------------------------------------
- /// A basic block-level pass to find all literals that will be
- /// allocated as statics by the JIT (in contrast to the Strings,
- /// which already are statics) and synthesize loads for them.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] basic_block
- /// The basic block currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- ReplaceStaticLiterals (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);
-
- //------------------------------------------------------------------
- /// A module-level pass to remove all global variables from the
- /// module since it no longer should export or import any symbols.
- //------------------------------------------------------------------
-
- //------------------------------------------------------------------
- /// The top-level pass implementation
- ///
- /// @param[in] llvm_module
- /// The module currently being processed.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool
- StripAllGVs (llvm::Module &llvm_module);
-
- class StaticDataAllocator {
- public:
- StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit);
- lldb_private::StreamString &GetStream()
- {
- return m_stream_string;
- }
- lldb::addr_t Allocate();
-
- lldb::TargetSP
- GetTarget();
- private:
- lldb_private::IRExecutionUnit &m_execution_unit;
- lldb_private::StreamString m_stream_string;
- lldb::addr_t m_allocation;
- };
-
- /// Flags
- bool m_resolve_vars; ///< True if external variable references and persistent variable references should be resolved
- std::string 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
- StaticDataAllocator m_data_allocator; ///< The allocator to use for constant strings
- 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; ///< If non-NULL, the stream on which errors should be printed
-
- 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,
- FunctionValueCache &value_maker,
- FunctionValueCache &entry_instruction_finder);
-
- //------------------------------------------------------------------
- /// 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
diff --git a/include/lldb/Expression/IRInterpreter.h b/include/lldb/Expression/IRInterpreter.h
index c314bf1099ea..4eb81bc68d19 100644
--- a/include/lldb/Expression/IRInterpreter.h
+++ b/include/lldb/Expression/IRInterpreter.h
@@ -13,7 +13,6 @@
#include "lldb/lldb-public.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Stream.h"
-#include "lldb/Symbol/TaggedASTType.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Pass.h"
diff --git a/include/lldb/Expression/IRMemoryMap.h b/include/lldb/Expression/IRMemoryMap.h
index 80add46ef0da..6fb718a341f7 100644
--- a/include/lldb/Expression/IRMemoryMap.h
+++ b/include/lldb/Expression/IRMemoryMap.h
@@ -50,7 +50,12 @@ public:
eAllocationPolicyProcessOnly ///< The intent is that this allocation exist only in the process.
};
- lldb::addr_t Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error);
+ lldb::addr_t Malloc (size_t size,
+ uint8_t alignment,
+ uint32_t permissions,
+ AllocationPolicy policy,
+ bool zero_memory,
+ Error &error);
void Leak (lldb::addr_t process_address, Error &error);
void Free (lldb::addr_t process_address, Error &error);
@@ -124,7 +129,7 @@ private:
typedef std::map<lldb::addr_t, Allocation> AllocationMap;
AllocationMap m_allocations;
- lldb::addr_t FindSpace (size_t size);
+ lldb::addr_t FindSpace (size_t size, bool zero_memory = false);
bool ContainsHostOnlyAllocations ();
AllocationMap::iterator FindAllocation (lldb::addr_t addr, size_t size);
diff --git a/include/lldb/Expression/IRToDWARF.h b/include/lldb/Expression/IRToDWARF.h
deleted file mode 100644
index a4ae9b7ebfae..000000000000
--- a/include/lldb/Expression/IRToDWARF.h
+++ /dev/null
@@ -1,111 +0,0 @@
-//===-- IRToDWARF.h ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_IRToDWARF_h_
-#define liblldb_IRToDWARF_h_
-
-#include "llvm/Pass.h"
-#include "llvm/IR/LegacyPassManager.h"
-
-#include "lldb/lldb-public.h"
-
-class Relocator;
-//----------------------------------------------------------------------
-/// @class IRToDWARF IRToDWARF.h "lldb/Expression/IRToDWARF.h"
-/// @brief Transforms the IR for a function into a DWARF location expression
-///
-/// Once an expression has been parsed and converted to IR, it can run
-/// in two contexts: interpreted by LLDB as a DWARF location expression,
-/// or compiled by the JIT and inserted into the target process for
-/// execution.
-///
-/// IRToDWARF makes the first possible, by traversing the control flow
-/// graph and writing the code for each basic block out as location
-/// expression bytecode. To ensure that the links between the basic blocks
-/// remain intact, it uses a relocator that records the location of every
-/// location expression instruction that has a relocatable operand, the
-/// target of that operand (as a basic block), and the mapping of each basic
-/// block to an actual location. After all code has been written out, the
-/// relocator post-processes it and performs all necessary relocations.
-//----------------------------------------------------------------------
-class IRToDWARF : public llvm::ModulePass
-{
-public:
- //------------------------------------------------------------------
- /// Constructor
- ///
- /// @param[in] local_vars
- /// A list of variables to populate with the local variables this
- /// expression uses.
- ///
- /// @param[in] decl_map
- /// The list of externally-referenced variables for the expression,
- /// for use in looking up globals.
- ///
- /// @param[in] stream
- /// The stream to dump DWARF bytecode onto.
- ///
- /// @param[in] func_name
- /// The name of the function to translate to DWARF.
- //------------------------------------------------------------------
- IRToDWARF(lldb_private::ClangExpressionVariableList &local_vars,
- lldb_private::ClangExpressionDeclMap *decl_map,
- lldb_private::StreamString &strm,
- const char* func_name = "$__lldb_expr");
-
- //------------------------------------------------------------------
- /// Destructor
- //------------------------------------------------------------------
- virtual ~IRToDWARF();
-
- //------------------------------------------------------------------
- /// Run this IR transformer on a single module
- ///
- /// @param[in] M
- /// The module to run on. This module is searched for the function
- /// $__lldb_expr, and that function is converted to a location
- /// expression.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool runOnModule(llvm::Module &M);
-
- //------------------------------------------------------------------
- /// Interface stub
- //------------------------------------------------------------------
- void assignPassManager(llvm::PMStack &PMS,
- llvm::PassManagerType T = llvm::PMT_ModulePassManager);
-
- //------------------------------------------------------------------
- /// Returns PMT_ModulePassManager
- //------------------------------------------------------------------
- llvm::PassManagerType getPotentialPassManagerType() const;
-private:
- //------------------------------------------------------------------
- /// Run this IR transformer on a single basic block
- ///
- /// @param[in] BB
- /// The basic block to transform.
- ///
- /// @param[in] Relocator
- /// The relocator to use when registering branches.
- ///
- /// @return
- /// True on success; false otherwise
- //------------------------------------------------------------------
- bool runOnBasicBlock(llvm::BasicBlock &BB, Relocator &Relocator);
-
- std::string m_func_name; ///< The name of the function to translate
- lldb_private::ClangExpressionVariableList &m_local_vars; ///< The list of local variables to populate while transforming
- lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The list of external variables
- lldb_private::StreamString &m_strm; ///< The stream to write bytecode to
-};
-
-#endif
diff --git a/include/lldb/Expression/LLVMUserExpression.h b/include/lldb/Expression/LLVMUserExpression.h
new file mode 100644
index 000000000000..e3d17986f4b3
--- /dev/null
+++ b/include/lldb/Expression/LLVMUserExpression.h
@@ -0,0 +1,118 @@
+//===-- LLVMUserExpression.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LLVMUserExpression_h
+#define liblldb_LLVMUserExpression_h
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <map>
+#include <vector>
+
+// Project includes
+#include "lldb/Expression/UserExpression.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class LLVMUserExpression LLVMUserExpression.h "lldb/Expression/LLVMUserExpression.h"
+/// @brief Encapsulates a one-time expression for use in lldb.
+///
+/// LLDB uses expressions for various purposes, notably to call functions
+/// and as a backend for the expr command. LLVMUserExpression is a virtual base
+/// class that encapsulates the objects needed to parse and JIT an expression.
+/// The actual parsing part will be provided by the specific implementations
+/// of LLVMUserExpression - which will be vended through the appropriate TypeSystem.
+//----------------------------------------------------------------------
+class LLVMUserExpression : public UserExpression
+{
+ public:
+ LLVMUserExpression(ExecutionContextScope &exe_scope,
+ const char *expr,
+ const char *expr_prefix,
+ lldb::LanguageType language,
+ ResultType desired_type,
+ const EvaluateExpressionOptions &options);
+ ~LLVMUserExpression() override;
+
+ lldb::ExpressionResults Execute(Stream &error_stream,
+ ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options,
+ lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result) override;
+
+ bool FinalizeJITExecution(Stream &error_stream,
+ 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;
+
+ bool
+ CanInterpret() override
+ {
+ return m_can_interpret;
+ }
+
+ //------------------------------------------------------------------
+ /// Return the string that the parser should parse. Must be a full
+ /// translation unit.
+ //------------------------------------------------------------------
+ const char *
+ Text() override
+ {
+ return m_transformed_text.c_str();
+ }
+
+ lldb::ModuleSP GetJITModule() override;
+
+ protected:
+ virtual void ScanContext(ExecutionContext &exe_ctx, lldb_private::Error &err) = 0;
+
+ bool PrepareToExecuteJITExpression(Stream &error_stream, ExecutionContext &exe_ctx, lldb::addr_t &struct_address);
+
+ virtual bool
+ AddArguments (ExecutionContext &exe_ctx,
+ std::vector<lldb::addr_t> &args,
+ lldb::addr_t struct_address,
+ Stream &error_stream) = 0;
+
+
+ lldb::addr_t m_stack_frame_bottom; ///< The bottom of the allocated stack frame.
+ lldb::addr_t m_stack_frame_top; ///< The top of the allocated stack frame.
+
+ bool m_allow_cxx; ///< True if the language allows C++.
+ bool m_allow_objc; ///< True if the language allows Objective-C.
+ std::string m_transformed_text; ///< The text of the expression, as send to the parser
+
+ std::shared_ptr<IRExecutionUnit> m_execution_unit_sp; ///< The execution unit the expression is stored in.
+ std::unique_ptr<Materializer> m_materializer_ap; ///< The materializer to use when running the expression.
+ lldb::ModuleWP m_jit_module_wp;
+ bool m_enforce_valid_object; ///< True if the expression parser should enforce the presence of a valid class pointer
+ ///in order to generate the expression as a method.
+ bool m_in_cplusplus_method; ///< True if the expression is compiled as a C++ member function (true if it was parsed
+ ///when exe_ctx was in a C++ method).
+ bool m_in_objectivec_method; ///< True if the expression is compiled as an Objective-C method (true if it was parsed
+ ///when exe_ctx was in an Objective-C method).
+ bool m_in_static_method; ///< True if the expression is compiled as a static (or class) method (currently true if it
+ ///was parsed when exe_ctx was in an Objective-C class method).
+ bool m_needs_object_ptr; ///< True if "this" or "self" must be looked up and passed in. False if the expression
+ ///doesn't really use them and they can be NULL.
+ bool m_const_object; ///< True if "this" is const.
+ Target *m_target; ///< The target for storing persistent data like types and variables.
+
+ bool m_can_interpret; ///< True if the expression could be evaluated statically; false otherwise.
+ lldb::addr_t
+ m_materialized_address; ///< The address at which the arguments to the expression have been materialized.
+ Materializer::DematerializerSP m_dematerializer_sp; ///< The dematerializer.
+};
+
+} // namespace lldb_private
+#endif
diff --git a/include/lldb/Expression/Materializer.h b/include/lldb/Expression/Materializer.h
index 208a08133923..f293fddc1022 100644
--- a/include/lldb/Expression/Materializer.h
+++ b/include/lldb/Expression/Materializer.h
@@ -7,18 +7,22 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_Materializer_h
-#define lldb_Materializer_h
+#ifndef liblldb_Materializer_h
+#define liblldb_Materializer_h
+// C Includes
+// C++ Includes
+#include <memory>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
#include "lldb/lldb-private-types.h"
#include "lldb/Core/Error.h"
#include "lldb/Expression/IRMemoryMap.h"
-#include "lldb/Host/Mutex.h"
-#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Target/StackFrame.h"
-#include <vector>
-
namespace lldb_private
{
@@ -32,8 +36,8 @@ public:
{
public:
Dematerializer () :
- m_materializer(NULL),
- m_map(NULL),
+ m_materializer(nullptr),
+ m_map(nullptr),
m_process_address(LLDB_INVALID_ADDRESS)
{
}
@@ -44,7 +48,6 @@ public:
}
void Dematerialize (Error &err,
- lldb::ClangExpressionVariableSP &result_sp,
lldb::addr_t frame_top,
lldb::addr_t frame_bottom);
@@ -54,6 +57,7 @@ public:
{
return m_materializer && m_map && (m_process_address != LLDB_INVALID_ADDRESS);
}
+
private:
friend class Materializer;
@@ -84,11 +88,28 @@ public:
DematerializerSP Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err);
- uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
- uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
- uint32_t AddResultVariable (const TypeFromUser &type, bool is_lvalue, bool keep_in_memory, Error &err);
- uint32_t AddSymbol (const Symbol &symbol_sp, Error &err);
- uint32_t AddRegister (const RegisterInfo &register_info, Error &err);
+ class PersistentVariableDelegate
+ {
+ public:
+ virtual ~PersistentVariableDelegate();
+ virtual ConstString GetName() = 0;
+ virtual void DidDematerialize(lldb::ExpressionVariableSP &variable) = 0;
+ };
+
+ uint32_t AddPersistentVariable (lldb::ExpressionVariableSP &persistent_variable_sp,
+ PersistentVariableDelegate *delegate,
+ Error &err);
+ uint32_t AddVariable (lldb::VariableSP &variable_sp,
+ Error &err);
+ uint32_t AddResultVariable (const CompilerType &type,
+ bool is_lvalue,
+ bool keep_in_memory,
+ PersistentVariableDelegate *delegate,
+ Error &err);
+ uint32_t AddSymbol (const Symbol &symbol_sp,
+ Error &err);
+ uint32_t AddRegister (const RegisterInfo &register_info,
+ Error &err);
uint32_t GetStructAlignment ()
{
@@ -100,14 +121,6 @@ public:
return m_current_offset;
}
- uint32_t GetResultOffset ()
- {
- if (m_result_entity)
- return m_result_entity->GetOffset();
- else
- return UINT32_MAX;
- }
-
class Entity
{
public:
@@ -117,11 +130,9 @@ public:
m_offset(0)
{
}
-
- virtual ~Entity ()
- {
- }
-
+
+ virtual ~Entity() = default;
+
virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) = 0;
@@ -147,8 +158,9 @@ public:
{
m_offset = offset;
}
+
protected:
- void SetSizeAndAlignmentFromType (ClangASTType &type);
+ void SetSizeAndAlignmentFromType (CompilerType &type);
uint32_t m_alignment;
uint32_t m_size;
@@ -163,11 +175,10 @@ private:
DematerializerWP m_dematerializer_wp;
EntityVector m_entities;
- Entity *m_result_entity;
uint32_t m_current_offset;
uint32_t m_struct_alignment;
};
-}
+} // namespace lldb_private
-#endif
+#endif // liblldb_Materializer_h
diff --git a/include/lldb/Expression/REPL.h b/include/lldb/Expression/REPL.h
new file mode 100644
index 000000000000..21d22de8e0d7
--- /dev/null
+++ b/include/lldb/Expression/REPL.h
@@ -0,0 +1,211 @@
+//===-- REPL.h --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_REPL_h
+#define lldb_REPL_h
+
+// C Includes
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/OptionGroupFormat.h"
+#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
+#include "lldb/../../source/Commands/CommandObjectExpression.h"
+
+namespace lldb_private
+{
+
+class REPL : public IOHandlerDelegate
+{
+public:
+ //----------------------------------------------------------------------
+ // See TypeSystem.h for how to add subclasses to this.
+ //----------------------------------------------------------------------
+ enum LLVMCastKind {
+ eKindClang,
+ eKindSwift,
+ eKindGo,
+ kNumKinds
+ };
+
+ LLVMCastKind getKind() const { return m_kind; }
+
+ REPL(LLVMCastKind kind, Target &target);
+
+ ~REPL() override;
+
+ //------------------------------------------------------------------
+ /// Get a REPL with an existing target (or, failing that, a debugger to use), and (optional) extra arguments for the compiler.
+ ///
+ /// @param[out] error
+ /// If this language is supported but the REPL couldn't be created, this error is populated with the reason.
+ ///
+ /// @param[in] language
+ /// The language to create a REPL for.
+ ///
+ /// @param[in] debugger
+ /// If provided, and target is nullptr, the debugger to use when setting up a top-level REPL.
+ ///
+ /// @param[in] target
+ /// If provided, the target to put the REPL inside.
+ ///
+ /// @param[in] repl_options
+ /// If provided, additional options for the compiler when parsing REPL expressions.
+ ///
+ /// @return
+ /// The range of the containing object in the target process.
+ //------------------------------------------------------------------
+ static lldb::REPLSP
+ Create (Error &Error, lldb::LanguageType language, Debugger *debugger, Target *target, const char *repl_options);
+
+ void
+ SetFormatOptions (const OptionGroupFormat &options)
+ {
+ m_format_options = options;
+ }
+
+ void
+ SetValueObjectDisplayOptions (const OptionGroupValueObjectDisplay &options)
+ {
+ m_varobj_options = options;
+ }
+
+ void
+ SetCommandOptions (const CommandObjectExpression::CommandOptions &options)
+ {
+ m_command_options = options;
+ }
+
+ void
+ SetCompilerOptions (const char *options)
+ {
+ if (options)
+ m_compiler_options = options;
+ }
+
+ lldb::IOHandlerSP
+ GetIOHandler ();
+
+ Error
+ RunLoop ();
+
+ //------------------------------------------------------------------
+ // IOHandler::Delegate functions
+ //------------------------------------------------------------------
+ void
+ IOHandlerActivated (IOHandler &io_handler) override;
+
+ bool
+ IOHandlerInterrupt (IOHandler &io_handler) override;
+
+ void
+ IOHandlerInputInterrupted (IOHandler &io_handler,
+ std::string &line) override;
+
+ const char *
+ IOHandlerGetFixIndentationCharacters () override;
+
+ ConstString
+ IOHandlerGetControlSequence (char ch) override;
+
+ const char *
+ IOHandlerGetCommandPrefix () override;
+
+ const char *
+ IOHandlerGetHelpPrologue () override;
+
+ bool
+ IOHandlerIsInputComplete (IOHandler &io_handler,
+ StringList &lines) override;
+
+ int
+ IOHandlerFixIndentation (IOHandler &io_handler,
+ const StringList &lines,
+ int cursor_position) override;
+
+ void
+ IOHandlerInputComplete (IOHandler &io_handler,
+ std::string &line) override;
+
+ int
+ IOHandlerComplete (IOHandler &io_handler,
+ const char *current_line,
+ const char *cursor,
+ const char *last_char,
+ int skip_first_n_matches,
+ int max_matches,
+ StringList &matches) override;
+
+protected:
+ static int
+ CalculateActualIndentation (const StringList &lines);
+
+ //----------------------------------------------------------------------
+ // Subclasses should override these functions to implement a functional REPL.
+ //----------------------------------------------------------------------
+
+ virtual Error
+ DoInitialization () = 0;
+
+ virtual ConstString
+ GetSourceFileBasename () = 0;
+
+ virtual const char *
+ GetAutoIndentCharacters () = 0;
+
+ virtual bool
+ SourceIsComplete (const std::string &source) = 0;
+
+ virtual lldb::offset_t
+ GetDesiredIndentation (const StringList &lines,
+ int cursor_position,
+ int tab_size) = 0; // LLDB_INVALID_OFFSET means no change
+
+ virtual lldb::LanguageType
+ GetLanguage () = 0;
+
+ virtual bool
+ PrintOneVariable (Debugger &debugger,
+ lldb::StreamFileSP &output_sp,
+ lldb::ValueObjectSP &valobj_sp,
+ ExpressionVariable *var = nullptr) = 0;
+
+ virtual int
+ CompleteCode(const std::string &current_code,
+ StringList &matches) = 0;
+
+ OptionGroupFormat m_format_options = OptionGroupFormat(lldb::eFormatDefault);
+ OptionGroupValueObjectDisplay m_varobj_options;
+ CommandObjectExpression::CommandOptions m_command_options;
+ std::string m_compiler_options;
+
+ bool m_enable_auto_indent = true;
+ std::string m_indent_str; // Use this string for each level of indentation
+ std::string m_current_indent_str;
+ uint32_t m_current_indent_level = 0;
+
+ std::string m_repl_source_path;
+ bool m_dedicated_repl_mode = false;
+
+ StringList m_code; // All accumulated REPL statements are saved here
+
+ Target &m_target;
+ lldb::IOHandlerSP m_io_handler_sp;
+ LLVMCastKind m_kind;
+
+private:
+ std::string
+ GetSourcePath();
+};
+
+} // namespace lldb_private
+
+#endif // lldb_REPL_h
diff --git a/include/lldb/Expression/ClangUserExpression.h b/include/lldb/Expression/UserExpression.h
index a549f5e8a547..517dfcd1dc47 100644
--- a/include/lldb/Expression/ClangUserExpression.h
+++ b/include/lldb/Expression/UserExpression.h
@@ -1,4 +1,4 @@
-//===-- ClangUserExpression.h -----------------------------------*- C++ -*-===//
+//===-- UserExpression.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,46 +7,44 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangUserExpression_h_
-#define liblldb_ClangUserExpression_h_
+#ifndef liblldb_UserExpression_h_
+#define liblldb_UserExpression_h_
// C Includes
// C++ Includes
+#include <memory>
#include <string>
-#include <map>
#include <vector>
// Other libraries and framework includes
// Project includes
-
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangExpressionVariable.h"
-#include "lldb/Expression/IRForTarget.h"
+#include "lldb/Expression/Expression.h"
#include "lldb/Expression/Materializer.h"
-#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Target.h"
namespace lldb_private
{
//----------------------------------------------------------------------
-/// @class ClangUserExpression ClangUserExpression.h "lldb/Expression/ClangUserExpression.h"
-/// @brief Encapsulates a single expression for use with Clang
+/// @class UserExpression UserExpression.h "lldb/Expression/UserExpression.h"
+/// @brief Encapsulates a one-time expression for use in lldb.
///
/// LLDB uses expressions for various purposes, notably to call functions
-/// and as a backend for the expr command. ClangUserExpression encapsulates
-/// the objects needed to parse and interpret or JIT an expression. It
-/// uses the Clang parser to produce LLVM IR from the expression.
+/// and as a backend for the expr command. UserExpression is a virtual base
+/// class that encapsulates the objects needed to parse and interpret or
+/// JIT an expression. The actual parsing part will be provided by the specific
+/// implementations of UserExpression - which will be vended through the
+/// appropriate TypeSystem.
//----------------------------------------------------------------------
-class ClangUserExpression : public ClangExpression
+class UserExpression : public Expression
{
public:
-
enum { kDefaultTimeout = 500000u };
+
//------------------------------------------------------------------
/// Constructor
///
@@ -54,7 +52,7 @@ public:
/// The expression to parse.
///
/// @param[in] expr_prefix
- /// If non-NULL, a C string containing translation-unit level
+ /// If non-nullptr, a C string containing translation-unit level
/// definitions to be included when the expression is parsed.
///
/// @param[in] language
@@ -66,16 +64,17 @@ public:
/// If not eResultTypeAny, the type to use for the expression
/// result.
//------------------------------------------------------------------
- ClangUserExpression (const char *expr,
- const char *expr_prefix,
- lldb::LanguageType language,
- ResultType desired_type);
+ UserExpression (ExecutionContextScope &exe_scope,
+ const char *expr,
+ const char *expr_prefix,
+ lldb::LanguageType language,
+ ResultType desired_type,
+ const EvaluateExpressionOptions &options);
//------------------------------------------------------------------
/// Destructor
//------------------------------------------------------------------
- virtual
- ~ClangUserExpression ();
+ ~UserExpression() override;
//------------------------------------------------------------------
/// Parse the expression
@@ -98,18 +97,14 @@ public:
/// @return
/// True on success (no errors); false otherwise.
//------------------------------------------------------------------
- bool
+ virtual bool
Parse (Stream &error_stream,
ExecutionContext &exe_ctx,
lldb_private::ExecutionPolicy execution_policy,
bool keep_result_in_memory,
- bool generate_debug_info);
+ bool generate_debug_info) = 0;
- bool
- CanInterpret ()
- {
- return m_can_interpret;
- }
+ virtual bool CanInterpret() = 0;
bool
MatchesContext (ExecutionContext &exe_ctx);
@@ -128,9 +123,9 @@ public:
/// Expression evaluation options.
///
/// @param[in] shared_ptr_to_me
- /// This is a shared pointer to this ClangUserExpression. This is
+ /// This is a shared pointer to this UserExpression. This is
/// needed because Execute can push a thread plan that will hold onto
- /// the ClangUserExpression for an unbounded period of time. So you
+ /// the UserExpression for an unbounded period of time. So you
/// need to give the thread plan a reference to this object that can
/// keep it alive.
///
@@ -141,12 +136,10 @@ public:
/// @return
/// A Process::Execution results value.
//------------------------------------------------------------------
- lldb::ExpressionResults
- Execute (Stream &error_stream,
- ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions& options,
- lldb::ClangUserExpressionSP &shared_ptr_to_me,
- lldb::ClangExpressionVariableSP &result);
+ virtual lldb::ExpressionResults Execute(Stream &error_stream, ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options,
+ lldb::UserExpressionSP &shared_ptr_to_me,
+ lldb::ExpressionVariableSP &result) = 0;
//------------------------------------------------------------------
/// Apply the side effects of the function to program state.
@@ -171,21 +164,18 @@ public:
/// @return
/// A Process::Execution results value.
//------------------------------------------------------------------
- bool
- FinalizeJITExecution (Stream &error_stream,
- ExecutionContext &exe_ctx,
- lldb::ClangExpressionVariableSP &result,
- lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
- lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS);
+ virtual bool FinalizeJITExecution(Stream &error_stream, ExecutionContext &exe_ctx,
+ lldb::ExpressionVariableSP &result,
+ lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
+ lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) = 0;
//------------------------------------------------------------------
- /// Return the string that the parser should parse. Must be a full
- /// translation unit.
+ /// Return the string that the parser should parse.
//------------------------------------------------------------------
const char *
- Text ()
+ Text() override
{
- return m_transformed_text.c_str();
+ return m_expr_text.c_str();
}
//------------------------------------------------------------------
@@ -203,7 +193,7 @@ public:
/// function.
//------------------------------------------------------------------
const char *
- FunctionName ()
+ FunctionName() override
{
return "$__lldb_expr";
}
@@ -212,39 +202,18 @@ public:
/// Return the language that should be used when parsing. To use
/// the default, return eLanguageTypeUnknown.
//------------------------------------------------------------------
- virtual lldb::LanguageType
- Language ()
+ lldb::LanguageType
+ Language() override
{
return m_language;
}
//------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- ClangExpressionDeclMap *
- DeclMap ()
- {
- return m_expr_decl_map.get();
- }
-
- //------------------------------------------------------------------
- /// 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);
-
- //------------------------------------------------------------------
/// Return the desired result type of the function, or
/// eResultTypeAny if indifferent.
//------------------------------------------------------------------
- virtual ResultType
- DesiredResultType ()
+ ResultType
+ DesiredResultType() override
{
return m_desired_type;
}
@@ -254,7 +223,7 @@ public:
/// expression.
//------------------------------------------------------------------
bool
- NeedsValidation ()
+ NeedsValidation() override
{
return true;
}
@@ -264,63 +233,87 @@ public:
/// resolved.
//------------------------------------------------------------------
bool
- NeedsVariableResolution ()
+ NeedsVariableResolution() override
{
return true;
}
+
+ EvaluateExpressionOptions *
+ GetOptions() override
+ {
+ return &m_options;
+ }
+
+ virtual lldb::ExpressionVariableSP
+ GetResultAfterDematerialization(ExecutionContextScope *exe_scope)
+ {
+ return lldb::ExpressionVariableSP();
+ }
+
+ virtual lldb::ModuleSP
+ GetJITModule()
+ {
+ return lldb::ModuleSP();
+ }
//------------------------------------------------------------------
- /// Evaluate one expression and return its result.
+ /// Evaluate one expression in the scratch context of the
+ /// target passed in the exe_ctx and return its result.
///
/// @param[in] exe_ctx
/// The execution context to use when evaluating the expression.
///
/// @param[in] options
- /// Expression evaluation options.
+ /// Expression evaluation options. N.B. The language in the
+ /// evaluation options will be used to determine the language used for
+ /// expression evaluation.
///
/// @param[in] expr_cstr
/// A C string containing the expression to be evaluated.
///
/// @param[in] expr_prefix
- /// If non-NULL, a C string containing translation-unit level
+ /// If non-nullptr, a C string containing translation-unit level
/// definitions to be included when the expression is parsed.
///
- /// @param[in/out] result_valobj_sp
+ /// @param[in,out] result_valobj_sp
/// If execution is successful, the result valobj is placed here.
///
- /// @param[out]
+ /// @param[out] error
/// Filled in with an error in case the expression evaluation
/// fails to parse, run, or evaluated.
///
+ /// @param[in] line_offset
+ /// The offset of the first line of the expression from the "beginning" of a virtual source file used for error reporting and debug info.
+ ///
+ /// @param[out] jit_module_sp_ptr
+ /// If non-nullptr, used to persist the generated IR module.
+ ///
/// @result
/// A Process::ExpressionResults value. eExpressionCompleted for success.
//------------------------------------------------------------------
static lldb::ExpressionResults
- Evaluate (ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions& options,
- const char *expr_cstr,
- const char *expr_prefix,
- lldb::ValueObjectSP &result_valobj_sp,
- Error &error);
+ Evaluate(ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions& options,
+ const char *expr_cstr,
+ const char *expr_prefix,
+ lldb::ValueObjectSP &result_valobj_sp,
+ Error &error,
+ uint32_t line_offset = 0,
+ lldb::ModuleSP *jit_module_sp_ptr = nullptr);
static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression.
-private:
+
+protected:
+ static lldb::addr_t
+ GetObjectPointer (lldb::StackFrameSP frame_sp,
+ ConstString &object_name,
+ Error &err);
+
//------------------------------------------------------------------
/// Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment.
//------------------------------------------------------------------
void
- ScanContext (ExecutionContext &exe_ctx,
- lldb_private::Error &err);
-
- bool
- PrepareToExecuteJITExpression (Stream &error_stream,
- ExecutionContext &exe_ctx,
- lldb::addr_t &struct_address,
- lldb::addr_t &object_ptr,
- lldb::addr_t &cmd_ptr);
-
- void
InstallContext (ExecutionContext &exe_ctx);
bool
@@ -329,37 +322,14 @@ private:
lldb::ProcessSP &process_sp,
lldb::StackFrameSP &frame_sp);
- lldb::ProcessWP m_process_wp; ///< The process used as the context for the expression.
Address m_address; ///< The address the process is stopped in.
- lldb::addr_t m_stack_frame_bottom; ///< The bottom of the allocated stack frame.
- lldb::addr_t m_stack_frame_top; ///< The top of the allocated stack frame.
-
std::string m_expr_text; ///< The text of the expression, as typed by the user
std::string m_expr_prefix; ///< The text of the translation-level definitions, as provided by the user
lldb::LanguageType m_language; ///< The language to use when parsing (eLanguageTypeUnknown means use defaults)
- bool m_allow_cxx; ///< True if the language allows C++.
- bool m_allow_objc; ///< True if the language allows Objective-C.
- std::string m_transformed_text; ///< The text of the expression, as send to the parser
ResultType m_desired_type; ///< The type to coerce the expression's result to. If eResultTypeAny, inferred from the expression.
-
- std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map; ///< The map to use when parsing the expression.
- std::shared_ptr<IRExecutionUnit> m_execution_unit_sp; ///< The execution unit the expression is stored in.
- std::unique_ptr<Materializer> m_materializer_ap; ///< The materializer to use when running the expression.
- std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer; ///< The result synthesizer, if one is needed.
- lldb::ModuleWP m_jit_module_wp;
- bool m_enforce_valid_object; ///< True if the expression parser should enforce the presence of a valid class pointer in order to generate the expression as a method.
- bool m_in_cplusplus_method; ///< True if the expression is compiled as a C++ member function (true if it was parsed when exe_ctx was in a C++ method).
- bool m_in_objectivec_method; ///< True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was in an Objective-C method).
- bool m_in_static_method; ///< True if the expression is compiled as a static (or class) method (currently true if it was parsed when exe_ctx was in an Objective-C class method).
- bool m_needs_object_ptr; ///< True if "this" or "self" must be looked up and passed in. False if the expression doesn't really use them and they can be NULL.
- bool m_const_object; ///< True if "this" is const.
- Target *m_target; ///< The target for storing persistent data like types and variables.
-
- bool m_can_interpret; ///< True if the expression could be evaluated statically; false otherwise.
- lldb::addr_t m_materialized_address; ///< The address at which the arguments to the expression have been materialized.
- Materializer::DematerializerSP m_dematerializer_sp; ///< The dematerializer.
+ EvaluateExpressionOptions m_options; ///< Additional options provided by the user.
};
} // namespace lldb_private
-#endif // liblldb_ClangUserExpression_h_
+#endif // liblldb_UserExpression_h_
diff --git a/include/lldb/Expression/ClangUtilityFunction.h b/include/lldb/Expression/UtilityFunction.h
index bb5601fa2914..bee83d8111e4 100644
--- a/include/lldb/Expression/ClangUtilityFunction.h
+++ b/include/lldb/Expression/UtilityFunction.h
@@ -1,4 +1,4 @@
-//===-- ClangUtilityFunction.h ----------------------------------*- C++ -*-===//
+//===-- UtilityFunction.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,36 +7,33 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ClangUtilityFunction_h_
-#define liblldb_ClangUtilityFunction_h_
+#ifndef liblldb_UtilityFunction_h_
+#define liblldb_UtilityFunction_h_
// C Includes
// C++ Includes
+#include <memory>
#include <string>
-#include <map>
-#include <vector>
// Other libraries and framework includes
// Project includes
-
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/Expression.h"
namespace lldb_private
{
//----------------------------------------------------------------------
-/// @class ClangUtilityFunction ClangUtilityFunction.h "lldb/Expression/ClangUtilityFunction.h"
-/// @brief Encapsulates a single expression for use with Clang
+/// @class UtilityFunction UtilityFunction.h "lldb/Expression/UtilityFunction.h"
+/// @brief Encapsulates a bit of source code that provides a function that is callable
///
/// LLDB uses expressions for various purposes, notably to call functions
-/// and as a backend for the expr command. ClangUtilityFunction encapsulates
+/// and as a backend for the expr command. UtilityFunction encapsulates
/// a self-contained function meant to be used from other code. Utility
/// functions can perform error-checking for ClangUserExpressions,
//----------------------------------------------------------------------
-class ClangUtilityFunction : public ClangExpression
+class UtilityFunction : public Expression
{
public:
//------------------------------------------------------------------
@@ -48,11 +45,11 @@ public:
/// @param[in] name
/// The name of the function, as used in the text.
//------------------------------------------------------------------
- ClangUtilityFunction (const char *text,
- const char *name);
+ UtilityFunction (ExecutionContextScope &exe_scope,
+ const char *text,
+ const char *name);
- virtual
- ~ClangUtilityFunction ();
+ ~UtilityFunction() override;
//------------------------------------------------------------------
/// Install the utility function into a process
@@ -66,13 +63,13 @@ public:
/// @return
/// True on success (no errors); false otherwise.
//------------------------------------------------------------------
- bool
- Install (Stream &error_stream, ExecutionContext &exe_ctx);
+ virtual bool
+ Install (Stream &error_stream, ExecutionContext &exe_ctx) = 0;
//------------------------------------------------------------------
/// Check whether the given PC is inside the function
///
- /// Especially useful if the function dereferences NULL to indicate a failed
+ /// Especially useful if the function dereferences nullptr to indicate a failed
/// assert.
///
/// @param[in] pc
@@ -89,14 +86,13 @@ public:
// so this always returns false if the function is not JIT compiled yet
return (address >= m_jit_start_addr && address < m_jit_end_addr);
}
-
-
+
//------------------------------------------------------------------
/// Return the string that the parser should parse. Must be a full
/// translation unit.
//------------------------------------------------------------------
const char *
- Text ()
+ Text() override
{
return m_function_text.c_str();
}
@@ -107,43 +103,19 @@ public:
/// function.
//------------------------------------------------------------------
const char *
- FunctionName ()
+ FunctionName() override
{
return m_function_name.c_str();
}
//------------------------------------------------------------------
- /// Return the object that the parser should use when resolving external
- /// values. May be NULL if everything should be self-contained.
- //------------------------------------------------------------------
- ClangExpressionDeclMap *
- DeclMap ()
- {
- return m_expr_decl_map.get();
- }
-
- //------------------------------------------------------------------
/// Return the object that the parser should use when registering
- /// local variables. May be NULL if the Expression doesn't care.
+ /// local variables. May be nullptr if the Expression doesn't care.
//------------------------------------------------------------------
- ClangExpressionVariableList *
+ ExpressionVariableList *
LocalVariables ()
{
- return NULL;
- }
-
- //------------------------------------------------------------------
- /// 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)
- {
- return NULL;
+ return nullptr;
}
//------------------------------------------------------------------
@@ -151,7 +123,7 @@ public:
/// expression.
//------------------------------------------------------------------
bool
- NeedsValidation ()
+ NeedsValidation() override
{
return false;
}
@@ -161,19 +133,30 @@ public:
/// resolved.
//------------------------------------------------------------------
bool
- NeedsVariableResolution ()
+ NeedsVariableResolution() override
{
return false;
}
-private:
- std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map; ///< The map to use when parsing and materializing the expression.
+ // This makes the function caller function.
+ FunctionCaller *
+ MakeFunctionCaller(const CompilerType &return_type, const ValueList &arg_value_list, Error &error);
+
+ // This one retrieves the function caller that is already made. If you haven't made it yet, this returns nullptr
+ FunctionCaller *
+ GetFunctionCaller()
+ {
+ return m_caller_up.get();
+ }
+
+protected:
std::shared_ptr<IRExecutionUnit> m_execution_unit_sp;
lldb::ModuleWP m_jit_module_wp;
std::string m_function_text; ///< The text of the function. Must be a well-formed translation unit.
std::string m_function_name; ///< The name of the function.
+ std::unique_ptr<FunctionCaller> m_caller_up;
};
} // namespace lldb_private
-#endif // liblldb_ClangUtilityFunction_h_
+#endif // liblldb_UtilityFunction_h_