diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
commit | e81d9d49145e432d917eea3a70d2ae74dcad1d89 (patch) | |
tree | 9ed5e1a91f242e2cb5911577356e487a55c01b78 /include/lldb/Expression | |
parent | 85d8ef8f1f0e0e063a8571944302be2d2026f823 (diff) |
Notes
Diffstat (limited to 'include/lldb/Expression')
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 §ion_list); + void + PopulateSectionList(lldb_private::ObjectFile *obj_file, + lldb_private::SectionList §ion_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 ®ister_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 ®ister_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 ¤t_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_ |