aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Symbol
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2013-08-23 17:46:38 +0000
committerEd Maste <emaste@FreeBSD.org>2013-08-23 17:46:38 +0000
commitf034231a6a1fd5d6395206c1651de8cd9402cca3 (patch)
treef561dabc721ad515599172c16da3a4400b7f4aec /include/lldb/Symbol
downloadsrc-f034231a6a1fd5d6395206c1651de8cd9402cca3.tar.gz
src-f034231a6a1fd5d6395206c1651de8cd9402cca3.zip
Import lldb as of SVN r188801
(A number of files not required for the FreeBSD build have been removed.) Sponsored by: DARPA, AFRL
Notes
Notes: svn path=/vendor/lldb/dist/; revision=254721
Diffstat (limited to 'include/lldb/Symbol')
-rw-r--r--include/lldb/Symbol/Block.h496
-rw-r--r--include/lldb/Symbol/ClangASTContext.h441
-rw-r--r--include/lldb/Symbol/ClangASTImporter.h371
-rw-r--r--include/lldb/Symbol/ClangASTType.h679
-rw-r--r--include/lldb/Symbol/ClangExternalASTSourceCallbacks.h171
-rw-r--r--include/lldb/Symbol/ClangExternalASTSourceCommon.h188
-rw-r--r--include/lldb/Symbol/ClangNamespaceDecl.h103
-rw-r--r--include/lldb/Symbol/CompileUnit.h422
-rw-r--r--include/lldb/Symbol/DWARFCallFrameInfo.h150
-rw-r--r--include/lldb/Symbol/Declaration.h278
-rw-r--r--include/lldb/Symbol/FuncUnwinders.h106
-rw-r--r--include/lldb/Symbol/Function.h638
-rw-r--r--include/lldb/Symbol/LineEntry.h174
-rw-r--r--include/lldb/Symbol/LineTable.h422
-rw-r--r--include/lldb/Symbol/ObjectContainer.h236
-rw-r--r--include/lldb/Symbol/ObjectFile.h706
-rw-r--r--include/lldb/Symbol/Symbol.h317
-rw-r--r--include/lldb/Symbol/SymbolContext.h566
-rw-r--r--include/lldb/Symbol/SymbolContextScope.h137
-rw-r--r--include/lldb/Symbol/SymbolFile.h167
-rw-r--r--include/lldb/Symbol/SymbolVendor.h207
-rw-r--r--include/lldb/Symbol/Symtab.h160
-rw-r--r--include/lldb/Symbol/TaggedASTType.h61
-rw-r--r--include/lldb/Symbol/Type.h596
-rw-r--r--include/lldb/Symbol/TypeList.h88
-rw-r--r--include/lldb/Symbol/TypeVendor.h61
-rw-r--r--include/lldb/Symbol/UnwindPlan.h499
-rw-r--r--include/lldb/Symbol/UnwindTable.h69
-rw-r--r--include/lldb/Symbol/Variable.h184
-rw-r--r--include/lldb/Symbol/VariableList.h95
-rw-r--r--include/lldb/Symbol/VerifyDecl.h20
31 files changed, 8808 insertions, 0 deletions
diff --git a/include/lldb/Symbol/Block.h b/include/lldb/Symbol/Block.h
new file mode 100644
index 000000000000..a2d703b9069c
--- /dev/null
+++ b/include/lldb/Symbol/Block.h
@@ -0,0 +1,496 @@
+//===-- Block.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_Block_h_
+#define liblldb_Block_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Symbol/LineEntry.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Block Block.h "lldb/Symbol/Block.h"
+/// @brief A class that describes a single lexical block.
+///
+/// A Function object owns a BlockList object which owns one or more
+/// Block objects. The BlockList object contains a section offset
+/// address range, and Block objects contain one or more ranges
+/// which are offsets into that range. Blocks are can have discontiguous
+/// ranges within the BlockList adress range, and each block can
+/// contain child blocks each with their own sets of ranges.
+///
+/// Each block has a variable list that represents local, argument, and
+/// static variables that are scoped to the block.
+///
+/// Inlined functions are representated by attaching a
+/// InlineFunctionInfo shared pointer object to a block. Inlined
+/// functions are represented as named blocks.
+//----------------------------------------------------------------------
+class Block :
+ public UserID,
+ public SymbolContextScope
+{
+public:
+ typedef RangeArray<uint32_t, uint32_t, 1> RangeList;
+ typedef RangeList::Entry Range;
+
+ //------------------------------------------------------------------
+ /// Construct with a User ID \a uid, \a depth.
+ ///
+ /// Initialize this block with the specified UID \a uid. The
+ /// \a depth in the \a block_list is used to represent the parent,
+ /// sibling, and child block information and also allows for partial
+ /// parsing at the block level.
+ ///
+ /// @param[in] uid
+ /// The UID for a given block. This value is given by the
+ /// SymbolFile plug-in and can be any value that helps the
+ /// SymbolFile plug-in to match this block back to the debug
+ /// information data that it parses for further or more in
+ /// depth parsing. Common values would be the index into a
+ /// table, or an offset into the debug information.
+ ///
+ /// @param[in] depth
+ /// The integer depth of this block in the block list hierarchy.
+ ///
+ /// @param[in] block_list
+ /// The block list that this object belongs to.
+ ///
+ /// @see BlockList
+ //------------------------------------------------------------------
+ Block (lldb::user_id_t uid);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ virtual ~Block ();
+
+ //------------------------------------------------------------------
+ /// Add a child to this object.
+ ///
+ /// @param[in] child_block_sp
+ /// A shared pointer to a child block that will get added to
+ /// this block.
+ //------------------------------------------------------------------
+ void
+ AddChild (const lldb::BlockSP &child_block_sp);
+
+ //------------------------------------------------------------------
+ /// Add a new offset range to this block.
+ ///
+ /// @param[in] start_offset
+ /// An offset into this Function's address range that
+ /// describes the start address of a range for this block.
+ ///
+ /// @param[in] end_offset
+ /// An offset into this Function's address range that
+ /// describes the end address of a range for this block.
+ //------------------------------------------------------------------
+ void
+ AddRange (const Range& range);
+
+ void
+ FinalizeRanges ();
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext(SymbolContext* sc);
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ();
+
+ virtual CompileUnit *
+ CalculateSymbolContextCompileUnit ();
+
+ virtual Function *
+ CalculateSymbolContextFunction ();
+
+ virtual Block *
+ CalculateSymbolContextBlock ();
+
+ //------------------------------------------------------------------
+ /// Check if an offset is in one of the block offset ranges.
+ ///
+ /// @param[in] range_offset
+ /// An offset into the Function's address range.
+ ///
+ /// @return
+ /// Returns \b true if \a range_offset falls in one of this
+ /// block's ranges, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Contains (lldb::addr_t range_offset) const;
+
+ //------------------------------------------------------------------
+ /// Check if a offset range is in one of the block offset ranges.
+ ///
+ /// @param[in] range
+ /// An offset range into the Function's address range.
+ ///
+ /// @return
+ /// Returns \b true if \a range falls in one of this
+ /// block's ranges, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Contains (const Range& range) const;
+
+ //------------------------------------------------------------------
+ /// Check if this object contains "block" as a child block at any
+ /// depth.
+ ///
+ /// @param[in] block
+ /// A potential child block.
+ ///
+ /// @return
+ /// Returns \b true if \a block is a child of this block, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ bool
+ Contains (const Block *block) const;
+
+ //------------------------------------------------------------------
+ /// Dump the block contents.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] base_addr
+ /// The resolved start address of the Function's address
+ /// range. This should be resolved as the file or load address
+ /// prior to passing the value into this function for dumping.
+ ///
+ /// @param[in] depth
+ /// Limit the number of levels deep that this function should
+ /// print as this block can contain child blocks. Specify
+ /// INT_MAX to dump all child blocks.
+ ///
+ /// @param[in] show_context
+ /// If \b true, variables will dump their context information.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, lldb::addr_t base_addr, int32_t depth, bool show_context) const;
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext(Stream *s);
+
+ void
+ DumpAddressRanges (Stream *s,
+ lldb::addr_t base_addr);
+
+ void
+ GetDescription (Stream *s,
+ Function *function,
+ lldb::DescriptionLevel level,
+ Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Get the parent block.
+ ///
+ /// @return
+ /// The parent block pointer, or NULL if this block has no
+ /// parent.
+ //------------------------------------------------------------------
+ Block *
+ GetParent () const;
+
+
+ //------------------------------------------------------------------
+ /// Get the inlined block that contains this block.
+ ///
+ /// @return
+ /// If this block contains inlined function info, it will return
+ /// this block, else parent blocks will be searched to see if
+ /// any contain this block. NULL will be returned if this block
+ /// nor any parent blocks are inlined function blocks.
+ //------------------------------------------------------------------
+ Block *
+ GetContainingInlinedBlock ();
+
+ //------------------------------------------------------------------
+ /// Get the inlined parent block for this block.
+ ///
+ /// @return
+ /// The parent block pointer, or NULL if this block has no
+ /// parent.
+ //------------------------------------------------------------------
+ Block *
+ GetInlinedParent ();
+
+ //------------------------------------------------------------------
+ /// Get the sibling block for this block.
+ ///
+ /// @return
+ /// The sibling block pointer, or NULL if this block has no
+ /// sibling.
+ //------------------------------------------------------------------
+ Block *
+ GetSibling () const;
+
+ //------------------------------------------------------------------
+ /// Get the first child block.
+ ///
+ /// @return
+ /// The first child block pointer, or NULL if this block has no
+ /// children.
+ //------------------------------------------------------------------
+ Block *
+ GetFirstChild () const
+ {
+ if (m_children.empty())
+ return NULL;
+ return m_children.front().get();
+ }
+
+ //------------------------------------------------------------------
+ /// Get the variable list for this block only.
+ ///
+ /// @param[in] can_create
+ /// If \b true, the variables can be parsed if they already
+ /// haven't been, else the current state of the block will be
+ /// returned.
+ ///
+ /// @return
+ /// A variable list shared pointer that contains all variables
+ /// for this block.
+ //------------------------------------------------------------------
+ lldb::VariableListSP
+ GetBlockVariableList (bool can_create);
+
+
+ //------------------------------------------------------------------
+ /// Get the variable list for this block and optionally all child
+ /// blocks if \a get_child_variables is \b true.
+ ///
+ /// @param[in] get_child_variables
+ /// If \b true, all variables from all child blocks will be
+ /// added to the variable list.
+ ///
+ /// @param[in] can_create
+ /// If \b true, the variables can be parsed if they already
+ /// haven't been, else the current state of the block will be
+ /// returned. Passing \b true for this parameter can be used
+ /// to see the current state of what has been parsed up to this
+ /// point.
+ ///
+ /// @param[in] add_inline_child_block_variables
+ /// If this is \b false, no child variables of child blocks
+ /// that are inlined functions will be gotten. If \b true then
+ /// all child variables will be added regardless of whether they
+ /// come from inlined functions or not.
+ ///
+ /// @return
+ /// A variable list shared pointer that contains all variables
+ /// for this block.
+ //------------------------------------------------------------------
+ uint32_t
+ AppendBlockVariables (bool can_create,
+ bool get_child_block_variables,
+ bool stop_if_child_block_is_inlined_function,
+ VariableList *variable_list);
+
+ //------------------------------------------------------------------
+ /// Appends the variables from this block, and optionally from all
+ /// parent blocks, to \a variable_list.
+ ///
+ /// @param[in] can_create
+ /// If \b true, the variables can be parsed if they already
+ /// haven't been, else the current state of the block will be
+ /// returned. Passing \b true for this parameter can be used
+ /// to see the current state of what has been parsed up to this
+ /// point.
+ ///
+ /// @param[in] get_parent_variables
+ /// If \b true, all variables from all parent blocks will be
+ /// added to the variable list.
+ ///
+ /// @param[in] stop_if_block_is_inlined_function
+ /// If \b true, all variables from all parent blocks will be
+ /// added to the variable list until there are no parent blocks
+ /// or the parent block has inlined function info.
+ ///
+ /// @param[in/out] variable_list
+ /// All variables in this block, and optionally all parent
+ /// blocks will be added to this list.
+ ///
+ /// @return
+ /// The number of variable that were appended to \a
+ /// variable_list.
+ //------------------------------------------------------------------
+ uint32_t
+ AppendVariables (bool can_create,
+ bool get_parent_variables,
+ bool stop_if_block_is_inlined_function,
+ VariableList *variable_list);
+
+ //------------------------------------------------------------------
+ /// Get const accessor for any inlined function information.
+ ///
+ /// @return
+ /// A comst pointer to any inlined function information, or NULL
+ /// if this is a regular block.
+ //------------------------------------------------------------------
+ const InlineFunctionInfo*
+ GetInlinedFunctionInfo () const
+ {
+ return m_inlineInfoSP.get();
+ }
+
+ clang::DeclContext *
+ GetClangDeclContext();
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// Returns the cost of this object plus any owned objects from the
+ /// ranges, variables, and inline function information.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ //------------------------------------------------------------------
+ size_t
+ MemorySize() const;
+
+ //------------------------------------------------------------------
+ /// Set accessor for any inlined function information.
+ ///
+ /// @param[in] name
+ /// The method name for the inlined function. This value should
+ /// not be NULL.
+ ///
+ /// @param[in] mangled
+ /// The mangled method name for the inlined function. This can
+ /// be NULL if there is no mangled name for an inlined function
+ /// or if the name is the same as \a name.
+ ///
+ /// @param[in] decl_ptr
+ /// A optional pointer to declaration information for the
+ /// inlined function information. This value can be NULL to
+ /// indicate that no declaration information is available.
+ ///
+ /// @param[in] call_decl_ptr
+ /// Optional calling location declaration information that
+ /// describes from where this inlined function was called.
+ //------------------------------------------------------------------
+ void
+ SetInlinedFunctionInfo (const char *name,
+ const char *mangled,
+ const Declaration *decl_ptr,
+ const Declaration *call_decl_ptr);
+
+
+ void
+ SetParentScope (SymbolContextScope *parent_scope)
+ {
+ m_parent_scope = parent_scope;
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the variable list.
+ ///
+ /// Called by the SymbolFile plug-ins after they have parsed the
+ /// variable lists and are ready to hand ownership of the list over
+ /// to this object.
+ ///
+ /// @param[in] variable_list_sp
+ /// A shared pointer to a VariableList.
+ //------------------------------------------------------------------
+ void
+ SetVariableList (lldb::VariableListSP& variable_list_sp)
+ {
+ m_variable_list_sp = variable_list_sp;
+ }
+
+
+
+ bool
+ BlockInfoHasBeenParsed() const
+ {
+ return m_parsed_block_info;
+ }
+
+ void
+ SetBlockInfoHasBeenParsed (bool b, bool set_children);
+
+ Block *
+ FindBlockByID (lldb::user_id_t block_id);
+
+ size_t
+ GetNumRanges () const
+ {
+ return m_ranges.GetSize();
+ }
+
+ bool
+ GetRangeContainingOffset (const lldb::addr_t offset, Range &range);
+
+ bool
+ GetRangeContainingAddress (const Address& addr, AddressRange &range);
+
+ bool
+ GetRangeContainingLoadAddress (lldb::addr_t load_addr, Target &target, AddressRange &range);
+
+ uint32_t
+ GetRangeIndexContainingAddress (const Address& addr);
+
+ //------------------------------------------------------------------
+ // Since blocks might have multiple discontiguous addresss ranges,
+ // we need to be able to get at any of the address ranges in a block.
+ //------------------------------------------------------------------
+ bool
+ GetRangeAtIndex (uint32_t range_idx,
+ AddressRange &range);
+
+ bool
+ GetStartAddress (Address &addr);
+
+ void
+ SetDidParseVariables (bool b, bool set_children);
+
+protected:
+ typedef std::vector<lldb::BlockSP> collection;
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ SymbolContextScope *m_parent_scope;
+ collection m_children;
+ RangeList m_ranges;
+ lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information.
+ lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, static and paramter variables scoped to this block.
+ bool m_parsed_block_info:1, ///< Set to true if this block and it's children have all been parsed
+ m_parsed_block_variables:1,
+ m_parsed_child_blocks:1;
+
+ // A parent of child blocks can be asked to find a sibling block given
+ // one of its child blocks
+ Block *
+ GetSiblingForChild (const Block *child_block) const;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (Block);
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_Block_h_
diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h
new file mode 100644
index 000000000000..75fc07b480e1
--- /dev/null
+++ b/include/lldb/Symbol/ClangASTContext.h
@@ -0,0 +1,441 @@
+//===-- ClangASTContext.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_ClangASTContext_h_
+#define liblldb_ClangASTContext_h_
+
+// C Includes
+#include <stdint.h>
+
+// C++ Includes
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "clang/AST/TemplateBase.h"
+
+
+// Project includes
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Symbol/ClangASTType.h"
+
+namespace lldb_private {
+
+class Declaration;
+
+class ClangASTContext
+{
+public:
+ typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *);
+ typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ClangASTContext (const char *triple = NULL);
+
+ ~ClangASTContext();
+
+ clang::ASTContext *
+ getASTContext();
+
+ clang::Builtin::Context *
+ getBuiltinContext();
+
+ clang::IdentifierTable *
+ getIdentifierTable();
+
+ clang::LangOptions *
+ getLanguageOptions();
+
+ clang::SelectorTable *
+ getSelectorTable();
+
+ clang::FileManager *
+ getFileManager();
+
+ clang::SourceManager *
+ getSourceManager();
+
+ clang::DiagnosticsEngine *
+ getDiagnosticsEngine();
+
+ clang::DiagnosticConsumer *
+ getDiagnosticConsumer();
+
+ clang::TargetOptions *
+ getTargetOptions();
+
+ clang::TargetInfo *
+ getTargetInfo();
+
+ void
+ Clear();
+
+ const char *
+ GetTargetTriple ();
+
+ void
+ SetTargetTriple (const char *target_triple);
+
+ void
+ SetArchitecture (const ArchSpec &arch);
+
+ bool
+ HasExternalSource ();
+
+ void
+ SetExternalSource (llvm::OwningPtr<clang::ExternalASTSource> &ast_source_ap);
+
+ void
+ RemoveExternalSource ();
+
+ bool
+ GetCompleteDecl (clang::Decl *decl)
+ {
+ return ClangASTContext::GetCompleteDecl(getASTContext(), decl);
+ }
+
+ static bool
+ GetCompleteDecl (clang::ASTContext *ast,
+ clang::Decl *decl);
+
+ void SetMetadataAsUserID (const void *object,
+ lldb::user_id_t user_id);
+
+ void SetMetadata (const void *object,
+ ClangASTMetadata &meta_data)
+ {
+ SetMetadata(getASTContext(), object, meta_data);
+ }
+
+ static void
+ SetMetadata (clang::ASTContext *ast,
+ const void *object,
+ ClangASTMetadata &meta_data);
+
+ ClangASTMetadata *
+ GetMetadata (const void *object)
+ {
+ return GetMetadata(getASTContext(), object);
+ }
+
+ static ClangASTMetadata *
+ GetMetadata (clang::ASTContext *ast,
+ const void *object);
+
+ //------------------------------------------------------------------
+ // Basic Types
+ //------------------------------------------------------------------
+ ClangASTType
+ GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding,
+ uint32_t bit_size);
+
+ static ClangASTType
+ GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast,
+ lldb::Encoding encoding,
+ uint32_t bit_size);
+
+ ClangASTType
+ GetBasicType (lldb::BasicType type);
+
+ static ClangASTType
+ GetBasicType (clang::ASTContext *ast, lldb::BasicType type);
+
+ static ClangASTType
+ GetBasicType (clang::ASTContext *ast, const ConstString &name);
+
+ static lldb::BasicType
+ GetBasicTypeEnumeration (const ConstString &name);
+
+ ClangASTType
+ GetBuiltinTypeForDWARFEncodingAndBitSize (
+ const char *type_name,
+ uint32_t dw_ate,
+ uint32_t bit_size);
+
+ ClangASTType
+ GetCStringType(bool is_const);
+
+ static ClangASTType
+ GetUnknownAnyType(clang::ASTContext *ast);
+
+ ClangASTType
+ GetUnknownAnyType()
+ {
+ return ClangASTContext::GetUnknownAnyType(getASTContext());
+ }
+
+ uint32_t
+ GetPointerByteSize ();
+
+ static clang::DeclContext *
+ GetTranslationUnitDecl (clang::ASTContext *ast);
+
+ clang::DeclContext *
+ GetTranslationUnitDecl ()
+ {
+ return GetTranslationUnitDecl (getASTContext());
+ }
+
+ static bool
+ GetClassMethodInfoForDeclContext (clang::DeclContext *decl_ctx,
+ lldb::LanguageType &language,
+ bool &is_instance_method,
+ ConstString &language_object_name);
+
+ static ClangASTType
+ CopyType(clang::ASTContext *dest_context,
+ ClangASTType source_type);
+
+ static clang::Decl *
+ CopyDecl (clang::ASTContext *dest_context,
+ clang::ASTContext *source_context,
+ clang::Decl *source_decl);
+
+ static bool
+ AreTypesSame(ClangASTType type1,
+ ClangASTType type2,
+ bool ignore_qualifiers = false);
+
+ ClangASTType
+ GetTypeForDecl (clang::TagDecl *decl);
+
+ ClangASTType
+ GetTypeForDecl (clang::ObjCInterfaceDecl *objc_decl);
+
+ //------------------------------------------------------------------
+ // Structure, Unions, Classes
+ //------------------------------------------------------------------
+
+ static clang::AccessSpecifier
+ ConvertAccessTypeToAccessSpecifier (lldb::AccessType access);
+
+ static clang::AccessSpecifier
+ UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs);
+
+ static uint32_t
+ GetNumBaseClasses (const clang::CXXRecordDecl *cxx_record_decl,
+ bool omit_empty_base_classes);
+
+ static uint32_t
+ GetIndexForRecordBase (const clang::RecordDecl *record_decl,
+ const clang::CXXBaseSpecifier *base_spec,
+ bool omit_empty_base_classes);
+
+ ClangASTType
+ CreateRecordType (clang::DeclContext *decl_ctx,
+ lldb::AccessType access_type,
+ const char *name,
+ int kind,
+ lldb::LanguageType language,
+ ClangASTMetadata *metadata = NULL);
+
+ class TemplateParameterInfos
+ {
+ public:
+ bool
+ IsValid() const
+ {
+ if (args.empty())
+ return false;
+ return args.size() == names.size();
+ }
+
+ size_t
+ GetSize () const
+ {
+ if (IsValid())
+ return args.size();
+ return 0;
+ }
+
+ llvm::SmallVector<const char *, 8> names;
+ llvm::SmallVector<clang::TemplateArgument, 8> args;
+ };
+
+ clang::FunctionTemplateDecl *
+ CreateFunctionTemplateDecl (clang::DeclContext *decl_ctx,
+ clang::FunctionDecl *func_decl,
+ const char *name,
+ const TemplateParameterInfos &infos);
+
+ void
+ CreateFunctionTemplateSpecializationInfo (clang::FunctionDecl *func_decl,
+ clang::FunctionTemplateDecl *Template,
+ const TemplateParameterInfos &infos);
+
+ clang::ClassTemplateDecl *
+ CreateClassTemplateDecl (clang::DeclContext *decl_ctx,
+ lldb::AccessType access_type,
+ const char *class_name,
+ int kind,
+ const TemplateParameterInfos &infos);
+
+ clang::ClassTemplateSpecializationDecl *
+ CreateClassTemplateSpecializationDecl (clang::DeclContext *decl_ctx,
+ clang::ClassTemplateDecl *class_template_decl,
+ int kind,
+ const TemplateParameterInfos &infos);
+
+ ClangASTType
+ CreateClassTemplateSpecializationType (clang::ClassTemplateSpecializationDecl *class_template_specialization_decl);
+
+ static clang::DeclContext *
+ GetAsDeclContext (clang::CXXMethodDecl *cxx_method_decl);
+
+ static clang::DeclContext *
+ GetAsDeclContext (clang::ObjCMethodDecl *objc_method_decl);
+
+
+ static bool
+ CheckOverloadedOperatorKindParameterCount (uint32_t op_kind,
+ uint32_t num_params);
+
+ bool
+ FieldIsBitfield (clang::FieldDecl* field,
+ uint32_t& bitfield_bit_size);
+
+ static bool
+ FieldIsBitfield (clang::ASTContext *ast,
+ clang::FieldDecl* field,
+ uint32_t& bitfield_bit_size);
+
+ static bool
+ RecordHasFields (const clang::RecordDecl *record_decl);
+
+
+ ClangASTType
+ CreateObjCClass (const char *name,
+ clang::DeclContext *decl_ctx,
+ bool isForwardDecl,
+ bool isInternal,
+ ClangASTMetadata *metadata = NULL);
+
+ // Returns a mask containing bits from the ClangASTContext::eTypeXXX enumerations
+
+
+ //------------------------------------------------------------------
+ // Namespace Declarations
+ //------------------------------------------------------------------
+
+ clang::NamespaceDecl *
+ GetUniqueNamespaceDeclaration (const char *name,
+ clang::DeclContext *decl_ctx);
+
+ //------------------------------------------------------------------
+ // Function Types
+ //------------------------------------------------------------------
+
+ clang::FunctionDecl *
+ CreateFunctionDeclaration (clang::DeclContext *decl_ctx,
+ const char *name,
+ const ClangASTType &function_Type,
+ int storage,
+ bool is_inline);
+
+ static ClangASTType
+ CreateFunctionType (clang::ASTContext *ast,
+ const ClangASTType &result_type,
+ const ClangASTType *args,
+ unsigned num_args,
+ bool is_variadic,
+ unsigned type_quals);
+
+ ClangASTType
+ CreateFunctionType (const ClangASTType &result_type,
+ const ClangASTType *args,
+ unsigned num_args,
+ bool is_variadic,
+ unsigned type_quals)
+ {
+ return ClangASTContext::CreateFunctionType(getASTContext(),
+ result_type,
+ args,
+ num_args,
+ is_variadic,
+ type_quals);
+ }
+
+ clang::ParmVarDecl *
+ CreateParameterDeclaration (const char *name,
+ const ClangASTType &param_type,
+ int storage);
+
+ void
+ SetFunctionParameters (clang::FunctionDecl *function_decl,
+ clang::ParmVarDecl **params,
+ unsigned num_params);
+
+ //------------------------------------------------------------------
+ // Array Types
+ //------------------------------------------------------------------
+
+ ClangASTType
+ CreateArrayType (const ClangASTType &element_type,
+ size_t element_count,
+ bool is_vector);
+
+ //------------------------------------------------------------------
+ // Enumeration Types
+ //------------------------------------------------------------------
+ ClangASTType
+ CreateEnumerationType (const char *name,
+ clang::DeclContext *decl_ctx,
+ const Declaration &decl,
+ const ClangASTType &integer_qual_type);
+
+ //------------------------------------------------------------------
+ // Floating point functions
+ //------------------------------------------------------------------
+
+ ClangASTType
+ GetFloatTypeFromBitSize (size_t bit_size)
+ {
+ return GetFloatTypeFromBitSize (getASTContext(), bit_size);
+ }
+
+ static ClangASTType
+ GetFloatTypeFromBitSize (clang::ASTContext *ast,
+ size_t bit_size);
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from ClangASTContext can see and modify these
+ //------------------------------------------------------------------
+ std::string m_target_triple;
+ std::unique_ptr<clang::ASTContext> m_ast_ap;
+ std::unique_ptr<clang::LangOptions> m_language_options_ap;
+ std::unique_ptr<clang::FileManager> m_file_manager_ap;
+ std::unique_ptr<clang::FileSystemOptions> m_file_system_options_ap;
+ std::unique_ptr<clang::SourceManager> m_source_manager_ap;
+ std::unique_ptr<clang::DiagnosticsEngine> m_diagnostics_engine_ap;
+ std::unique_ptr<clang::DiagnosticConsumer> m_diagnostic_consumer_ap;
+ llvm::IntrusiveRefCntPtr<clang::TargetOptions> m_target_options_rp;
+ std::unique_ptr<clang::TargetInfo> m_target_info_ap;
+ std::unique_ptr<clang::IdentifierTable> m_identifier_table_ap;
+ std::unique_ptr<clang::SelectorTable> m_selector_table_ap;
+ std::unique_ptr<clang::Builtin::Context> m_builtins_ap;
+ CompleteTagDeclCallback m_callback_tag_decl;
+ CompleteObjCInterfaceDeclCallback m_callback_objc_decl;
+ void * m_callback_baton;
+ uint32_t m_pointer_byte_size;
+private:
+ //------------------------------------------------------------------
+ // For ClangASTContext only
+ //------------------------------------------------------------------
+ ClangASTContext(const ClangASTContext&);
+ const ClangASTContext& operator=(const ClangASTContext&);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangASTContext_h_
diff --git a/include/lldb/Symbol/ClangASTImporter.h b/include/lldb/Symbol/ClangASTImporter.h
new file mode 100644
index 000000000000..10df7da893a8
--- /dev/null
+++ b/include/lldb/Symbol/ClangASTImporter.h
@@ -0,0 +1,371 @@
+//===-- ClangASTImporter.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_ClangASTImporter_h_
+#define liblldb_ClangASTImporter_h_
+
+#include <map>
+#include <set>
+
+#include "lldb/lldb-types.h"
+#include "clang/AST/ASTImporter.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "lldb/Symbol/ClangNamespaceDecl.h"
+
+namespace lldb_private {
+
+class ClangASTMetrics
+{
+public:
+ static void DumpCounters (Log *log);
+ static void ClearLocalCounters ()
+ {
+ local_counters = { 0, 0, 0, 0, 0, 0 };
+ }
+
+ static void RegisterVisibleQuery ()
+ {
+ ++global_counters.m_visible_query_count;
+ ++local_counters.m_visible_query_count;
+ }
+
+ static void RegisterLexicalQuery ()
+ {
+ ++global_counters.m_lexical_query_count;
+ ++local_counters.m_lexical_query_count;
+ }
+
+ static void RegisterLLDBImport ()
+ {
+ ++global_counters.m_lldb_import_count;
+ ++local_counters.m_lldb_import_count;
+ }
+
+ static void RegisterClangImport ()
+ {
+ ++global_counters.m_clang_import_count;
+ ++local_counters.m_clang_import_count;
+ }
+
+ static void RegisterDeclCompletion ()
+ {
+ ++global_counters.m_decls_completed_count;
+ ++local_counters.m_decls_completed_count;
+ }
+
+ static void RegisterRecordLayout ()
+ {
+ ++global_counters.m_record_layout_count;
+ ++local_counters.m_record_layout_count;
+ }
+
+private:
+ struct Counters
+ {
+ uint64_t m_visible_query_count;
+ uint64_t m_lexical_query_count;
+ uint64_t m_lldb_import_count;
+ uint64_t m_clang_import_count;
+ uint64_t m_decls_completed_count;
+ uint64_t m_record_layout_count;
+ };
+
+ static Counters global_counters;
+ static Counters local_counters;
+
+ static void DumpCounters (Log *log, Counters &counters);
+};
+
+class ClangASTImporter
+{
+public:
+ ClangASTImporter () :
+ m_file_manager(clang::FileSystemOptions())
+ {
+ }
+
+ clang::QualType
+ CopyType (clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ clang::QualType type);
+
+ lldb::clang_type_t
+ CopyType (clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ lldb::clang_type_t type);
+
+ clang::Decl *
+ CopyDecl (clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ clang::Decl *decl);
+
+ lldb::clang_type_t
+ DeportType (clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ lldb::clang_type_t type);
+
+ clang::Decl *
+ DeportDecl (clang::ASTContext *dst_ctx,
+ clang::ASTContext *src_ctx,
+ clang::Decl *decl);
+
+ void
+ CompleteDecl (clang::Decl *decl);
+
+ bool
+ CompleteTagDecl (clang::TagDecl *decl);
+
+ bool
+ CompleteTagDeclWithOrigin (clang::TagDecl *decl, clang::TagDecl *origin);
+
+ bool
+ CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl);
+
+ bool
+ RequireCompleteType (clang::QualType type);
+
+ bool
+ ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx)
+ {
+ DeclOrigin origin = GetDeclOrigin(decl);
+
+ if (original_decl)
+ *original_decl = origin.decl;
+
+ if (original_ctx)
+ *original_ctx = origin.ctx;
+
+ return origin.Valid();
+ }
+
+ void
+ SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl);
+
+ ClangASTMetadata *
+ GetDeclMetadata (const clang::Decl *decl);
+
+ //
+ // Namespace maps
+ //
+
+ typedef std::vector < std::pair<lldb::ModuleSP, ClangNamespaceDecl> > NamespaceMap;
+ typedef std::shared_ptr<NamespaceMap> NamespaceMapSP;
+
+ void RegisterNamespaceMap (const clang::NamespaceDecl *decl,
+ NamespaceMapSP &namespace_map);
+
+ NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl);
+
+ void BuildNamespaceMap (const clang::NamespaceDecl *decl);
+
+ //
+ // Comleters for maps
+ //
+
+ class MapCompleter
+ {
+ public:
+ virtual ~MapCompleter ();
+
+ virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map,
+ const ConstString &name,
+ NamespaceMapSP &parent_map) const = 0;
+ };
+
+ void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer)
+ {
+ ASTContextMetadataSP context_md;
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter == m_metadata_map.end())
+ {
+ context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
+ m_metadata_map[dst_ctx] = context_md;
+ }
+ else
+ {
+ context_md = context_md_iter->second;
+ }
+
+ context_md->m_map_completer = &completer;
+ }
+
+ void ForgetDestination (clang::ASTContext *dst_ctx);
+ void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
+private:
+ struct DeclOrigin
+ {
+ DeclOrigin () :
+ ctx(NULL),
+ decl(NULL)
+ {
+ }
+
+ DeclOrigin (clang::ASTContext *_ctx,
+ clang::Decl *_decl) :
+ ctx(_ctx),
+ decl(_decl)
+ {
+ }
+
+ DeclOrigin (const DeclOrigin &rhs)
+ {
+ ctx = rhs.ctx;
+ decl = rhs.decl;
+ }
+
+ void operator= (const DeclOrigin &rhs)
+ {
+ ctx = rhs.ctx;
+ decl = rhs.decl;
+ }
+
+ bool
+ Valid ()
+ {
+ return (ctx != NULL || decl != NULL);
+ }
+
+ clang::ASTContext *ctx;
+ clang::Decl *decl;
+ };
+
+ typedef std::map<const clang::Decl *, DeclOrigin> OriginMap;
+
+ class Minion : public clang::ASTImporter
+ {
+ public:
+ Minion (ClangASTImporter &master,
+ clang::ASTContext *target_ctx,
+ clang::ASTContext *source_ctx) :
+ clang::ASTImporter(*target_ctx,
+ master.m_file_manager,
+ *source_ctx,
+ master.m_file_manager,
+ true /*minimal*/),
+ m_decls_to_deport(NULL),
+ m_decls_already_deported(NULL),
+ m_master(master),
+ m_source_ctx(source_ctx)
+ {
+ }
+
+ // A call to "InitDeportWorkQueues" puts the minion into deport mode.
+ // In deport mode, every copied Decl that could require completion is
+ // recorded and placed into the decls_to_deport set.
+ //
+ // A call to "ExecuteDeportWorkQueues" completes all the Decls that
+ // are in decls_to_deport, adding any Decls it sees along the way that
+ // it hasn't already deported. It proceeds until decls_to_deport is
+ // empty.
+ //
+ // These calls must be paired. Leaving a minion in deport mode or
+ // trying to start deport minion with a new pair of queues will result
+ // in an assertion failure.
+
+ void InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport,
+ std::set<clang::NamedDecl *> *decls_already_deported);
+ void ExecuteDeportWorkQueues ();
+
+ void ImportDefinitionTo (clang::Decl *to, clang::Decl *from);
+
+ clang::Decl *Imported (clang::Decl *from, clang::Decl *to);
+
+ std::set<clang::NamedDecl *> *m_decls_to_deport;
+ std::set<clang::NamedDecl *> *m_decls_already_deported;
+ ClangASTImporter &m_master;
+ clang::ASTContext *m_source_ctx;
+ };
+
+ typedef std::shared_ptr<Minion> MinionSP;
+ typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
+ typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
+
+ struct ASTContextMetadata
+ {
+ ASTContextMetadata(clang::ASTContext *dst_ctx) :
+ m_dst_ctx (dst_ctx),
+ m_minions (),
+ m_origins (),
+ m_namespace_maps (),
+ m_map_completer (NULL)
+ {
+ }
+
+ clang::ASTContext *m_dst_ctx;
+ MinionMap m_minions;
+ OriginMap m_origins;
+
+ NamespaceMetaMap m_namespace_maps;
+ MapCompleter *m_map_completer;
+ };
+
+ typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP;
+ typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap;
+
+ ContextMetadataMap m_metadata_map;
+
+ ASTContextMetadataSP
+ GetContextMetadata (clang::ASTContext *dst_ctx)
+ {
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter == m_metadata_map.end())
+ {
+ ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
+ m_metadata_map[dst_ctx] = context_md;
+ return context_md;
+ }
+ else
+ {
+ return context_md_iter->second;
+ }
+ }
+
+ ASTContextMetadataSP
+ MaybeGetContextMetadata (clang::ASTContext *dst_ctx)
+ {
+ ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
+
+ if (context_md_iter != m_metadata_map.end())
+ return context_md_iter->second;
+ else
+ return ASTContextMetadataSP();
+ }
+
+ MinionSP
+ GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx)
+ {
+ ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
+
+ MinionMap &minions = context_md->m_minions;
+ MinionMap::iterator minion_iter = minions.find(src_ctx);
+
+ if (minion_iter == minions.end())
+ {
+ MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
+ minions[src_ctx] = minion;
+ return minion;
+ }
+ else
+ {
+ return minion_iter->second;
+ }
+ }
+
+ DeclOrigin
+ GetDeclOrigin (const clang::Decl *decl);
+
+ clang::FileManager m_file_manager;
+};
+
+}
+
+#endif
diff --git a/include/lldb/Symbol/ClangASTType.h b/include/lldb/Symbol/ClangASTType.h
new file mode 100644
index 000000000000..d9e754e8ceb9
--- /dev/null
+++ b/include/lldb/Symbol/ClangASTType.h
@@ -0,0 +1,679 @@
+//===-- ClangASTType.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_ClangASTType_h_
+#define liblldb_ClangASTType_h_
+
+#include <string>
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "clang/AST/Type.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// A class that can carry around a clang ASTContext and a opaque clang
+// QualType. A clang::QualType can be easily reconstructed from an
+// opaque clang type and often the ASTContext is needed when doing
+// various type related tasks, so this class allows both items to travel
+// in a single very lightweight class that can be used. There are many
+// static equivalents of the member functions that allow the ASTContext
+// and the opaque clang QualType to be specified for ease of use and
+// to avoid code duplication.
+//----------------------------------------------------------------------
+class ClangASTType
+{
+public:
+ enum {
+ eTypeHasChildren = (1u << 0),
+ eTypeHasValue = (1u << 1),
+ eTypeIsArray = (1u << 2),
+ eTypeIsBlock = (1u << 3),
+ eTypeIsBuiltIn = (1u << 4),
+ eTypeIsClass = (1u << 5),
+ eTypeIsCPlusPlus = (1u << 6),
+ eTypeIsEnumeration = (1u << 7),
+ eTypeIsFuncPrototype = (1u << 8),
+ eTypeIsMember = (1u << 9),
+ eTypeIsObjC = (1u << 10),
+ eTypeIsPointer = (1u << 11),
+ eTypeIsReference = (1u << 12),
+ eTypeIsStructUnion = (1u << 13),
+ eTypeIsTemplate = (1u << 14),
+ eTypeIsTypedef = (1u << 15),
+ eTypeIsVector = (1u << 16),
+ eTypeIsScalar = (1u << 17),
+ eTypeIsInteger = (1u << 18),
+ eTypeIsFloat = (1u << 19),
+ eTypeIsComplex = (1u << 20),
+ eTypeIsSigned = (1u << 21)
+ };
+
+
+ //----------------------------------------------------------------------
+ // Constructors and Destructors
+ //----------------------------------------------------------------------
+ ClangASTType (clang::ASTContext *ast_context, lldb::clang_type_t type) :
+ m_type (type),
+ m_ast (ast_context)
+ {
+ }
+
+ ClangASTType (clang::ASTContext *ast_context, clang::QualType qual_type);
+
+ ClangASTType (const ClangASTType &rhs) :
+ m_type (rhs.m_type),
+ m_ast (rhs.m_ast)
+ {
+ }
+
+ ClangASTType () :
+ m_type (0),
+ m_ast (0)
+ {
+ }
+
+ ~ClangASTType();
+
+ //----------------------------------------------------------------------
+ // Operators
+ //----------------------------------------------------------------------
+
+ const ClangASTType &
+ operator= (const ClangASTType &rhs)
+ {
+ m_type = rhs.m_type;
+ m_ast = rhs.m_ast;
+ return *this;
+ }
+
+
+ //----------------------------------------------------------------------
+ // Tests
+ //----------------------------------------------------------------------
+
+ operator bool () const
+ {
+ return m_type != NULL && m_ast != NULL;
+ }
+
+ bool
+ operator < (const ClangASTType &rhs) const
+ {
+ if (m_ast == rhs.m_ast)
+ return m_type < rhs.m_type;
+ return m_ast < rhs.m_ast;
+ }
+
+ bool
+ IsValid () const
+ {
+ return m_type != NULL && m_ast != NULL;
+ }
+
+ bool
+ IsArrayType (ClangASTType *element_type,
+ uint64_t *size,
+ bool *is_incomplete) const;
+
+ bool
+ IsArrayOfScalarType () const;
+
+ bool
+ IsAggregateType () const;
+
+ bool
+ IsBeingDefined () const;
+
+ bool
+ IsCharType () const;
+
+ bool
+ IsCompleteType () const;
+
+ bool
+ IsConst() const;
+
+ bool
+ IsCStringType (uint32_t &length) const;
+
+ bool
+ IsCXXClassType () const;
+
+ bool
+ IsDefined() const;
+
+ bool
+ IsFloatingPointType (uint32_t &count, bool &is_complex) const;
+
+ bool
+ IsFunctionType (bool *is_variadic_ptr = NULL) const;
+
+ bool
+ IsVariadicFunctionType () const;
+
+ bool
+ IsFunctionPointerType () const;
+
+ bool
+ IsIntegerType (bool &is_signed) const;
+
+ bool
+ IsObjCClassType () const;
+
+ bool
+ IsObjCClassTypeAndHasIVars (bool check_superclass) const;
+
+ bool
+ IsObjCObjectOrInterfaceType () const;
+
+ bool
+ IsObjCObjectPointerType (ClangASTType *target_type = NULL);
+
+ bool
+ IsPolymorphicClass () const;
+
+ bool
+ IsPossibleCPlusPlusDynamicType (ClangASTType *target_type = NULL) const
+ {
+ return IsPossibleDynamicType (target_type, true, false);
+ }
+
+ bool
+ IsPossibleDynamicType (ClangASTType *target_type, // Can pass NULL
+ bool check_cplusplus,
+ bool check_objc) const;
+
+
+ bool
+ IsPointerToScalarType () const;
+
+ bool
+ IsPointerType (ClangASTType *pointee_type = NULL) const;
+
+ bool
+ IsPointerOrReferenceType (ClangASTType *pointee_type = NULL) const;
+
+ bool
+ IsReferenceType (ClangASTType *pointee_type = NULL) const;
+
+ bool
+ IsScalarType () const;
+
+ bool
+ IsTypedefType () const;
+
+ bool
+ IsVoidType () const;
+
+ bool
+ GetCXXClassName (std::string &class_name) const;
+
+ bool
+ GetObjCClassName (std::string &class_name);
+
+
+ //----------------------------------------------------------------------
+ // Type Completion
+ //----------------------------------------------------------------------
+
+ bool
+ GetCompleteType () const;
+
+ //----------------------------------------------------------------------
+ // AST related queries
+ //----------------------------------------------------------------------
+
+ size_t
+ GetPointerByteSize () const;
+
+ //----------------------------------------------------------------------
+ // Accessors
+ //----------------------------------------------------------------------
+
+ clang::ASTContext *
+ GetASTContext() const
+ {
+ return m_ast;
+ }
+
+ ConstString
+ GetConstQualifiedTypeName () const;
+
+ ConstString
+ GetConstTypeName () const;
+
+ std::string
+ GetTypeName () const;
+
+ uint32_t
+ GetTypeInfo (ClangASTType *pointee_or_element_clang_type = NULL) const;
+
+ lldb::LanguageType
+ GetMinimumLanguage ();
+
+ lldb::clang_type_t
+ GetOpaqueQualType() const
+ {
+ return m_type;
+ }
+
+ lldb::TypeClass
+ GetTypeClass () const;
+
+ void
+ SetClangType (clang::ASTContext *ast, lldb::clang_type_t type)
+ {
+ m_ast = ast;
+ m_type = type;
+ }
+
+ void
+ SetClangType (clang::ASTContext *ast, clang::QualType qual_type);
+
+ unsigned
+ GetTypeQualifiers() const;
+
+ //----------------------------------------------------------------------
+ // Creating related types
+ //----------------------------------------------------------------------
+
+ ClangASTType
+ AddConstModifier () const;
+
+ ClangASTType
+ AddRestrictModifier () const;
+
+ ClangASTType
+ AddVolatileModifier () const;
+
+ // Using the current type, create a new typedef to that type using "typedef_name"
+ // as the name and "decl_ctx" as the decl context.
+ ClangASTType
+ CreateTypedefType (const char *typedef_name,
+ clang::DeclContext *decl_ctx) const;
+
+ ClangASTType
+ GetArrayElementType (uint64_t& stride) const;
+
+ ClangASTType
+ GetCanonicalType () const;
+
+ ClangASTType
+ GetFullyUnqualifiedType () const;
+
+ // Returns -1 if this isn't a function of if the fucntion doesn't have a prototype
+ // Returns a value >= 0 if there is a prototype.
+ int
+ GetFunctionArgumentCount () const;
+
+ ClangASTType
+ GetFunctionArgumentTypeAtIndex (size_t idx);
+
+ ClangASTType
+ GetFunctionReturnType () const;
+
+ ClangASTType
+ GetLValueReferenceType () const;
+
+ ClangASTType
+ GetNonReferenceType () const;
+
+ ClangASTType
+ GetPointeeType () const;
+
+ ClangASTType
+ GetPointerType () const;
+
+ ClangASTType
+ GetRValueReferenceType () const;
+
+ // If the current object represents a typedef type, get the underlying type
+ ClangASTType
+ GetTypedefedType () const;
+
+ ClangASTType
+ RemoveFastQualifiers () const;
+
+ //----------------------------------------------------------------------
+ // Create related types using the current type's AST
+ //----------------------------------------------------------------------
+ ClangASTType
+ GetBasicTypeFromAST (lldb::BasicType basic_type) const;
+
+ //----------------------------------------------------------------------
+ // Exploring the type
+ //----------------------------------------------------------------------
+
+ uint64_t
+ GetByteSize () const;
+
+ uint64_t
+ GetBitSize () const;
+
+ lldb::Encoding
+ GetEncoding (uint64_t &count) const;
+
+ lldb::Format
+ GetFormat () const;
+
+ size_t
+ GetTypeBitAlign () const;
+
+ uint32_t
+ GetNumChildren (bool omit_empty_base_classes) const;
+
+ lldb::BasicType
+ GetBasicTypeEnumeration () const;
+
+ static lldb::BasicType
+ GetBasicTypeEnumeration (const ConstString &name);
+
+ uint32_t
+ GetNumDirectBaseClasses () const;
+
+ uint32_t
+ GetNumVirtualBaseClasses () const;
+
+ uint32_t
+ GetNumFields () const;
+
+ ClangASTType
+ GetDirectBaseClassAtIndex (size_t idx,
+ uint32_t *bit_offset_ptr) const;
+
+ ClangASTType
+ GetVirtualBaseClassAtIndex (size_t idx,
+ uint32_t *bit_offset_ptr) const;
+
+ ClangASTType
+ GetFieldAtIndex (size_t idx,
+ std::string& name,
+ uint64_t *bit_offset_ptr,
+ uint32_t *bitfield_bit_size_ptr,
+ bool *is_bitfield_ptr) const;
+
+ uint32_t
+ GetIndexOfFieldWithName (const char* name,
+ ClangASTType* field_clang_type = NULL,
+ uint64_t *bit_offset_ptr = NULL,
+ uint32_t *bitfield_bit_size_ptr = NULL,
+ bool *is_bitfield_ptr = NULL) const;
+
+ uint32_t
+ GetNumPointeeChildren () const;
+
+ ClangASTType
+ GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
+ const char *parent_name,
+ size_t idx,
+ bool transparent_pointers,
+ bool omit_empty_base_classes,
+ bool ignore_array_bounds,
+ std::string& child_name,
+ uint32_t &child_byte_size,
+ int32_t &child_byte_offset,
+ uint32_t &child_bitfield_bit_size,
+ uint32_t &child_bitfield_bit_offset,
+ bool &child_is_base_class,
+ bool &child_is_deref_of_parent) const;
+
+ // Lookup a child given a name. This function will match base class names
+ // and member member names in "clang_type" only, not descendants.
+ uint32_t
+ GetIndexOfChildWithName (const char *name,
+ bool omit_empty_base_classes) const;
+
+ // Lookup a child member given a name. This function will match member names
+ // only and will descend into "clang_type" children in search for the first
+ // member in this class, or any base class that matches "name".
+ // TODO: Return all matches for a given name by returning a vector<vector<uint32_t>>
+ // so we catch all names that match a given child name, not just the first.
+ size_t
+ GetIndexOfChildMemberWithName (const char *name,
+ bool omit_empty_base_classes,
+ std::vector<uint32_t>& child_indexes) const;
+
+ size_t
+ GetNumTemplateArguments () const;
+
+ ClangASTType
+ GetTemplateArgument (size_t idx,
+ lldb::TemplateArgumentKind &kind) const;
+
+
+ //----------------------------------------------------------------------
+ // Modifying RecordType
+ //----------------------------------------------------------------------
+ clang::FieldDecl *
+ AddFieldToRecordType (const char *name,
+ const ClangASTType &field_type,
+ lldb::AccessType access,
+ uint32_t bitfield_bit_size);
+
+ void
+ BuildIndirectFields ();
+
+ clang::VarDecl *
+ AddVariableToRecordType (const char *name,
+ const ClangASTType &var_type,
+ lldb::AccessType access);
+
+ clang::CXXMethodDecl *
+ AddMethodToCXXRecordType (const char *name,
+ const ClangASTType &method_type,
+ lldb::AccessType access,
+ bool is_virtual,
+ bool is_static,
+ bool is_inline,
+ bool is_explicit,
+ bool is_attr_used,
+ bool is_artificial);
+
+ // C++ Base Classes
+ clang::CXXBaseSpecifier *
+ CreateBaseClassSpecifier (lldb::AccessType access,
+ bool is_virtual,
+ bool base_of_class);
+
+ static void
+ DeleteBaseClassSpecifiers (clang::CXXBaseSpecifier **base_classes,
+ unsigned num_base_classes);
+
+ bool
+ SetBaseClassesForClassType (clang::CXXBaseSpecifier const * const *base_classes,
+ unsigned num_base_classes);
+
+
+ bool
+ SetObjCSuperClass (const ClangASTType &superclass_clang_type);
+
+ bool
+ AddObjCClassProperty (const char *property_name,
+ const ClangASTType &property_clang_type,
+ clang::ObjCIvarDecl *ivar_decl,
+ const char *property_setter_name,
+ const char *property_getter_name,
+ uint32_t property_attributes,
+ ClangASTMetadata *metadata);
+
+ clang::ObjCMethodDecl *
+ AddMethodToObjCObjectType (const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
+ const ClangASTType &method_clang_type,
+ lldb::AccessType access,
+ bool is_artificial);
+
+ clang::DeclContext *
+ GetDeclContextForType () const;
+
+
+ bool
+ SetDefaultAccessForRecordFields (int default_accessibility,
+ int *assigned_accessibilities,
+ size_t num_assigned_accessibilities);
+
+ bool
+ SetHasExternalStorage (bool has_extern);
+
+
+ //------------------------------------------------------------------
+ // clang::TagType
+ //------------------------------------------------------------------
+
+ bool
+ SetTagTypeKind (int kind) const;
+
+ //------------------------------------------------------------------
+ // Tag Declarations
+ //------------------------------------------------------------------
+ bool
+ StartTagDeclarationDefinition ();
+
+ bool
+ CompleteTagDeclarationDefinition ();
+
+ //----------------------------------------------------------------------
+ // Modifying Enumeration types
+ //----------------------------------------------------------------------
+ bool
+ AddEnumerationValueToEnumerationType (const ClangASTType &enumerator_qual_type,
+ const Declaration &decl,
+ const char *name,
+ int64_t enum_value,
+ uint32_t enum_value_bit_size);
+
+
+
+ ClangASTType
+ GetEnumerationIntegerType () const;
+
+
+ //------------------------------------------------------------------
+ // Pointers & References
+ //------------------------------------------------------------------
+
+ // Call this function using the class type when you want to make a
+ // member pointer type to pointee_type.
+ ClangASTType
+ CreateMemberPointerType (const ClangASTType &pointee_type) const;
+
+
+ // Converts "s" to a floating point value and place resulting floating
+ // point bytes in the "dst" buffer.
+ size_t
+ ConvertStringToFloatValue (const char *s,
+ uint8_t *dst,
+ size_t dst_size) const;
+ //----------------------------------------------------------------------
+ // Dumping types
+ //----------------------------------------------------------------------
+ void
+ DumpValue (ExecutionContext *exe_ctx,
+ Stream *s,
+ lldb::Format format,
+ const DataExtractor &data,
+ lldb::offset_t data_offset,
+ size_t data_byte_size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset,
+ bool show_types,
+ bool show_summary,
+ bool verbose,
+ uint32_t depth);
+
+ bool
+ DumpTypeValue (Stream *s,
+ lldb::Format format,
+ const DataExtractor &data,
+ lldb::offset_t data_offset,
+ size_t data_byte_size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset,
+ ExecutionContextScope *exe_scope);
+
+ void
+ DumpSummary (ExecutionContext *exe_ctx,
+ Stream *s,
+ const DataExtractor &data,
+ lldb::offset_t data_offset,
+ size_t data_byte_size);
+
+ void
+ DumpTypeDescription () const; // Dump to stdout
+
+ void
+ DumpTypeDescription (Stream *s) const;
+
+ bool
+ GetValueAsScalar (const DataExtractor &data,
+ lldb::offset_t data_offset,
+ size_t data_byte_size,
+ Scalar &value) const;
+
+ bool
+ SetValueFromScalar (const Scalar &value,
+ Stream &strm);
+
+ bool
+ ReadFromMemory (ExecutionContext *exe_ctx,
+ lldb::addr_t addr,
+ AddressType address_type,
+ DataExtractor &data);
+
+ bool
+ WriteToMemory (ExecutionContext *exe_ctx,
+ lldb::addr_t addr,
+ AddressType address_type,
+ StreamString &new_value);
+
+
+ clang::RecordDecl *
+ GetAsRecordDecl () const;
+
+ clang::CXXRecordDecl *
+ GetAsCXXRecordDecl () const;
+
+ clang::ObjCInterfaceDecl *
+ GetAsObjCInterfaceDecl () const;
+
+ void
+ Clear()
+ {
+ m_type = NULL;
+ m_ast = NULL;
+ }
+
+ clang::QualType
+ GetQualType () const
+ {
+ if (m_type)
+ return clang::QualType::getFromOpaquePtr(m_type);
+ return clang::QualType();
+ }
+ clang::QualType
+ GetCanonicalQualType () const
+ {
+ if (m_type)
+ return clang::QualType::getFromOpaquePtr(m_type).getCanonicalType();
+ return clang::QualType();
+ }
+
+private:
+ lldb::clang_type_t m_type;
+ clang::ASTContext *m_ast;
+
+};
+
+bool operator == (const ClangASTType &lhs, const ClangASTType &rhs);
+bool operator != (const ClangASTType &lhs, const ClangASTType &rhs);
+
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_ClangASTType_h_
diff --git a/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h b/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h
new file mode 100644
index 000000000000..0c8121135ef0
--- /dev/null
+++ b/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h
@@ -0,0 +1,171 @@
+//===-- ClangExternalASTSourceCallbacks.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_ClangExternalASTSourceCallbacks_h_
+#define liblldb_ClangExternalASTSourceCallbacks_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <vector>
+#include <stdint.h>
+
+// Other libraries and framework includes
+#include "clang/AST/CharUnits.h"
+
+// Project includes
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+
+namespace lldb_private {
+
+class ClangExternalASTSourceCallbacks : public ClangExternalASTSourceCommon
+{
+public:
+
+ typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *);
+ typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *);
+ typedef void (*FindExternalVisibleDeclsByNameCallback)(void *baton, const clang::DeclContext *DC, clang::DeclarationName Name, llvm::SmallVectorImpl <clang::NamedDecl *> *results);
+ typedef bool (*LayoutRecordTypeCallback)(void *baton,
+ 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);
+
+ ClangExternalASTSourceCallbacks (CompleteTagDeclCallback tag_decl_callback,
+ CompleteObjCInterfaceDeclCallback objc_decl_callback,
+ FindExternalVisibleDeclsByNameCallback find_by_name_callback,
+ LayoutRecordTypeCallback layout_record_type_callback,
+ void *callback_baton) :
+ m_callback_tag_decl (tag_decl_callback),
+ m_callback_objc_decl (objc_decl_callback),
+ m_callback_find_by_name (find_by_name_callback),
+ m_callback_layout_record_type (layout_record_type_callback),
+ m_callback_baton (callback_baton)
+ {
+ }
+
+ //------------------------------------------------------------------
+ // clang::ExternalASTSource
+ //------------------------------------------------------------------
+
+ virtual clang::Decl *
+ GetExternalDecl (uint32_t ID)
+ {
+ // This method only needs to be implemented if the AST source ever
+ // passes back decl sets as VisibleDeclaration objects.
+ return 0;
+ }
+
+ virtual clang::Stmt *
+ GetExternalDeclStmt (uint64_t Offset)
+ {
+ // This operation is meant to be used via a LazyOffsetPtr. It only
+ // needs to be implemented if the AST source uses methods like
+ // FunctionDecl::setLazyBody when building decls.
+ return 0;
+ }
+
+ virtual clang::Selector
+ GetExternalSelector (uint32_t ID)
+ {
+ // This operation only needs to be implemented if the AST source
+ // returns non-zero for GetNumKnownSelectors().
+ return clang::Selector();
+ }
+
+ virtual uint32_t
+ GetNumExternalSelectors()
+ {
+ return 0;
+ }
+
+ virtual clang::CXXBaseSpecifier *
+ GetExternalCXXBaseSpecifiers(uint64_t Offset)
+ {
+ return NULL;
+ }
+
+ virtual void
+ MaterializeVisibleDecls (const clang::DeclContext *decl_ctx)
+ {
+ return;
+ }
+
+ virtual clang::ExternalLoadResult
+ FindExternalLexicalDecls (const clang::DeclContext *decl_ctx,
+ bool (*isKindWeWant)(clang::Decl::Kind),
+ llvm::SmallVectorImpl<clang::Decl*> &decls)
+ {
+ // This is used to support iterating through an entire lexical context,
+ // which isn't something the debugger should ever need to do.
+ return clang::ELR_Failure;
+ }
+
+ virtual bool
+ FindExternalVisibleDeclsByName (const clang::DeclContext *decl_ctx,
+ clang::DeclarationName decl_name);
+
+ virtual void
+ CompleteType (clang::TagDecl *tag_decl);
+
+ virtual void
+ CompleteType (clang::ObjCInterfaceDecl *objc_decl);
+
+ 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);
+ void
+ SetExternalSourceCallbacks (CompleteTagDeclCallback tag_decl_callback,
+ CompleteObjCInterfaceDeclCallback objc_decl_callback,
+ FindExternalVisibleDeclsByNameCallback find_by_name_callback,
+ LayoutRecordTypeCallback layout_record_type_callback,
+ void *callback_baton)
+ {
+ m_callback_tag_decl = tag_decl_callback;
+ m_callback_objc_decl = objc_decl_callback;
+ m_callback_find_by_name = find_by_name_callback;
+ m_callback_layout_record_type = layout_record_type_callback;
+ m_callback_baton = callback_baton;
+ }
+
+ void
+ RemoveExternalSourceCallbacks (void *callback_baton)
+ {
+ if (callback_baton == m_callback_baton)
+ {
+ m_callback_tag_decl = NULL;
+ m_callback_objc_decl = NULL;
+ m_callback_find_by_name = NULL;
+ m_callback_layout_record_type = NULL;
+ }
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from ClangExternalASTSourceCallbacks can see and modify these
+ //------------------------------------------------------------------
+ CompleteTagDeclCallback m_callback_tag_decl;
+ CompleteObjCInterfaceDeclCallback m_callback_objc_decl;
+ FindExternalVisibleDeclsByNameCallback m_callback_find_by_name;
+ LayoutRecordTypeCallback m_callback_layout_record_type;
+ void * m_callback_baton;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangExternalASTSourceCallbacks_h_
diff --git a/include/lldb/Symbol/ClangExternalASTSourceCommon.h b/include/lldb/Symbol/ClangExternalASTSourceCommon.h
new file mode 100644
index 000000000000..72d77e74ca90
--- /dev/null
+++ b/include/lldb/Symbol/ClangExternalASTSourceCommon.h
@@ -0,0 +1,188 @@
+//===-- ClangExternalASTSourceCommon.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_ClangExternalASTSourceCommon_h
+#define liblldb_ClangExternalASTSourceCommon_h
+
+// Clang headers like to use NDEBUG inside of them to enable/disable debug
+// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing
+// or another. This is bad because it means that if clang was built in release
+// mode, it assumes that you are building in release mode which is not always
+// the case. You can end up with functions that are defined as empty in header
+// files when NDEBUG is not defined, and this can cause link errors with the
+// clang .a files that you have since you might be missing functions in the .a
+// file. So we have to define NDEBUG when including clang headers to avoid any
+// mismatches. This is covered by rdar://problem/8691220
+
+#if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF)
+#define LLDB_DEFINED_NDEBUG_FOR_CLANG
+#define NDEBUG
+// Need to include assert.h so it is as clang would expect it to be (disabled)
+#include <assert.h>
+#endif
+
+#include "clang/AST/ExternalASTSource.h"
+
+#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
+#undef NDEBUG
+#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
+// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
+#include <assert.h>
+#endif
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/dwarf.h"
+
+namespace lldb_private {
+
+class ClangASTMetadata
+{
+public:
+ ClangASTMetadata () :
+ m_user_id(0),
+ m_union_is_user_id(false),
+ m_union_is_isa_ptr(false),
+ m_has_object_ptr(false),
+ m_is_self (false),
+ m_is_dynamic_cxx (true)
+ {
+ }
+
+ bool
+ GetIsDynamicCXXType () const
+ {
+ return m_is_dynamic_cxx;
+ }
+
+ void
+ SetIsDynamicCXXType (bool b)
+ {
+ m_is_dynamic_cxx = b;
+ }
+
+ void
+ SetUserID (lldb::user_id_t user_id)
+ {
+ m_user_id = user_id;
+ m_union_is_user_id = true;
+ m_union_is_isa_ptr = false;
+ }
+
+ lldb::user_id_t
+ GetUserID () const
+ {
+ if (m_union_is_user_id)
+ return m_user_id;
+ else
+ return LLDB_INVALID_UID;
+ }
+
+ void
+ SetISAPtr (uint64_t isa_ptr)
+ {
+ m_isa_ptr = isa_ptr;
+ m_union_is_user_id = false;
+ m_union_is_isa_ptr = true;
+ }
+
+ uint64_t
+ GetISAPtr () const
+ {
+ if (m_union_is_isa_ptr)
+ return m_isa_ptr;
+ else
+ return 0;
+ }
+
+ void
+ SetObjectPtrName(const char *name)
+ {
+ m_has_object_ptr = true;
+ if (strcmp (name, "self") == 0)
+ m_is_self = true;
+ else if (strcmp (name, "this") == 0)
+ m_is_self = false;
+ else
+ m_has_object_ptr = false;
+ }
+
+ lldb::LanguageType
+ GetObjectPtrLanguage () const
+ {
+ if (m_has_object_ptr)
+ {
+ if (m_is_self)
+ return lldb::eLanguageTypeObjC;
+ else
+ return lldb::eLanguageTypeC_plus_plus;
+ }
+ return lldb::eLanguageTypeUnknown;
+
+ }
+ const char *
+ GetObjectPtrName() const
+ {
+ if (m_has_object_ptr)
+ {
+ if (m_is_self)
+ return "self";
+ else
+ return "this";
+ }
+ else
+ return NULL;
+ }
+
+ bool
+ HasObjectPtr() const
+ {
+ return m_has_object_ptr;
+ }
+
+ void
+ Dump (Stream *s);
+
+private:
+ union
+ {
+ lldb::user_id_t m_user_id;
+ uint64_t m_isa_ptr;
+ };
+ bool m_union_is_user_id : 1,
+ m_union_is_isa_ptr : 1,
+ m_has_object_ptr : 1,
+ m_is_self : 1,
+ m_is_dynamic_cxx : 1;
+
+};
+
+class ClangExternalASTSourceCommon : public clang::ExternalASTSource
+{
+public:
+ ClangExternalASTSourceCommon();
+ ~ClangExternalASTSourceCommon();
+
+ virtual ClangASTMetadata *GetMetadata(const void *object);
+ virtual void SetMetadata(const void *object, ClangASTMetadata &metadata);
+ virtual bool HasMetadata(const void *object);
+private:
+ typedef llvm::DenseMap<const void *, ClangASTMetadata> MetadataMap;
+
+ MetadataMap m_metadata;
+ uint64_t m_magic; ///< Because we don't have RTTI, we must take it
+ ///< on faith that any valid ExternalASTSource that
+ ///< we try to use the *Metadata APIs on inherits
+ ///< from ClangExternalASTSourceCommon. This magic
+ ///< number exists to enforce that.
+};
+
+}
+
+#endif
diff --git a/include/lldb/Symbol/ClangNamespaceDecl.h b/include/lldb/Symbol/ClangNamespaceDecl.h
new file mode 100644
index 000000000000..d10ab2a29665
--- /dev/null
+++ b/include/lldb/Symbol/ClangNamespaceDecl.h
@@ -0,0 +1,103 @@
+//===-- ClangNamespaceDecl.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_ClangNamespaceDecl_h_
+#define liblldb_ClangNamespaceDecl_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ClangForward.h"
+
+namespace lldb_private {
+
+class ClangNamespaceDecl
+{
+public:
+ ClangNamespaceDecl () :
+ m_ast (NULL),
+ m_namespace_decl (NULL)
+ {
+ }
+
+ ClangNamespaceDecl (clang::ASTContext *ast, clang::NamespaceDecl *namespace_decl) :
+ m_ast (ast),
+ m_namespace_decl (namespace_decl)
+ {
+ }
+
+ ClangNamespaceDecl (const ClangNamespaceDecl &rhs) :
+ m_ast (rhs.m_ast),
+ m_namespace_decl (rhs.m_namespace_decl)
+ {
+ }
+
+ const ClangNamespaceDecl &
+ operator = (const ClangNamespaceDecl &rhs)
+ {
+ m_ast = rhs.m_ast;
+ m_namespace_decl = rhs.m_namespace_decl;
+ return *this;
+ }
+
+ //------------------------------------------------------------------
+ /// Convert to bool operator.
+ ///
+ /// This allows code to check a ClangNamespaceDecl object to see if
+ /// it contains a valid namespace decl using code such as:
+ ///
+ /// @code
+ /// ClangNamespaceDecl ns_decl(...);
+ /// if (ns_decl)
+ /// { ...
+ /// @endcode
+ ///
+ /// @return
+ /// /b True this object contains a valid namespace decl, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ operator bool() const
+ {
+ return m_ast != NULL && m_namespace_decl != NULL;
+ }
+
+ clang::ASTContext *
+ GetASTContext() const
+ {
+ return m_ast;
+ }
+
+ void
+ SetASTContext (clang::ASTContext *ast)
+ {
+ m_ast = ast;
+ }
+
+ clang::NamespaceDecl *
+ GetNamespaceDecl () const
+ {
+ return m_namespace_decl;
+ }
+
+ void
+ SetNamespaceDecl (clang::NamespaceDecl *namespace_decl)
+ {
+ m_namespace_decl = namespace_decl;
+ }
+
+ std::string
+ GetQualifiedName () const;
+
+protected:
+ clang::ASTContext *m_ast;
+ clang::NamespaceDecl *m_namespace_decl;
+};
+
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_ClangNamespaceDecl_h_
diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h
new file mode 100644
index 000000000000..5de93670c5a7
--- /dev/null
+++ b/include/lldb/Symbol/CompileUnit.h
@@ -0,0 +1,422 @@
+//===-- CompileUnit.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_CompUnit_h_
+#define liblldb_CompUnit_h_
+
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/UserID.h"
+
+namespace lldb_private {
+//----------------------------------------------------------------------
+/// @class CompileUnit CompileUnit.h "lldb/Symbol/CompileUnit.h"
+/// @brief A class that describes a compilation unit.
+///
+/// A representation of a compilation unit, or compiled source file.
+/// The UserID of the compile unit is specified by the SymbolFile
+/// plug-in and can have any value as long as the value is unique
+/// within the Module that owns this compile units.
+///
+/// Each compile unit has a list of functions, global and static
+/// variables, support file list (include files and inlined source
+/// files), and a line table.
+//----------------------------------------------------------------------
+class CompileUnit :
+ public std::enable_shared_from_this<CompileUnit>,
+ public ModuleChild,
+ public FileSpec,
+ public UserID,
+ public SymbolContextScope
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with a module, path, UID and language.
+ ///
+ /// Initialize the compile unit given the owning \a module, a path
+ /// to convert into a FileSpec, the SymbolFile plug-in supplied
+ /// \a uid, and the source language type.
+ ///
+ /// @param[in] module
+ /// The parent module that owns this compile unit. This value
+ /// must be a valid pointer value.
+ ///
+ /// @param[in] user_data
+ /// User data where the SymbolFile parser can store data.
+ ///
+ /// @param[in] pathname
+ /// The path to the source file for this compile unit.
+ ///
+ /// @param[in] uid
+ /// The user ID of the compile unit. This value is supplied by
+ /// the SymbolFile plug-in and should be a value that allows
+ /// the SymbolFile plug-in to easily locate and parse additional
+ /// information for the compile unit.
+ ///
+ /// @param[in] language
+ /// A language enumeration type that describes the main language
+ /// of this compile unit.
+ ///
+ /// @see lldb::LanguageType
+ //------------------------------------------------------------------
+ CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, lldb::user_id_t uid, lldb::LanguageType language);
+
+ //------------------------------------------------------------------
+ /// Construct with a module, file spec, UID and language.
+ ///
+ /// Initialize the compile unit given the owning \a module, a path
+ /// to convert into a FileSpec, the SymbolFile plug-in supplied
+ /// \a uid, and the source language type.
+ ///
+ /// @param[in] module
+ /// The parent module that owns this compile unit. This value
+ /// must be a valid pointer value.
+ ///
+ /// @param[in] user_data
+ /// User data where the SymbolFile parser can store data.
+ ///
+ /// @param[in] file_spec
+ /// The file specification for the source file of this compile
+ /// unit.
+ ///
+ /// @param[in] uid
+ /// The user ID of the compile unit. This value is supplied by
+ /// the SymbolFile plug-in and should be a value that allows
+ /// the plug-in to easily locate and parse
+ /// additional information for the compile unit.
+ ///
+ /// @param[in] language
+ /// A language enumeration type that describes the main language
+ /// of this compile unit.
+ ///
+ /// @see lldb::LanguageType
+ //------------------------------------------------------------------
+ CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, lldb::LanguageType language);
+
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
+ virtual
+ ~CompileUnit();
+
+ //------------------------------------------------------------------
+ /// Add a function to this compile unit.
+ ///
+ /// Typically called by the SymbolFile plug-ins as they partially
+ /// parse the debug information.
+ ///
+ /// @param[in] function_sp
+ /// A shared pointer to the a Function object.
+ //------------------------------------------------------------------
+ void
+ AddFunction(lldb::FunctionSP& function_sp);
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext(SymbolContext* sc);
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ();
+
+ virtual CompileUnit *
+ CalculateSymbolContextCompileUnit ();
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext(Stream *s);
+
+ lldb::LanguageType
+ GetLanguage();
+
+ void
+ SetLanguage(lldb::LanguageType language)
+ {
+ m_flags.Set(flagsParsedLanguage);
+ m_language = language;
+ }
+
+ void
+ GetDescription(Stream *s, lldb::DescriptionLevel level) const;
+
+ //------------------------------------------------------------------
+ /// Get a shared pointer to a function in this compile unit by
+ /// index.
+ ///
+ /// Typically called when iterating though all functions in a
+ /// compile unit after all functions have been parsed. This provides
+ /// raw access to the function shared pointer list and will not
+ /// cause the SymbolFile plug-in to parse any unparsed functions.
+ ///
+ /// @param[in] idx
+ /// An index into the function list.
+ ///
+ /// @return
+ /// A shared pointer to a function that might contain a NULL
+ /// Function class pointer.
+ //------------------------------------------------------------------
+ lldb::FunctionSP
+ GetFunctionAtIndex (size_t idx);
+
+ //------------------------------------------------------------------
+ /// Dump the compile unit contents to the stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] show_context
+ /// If \b true, variables will dump their symbol context
+ /// information.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, bool show_context) const;
+
+ //------------------------------------------------------------------
+ /// Find the line entry by line and optional inlined file spec.
+ ///
+ /// Finds the first line entry that has an index greater than
+ /// \a start_idx that matches \a line. If \a file_spec_ptr
+ /// is NULL, then the search matches line entries whose file matches
+ /// the file for the compile unit. If \a file_spec_ptr is
+ /// not NULL, line entries must match the specified file spec (for
+ /// inlined line table entries).
+ ///
+ /// Multiple calls to this function can find all entries that match
+ /// a given file and line by starting with \a start_idx equal to zero,
+ /// and calling this function back with the return valeu + 1.
+ ///
+ /// @param[in] start_idx
+ /// The zero based index at which to start looking for matches.
+ ///
+ /// @param[in] line
+ /// The line number to search for.
+ ///
+ /// @param[in] file_spec_ptr
+ /// If non-NULL search for entries that match this file spec,
+ /// else if NULL, search for line entries that match the compile
+ /// unit file.
+ ///
+ /// @param[in] exact
+ /// If \btrue match only if there is a line table entry for this line number.
+ /// If \bfalse, find the line table entry equal to or after this line number.
+ ///
+ /// @param[out] line_entry
+ /// If non-NULL, a copy of the line entry that was found.
+ ///
+ /// @return
+ /// The zero based index of a matching line entry, or UINT32_MAX
+ /// if no matching line entry is found.
+ //------------------------------------------------------------------
+ uint32_t
+ FindLineEntry (uint32_t start_idx,
+ uint32_t line,
+ const FileSpec* file_spec_ptr,
+ bool exact,
+ LineEntry *line_entry);
+
+ //------------------------------------------------------------------
+ /// Get the line table for the compile unit.
+ ///
+ /// Called by clients and the SymbolFile plug-in. The SymbolFile
+ /// plug-ins use this function to determine if the line table has
+ /// be parsed yet. Clients use this function to get the line table
+ /// from a compile unit.
+ ///
+ /// @return
+ /// The line table object pointer, or NULL if this line table
+ /// hasn't been parsed yet.
+ //------------------------------------------------------------------
+ LineTable*
+ GetLineTable ();
+
+ //------------------------------------------------------------------
+ /// Get the compile unit's support file list.
+ ///
+ /// The support file list is used by the line table, and any objects
+ /// that have valid Declaration objects.
+ ///
+ /// @return
+ /// A support file list object.
+ //------------------------------------------------------------------
+ FileSpecList&
+ GetSupportFiles ();
+
+ //------------------------------------------------------------------
+ /// Get the SymbolFile plug-in user data.
+ ///
+ /// SymbolFile plug-ins can store user data to internal state or
+ /// objects to quickly allow them to parse more information for a
+ /// given object.
+ ///
+ /// @return
+ /// The user data stored with the CompileUnit when it was
+ /// constructed.
+ //------------------------------------------------------------------
+ void *
+ GetUserData () const;
+
+ //------------------------------------------------------------------
+ /// Get the variable list for a compile unit.
+ ///
+ /// Called by clients to get the variable list for a compile unit.
+ /// The variable list will contain all global and static variables
+ /// that were defined at the compile unit level.
+ ///
+ /// @param[in] can_create
+ /// If \b true, the variable list will be parsed on demand. If
+ /// \b false, the current variable list will be returned even
+ /// if it contains a NULL VariableList object (typically
+ /// called by dumping routines that want to display only what
+ /// has currently been parsed).
+ ///
+ /// @return
+ /// A shared pointer to a variable list, that can contain NULL
+ /// VariableList pointer if there are no global or static
+ /// variables.
+ //------------------------------------------------------------------
+ lldb::VariableListSP
+ GetVariableList (bool can_create);
+
+ //------------------------------------------------------------------
+ /// Finds a function by user ID.
+ ///
+ /// Typically used by SymbolFile plug-ins when partially parsing
+ /// the debug information to see if the function has been parsed
+ /// yet.
+ ///
+ /// @param[in] uid
+ /// The user ID of the function to find. This value is supplied
+ /// by the SymbolFile plug-in and should be a value that
+ /// allows the plug-in to easily locate and parse additional
+ /// information in the function.
+ ///
+ /// @return
+ /// A shared pointer to the function object that might contain
+ /// a NULL Function pointer.
+ //------------------------------------------------------------------
+ lldb::FunctionSP
+ FindFunctionByUID (lldb::user_id_t uid);
+
+ //------------------------------------------------------------------
+ /// Set the line table for the compile unit.
+ ///
+ /// Called by the SymbolFile plug-in when if first parses the line
+ /// table and hands ownership of the line table to this object. The
+ /// compile unit owns the line table object and will delete the
+ /// object when it is deleted.
+ ///
+ /// @param[in] line_table
+ /// A line table object pointer that this object now owns.
+ //------------------------------------------------------------------
+ void
+ SetLineTable(LineTable* line_table);
+
+ //------------------------------------------------------------------
+ /// Set accessor for the variable list.
+ ///
+ /// Called by the SymbolFile plug-ins after they have parsed the
+ /// variable lists and are ready to hand ownership of the list over
+ /// to this object.
+ ///
+ /// @param[in] variable_list_sp
+ /// A shared pointer to a VariableList.
+ //------------------------------------------------------------------
+ void
+ SetVariableList (lldb::VariableListSP& variable_list_sp);
+
+ //------------------------------------------------------------------
+ /// Resolve symbol contexts by file and line.
+ ///
+ /// Given a file in \a file_spec, and a line number, find all
+ /// instances and append them to the supplied symbol context list
+ /// \a sc_list.
+ ///
+ /// @param[in] file_spec
+ /// A file specification. If \a file_spec contains no directory
+ /// information, only the basename will be used when matching
+ /// contexts. If the directory in \a file_spec is valid, a
+ /// complete file specification match will be performed.
+ ///
+ /// @param[in] line
+ /// The line number to match against the compile unit's line
+ /// tables.
+ ///
+ /// @param[in] check_inlines
+ /// If \b true this function will also match any inline
+ /// file and line matches. If \b false, the compile unit's
+ /// file specification must match \a file_spec for any matches
+ /// to be returned.
+ ///
+ /// @param[in] exact
+ /// If true, only resolve the context if \a line exists in the line table.
+ /// If false, resolve the context to the closest line greater than \a line
+ /// in the line table.
+ ///
+ /// @param[in] resolve_scope
+ /// For each matching line entry, this bitfield indicates what
+ /// values within each SymbolContext that gets added to \a
+ /// sc_list will be resolved. See the SymbolContext::Scope
+ /// enumeration for a list of all available bits that can be
+ /// resolved. Only SymbolContext entries that can be resolved
+ /// using a LineEntry base address will be able to be resolved.
+ ///
+ /// @param[out] sc_list
+ /// A SymbolContext list class that willl get any matching
+ /// entries appended to.
+ ///
+ /// @return
+ /// The number of new matches that were added to \a sc_list.
+ ///
+ /// @see enum SymbolContext::Scope
+ //------------------------------------------------------------------
+ uint32_t
+ ResolveSymbolContext (const FileSpec& file_spec,
+ uint32_t line,
+ bool check_inlines,
+ bool exact,
+ uint32_t resolve_scope,
+ SymbolContextList &sc_list);
+
+
+protected:
+ void *m_user_data; ///< User data for the SymbolFile parser to store information into.
+ lldb::LanguageType m_language; ///< The programming language enumeration value.
+ Flags m_flags; ///< Compile unit flags that help with partial parsing.
+ std::vector<lldb::FunctionSP> m_functions; ///< The sparsely populated list of shared pointers to functions
+ ///< that gets populated as functions get partially parsed.
+ FileSpecList m_support_files; ///< Files associated with this compile unit's line table and declarations.
+ std::unique_ptr<LineTable> m_line_table_ap; ///< Line table that will get parsed on demand.
+ lldb::VariableListSP m_variables; ///< Global and static variable list that will get parsed on demand.
+
+private:
+ enum
+ {
+ flagsParsedAllFunctions = (1u << 0), ///< Have we already parsed all our functions
+ flagsParsedVariables = (1u << 1), ///< Have we already parsed globals and statics?
+ flagsParsedSupportFiles = (1u << 2), ///< Have we already parsed the support files for this compile unit?
+ flagsParsedLineTable = (1u << 3), ///< Have we parsed the line table already?
+ flagsParsedLanguage = (1u << 4) ///< Have we parsed the line table already?
+ };
+
+ DISALLOW_COPY_AND_ASSIGN (CompileUnit);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_CompUnit_h_
diff --git a/include/lldb/Symbol/DWARFCallFrameInfo.h b/include/lldb/Symbol/DWARFCallFrameInfo.h
new file mode 100644
index 000000000000..13a14f8c4041
--- /dev/null
+++ b/include/lldb/Symbol/DWARFCallFrameInfo.h
@@ -0,0 +1,150 @@
+//===-- DWARFCallFrameInfo.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_DWARFCallFrameInfo_h_
+#define liblldb_DWARFCallFrameInfo_h_
+
+#include <map>
+
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Core/VMRange.h"
+#include "lldb/Core/dwarf.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// DWARFCallFrameInfo is a class which can read eh_frame and DWARF
+// Call Frame Information FDEs. It stores little information internally.
+// Only two APIs are exported - one to find the high/low pc values
+// of a function given a text address via the information in the
+// eh_frame / debug_frame, and one to generate an UnwindPlan based
+// on the FDE in the eh_frame / debug_frame section.
+
+class DWARFCallFrameInfo
+{
+public:
+
+ DWARFCallFrameInfo (ObjectFile& objfile,
+ lldb::SectionSP& section,
+ lldb::RegisterKind reg_kind,
+ bool is_eh_frame);
+
+ ~DWARFCallFrameInfo();
+
+ // Locate an AddressRange that includes the provided Address in this
+ // object's eh_frame/debug_info
+ // Returns true if a range is found to cover that address.
+ bool
+ GetAddressRange (Address addr, AddressRange &range);
+
+ // Return an UnwindPlan based on the call frame information encoded
+ // in the FDE of this DWARFCallFrameInfo section.
+ bool
+ GetUnwindPlan (Address addr, UnwindPlan& unwind_plan);
+
+ typedef RangeVector<lldb::addr_t, uint32_t> FunctionAddressAndSizeVector;
+
+ //------------------------------------------------------------------
+ // Build a vector of file address and size for all functions in this Module
+ // based on the eh_frame FDE entries.
+ //
+ // The eh_frame information can be a useful source of file address and size of
+ // the functions in a Module. Often a binary's non-exported symbols are stripped
+ // before shipping so lldb won't know the start addr / size of many functions
+ // in the Module. But the eh_frame can help to give the addresses of these
+ // stripped symbols, at least.
+ //
+ // @param[out] function_info
+ // A vector provided by the caller is filled out. May be empty if no FDEs/no eh_frame
+ // is present in this Module.
+
+ void
+ GetFunctionAddressAndSizeVector (FunctionAddressAndSizeVector &function_info);
+
+private:
+ enum
+ {
+ CFI_AUG_MAX_SIZE = 8,
+ CFI_HEADER_SIZE = 8
+ };
+
+ struct CIE
+ {
+ dw_offset_t cie_offset;
+ uint8_t version;
+ char augmentation[CFI_AUG_MAX_SIZE]; // This is typically empty or very short.
+ uint32_t code_align;
+ int32_t data_align;
+ uint32_t return_addr_reg_num;
+ dw_offset_t inst_offset; // offset of CIE instructions in mCFIData
+ uint32_t inst_length; // length of CIE instructions in mCFIData
+ uint8_t ptr_encoding;
+ lldb_private::UnwindPlan::Row initial_row;
+
+ CIE(dw_offset_t offset) : cie_offset(offset), version (-1), code_align (0),
+ data_align (0), return_addr_reg_num (LLDB_INVALID_REGNUM), inst_offset (0),
+ inst_length (0), ptr_encoding (0), initial_row() {}
+ };
+
+ typedef std::shared_ptr<CIE> CIESP;
+
+ typedef std::map<off_t, CIESP> cie_map_t;
+
+ // Start address (file address), size, offset of FDE location
+ // used for finding an FDE for a given File address; the start address field is
+ // an offset into an individual Module.
+ typedef RangeDataVector<lldb::addr_t, uint32_t, dw_offset_t> FDEEntryMap;
+
+ bool
+ IsEHFrame() const;
+
+ bool
+ GetFDEEntryByFileAddress (lldb::addr_t file_offset, FDEEntryMap::Entry& fde_entry);
+
+ void
+ GetFDEIndex ();
+
+ bool
+ FDEToUnwindPlan (uint32_t offset, Address startaddr, UnwindPlan& unwind_plan);
+
+ const CIE*
+ GetCIE(dw_offset_t cie_offset);
+
+ void
+ GetCFIData();
+
+ ObjectFile& m_objfile;
+ lldb::SectionSP m_section_sp;
+ lldb::RegisterKind m_reg_kind;
+ Flags m_flags;
+ cie_map_t m_cie_map;
+
+ DataExtractor m_cfi_data;
+ bool m_cfi_data_initialized; // only copy the section into the DE once
+
+ FDEEntryMap m_fde_index;
+ bool m_fde_index_initialized; // only scan the section for FDEs once
+ Mutex m_fde_index_mutex; // and isolate the thread that does it
+
+ bool m_is_eh_frame;
+
+ CIESP
+ ParseCIE (const uint32_t cie_offset);
+
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_DWARFCallFrameInfo_h_
diff --git a/include/lldb/Symbol/Declaration.h b/include/lldb/Symbol/Declaration.h
new file mode 100644
index 000000000000..f014571595f0
--- /dev/null
+++ b/include/lldb/Symbol/Declaration.h
@@ -0,0 +1,278 @@
+//===-- Declaration.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_Declaration_h_
+#define liblldb_Declaration_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Host/FileSpec.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Declaration Declaration.h "lldb/Symbol/Declaration.h"
+/// @brief A class that describes the declaration location of a
+/// lldb object.
+///
+/// The declarations include the file specification, line number, and
+/// the column info and can help track where functions, blocks, inlined
+/// functions, types, variables, any many other debug core objects were
+/// declared.
+//----------------------------------------------------------------------
+class Declaration
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor.
+ //------------------------------------------------------------------
+ Declaration () :
+ m_file (),
+ m_line (0)
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ ,m_column (0)
+#endif
+ {
+ }
+
+
+ //------------------------------------------------------------------
+ /// Construct with file specification, and optional line and column.
+ ///
+ /// @param[in] file_spec
+ /// The file specification that describes where this was
+ /// declared.
+ ///
+ /// @param[in] line
+ /// The line number that describes where this was declared. Set
+ /// to zero if there is no line number information.
+ ///
+ /// @param[in] column
+ /// The column number that describes where this was declared.
+ /// Set to zero if there is no column number information.
+ //------------------------------------------------------------------
+ Declaration (const FileSpec& file_spec, uint32_t line = 0, uint32_t column = 0) :
+ m_file (file_spec),
+ m_line (line)
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ ,m_column (column)
+#endif
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Construct with a reference to another Declaration object.
+ //------------------------------------------------------------------
+ Declaration (const Declaration& rhs) :
+ m_file (rhs.m_file),
+ m_line (rhs.m_line)
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ ,m_column (rhs.m_column)
+#endif
+ {
+
+ }
+
+ //------------------------------------------------------------------
+ /// Construct with a pointer to another Declaration object.
+ //------------------------------------------------------------------
+ Declaration(const Declaration* decl_ptr) :
+ m_file(),
+ m_line(0)
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ ,m_column(0)
+#endif
+ {
+ if (decl_ptr)
+ *this = *decl_ptr;
+ }
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Sets the file specification to be empty, and the line and column
+ /// to zero.
+ //------------------------------------------------------------------
+ void
+ Clear ()
+ {
+ m_file.Clear();
+ m_line= 0;
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ m_column = 0;
+#endif
+ }
+
+ //------------------------------------------------------------------
+ /// Compare two declaration objects.
+ ///
+ /// Compares the two file specifications from \a lhs and \a rhs. If
+ /// the file specifications are equal, then continue to compare the
+ /// line number and column numbers respectively.
+ ///
+ /// @param[in] lhs
+ /// The Left Hand Side const Declaration object reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const Declaration object reference.
+ ///
+ /// @return
+ /// @li -1 if lhs < rhs
+ /// @li 0 if lhs == rhs
+ /// @li 1 if lhs > rhs
+ //------------------------------------------------------------------
+ static int
+ Compare (const Declaration& lhs, const Declaration& rhs);
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, bool show_fullpaths) const;
+
+ bool
+ DumpStopContext (Stream *s, bool show_fullpaths) const;
+ //------------------------------------------------------------------
+ /// Get accessor for the declaration column number.
+ ///
+ /// @return
+ /// Non-zero indicates a valid column number, zero indicates no
+ /// column information is available.
+ //------------------------------------------------------------------
+ uint32_t
+ GetColumn () const
+ {
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ return m_column;
+#else
+ return 0;
+#endif
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor for file specification.
+ ///
+ /// @return
+ /// A reference to the file specification object.
+ //------------------------------------------------------------------
+ FileSpec&
+ GetFile ()
+ {
+ return m_file;
+ }
+
+ //------------------------------------------------------------------
+ /// Get const accessor for file specification.
+ ///
+ /// @return
+ /// A const reference to the file specification object.
+ //------------------------------------------------------------------
+ const FileSpec&
+ GetFile () const
+ {
+ return m_file;
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor for the declaration line number.
+ ///
+ /// @return
+ /// Non-zero indicates a valid line number, zero indicates no
+ /// line information is available.
+ //------------------------------------------------------------------
+ uint32_t
+ GetLine () const
+ {
+ return m_line;
+ }
+
+
+ bool
+ IsValid() const
+ {
+ return m_file && m_line != 0;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ /// The returned value does not include the bytes for any
+ /// shared string values.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ size_t
+ MemorySize () const;
+
+ //------------------------------------------------------------------
+ /// Set accessor for the declaration column number.
+ ///
+ /// @param[in] column
+ /// Non-zero indicates a valid column number, zero indicates no
+ /// column information is available.
+ //------------------------------------------------------------------
+ void
+ SetColumn (uint32_t column)
+ {
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ m_column = col;
+#endif
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the declaration file specification.
+ ///
+ /// @param[in] file_spec
+ /// The new declaration file specifciation.
+ //------------------------------------------------------------------
+ void
+ SetFile (const FileSpec& file_spec)
+ {
+ m_file = file_spec;
+ }
+
+ //------------------------------------------------------------------
+ /// Set accessor for the declaration line number.
+ ///
+ /// @param[in] line
+ /// Non-zero indicates a valid line number, zero indicates no
+ /// line information is available.
+ //------------------------------------------------------------------
+ void
+ SetLine (uint32_t line)
+ {
+ m_line = line;
+ }
+protected:
+ //------------------------------------------------------------------
+ /// Member variables.
+ //------------------------------------------------------------------
+ FileSpec m_file; ///< The file specification that points to the
+ ///< source file where the declaration occurred.
+ uint32_t m_line; ///< Non-zero values indicates a valid line number,
+ ///< zero indicates no line number information is available.
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ uint32_t m_column; ///< Non-zero values indicates a valid column number,
+ ///< zero indicates no column information is available.
+#endif
+};
+
+bool
+operator == (const Declaration &lhs, const Declaration &rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_Declaration_h_
diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h
new file mode 100644
index 000000000000..fa48dc27e123
--- /dev/null
+++ b/include/lldb/Symbol/FuncUnwinders.h
@@ -0,0 +1,106 @@
+#ifndef liblldb_FuncUnwinders_h
+#define liblldb_FuncUnwinders_h
+
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private {
+
+class UnwindTable;
+
+class FuncUnwinders
+{
+public:
+ // FuncUnwinders objects are used to track UnwindPlans for a function
+ // (named or not - really just an address range)
+
+ // We'll record three different UnwindPlans for each address range:
+ // 1. Unwinding from a call site (a valid exception throw location)
+ // This is often sourced from the eh_frame exception handling info
+ // 2. Unwinding from a non-call site (any location in the function)
+ // This is often done by analyzing the function prologue assembly
+ // langauge instructions
+ // 3. A fast unwind method for this function which only retrieves a
+ // limited set of registers necessary to walk the stack
+ // 4. An architectural default unwind plan when none of the above are
+ // available for some reason.
+
+ // Additionally, FuncUnwinds object can be asked where the prologue
+ // instructions are finished for migrating breakpoints past the
+ // stack frame setup instructions when we don't have line table information.
+
+ FuncUnwinders (lldb_private::UnwindTable& unwind_table, lldb_private::UnwindAssembly *assembly_profiler, AddressRange range);
+
+ ~FuncUnwinders ();
+
+ // current_offset is the byte offset into the function.
+ // 0 means no instructions have executed yet. -1 means the offset is unknown.
+ // On architectures where the pc points to the next instruction that will execute, this
+ // offset value will have already been decremented by 1 to stay within the bounds of the
+ // correct function body.
+ lldb::UnwindPlanSP
+ GetUnwindPlanAtCallSite (int current_offset);
+
+ lldb::UnwindPlanSP
+ GetUnwindPlanAtNonCallSite (lldb_private::Thread& thread);
+
+ lldb::UnwindPlanSP
+ GetUnwindPlanFastUnwind (lldb_private::Thread& Thread);
+
+ lldb::UnwindPlanSP
+ GetUnwindPlanArchitectureDefault (lldb_private::Thread& thread);
+
+ lldb::UnwindPlanSP
+ GetUnwindPlanArchitectureDefaultAtFunctionEntry (lldb_private::Thread& thread);
+
+ Address&
+ GetFirstNonPrologueInsn (Target& target);
+
+ const Address&
+ GetFunctionStartAddress () const;
+
+ bool
+ ContainsAddress (const Address& addr) const
+ {
+ return m_range.ContainsFileAddress (addr);
+ }
+
+ // When we're doing an unwind using the UnwindPlanAtNonCallSite and we find an
+ // impossible unwind condition, we know that the UnwindPlan is invalid. Calling
+ // this method on the FuncUnwinder will tell it to replace that UnwindPlan with
+ // the architectural default UnwindPlan so hopefully our stack walk will get past
+ // this frame.
+ void
+ InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& Thread);
+
+private:
+ UnwindTable& m_unwind_table;
+ UnwindAssembly *m_assembly_profiler;
+ AddressRange m_range;
+
+ Mutex m_mutex;
+ lldb::UnwindPlanSP m_unwind_plan_call_site_sp;
+ lldb::UnwindPlanSP m_unwind_plan_non_call_site_sp;
+ lldb::UnwindPlanSP m_unwind_plan_fast_sp;
+ lldb::UnwindPlanSP m_unwind_plan_arch_default_sp;
+ lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp;
+
+ bool m_tried_unwind_at_call_site:1,
+ m_tried_unwind_at_non_call_site:1,
+ m_tried_unwind_fast:1,
+ m_tried_unwind_arch_default:1,
+ m_tried_unwind_arch_default_at_func_entry:1;
+
+
+ Address m_first_non_prologue_insn;
+
+ DISALLOW_COPY_AND_ASSIGN (FuncUnwinders);
+
+}; // class FuncUnwinders
+
+} // namespace lldb_private
+
+
+#endif //liblldb_FuncUnwinders_h
diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h
new file mode 100644
index 000000000000..787f81c5ad27
--- /dev/null
+++ b/include/lldb/Symbol/Function.h
@@ -0,0 +1,638 @@
+//===-- Function.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_Function_h_
+#define liblldb_Function_h_
+
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/Declaration.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Core/Mangled.h"
+#include "lldb/Core/UserID.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class FunctionInfo Function.h "lldb/Symbol/Function.h"
+/// @brief A class that contains generic function information.
+///
+/// This provides generic function information that gets resused between
+/// inline functions and function types.
+//----------------------------------------------------------------------
+class FunctionInfo
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with the function method name and optional declaration
+ /// information.
+ ///
+ /// @param[in] name
+ /// A C string name for the method name for this function. This
+ /// value should not be the mangled named, but the simple method
+ /// name.
+ ///
+ /// @param[in] decl_ptr
+ /// Optional declaration information that describes where the
+ /// function was declared. This can be NULL.
+ //------------------------------------------------------------------
+ FunctionInfo (const char *name, const Declaration *decl_ptr);
+
+ //------------------------------------------------------------------
+ /// Construct with the function method name and optional declaration
+ /// information.
+ ///
+ /// @param[in] name
+ /// A name for the method name for this function. This value
+ /// should not be the mangled named, but the simple method name.
+ ///
+ /// @param[in] decl_ptr
+ /// Optional declaration information that describes where the
+ /// function was declared. This can be NULL.
+ //------------------------------------------------------------------
+ FunctionInfo (const ConstString& name, const Declaration *decl_ptr);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since classes inherit from this class.
+ //------------------------------------------------------------------
+ virtual
+ ~FunctionInfo ();
+
+ //------------------------------------------------------------------
+ /// Compare two function information objects.
+ ///
+ /// First compares the method names, and if equal, then compares
+ /// the declaration information.
+ ///
+ /// @param[in] lhs
+ /// The Left Hand Side const FunctionInfo object reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const FunctionInfo object reference.
+ ///
+ /// @return
+ /// @li -1 if lhs < rhs
+ /// @li 0 if lhs == rhs
+ /// @li 1 if lhs > rhs
+ //------------------------------------------------------------------
+ static int
+ Compare (const FunctionInfo& lhs, const FunctionInfo& rhs);
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, bool show_fullpaths) const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the declaration information.
+ ///
+ /// @return
+ /// A reference to the declaration object.
+ //------------------------------------------------------------------
+ Declaration&
+ GetDeclaration ();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the declaration information.
+ ///
+ /// @return
+ /// A const reference to the declaration object.
+ //------------------------------------------------------------------
+ const Declaration&
+ GetDeclaration () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the method name.
+ ///
+ /// @return
+ /// A const reference to the method name object.
+ //------------------------------------------------------------------
+ const ConstString&
+ GetName () const;
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ /// The returned value does not include the bytes for any
+ /// shared string values.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ virtual size_t
+ MemorySize () const;
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ ConstString m_name; ///< Function method name (not a mangled name).
+ Declaration m_declaration; ///< Information describing where this function information was defined.
+};
+
+
+//----------------------------------------------------------------------
+/// @class InlineFunctionInfo Function.h "lldb/Symbol/Function.h"
+/// @brief A class that describes information for an inlined function.
+//----------------------------------------------------------------------
+class InlineFunctionInfo : public FunctionInfo
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with the function method name, mangled name, and
+ /// optional declaration information.
+ ///
+ /// @param[in] name
+ /// A C string name for the method name for this function. This
+ /// value should not be the mangled named, but the simple method
+ /// name.
+ ///
+ /// @param[in] mangled
+ /// A C string name for the mangled name for this function. This
+ /// value can be NULL if there is no mangled information.
+ ///
+ /// @param[in] decl_ptr
+ /// Optional declaration information that describes where the
+ /// function was declared. This can be NULL.
+ ///
+ /// @param[in] call_decl_ptr
+ /// Optional calling location declaration information that
+ /// describes from where this inlined function was called.
+ //------------------------------------------------------------------
+ InlineFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr);
+
+ //------------------------------------------------------------------
+ /// Construct with the function method name, mangled name, and
+ /// optional declaration information.
+ ///
+ /// @param[in] name
+ /// A name for the method name for this function. This value
+ /// should not be the mangled named, but the simple method name.
+ ///
+ /// @param[in] mangled
+ /// A name for the mangled name for this function. This value
+ /// can be empty if there is no mangled information.
+ ///
+ /// @param[in] decl_ptr
+ /// Optional declaration information that describes where the
+ /// function was declared. This can be NULL.
+ ///
+ /// @param[in] call_decl_ptr
+ /// Optional calling location declaration information that
+ /// describes from where this inlined function was called.
+ //------------------------------------------------------------------
+ InlineFunctionInfo(const ConstString& name, const Mangled &mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~InlineFunctionInfo();
+
+ //------------------------------------------------------------------
+ /// Compare two inlined function information objects.
+ ///
+ /// First compares the FunctionInfo objects, and if equal,
+ /// compares the mangled names.
+ ///
+ /// @param[in] lhs
+ /// The Left Hand Side const InlineFunctionInfo object
+ /// reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const InlineFunctionInfo object
+ /// reference.
+ ///
+ /// @return
+ /// @li -1 if lhs < rhs
+ /// @li 0 if lhs == rhs
+ /// @li 1 if lhs > rhs
+ //------------------------------------------------------------------
+ int
+ Compare(const InlineFunctionInfo& lhs, const InlineFunctionInfo& rhs);
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump(Stream *s, bool show_fullpaths) const;
+
+ void
+ DumpStopContext (Stream *s) const;
+
+ const ConstString &
+ GetName () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the call site declaration information.
+ ///
+ /// @return
+ /// A reference to the declaration object.
+ //------------------------------------------------------------------
+ Declaration&
+ GetCallSite ();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the call site declaration information.
+ ///
+ /// @return
+ /// A const reference to the declaration object.
+ //------------------------------------------------------------------
+ const Declaration&
+ GetCallSite () const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for the mangled name object.
+ ///
+ /// @return
+ /// A reference to the mangled name object.
+ //------------------------------------------------------------------
+ Mangled&
+ GetMangled();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the mangled name object.
+ ///
+ /// @return
+ /// A const reference to the mangled name object.
+ //------------------------------------------------------------------
+ const Mangled&
+ GetMangled() const;
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ /// The returned value does not include the bytes for any
+ /// shared string values.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ virtual size_t
+ MemorySize() const;
+
+private:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ Mangled m_mangled; ///< Mangled inlined function name (can be empty if there is no mangled information).
+ Declaration m_call_decl;
+};
+
+//----------------------------------------------------------------------
+/// @class Function Function.h "lldb/Symbol/Function.h"
+/// @brief A class that describes a function.
+///
+/// Functions belong to CompileUnit objects (Function::m_comp_unit),
+/// have unique user IDs (Function::UserID), know how to reconstruct
+/// their symbol context (Function::SymbolContextScope), have a
+/// specific function type (Function::m_type_uid), have a simple
+/// method name (FunctionInfo::m_name), be declared at a specific
+/// location (FunctionInfo::m_declaration), possibly have mangled
+/// names (Function::m_mangled), an optional return type
+/// (Function::m_type), and contains lexical blocks
+/// (Function::m_blocks).
+///
+/// The function inforation is split into a few pieces:
+/// @li The concrete instance information
+/// @li The abstract information
+///
+/// The abstract information is found in the function type (Type) that
+/// describes a function information, return type and parameter types.
+///
+/// The concreate information is the address range information and
+/// specific locations for an instance of this function.
+//----------------------------------------------------------------------
+class Function :
+ public UserID,
+ public SymbolContextScope
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with a compile unit, function UID, function type UID,
+ /// optional mangled name, function type, and a section offset
+ /// based address range.
+ ///
+ /// @param[in] comp_unit
+ /// The compile unit to which this function belongs.
+ ///
+ /// @param[in] func_uid
+ /// The UID for this function. This value is provided by the
+ /// SymbolFile plug-in and can be any value that allows
+ /// the plug-in to quickly find and parse more detailed
+ /// information when and if more information is needed.
+ ///
+ /// @param[in] func_type_uid
+ /// The type UID for the function Type to allow for lazy type
+ /// parsing from the debug information.
+ ///
+ /// @param[in] mangled
+ /// The optional mangled name for this function. If empty, there
+ /// is no mangled information.
+ ///
+ /// @param[in] func_type
+ /// The optional function type. If NULL, the function type will
+ /// be parsed on demand when accessed using the
+ /// Function::GetType() function by asking the SymbolFile
+ /// plug-in to get the type for \a func_type_uid.
+ ///
+ /// @param[in] range
+ /// The section offset based address for this function.
+ //------------------------------------------------------------------
+ Function (
+ CompileUnit *comp_unit,
+ lldb::user_id_t func_uid,
+ lldb::user_id_t func_type_uid,
+ const Mangled &mangled,
+ Type * func_type,
+ const AddressRange& range);
+
+ //------------------------------------------------------------------
+ /// Construct with a compile unit, function UID, function type UID,
+ /// optional mangled name, function type, and a section offset
+ /// based address range.
+ ///
+ /// @param[in] comp_unit
+ /// The compile unit to which this function belongs.
+ ///
+ /// @param[in] func_uid
+ /// The UID for this function. This value is provided by the
+ /// SymbolFile plug-in and can be any value that allows
+ /// the plug-in to quickly find and parse more detailed
+ /// information when and if more information is needed.
+ ///
+ /// @param[in] func_type_uid
+ /// The type UID for the function Type to allow for lazy type
+ /// parsing from the debug information.
+ ///
+ /// @param[in] mangled
+ /// The optional mangled name for this function. If empty, there
+ /// is no mangled information.
+ ///
+ /// @param[in] func_type
+ /// The optional function type. If NULL, the function type will
+ /// be parsed on demand when accessed using the
+ /// Function::GetType() function by asking the SymbolFile
+ /// plug-in to get the type for \a func_type_uid.
+ ///
+ /// @param[in] range
+ /// The section offset based address for this function.
+ //------------------------------------------------------------------
+ Function (
+ CompileUnit *comp_unit,
+ lldb::user_id_t func_uid,
+ lldb::user_id_t func_type_uid,
+ const char *mangled,
+ Type * func_type,
+ const AddressRange& range);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~Function ();
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext(SymbolContext* sc);
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ();
+
+ virtual CompileUnit *
+ CalculateSymbolContextCompileUnit ();
+
+ virtual Function *
+ CalculateSymbolContextFunction ();
+
+ const AddressRange &
+ GetAddressRange()
+ {
+ return m_range;
+ }
+
+ //------------------------------------------------------------------
+ /// Find the file and line number of the source location of the start
+ /// of the function. This will use the declaration if present and fall
+ /// back on the line table if that fails. So there may NOT be a line
+ /// table entry for this source file/line combo.
+ ///
+ /// @param[out] source_file
+ /// The source file.
+ ///
+ /// @param[out] line_no
+ /// The line number.
+ //------------------------------------------------------------------
+ void
+ GetStartLineSourceInfo (FileSpec &source_file, uint32_t &line_no);
+
+ //------------------------------------------------------------------
+ /// Find the file and line number of the source location of the end
+ /// of the function.
+ ///
+ ///
+ /// @param[out] source_file
+ /// The source file.
+ ///
+ /// @param[out] line_no
+ /// The line number.
+ //------------------------------------------------------------------
+ void
+ GetEndLineSourceInfo (FileSpec &source_file, uint32_t &line_no);
+
+ //------------------------------------------------------------------
+ /// Get accessor for the block list.
+ ///
+ /// @return
+ /// The block list object that describes all lexical blocks
+ /// in the function.
+ ///
+ /// @see BlockList
+ //------------------------------------------------------------------
+ Block&
+ GetBlock (bool can_create);
+
+ //------------------------------------------------------------------
+ /// Get accessor for the compile unit that owns this function.
+ ///
+ /// @return
+ /// A compile unit object pointer.
+ //------------------------------------------------------------------
+ CompileUnit*
+ GetCompileUnit();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the compile unit that owns this function.
+ ///
+ /// @return
+ /// A const compile unit object pointer.
+ //------------------------------------------------------------------
+ const CompileUnit*
+ GetCompileUnit() const;
+
+ void
+ GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target);
+
+ //------------------------------------------------------------------
+ /// Get accessor for the frame base location.
+ ///
+ /// @return
+ /// A location expression that describes the function frame
+ /// base.
+ //------------------------------------------------------------------
+ DWARFExpression &
+ GetFrameBaseExpression()
+ {
+ return m_frame_base;
+ }
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the frame base location.
+ ///
+ /// @return
+ /// A const compile unit object pointer.
+ //------------------------------------------------------------------
+ const DWARFExpression &
+ GetFrameBaseExpression() const
+ {
+ return m_frame_base;
+ }
+
+ const ConstString &
+ GetName() const
+ {
+ return m_mangled.GetName();
+ }
+
+ const Mangled &
+ GetMangled() const
+ {
+ return m_mangled;
+ }
+
+ //------------------------------------------------------------------
+ /// Get the DeclContext for this function, if available.
+ ///
+ /// @return
+ /// The DeclContext, or NULL if none exists.
+ //------------------------------------------------------------------
+ clang::DeclContext *
+ GetClangDeclContext();
+
+ //------------------------------------------------------------------
+ /// Get accessor for the type that describes the function
+ /// return value type, and paramter types.
+ ///
+ /// @return
+ /// A type object pointer.
+ //------------------------------------------------------------------
+ Type*
+ GetType();
+
+ //------------------------------------------------------------------
+ /// Get const accessor for the type that describes the function
+ /// return value type, and paramter types.
+ ///
+ /// @return
+ /// A const type object pointer.
+ //------------------------------------------------------------------
+ const Type*
+ GetType() const;
+
+ ClangASTType
+ GetClangType ();
+
+ uint32_t
+ GetPrologueByteSize ();
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] show_context
+ /// If \b true, variables will dump their symbol context
+ /// information.
+ //------------------------------------------------------------------
+ void
+ Dump(Stream *s, bool show_context) const;
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext(Stream *s);
+
+ //------------------------------------------------------------------
+ /// Get the memory cost of this object.
+ ///
+ /// @return
+ /// The number of bytes that this object occupies in memory.
+ /// The returned value does not include the bytes for any
+ /// shared string values.
+ ///
+ /// @see ConstString::StaticMemorySize ()
+ //------------------------------------------------------------------
+ size_t
+ MemorySize () const;
+
+protected:
+
+ enum
+ {
+ flagsCalculatedPrologueSize = (1 << 0) ///< Have we already tried to calculate the prologue size?
+ };
+
+
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ CompileUnit *m_comp_unit; ///< The compile unit that owns this function.
+ lldb::user_id_t m_type_uid; ///< The user ID of for the prototype Type for this function.
+ Type * m_type; ///< The function prototype type for this function that include the function info (FunctionInfo), return type and parameters.
+ Mangled m_mangled; ///< The mangled function name if any, if empty, there is no mangled information.
+ Block m_block; ///< All lexical blocks contained in this function.
+ AddressRange m_range; ///< The function address range that covers the widest range needed to contain all blocks
+ DWARFExpression m_frame_base; ///< The frame base expression for variables that are relative to the frame pointer.
+ Flags m_flags;
+ uint32_t m_prologue_byte_size; ///< Compute the prologue size once and cache it
+private:
+ DISALLOW_COPY_AND_ASSIGN(Function);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Function_h_
diff --git a/include/lldb/Symbol/LineEntry.h b/include/lldb/Symbol/LineEntry.h
new file mode 100644
index 000000000000..d7750cd34916
--- /dev/null
+++ b/include/lldb/Symbol/LineEntry.h
@@ -0,0 +1,174 @@
+//===-- LineEntry.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_LineEntry_h_
+#define liblldb_LineEntry_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Host/FileSpec.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class LineEntry LineEntry.h "lldb/Symbol/LineEntry.h"
+/// @brief A line table entry class.
+//----------------------------------------------------------------------
+struct LineEntry
+{
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize all member variables to invalid values.
+ //------------------------------------------------------------------
+ LineEntry ();
+
+ LineEntry
+ (
+ const lldb::SectionSP &section_sp,
+ lldb::addr_t section_offset,
+ lldb::addr_t byte_size,
+ const FileSpec &file,
+ uint32_t _line,
+ uint16_t _column,
+ bool _is_start_of_statement,
+ bool _is_start_of_basic_block,
+ bool _is_prologue_end,
+ bool _is_epilogue_begin,
+ bool _is_terminal_entry
+ );
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Clears all member variables to invalid values.
+ //------------------------------------------------------------------
+ void
+ Clear ();
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] comp_unit
+ /// The compile unit object that contains the support file
+ /// list so the line entry can dump the file name (since this
+ /// object contains a file index into the support file list).
+ ///
+ /// @param[in] show_file
+ /// If \b true, display the filename with the line entry which
+ /// requires that the compile unit object \a comp_unit be a
+ /// valid pointer.
+ ///
+ /// @param[in] style
+ /// The display style for the section offset address.
+ ///
+ /// @return
+ /// Returns \b true if the address was able to be displayed
+ /// using \a style. File and load addresses may be unresolved
+ /// and it may not be possible to display a valid address value.
+ /// Returns \b false if the address was not able to be properly
+ /// dumped.
+ ///
+ /// @see Address::DumpStyle
+ //------------------------------------------------------------------
+ bool
+ Dump (Stream *s, Target *target, bool show_file, Address::DumpStyle style, Address::DumpStyle fallback_style, bool show_range) const;
+
+ bool
+ GetDescription (Stream *s,
+ lldb::DescriptionLevel level,
+ CompileUnit* cu,
+ Target *target,
+ bool show_address_only) const;
+
+ //------------------------------------------------------------------
+ /// Dumps information specific to a process that stops at this
+ /// line entry to the supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] comp_unit
+ /// The compile unit object that contains the support file
+ /// list so the line entry can dump the file name (since this
+ /// object contains a file index into the support file list).
+ ///
+ /// @return
+ /// Returns \b true if the file and line were properly dumped,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ DumpStopContext (Stream *s, bool show_fullpaths) const;
+
+ //------------------------------------------------------------------
+ /// Check if a line entry object is valid.
+ ///
+ /// @return
+ /// Returns \b true if the line entry contains a valid section
+ /// offset address, file index, and line number, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsValid () const;
+
+ //------------------------------------------------------------------
+ /// Compare two LineEntry objects.
+ ///
+ /// @param[in] lhs
+ /// The Left Hand Side const LineEntry object reference.
+ ///
+ /// @param[in] rhs
+ /// The Right Hand Side const LineEntry object reference.
+ ///
+ /// @return
+ /// @li -1 if lhs < rhs
+ /// @li 0 if lhs == rhs
+ /// @li 1 if lhs > rhs
+ //------------------------------------------------------------------
+ static int
+ Compare (const LineEntry& lhs, const LineEntry& rhs);
+
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ AddressRange range; ///< The section offset address range for this line entry.
+ FileSpec file;
+ uint32_t line; ///< The source line number, or zero if there is no line number information.
+ uint16_t column; ///< The column number of the source line, or zero if there is no column information.
+ uint16_t is_start_of_statement:1, ///< Indicates this entry is the beginning of a statement.
+ is_start_of_basic_block:1, ///< Indicates this entry is the beginning of a basic block.
+ is_prologue_end:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an entry breakpoint of a function.
+ is_epilogue_begin:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an exit breakpoint of a function.
+ is_terminal_entry:1; ///< Indicates this entry is that of the first byte after the end of a sequence of target machine instructions.
+};
+
+//------------------------------------------------------------------
+/// Less than operator.
+///
+/// @param[in] lhs
+/// The Left Hand Side const LineEntry object reference.
+///
+/// @param[in] rhs
+/// The Right Hand Side const LineEntry object reference.
+///
+/// @return
+/// Returns \b true if lhs < rhs, false otherwise.
+//------------------------------------------------------------------
+bool operator<(const LineEntry& lhs, const LineEntry& rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_LineEntry_h_
diff --git a/include/lldb/Symbol/LineTable.h b/include/lldb/Symbol/LineTable.h
new file mode 100644
index 000000000000..477c8455ded8
--- /dev/null
+++ b/include/lldb/Symbol/LineTable.h
@@ -0,0 +1,422 @@
+//===-- LineTable.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_LineTable_h_
+#define liblldb_LineTable_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Symbol/LineEntry.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/RangeMap.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class LineSequence LineTable.h "lldb/Symbol/LineTable.h"
+/// @brief An abstract base class used during symbol table creation.
+//----------------------------------------------------------------------
+class LineSequence
+{
+public:
+ LineSequence ();
+
+ virtual
+ ~LineSequence() {}
+
+ virtual void
+ Clear() = 0;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (LineSequence);
+};
+
+//----------------------------------------------------------------------
+/// @class LineTable LineTable.h "lldb/Symbol/LineTable.h"
+/// @brief A line table class.
+//----------------------------------------------------------------------
+class LineTable
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with compile unit.
+ ///
+ /// @param[in] comp_unit
+ /// The compile unit to which this line table belongs.
+ //------------------------------------------------------------------
+ LineTable (CompileUnit* comp_unit);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~LineTable ();
+
+ //------------------------------------------------------------------
+ /// Adds a new line entry to this line table.
+ ///
+ /// All line entries are maintained in file address order.
+ ///
+ /// @param[in] line_entry
+ /// A const reference to a new line_entry to add to this line
+ /// table.
+ ///
+ /// @see Address::DumpStyle
+ //------------------------------------------------------------------
+// void
+// AddLineEntry (const LineEntry& line_entry);
+
+ // Called when you can't guarantee the addresses are in increasing order
+ void
+ InsertLineEntry (lldb::addr_t file_addr,
+ uint32_t line,
+ uint16_t column,
+ uint16_t file_idx,
+ bool is_start_of_statement,
+ bool is_start_of_basic_block,
+ bool is_prologue_end,
+ bool is_epilogue_begin,
+ bool is_terminal_entry);
+
+ // Used to instantiate the LineSequence helper classw
+ LineSequence*
+ CreateLineSequenceContainer ();
+
+ // Append an entry to a caller-provided collection that will later be
+ // inserted in this line table.
+ void
+ AppendLineEntryToSequence (LineSequence* sequence,
+ lldb::addr_t file_addr,
+ uint32_t line,
+ uint16_t column,
+ uint16_t file_idx,
+ bool is_start_of_statement,
+ bool is_start_of_basic_block,
+ bool is_prologue_end,
+ bool is_epilogue_begin,
+ bool is_terminal_entry);
+
+ // Insert a sequence of entries into this line table.
+ void
+ InsertSequence (LineSequence* sequence);
+
+ //------------------------------------------------------------------
+ /// Dump all line entries in this line table to the stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] style
+ /// The display style for the address.
+ ///
+ /// @see Address::DumpStyle
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, Target *target,
+ Address::DumpStyle style,
+ Address::DumpStyle fallback_style,
+ bool show_line_ranges);
+
+ void
+ GetDescription (Stream *s,
+ Target *target,
+ lldb::DescriptionLevel level);
+
+ //------------------------------------------------------------------
+ /// Find a line entry that contains the section offset address \a
+ /// so_addr.
+ ///
+ /// @param[in] so_addr
+ /// A section offset address object containing the address we
+ /// are searching for.
+ ///
+ /// @param[out] line_entry
+ /// A copy of the line entry that was found if \b true is
+ /// returned, otherwise \a entry is left unmodified.
+ ///
+ /// @param[out] index_ptr
+ /// A pointer to a 32 bit integer that will get the actual line
+ /// entry index if it is not NULL.
+ ///
+ /// @return
+ /// Returns \b true if \a so_addr is contained in a line entry
+ /// in this line table, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ FindLineEntryByAddress (const Address &so_addr, LineEntry& line_entry, uint32_t *index_ptr = NULL);
+
+ //------------------------------------------------------------------
+ /// Find a line entry index that has a matching file index and
+ /// source line number.
+ ///
+ /// Finds the next line entry that has a matching \a file_idx and
+ /// source line number \a line starting at the \a start_idx entries
+ /// into the line entry collection.
+ ///
+ /// @param[in] start_idx
+ /// The number of entries to skip when starting the search.
+ ///
+ /// @param[out] file_idx
+ /// The file index to search for that should be found prior
+ /// to calling this function using the following functions:
+ /// CompileUnit::GetSupportFiles()
+ /// FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const
+ ///
+ /// @param[in] line
+ /// The source line to match.
+ ///
+ /// @param[in] exact
+ /// If true, match only if you find a line entry exactly matching \a line.
+ /// If false, return the closest line entry greater than \a line.
+ ///
+ /// @param[out] line_entry
+ /// A reference to a line entry object that will get a copy of
+ /// the line entry if \b true is returned, otherwise \a
+ /// line_entry is left untouched.
+ ///
+ /// @return
+ /// Returns \b true if a matching line entry is found in this
+ /// line table, \b false otherwise.
+ ///
+ /// @see CompileUnit::GetSupportFiles()
+ /// @see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const
+ //------------------------------------------------------------------
+ uint32_t
+ FindLineEntryIndexByFileIndex (uint32_t start_idx,
+ uint32_t file_idx,
+ uint32_t line,
+ bool exact,
+ LineEntry* line_entry_ptr);
+
+ uint32_t
+ FindLineEntryIndexByFileIndex (uint32_t start_idx,
+ const std::vector<uint32_t> &file_indexes,
+ uint32_t line,
+ bool exact,
+ LineEntry* line_entry_ptr);
+
+ size_t
+ FineLineEntriesForFileIndex (uint32_t file_idx,
+ bool append,
+ SymbolContextList &sc_list);
+
+ //------------------------------------------------------------------
+ /// Get the line entry from the line table at index \a idx.
+ ///
+ /// @param[in] idx
+ /// An index into the line table entry collection.
+ ///
+ /// @return
+ /// A valid line entry if \a idx is a valid index, or an invalid
+ /// line entry if \a idx is not valid.
+ ///
+ /// @see LineTable::GetSize()
+ /// @see LineEntry::IsValid() const
+ //------------------------------------------------------------------
+ bool
+ GetLineEntryAtIndex(uint32_t idx, LineEntry& line_entry);
+
+ //------------------------------------------------------------------
+ /// Gets the size of the line table in number of line table entries.
+ ///
+ /// @return
+ /// The number of line table entries in this line table.
+ //------------------------------------------------------------------
+ uint32_t
+ GetSize () const;
+
+ typedef lldb_private::RangeArray<lldb::addr_t, lldb::addr_t, 32> FileAddressRanges;
+
+ //------------------------------------------------------------------
+ /// Gets all contiguous file address ranges for the entire line table.
+ ///
+ /// @param[out] file_ranges
+ /// A collection of file address ranges that will be filled in
+ /// by this function.
+ ///
+ /// @param[out] append
+ /// If \b true, then append to \a file_ranges, otherwise clear
+ /// \a file_ranges prior to adding any ranges.
+ ///
+ /// @return
+ /// The number of address ranges added to \a file_ranges
+ //------------------------------------------------------------------
+ size_t
+ GetContiguousFileAddressRanges (FileAddressRanges &file_ranges, bool append);
+
+ //------------------------------------------------------------------
+ /// Given a file range link map, relink the current line table
+ /// and return a fixed up line table.
+ ///
+ /// @param[out] file_range_map
+ /// A collection of file ranges that maps to new file ranges
+ /// that will be used when linking the line table.
+ ///
+ /// @return
+ /// A new line table if at least one line table entry was able
+ /// to be mapped.
+ //------------------------------------------------------------------
+ typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
+
+ LineTable *
+ LinkLineTable (const FileRangeMap &file_range_map);
+
+protected:
+
+ struct Entry
+ {
+ Entry () :
+ file_addr (LLDB_INVALID_ADDRESS),
+ line (0),
+ column (0),
+ file_idx (0),
+ is_start_of_statement (false),
+ is_start_of_basic_block (false),
+ is_prologue_end (false),
+ is_epilogue_begin (false),
+ is_terminal_entry (false)
+ {
+ }
+
+ Entry ( lldb::addr_t _file_addr,
+ uint32_t _line,
+ uint16_t _column,
+ uint16_t _file_idx,
+ bool _is_start_of_statement,
+ bool _is_start_of_basic_block,
+ bool _is_prologue_end,
+ bool _is_epilogue_begin,
+ bool _is_terminal_entry) :
+ file_addr (_file_addr),
+ line (_line),
+ column (_column),
+ file_idx (_file_idx),
+ is_start_of_statement (_is_start_of_statement),
+ is_start_of_basic_block (_is_start_of_basic_block),
+ is_prologue_end (_is_prologue_end),
+ is_epilogue_begin (_is_epilogue_begin),
+ is_terminal_entry (_is_terminal_entry)
+ {
+ }
+
+ int
+ bsearch_compare (const void *key, const void *arrmem);
+
+ void
+ Clear ()
+ {
+ file_addr = LLDB_INVALID_ADDRESS;
+ line = 0;
+ column = 0;
+ file_idx = 0;
+ is_start_of_statement = false;
+ is_start_of_basic_block = false;
+ is_prologue_end = false;
+ is_epilogue_begin = false;
+ is_terminal_entry = false;
+ }
+
+ static int
+ Compare (const Entry& lhs, const Entry& rhs)
+ {
+ // Compare the sections before calling
+ #define SCALAR_COMPARE(a,b) if (a < b) return -1; if (a > b) return +1
+ SCALAR_COMPARE (lhs.file_addr, rhs.file_addr);
+ SCALAR_COMPARE (lhs.line, rhs.line);
+ SCALAR_COMPARE (lhs.column, rhs.column);
+ SCALAR_COMPARE (lhs.is_start_of_statement, rhs.is_start_of_statement);
+ SCALAR_COMPARE (lhs.is_start_of_basic_block, rhs.is_start_of_basic_block);
+ // rhs and lhs reversed on purpose below.
+ SCALAR_COMPARE (rhs.is_prologue_end, lhs.is_prologue_end);
+ SCALAR_COMPARE (lhs.is_epilogue_begin, rhs.is_epilogue_begin);
+ // rhs and lhs reversed on purpose below.
+ SCALAR_COMPARE (rhs.is_terminal_entry, lhs.is_terminal_entry);
+ SCALAR_COMPARE (lhs.file_idx, rhs.file_idx);
+ #undef SCALAR_COMPARE
+ return 0;
+ }
+
+
+ class LessThanBinaryPredicate
+ {
+ public:
+ LessThanBinaryPredicate(LineTable *line_table);
+ bool operator() (const LineTable::Entry&, const LineTable::Entry&) const;
+ protected:
+ LineTable *m_line_table;
+ };
+
+ static bool EntryAddressLessThan (const Entry& lhs, const Entry& rhs)
+ {
+ return lhs.file_addr < rhs.file_addr;
+ }
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ lldb::addr_t file_addr; ///< The file address for this line entry
+ uint32_t line; ///< The source line number, or zero if there is no line number information.
+ uint16_t column; ///< The column number of the source line, or zero if there is no column information.
+ uint16_t file_idx:11, ///< The file index into CompileUnit's file table, or zero if there is no file information.
+ is_start_of_statement:1, ///< Indicates this entry is the beginning of a statement.
+ is_start_of_basic_block:1, ///< Indicates this entry is the beginning of a basic block.
+ is_prologue_end:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an entry breakpoint of a function.
+ is_epilogue_begin:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an exit breakpoint of a function.
+ is_terminal_entry:1; ///< Indicates this entry is that of the first byte after the end of a sequence of target machine instructions.
+ };
+
+ struct EntrySearchInfo
+ {
+ LineTable* line_table;
+ lldb_private::Section *a_section;
+ Entry *a_entry;
+ };
+
+ //------------------------------------------------------------------
+ // Types
+ //------------------------------------------------------------------
+ typedef std::vector<lldb_private::Section*> section_collection; ///< The collection type for the sections.
+ typedef std::vector<Entry> entry_collection; ///< The collection type for the line entries.
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ CompileUnit* m_comp_unit; ///< The compile unit that this line table belongs to.
+ entry_collection m_entries; ///< The collection of line entries in this line table.
+
+ //------------------------------------------------------------------
+ // Helper class
+ //------------------------------------------------------------------
+ class LineSequenceImpl : public LineSequence
+ {
+ public:
+ LineSequenceImpl() :
+ LineSequence()
+ {}
+
+ virtual
+ ~LineSequenceImpl()
+ {}
+
+ virtual void
+ Clear();
+
+ entry_collection m_entries; ///< The collection of line entries in this sequence.
+ };
+
+ bool
+ ConvertEntryAtIndexToLineEntry (uint32_t idx, LineEntry &line_entry);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (LineTable);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_LineTable_h_
diff --git a/include/lldb/Symbol/ObjectContainer.h b/include/lldb/Symbol/ObjectContainer.h
new file mode 100644
index 000000000000..7fb686245057
--- /dev/null
+++ b/include/lldb/Symbol/ObjectContainer.h
@@ -0,0 +1,236 @@
+//===-- ObjectContainer.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_ObjectContainer_h_
+#define liblldb_ObjectContainer_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Host/Endian.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ObjectContainer ObjectContainer.h "lldb/Symbol/ObjectContainer.h"
+/// @brief A plug-in interface definition class for object containers.
+///
+/// Object containers contain object files from one or more
+/// architectures, and also can contain one or more named objects.
+///
+/// Typical object containers are static libraries (.a files) that
+/// contain multiple named object files, and universal files that contain
+/// multiple architectures.
+//----------------------------------------------------------------------
+class ObjectContainer :
+ public PluginInterface,
+ public ModuleChild
+{
+public:
+ //------------------------------------------------------------------
+ /// Construct with a parent module, offset, and header data.
+ ///
+ /// Object files belong to modules and a valid module must be
+ /// supplied upon construction. The at an offset within a file for
+ /// objects that contain more than one architecture or object.
+ //------------------------------------------------------------------
+ ObjectContainer (const lldb::ModuleSP &module_sp,
+ const FileSpec *file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset) :
+ ModuleChild (module_sp),
+ m_file (), // This file can be different than the module's file spec
+ m_offset (file_offset),
+ m_length (length),
+ m_data ()
+ {
+ if (file)
+ m_file = *file;
+ if (data_sp)
+ m_data.SetData (data_sp, data_offset, length);
+ }
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be
+ /// inherited from by the plug-in instance.
+ //------------------------------------------------------------------
+ virtual
+ ~ObjectContainer()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the current contents of this object
+ /// to the supplied stream \a s. The dumping should include the
+ /// section list if it has been parsed, and the symbol table
+ /// if it has been parsed.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ virtual void
+ Dump (Stream *s) const = 0;
+
+ //------------------------------------------------------------------
+ /// Gets the architecture given an index.
+ ///
+ /// Copies the architecture specification for index \a idx.
+ ///
+ /// @param[in] idx
+ /// The architecture index to extract.
+ ///
+ /// @param[out] arch
+ /// A architecture object that will be filled in if \a idx is a
+ /// architecture valid index.
+ ///
+ /// @return
+ /// Returns \b true if \a idx is valid and \a arch has been
+ /// filled in, \b false otherwise.
+ ///
+ /// @see ObjectContainer::GetNumArchitectures() const
+ //------------------------------------------------------------------
+ virtual bool
+ GetArchitectureAtIndex (uint32_t idx, ArchSpec& arch) const
+ {
+ return false;
+ }
+
+ //------------------------------------------------------------------
+ /// Returns the offset into a file at which this object resides.
+ ///
+ /// Some files contain many object files, and this function allows
+ /// access to an object's offset within the file.
+ ///
+ /// @return
+ /// The offset in bytes into the file. Defaults to zero for
+ /// simple object files that a represented by an entire file.
+ //------------------------------------------------------------------
+ virtual lldb::addr_t
+ GetOffset () const
+ { return m_offset; }
+
+ virtual lldb::addr_t
+ GetByteSize () const
+ { return m_length; }
+
+ //------------------------------------------------------------------
+ /// Get the number of objects within this object file (archives).
+ ///
+ /// @return
+ /// Zero for object files that are not archives, or the number
+ /// of objects contained in the archive.
+ //------------------------------------------------------------------
+ virtual size_t
+ GetNumObjects () const
+ { return 0; }
+
+ //------------------------------------------------------------------
+ /// Get the number of architectures in this object file.
+ ///
+ /// The default implementation returns 1 as for object files that
+ /// contain a single architecture. ObjectContainer instances that
+ /// contain more than one architecture should override this function
+ /// and return an appropriate value.
+ ///
+ /// @return
+ /// The number of architectures contained in this object file.
+ //------------------------------------------------------------------
+ virtual size_t
+ GetNumArchitectures () const
+ { return 0; }
+
+ //------------------------------------------------------------------
+ /// Attempts to parse the object header.
+ ///
+ /// This function is used as a test to see if a given plug-in
+ /// instance can parse the header data already contained in
+ /// ObjectContainer::m_data. If an object file parser does not
+ /// recognize that magic bytes in a header, false should be returned
+ /// and the next plug-in can attempt to parse an object file.
+ ///
+ /// @return
+ /// Returns \b true if the header was parsed succesfully, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ ParseHeader () = 0;
+
+ //------------------------------------------------------------------
+ /// Selects an architecture in an object file.
+ ///
+ /// Object files that contain a single architecture should verify
+ /// that the specified \a arch matches the architecture in in
+ /// object file and return \b true or \b false accordingly.
+ ///
+ /// Object files that contain more than one architecture should
+ /// attempt to select that architecture, and if successful, clear
+ /// out any previous state from any previously selected architecture
+ /// and prepare to return information for the new architecture.
+ ///
+ /// @return
+ /// Returns a pointer to the object file of the requested \a
+ /// arch and optional \a name. Returns NULL of no such object
+ /// file exists in the container.
+ //------------------------------------------------------------------
+ virtual lldb::ObjectFileSP
+ GetObjectFile (const FileSpec *file) = 0;
+
+ virtual bool
+ ObjectAtIndexIsContainer (uint32_t object_idx)
+ {
+ return false;
+ }
+
+ virtual ObjectFile *
+ GetObjectFileAtIndex (uint32_t object_idx)
+ {
+ return NULL;
+ }
+
+ virtual ObjectContainer *
+ GetObjectContainerAtIndex (uint32_t object_idx)
+ {
+ return NULL;
+ }
+
+ virtual const char *
+ GetObjectNameAtIndex (uint32_t object_idx) const
+ {
+ return NULL;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ FileSpec m_file; ///< The file that represents this container objects (which can be different from the module's file).
+ lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory
+ lldb::addr_t m_length; ///< The size in bytes if known (can be zero).
+ DataExtractor m_data; ///< The data for this object file so things can be parsed lazily.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (ObjectContainer);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ObjectContainer_h_
diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h
new file mode 100644
index 000000000000..8934c31bb988
--- /dev/null
+++ b/include/lldb/Symbol/ObjectFile.h
@@ -0,0 +1,706 @@
+//===-- ObjectFile.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_ObjectFile_h_
+#define liblldb_ObjectFile_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/Symtab.h"
+#include "lldb/Symbol/UnwindTable.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class ObjectFile ObjectFile.h "lldb/Symbol/ObjectFile.h"
+/// @brief A plug-in interface definition class for object file parsers.
+///
+/// Object files belong to Module objects and know how to extract
+/// information from executable, shared library, and object (.o) files
+/// used by operating system runtime. The symbol table and section list
+/// for an object file.
+///
+/// Object files can be represented by the entire file, or by part of a
+/// file. Examples of object files that are part of a file include
+/// object files that contain information for multiple architectures in
+/// the same file, or archive files that contain multiple objects
+/// (ranlib archives) (possibly for multiple architectures as well).
+///
+/// Object archive files (e.g. ranlib archives) can contain
+/// multiple .o (object) files that must be selected by index or by name.
+/// The number of objects that an ObjectFile contains can be determined
+/// using the ObjectFile::GetNumObjects() const
+/// function, and followed by a call to
+/// ObjectFile::SelectObjectAtIndex (uint32_t) to change the currently
+/// selected object. Objects can also be selected by name using the
+/// ObjectFile::SelectObject(const char *) function.
+///
+/// Once an architecture is selected (and an object is selected for
+/// for archives), the object file information can be extracted from
+/// this abstract class.
+//----------------------------------------------------------------------
+class ObjectFile:
+ public std::enable_shared_from_this<ObjectFile>,
+ public PluginInterface,
+ public ModuleChild
+{
+friend class lldb_private::Module;
+
+public:
+ typedef enum
+ {
+ eTypeInvalid = 0,
+ eTypeCoreFile, /// A core file that has a checkpoint of a program's execution state
+ eTypeExecutable, /// A normal executable
+ eTypeDebugInfo, /// An object file that contains only debug information
+ eTypeDynamicLinker, /// The platform's dynamic linker executable
+ eTypeObjectFile, /// An intermediate object file
+ eTypeSharedLibrary, /// A shared library that can be used during execution
+ eTypeStubLibrary, /// A library that can be linked against but not used for execution
+ eTypeUnknown
+ } Type;
+
+ typedef enum
+ {
+ eStrataInvalid = 0,
+ eStrataUnknown,
+ eStrataUser,
+ eStrataKernel,
+ eStrataRawImage
+ } Strata;
+
+ //------------------------------------------------------------------
+ /// Construct with a parent module, offset, and header data.
+ ///
+ /// Object files belong to modules and a valid module must be
+ /// supplied upon construction. The at an offset within a file for
+ /// objects that contain more than one architecture or object.
+ //------------------------------------------------------------------
+ ObjectFile (const lldb::ModuleSP &module_sp,
+ const FileSpec *file_spec_ptr,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset);
+
+ ObjectFile (const lldb::ModuleSP &module_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr,
+ lldb::DataBufferSP& data_sp);
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class is designed to be
+ /// inherited from by the plug-in instance.
+ //------------------------------------------------------------------
+ virtual
+ ~ObjectFile();
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the current contents of this object
+ /// to the supplied stream \a s. The dumping should include the
+ /// section list if it has been parsed, and the symbol table
+ /// if it has been parsed.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ virtual void
+ Dump (Stream *s) = 0;
+
+ //------------------------------------------------------------------
+ /// Find a ObjectFile plug-in that can parse \a file_spec.
+ ///
+ /// Scans all loaded plug-in interfaces that implement versions of
+ /// the ObjectFile plug-in interface and returns the first
+ /// instance that can parse the file.
+ ///
+ /// @param[in] module
+ /// The parent module that owns this object file.
+ ///
+ /// @param[in] file_spec
+ /// A file specification that indicates which file to use as the
+ /// object file.
+ ///
+ /// @param[in] file_offset
+ /// The offset into the file at which to start parsing the
+ /// object. This is for files that contain multiple
+ /// architectures or objects.
+ ///
+ /// @param[in] file_size
+ /// The size of the current object file if it can be determined
+ /// or if it is known. This can be zero.
+ ///
+ /// @see ObjectFile::ParseHeader()
+ //------------------------------------------------------------------
+ static lldb::ObjectFileSP
+ FindPlugin (const lldb::ModuleSP &module_sp,
+ const FileSpec* file_spec,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t &data_offset);
+
+ //------------------------------------------------------------------
+ /// Find a ObjectFile plug-in that can parse a file in memory.
+ ///
+ /// Scans all loaded plug-in interfaces that implement versions of
+ /// the ObjectFile plug-in interface and returns the first
+ /// instance that can parse the file.
+ ///
+ /// @param[in] module
+ /// The parent module that owns this object file.
+ ///
+ /// @param[in] process_sp
+ /// A shared pointer to the process whose memory space contains
+ /// an object file. This will be stored as a std::weak_ptr.
+ ///
+ /// @param[in] header_addr
+ /// The address of the header for the object file in memory.
+ //------------------------------------------------------------------
+ static lldb::ObjectFileSP
+ FindPlugin (const lldb::ModuleSP &module_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr,
+ lldb::DataBufferSP &file_data_sp);
+
+
+ static size_t
+ GetModuleSpecifications (const FileSpec &file,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ ModuleSpecList &specs);
+
+ static size_t
+ GetModuleSpecifications (const lldb_private::FileSpec& file,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ lldb_private::ModuleSpecList &specs);
+ //------------------------------------------------------------------
+ /// Split a path into a file path with object name.
+ ///
+ /// For paths like "/tmp/foo.a(bar.o)" we often need to split a path
+ /// up into the actual path name and into the object name so we can
+ /// make a valid object file from it.
+ ///
+ /// @param[in] path_with_object
+ /// A path that might contain an archive path with a .o file
+ /// specified in parens in the basename of the path.
+ ///
+ /// @param[out] archive_file
+ /// If \b true is returned, \a file_spec will be filled in with
+ /// the path to the archive.
+ ///
+ /// @param[out] archive_object
+ /// If \b true is returned, \a object will be filled in with
+ /// the name of the object inside the archive.
+ ///
+ /// @return
+ /// \b true if the path matches the pattern of archive + object
+ /// and \a archive_file and \a archive_object are modified,
+ /// \b false otherwise and \a archive_file and \a archive_object
+ /// are guaranteed to be remain unchanged.
+ //------------------------------------------------------------------
+ static bool
+ SplitArchivePathWithObject (const char *path_with_object,
+ lldb_private::FileSpec &archive_file,
+ lldb_private::ConstString &archive_object,
+ bool must_exist);
+
+ //------------------------------------------------------------------
+ /// Gets the address size in bytes for the current object file.
+ ///
+ /// @return
+ /// The size of an address in bytes for the currently selected
+ /// architecture (and object for archives). Returns zero if no
+ /// architecture or object has been selected.
+ //------------------------------------------------------------------
+ virtual uint32_t
+ GetAddressByteSize () const = 0;
+
+ //------------------------------------------------------------------
+ /// Get the address type given a file address in an object file.
+ ///
+ /// Many binary file formats know what kinds
+ /// This is primarily for ARM binaries, though it can be applied to
+ /// any executable file format that supports different opcode types
+ /// within the same binary. ARM binaries support having both ARM and
+ /// Thumb within the same executable container. We need to be able
+ /// to get
+ /// @return
+ /// The size of an address in bytes for the currently selected
+ /// architecture (and object for archives). Returns zero if no
+ /// architecture or object has been selected.
+ //------------------------------------------------------------------
+ virtual lldb::AddressClass
+ GetAddressClass (lldb::addr_t file_addr);
+
+ //------------------------------------------------------------------
+ /// Extract the dependent modules from an object file.
+ ///
+ /// If an object file has information about which other images it
+ /// depends on (such as shared libraries), this function will
+ /// provide the list. Since many executables or shared libraries
+ /// may depend on the same files,
+ /// FileSpecList::AppendIfUnique(const FileSpec &) should be
+ /// used to make sure any files that are added are not already in
+ /// the list.
+ ///
+ /// @param[out] file_list
+ /// A list of file specification objects that gets dependent
+ /// files appended to.
+ ///
+ /// @return
+ /// The number of new files that were appended to \a file_list.
+ ///
+ /// @see FileSpecList::AppendIfUnique(const FileSpec &)
+ //------------------------------------------------------------------
+ virtual uint32_t
+ GetDependentModules (FileSpecList& file_list) = 0;
+
+ //------------------------------------------------------------------
+ /// Tells whether this object file is capable of being the main executable
+ /// for a process.
+ ///
+ /// @return
+ /// \b true if it is, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ IsExecutable () const = 0;
+
+ //------------------------------------------------------------------
+ /// Returns the offset into a file at which this object resides.
+ ///
+ /// Some files contain many object files, and this function allows
+ /// access to an object's offset within the file.
+ ///
+ /// @return
+ /// The offset in bytes into the file. Defaults to zero for
+ /// simple object files that a represented by an entire file.
+ //------------------------------------------------------------------
+ virtual lldb::addr_t
+ GetFileOffset () const
+ { return m_file_offset; }
+
+ virtual lldb::addr_t
+ GetByteSize () const
+ { return m_length; }
+
+ //------------------------------------------------------------------
+ /// Get accessor to the object file specification.
+ ///
+ /// @return
+ /// The file specification object pointer if there is one, or
+ /// NULL if this object is only from memory.
+ //------------------------------------------------------------------
+ virtual FileSpec&
+ GetFileSpec() { return m_file; }
+
+ //------------------------------------------------------------------
+ /// Get const accessor to the object file specification.
+ ///
+ /// @return
+ /// The const file specification object pointer if there is one,
+ /// or NULL if this object is only from memory.
+ //------------------------------------------------------------------
+ virtual const FileSpec&
+ GetFileSpec() const { return m_file; }
+
+ //------------------------------------------------------------------
+ /// Get the name of the cpu, vendor and OS for this object file.
+ ///
+ /// This value is a string that represents the target triple where
+ /// the cpu type, the vendor and the OS are encoded into a string.
+ ///
+ /// @param[out] target_triple
+ /// The string value of the target triple.
+ ///
+ /// @return
+ /// \b True if the target triple was able to be computed, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ GetArchitecture (ArchSpec &arch) = 0;
+
+ //------------------------------------------------------------------
+ /// Gets the section list for the currently selected architecture
+ /// (and object for archives).
+ ///
+ /// Section list parsing can be deferred by ObjectFile instances
+ /// until this accessor is called the first time.
+ ///
+ /// @return
+ /// The list of sections contained in this object file.
+ //------------------------------------------------------------------
+ virtual SectionList *
+ GetSectionList ();
+
+ virtual void
+ CreateSections (SectionList &unified_section_list) = 0;
+
+ //------------------------------------------------------------------
+ /// Gets the symbol table for the currently selected architecture
+ /// (and object for archives).
+ ///
+ /// Symbol table parsing can be deferred by ObjectFile instances
+ /// until this accessor is called the first time.
+ ///
+ /// @return
+ /// The symbol table for this object file.
+ //------------------------------------------------------------------
+ virtual Symtab *
+ GetSymtab () = 0;
+
+ //------------------------------------------------------------------
+ /// Detect if this object file has been stripped of local symbols.
+ ///
+ /// @return
+ /// Return \b true if the object file has been stripped of local
+ /// symbols.
+ //------------------------------------------------------------------
+ virtual bool
+ IsStripped () = 0;
+
+ //------------------------------------------------------------------
+ /// Frees the symbol table.
+ ///
+ /// This function should only be used when an object file is
+ ///
+ /// @param[in] flags
+ /// eSymtabFromUnifiedSectionList: Whether to clear symbol table
+ /// for unified module section list, or object file.
+ ///
+ /// @return
+ /// The symbol table for this object file.
+ //------------------------------------------------------------------
+ virtual void
+ ClearSymtab ();
+
+ //------------------------------------------------------------------
+ /// Gets the UUID for this object file.
+ ///
+ /// If the object file format contains a UUID, the value should be
+ /// returned. Else ObjectFile instances should return the MD5
+ /// checksum of all of the bytes for the object file (or memory for
+ /// memory based object files).
+ ///
+ /// @return
+ /// Returns \b true if a UUID was successfully extracted into
+ /// \a uuid, \b false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ GetUUID (lldb_private::UUID* uuid) = 0;
+
+ //------------------------------------------------------------------
+ /// Gets the symbol file spec list for this object file.
+ ///
+ /// If the object file format contains a debug symbol file link,
+ /// the values will be return in the FileSpecList.
+ ///
+ /// @return
+ /// Returns filespeclist.
+ //------------------------------------------------------------------
+ virtual lldb_private::FileSpecList
+ GetDebugSymbolFilePaths()
+ {
+ return FileSpecList();
+ }
+
+ //------------------------------------------------------------------
+ /// Gets whether endian swapping should occur when extracting data
+ /// from this object file.
+ ///
+ /// @return
+ /// Returns \b true if endian swapping is needed, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ virtual lldb::ByteOrder
+ GetByteOrder () const = 0;
+
+ //------------------------------------------------------------------
+ /// Attempts to parse the object header.
+ ///
+ /// This function is used as a test to see if a given plug-in
+ /// instance can parse the header data already contained in
+ /// ObjectFile::m_data. If an object file parser does not
+ /// recognize that magic bytes in a header, false should be returned
+ /// and the next plug-in can attempt to parse an object file.
+ ///
+ /// @return
+ /// Returns \b true if the header was parsed succesfully, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ virtual bool
+ ParseHeader () = 0;
+
+ //------------------------------------------------------------------
+ /// Returns a reference to the UnwindTable for this ObjectFile
+ ///
+ /// The UnwindTable contains FuncUnwinders objects for any function in
+ /// this ObjectFile. If a FuncUnwinders object hasn't been created yet
+ /// (i.e. the function has yet to be unwound in a stack walk), it
+ /// will be created when requested. Specifically, we do not create
+ /// FuncUnwinders objects for functions until they are needed.
+ ///
+ /// @return
+ /// Returns the unwind table for this object file.
+ //------------------------------------------------------------------
+ virtual lldb_private::UnwindTable&
+ GetUnwindTable () { return m_unwind_table; }
+
+ //------------------------------------------------------------------
+ /// Similar to Process::GetImageInfoAddress().
+ ///
+ /// Some platforms embed auxiliary structures useful to debuggers in the
+ /// address space of the inferior process. This method returns the address
+ /// of such a structure if the information can be resolved via entries in
+ /// the object file. ELF, for example, provides a means to hook into the
+ /// runtime linker so that a debugger may monitor the loading and unloading
+ /// of shared libraries.
+ ///
+ /// @return
+ /// The address of any auxiliary tables, or an invalid address if this
+ /// object file format does not support or contain such information.
+ virtual lldb_private::Address
+ GetImageInfoAddress () { return Address(); }
+
+ //------------------------------------------------------------------
+ /// Returns the address of the Entry Point in this object file - if
+ /// the object file doesn't have an entry point (because it is not an
+ /// executable file) then an invalid address is returned.
+ ///
+ /// @return
+ /// Returns the entry address for this module.
+ //------------------------------------------------------------------
+ virtual lldb_private::Address
+ GetEntryPointAddress () { return Address();}
+
+ //------------------------------------------------------------------
+ /// Returns the address that represents the header of this object
+ /// file.
+ ///
+ /// The header address is defined as where the header for the object
+ /// file is that describes the content of the file. If the header
+ /// doesn't appear in a section that is defined in the object file,
+ /// an address with no section is returned that has the file offset
+ /// set in the m_file_offset member of the lldb_private::Address object.
+ ///
+ /// @return
+ /// Returns the entry address for this module.
+ //------------------------------------------------------------------
+ virtual lldb_private::Address
+ GetHeaderAddress () { return Address(m_memory_addr);}
+
+
+ virtual uint32_t
+ GetNumThreadContexts ()
+ {
+ return 0;
+ }
+
+ virtual lldb::RegisterContextSP
+ GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread)
+ {
+ return lldb::RegisterContextSP();
+ }
+
+ //------------------------------------------------------------------
+ /// The object file should be able to calculate its type by looking
+ /// at its file header and possibly the sections or other data in
+ /// the object file. The file type is used in the debugger to help
+ /// select the correct plug-ins for the job at hand, so this is
+ /// important to get right. If any eTypeXXX definitions do not match
+ /// up with the type of file you are loading, please feel free to
+ /// add a new enumeration value.
+ ///
+ /// @return
+ /// The calculated file type for the current object file.
+ //------------------------------------------------------------------
+ virtual Type
+ CalculateType() = 0;
+
+ //------------------------------------------------------------------
+ /// In cases where the type can't be calculated (elf files), this
+ /// routine allows someone to explicitly set it. As an example,
+ /// SymbolVendorELF uses this routine to set eTypeDebugInfo when
+ /// loading debug link files.
+ virtual void
+ SetType (Type type)
+ {
+ m_type = type;
+ }
+
+ //------------------------------------------------------------------
+ /// The object file should be able to calculate the strata of the
+ /// object file.
+ ///
+ /// Many object files for platforms might be for either user space
+ /// debugging or for kernel debugging. If your object file subclass
+ /// can figure this out, it will help with debugger plug-in selection
+ /// when it comes time to debug.
+ ///
+ /// @return
+ /// The calculated object file strata for the current object
+ /// file.
+ //------------------------------------------------------------------
+ virtual Strata
+ CalculateStrata() = 0;
+
+ //------------------------------------------------------------------
+ /// Get the object file version numbers.
+ ///
+ /// Many object files have a set of version numbers that describe
+ /// the version of the executable or shared library. Typically there
+ /// are major, minor and build, but there may be more. This function
+ /// will extract the versions from object files if they are available.
+ ///
+ /// If \a versions is NULL, or if \a num_versions is 0, the return
+ /// value will indicate how many version numbers are available in
+ /// this object file. Then a subsequent call can be made to this
+ /// function with a value of \a versions and \a num_versions that
+ /// has enough storage to store some or all version numbers.
+ ///
+ /// @param[out] versions
+ /// A pointer to an array of uint32_t types that is \a num_versions
+ /// long. If this value is NULL, the return value will indicate
+ /// how many version numbers are required for a subsequent call
+ /// to this function so that all versions can be retrieved. If
+ /// the value is non-NULL, then at most \a num_versions of the
+ /// existing versions numbers will be filled into \a versions.
+ /// If there is no version information available, \a versions
+ /// will be filled with \a num_versions UINT32_MAX values
+ /// and zero will be returned.
+ ///
+ /// @param[in] num_versions
+ /// The maximum number of entries to fill into \a versions. If
+ /// this value is zero, then the return value will indicate
+ /// how many version numbers there are in total so another call
+ /// to this function can be make with adequate storage in
+ /// \a versions to get all of the version numbers. If \a
+ /// num_versions is less than the actual number of version
+ /// numbers in this object file, only \a num_versions will be
+ /// filled into \a versions (if \a versions is non-NULL).
+ ///
+ /// @return
+ /// This function always returns the number of version numbers
+ /// that this object file has regardless of the number of
+ /// version numbers that were copied into \a versions.
+ //------------------------------------------------------------------
+ virtual uint32_t
+ GetVersion (uint32_t *versions, uint32_t num_versions)
+ {
+ if (versions && num_versions)
+ {
+ for (uint32_t i=0; i<num_versions; ++i)
+ versions[i] = UINT32_MAX;
+ }
+ return 0;
+ }
+
+ //------------------------------------------------------------------
+ // Member Functions
+ //------------------------------------------------------------------
+ Type
+ GetType ()
+ {
+ if (m_type == eTypeInvalid)
+ m_type = CalculateType();
+ return m_type;
+ }
+
+ Strata
+ GetStrata ()
+ {
+ if (m_strata == eStrataInvalid)
+ m_strata = CalculateStrata();
+ return m_strata;
+ }
+
+ // When an object file is in memory, subclasses should try and lock
+ // the process weak pointer. If the process weak pointer produces a
+ // valid ProcessSP, then subclasses can call this function to read
+ // memory.
+ static lldb::DataBufferSP
+ ReadMemory (const lldb::ProcessSP &process_sp,
+ lldb::addr_t addr,
+ size_t byte_size);
+
+ size_t
+ GetData (off_t offset, size_t length, DataExtractor &data) const;
+
+ size_t
+ CopyData (off_t offset, size_t length, void *dst) const;
+
+ size_t
+ ReadSectionData (const Section *section,
+ off_t section_offset,
+ void *dst,
+ size_t dst_len) const;
+ size_t
+ ReadSectionData (const Section *section,
+ DataExtractor& section_data) const;
+
+ size_t
+ MemoryMapSectionData (const Section *section,
+ DataExtractor& section_data) const;
+
+ bool
+ IsInMemory () const
+ {
+ return m_memory_addr != LLDB_INVALID_ADDRESS;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ FileSpec m_file;
+ Type m_type;
+ Strata m_strata;
+ lldb::addr_t m_file_offset; ///< The offset in bytes into the file, or the address in memory
+ lldb::addr_t m_length; ///< The length of this object file if it is known (can be zero if length is unknown or can't be determined).
+ DataExtractor m_data; ///< The data for this object file so things can be parsed lazily.
+ lldb_private::UnwindTable m_unwind_table; /// < Table of FuncUnwinders objects created for this ObjectFile's functions
+ lldb::ProcessWP m_process_wp;
+ const lldb::addr_t m_memory_addr;
+ std::unique_ptr<lldb_private::SectionList> m_sections_ap;
+ std::unique_ptr<lldb_private::Symtab> m_symtab_ap;
+
+ //------------------------------------------------------------------
+ /// Sets the architecture for a module. At present the architecture
+ /// can only be set if it is invalid. It is not allowed to switch from
+ /// one concrete architecture to another.
+ ///
+ /// @param[in] new_arch
+ /// The architecture this module will be set to.
+ ///
+ /// @return
+ /// Returns \b true if the architecture was changed, \b
+ /// false otherwise.
+ //------------------------------------------------------------------
+ bool SetModulesArchitecture (const ArchSpec &new_arch);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (ObjectFile);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ObjectFile_h_
+
diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h
new file mode 100644
index 000000000000..11c1cc7af9ab
--- /dev/null
+++ b/include/lldb/Symbol/Symbol.h
@@ -0,0 +1,317 @@
+//===-- Symbol.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_Symbol_h_
+#define liblldb_Symbol_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/Mangled.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Symbol/SymbolContextScope.h"
+
+namespace lldb_private {
+
+class Symbol :
+ public SymbolContextScope
+{
+public:
+ // ObjectFile readers can classify their symbol table entries and searches can be made
+ // on specific types where the symbol values will have drastically different meanings
+ // and sorting requirements.
+ Symbol();
+
+ Symbol (uint32_t symID,
+ const char *name,
+ bool name_is_mangled,
+ lldb::SymbolType type,
+ bool external,
+ bool is_debug,
+ bool is_trampoline,
+ bool is_artificial,
+ const lldb::SectionSP &section_sp,
+ lldb::addr_t value,
+ lldb::addr_t size,
+ bool size_is_valid,
+ uint32_t flags);
+
+ Symbol (uint32_t symID,
+ const char *name,
+ bool name_is_mangled,
+ lldb::SymbolType type,
+ bool external,
+ bool is_debug,
+ bool is_trampoline,
+ bool is_artificial,
+ const AddressRange &range,
+ bool size_is_valid,
+ uint32_t flags);
+
+ Symbol (const Symbol& rhs);
+
+ const Symbol&
+ operator= (const Symbol& rhs);
+
+ void
+ Clear();
+
+ bool
+ Compare (const ConstString& name, lldb::SymbolType type) const;
+
+ void
+ Dump (Stream *s, Target *target, uint32_t index) const;
+
+ bool
+ ValueIsAddress() const;
+
+ //------------------------------------------------------------------
+ // Access the address value. Do NOT hand out the AddressRange as an
+ // object as the byte size of the address range may not be filled in
+ // and it should be accessed via GetByteSize().
+ //------------------------------------------------------------------
+ Address &
+ GetAddress()
+ {
+ return m_addr_range.GetBaseAddress();
+ }
+
+ //------------------------------------------------------------------
+ // Access the address value. Do NOT hand out the AddressRange as an
+ // object as the byte size of the address range may not be filled in
+ // and it should be accessed via GetByteSize().
+ //------------------------------------------------------------------
+ const Address &
+ GetAddress() const
+ {
+ return m_addr_range.GetBaseAddress();
+ }
+
+ const ConstString &
+ GetName () const
+ {
+ return m_mangled.GetName();
+ }
+
+ uint32_t
+ GetID() const
+ {
+ return m_uid;
+ }
+
+ void
+ SetID(uint32_t uid)
+ {
+ m_uid = uid;
+ }
+
+ Mangled&
+ GetMangled ()
+ {
+ return m_mangled;
+ }
+
+ const Mangled&
+ GetMangled () const
+ {
+ return m_mangled;
+ }
+
+ uint32_t
+ GetSiblingIndex () const;
+
+ lldb::SymbolType
+ GetType () const
+ {
+ return (lldb::SymbolType)m_type;
+ }
+
+ void
+ SetType (lldb::SymbolType type)
+ {
+ m_type = (lldb::SymbolType)type;
+ }
+
+ const char *
+ GetTypeAsString () const;
+
+ uint32_t
+ GetFlags () const
+ {
+ return m_flags;
+ }
+
+ void
+ SetFlags (uint32_t flags)
+ {
+ m_flags = flags;
+ }
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const;
+
+ bool
+ IsSynthetic () const
+ {
+ return m_is_synthetic;
+ }
+
+ void
+ SetIsSynthetic (bool b)
+ {
+ m_is_synthetic = b;
+ }
+
+
+ bool
+ GetSizeIsSynthesized() const
+ {
+ return m_size_is_synthesized;
+ }
+
+ void
+ SetSizeIsSynthesized(bool b)
+ {
+ m_size_is_synthesized = b;
+ }
+
+ bool
+ IsDebug () const
+ {
+ return m_is_debug;
+ }
+
+ void
+ SetDebug (bool b)
+ {
+ m_is_debug = b;
+ }
+
+ bool
+ IsExternal () const
+ {
+ return m_is_external;
+ }
+
+ void
+ SetExternal (bool b)
+ {
+ m_is_external = b;
+ }
+
+ bool
+ IsTrampoline () const;
+
+ bool
+ IsIndirect () const;
+
+ bool
+ GetByteSizeIsValid () const
+ {
+ return m_size_is_valid;
+ }
+
+ lldb::addr_t
+ GetByteSize () const;
+
+ void
+ SetByteSize (lldb::addr_t size)
+ {
+ m_size_is_valid = size > 0;
+ m_addr_range.SetByteSize(size);
+ }
+
+ bool
+ GetSizeIsSibling () const
+ {
+ return m_size_is_sibling;
+ }
+
+ void
+ SetSizeIsSibling (bool b)
+ {
+ m_size_is_sibling = b;
+ }
+
+// void
+// SetValue (Address &value)
+// {
+// m_addr_range.GetBaseAddress() = value;
+// }
+//
+// void
+// SetValue (const AddressRange &range)
+// {
+// m_addr_range = range;
+// }
+//
+// void
+// SetValue (lldb::addr_t value);
+// {
+// m_addr_range.GetBaseAddress().SetRawAddress(value);
+// }
+
+ // If m_type is "Code" or "Function" then this will return the prologue size
+ // in bytes, else it will return zero.
+ uint32_t
+ GetPrologueByteSize ();
+
+ bool
+ GetDemangledNameIsSynthesized() const
+ {
+ return m_demangled_is_synthesized;
+ }
+ void
+ SetDemangledNameIsSynthesized(bool b)
+ {
+ m_demangled_is_synthesized = b;
+ }
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext (SymbolContext *sc);
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ();
+
+ virtual Symbol *
+ CalculateSymbolContextSymbol ();
+
+ //------------------------------------------------------------------
+ /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
+ ///
+ /// @see SymbolContextScope
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext (Stream *s);
+
+protected:
+
+ uint32_t m_uid; // User ID (usually the original symbol table index)
+ uint16_t m_type_data; // data specific to m_type
+ uint16_t m_type_data_resolved:1, // True if the data in m_type_data has already been calculated
+ m_is_synthetic:1, // non-zero if this symbol is not actually in the symbol table, but synthesized from other info in the object file.
+ m_is_debug:1, // non-zero if this symbol is debug information in a symbol
+ m_is_external:1, // non-zero if this symbol is globally visible
+ m_size_is_sibling:1, // m_size contains the index of this symbol's sibling
+ m_size_is_synthesized:1,// non-zero if this symbol's size was calculated using a delta between this symbol and the next
+ m_size_is_valid:1,
+ m_demangled_is_synthesized:1, // The demangled name was created should not be used for expressions or other lookups
+ m_type:8;
+ Mangled m_mangled; // uniqued symbol name/mangled name pair
+ AddressRange m_addr_range; // Contains the value, or the section offset address when the value is an address in a section, and the size (if any)
+ uint32_t m_flags; // A copy of the flags from the original symbol table, the ObjectFile plug-in can interpret these
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Symbol_h_
diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h
new file mode 100644
index 000000000000..5b12adebf5f5
--- /dev/null
+++ b/include/lldb/Symbol/SymbolContext.h
@@ -0,0 +1,566 @@
+//===-- SymbolContext.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_SymbolContext_h_
+#define liblldb_SymbolContext_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/Mangled.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/LineEntry.h"
+
+namespace lldb_private {
+
+class SymbolContextScope;
+//----------------------------------------------------------------------
+/// @class SymbolContext SymbolContext.h "lldb/Symbol/SymbolContext.h"
+/// @brief Defines a symbol context baton that can be handed other debug
+/// core functions.
+///
+/// Many debugger functions require a context when doing lookups. This
+/// class provides a common structure that can be used as the result
+/// of a query that can contain a single result. Examples of such
+/// queries include
+/// @li Looking up a load address.
+//----------------------------------------------------------------------
+class SymbolContext
+{
+public:
+
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize all pointer members to NULL and all struct members
+ /// to their default state.
+ //------------------------------------------------------------------
+ SymbolContext ();
+
+ //------------------------------------------------------------------
+ /// Construct with an object that knows how to reconstruct its
+ /// symbol context.
+ ///
+ /// @param[in] sc_scope
+ /// A symbol context scope object that knows how to reconstruct
+ /// it's context.
+ //------------------------------------------------------------------
+ explicit
+ SymbolContext (SymbolContextScope *sc_scope);
+
+ //------------------------------------------------------------------
+ /// Construct with module, and optional compile unit, function,
+ /// block, line table, line entry and symbol.
+ ///
+ /// Initialize all pointer to the specified values.
+ ///
+ /// @param[in] module
+ /// A Module pointer to the module for this context.
+ ///
+ /// @param[in] comp_unit
+ /// A CompileUnit pointer to the compile unit for this context.
+ ///
+ /// @param[in] function
+ /// A Function pointer to the function for this context.
+ ///
+ /// @param[in] block
+ /// A Block pointer to the deepest block for this context.
+ ///
+ /// @param[in] line_entry
+ /// A LineEntry pointer to the line entry for this context.
+ ///
+ /// @param[in] symbol
+ /// A Symbol pointer to the symbol for this context.
+ //------------------------------------------------------------------
+ explicit
+ SymbolContext (const lldb::TargetSP &target_sp,
+ const lldb::ModuleSP &module_sp,
+ CompileUnit *comp_unit = NULL,
+ Function *function = NULL,
+ Block *block = NULL,
+ LineEntry *line_entry = NULL,
+ Symbol *symbol = NULL);
+
+ // This version sets the target to a NULL TargetSP if you don't know it.
+ explicit
+ SymbolContext (const lldb::ModuleSP &module_sp,
+ CompileUnit *comp_unit = NULL,
+ Function *function = NULL,
+ Block *block = NULL,
+ LineEntry *line_entry = NULL,
+ Symbol *symbol = NULL);
+
+ ~SymbolContext ();
+ //------------------------------------------------------------------
+ /// Copy constructor
+ ///
+ /// Makes a copy of the another SymbolContext object \a rhs.
+ ///
+ /// @param[in] rhs
+ /// A const SymbolContext object reference to copy.
+ //------------------------------------------------------------------
+ SymbolContext (const SymbolContext& rhs);
+
+ //------------------------------------------------------------------
+ /// Assignment operator.
+ ///
+ /// Copies the address value from another SymbolContext object \a
+ /// rhs into \a this object.
+ ///
+ /// @param[in] rhs
+ /// A const SymbolContext object reference to copy.
+ ///
+ /// @return
+ /// A const SymbolContext object reference to \a this.
+ //------------------------------------------------------------------
+ const SymbolContext&
+ operator= (const SymbolContext& rhs);
+
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Resets all pointer members to NULL, and clears any class objects
+ /// to their default state.
+ //------------------------------------------------------------------
+ void
+ Clear (bool clear_target);
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the
+ /// supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump (Stream *s, Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Dump the stop context in this object to a Stream.
+ ///
+ /// Dump the best description of this object to the stream. The
+ /// information displayed depends on the amount and quality of the
+ /// information in this context. If a module, function, file and
+ /// line number are available, they will be dumped. If only a
+ /// module and function or symbol name with offset is available,
+ /// that will be output. Else just the address at which the target
+ /// was stopped will be displayed.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ ///
+ /// @param[in] so_addr
+ /// The resolved section offset address.
+ //------------------------------------------------------------------
+ bool
+ DumpStopContext (Stream *s,
+ ExecutionContextScope *exe_scope,
+ const Address &so_addr,
+ bool show_fullpaths,
+ bool show_module,
+ bool show_inlined_frames) const;
+
+ //------------------------------------------------------------------
+ /// Get the address range contained within a symbol context.
+ ///
+ /// Address range priority is as follows:
+ /// - line_entry address range if line_entry is valid and eSymbolContextLineEntry is set in \a scope
+ /// - block address range if block is not NULL and eSymbolContextBlock is set in \a scope
+ /// - function address range if function is not NULL and eSymbolContextFunction is set in \a scope
+ /// - symbol address range if symbol is not NULL and eSymbolContextSymbol is set in \a scope
+ ///
+ /// @param[in] scope
+ /// A mask of symbol context bits telling this function which
+ /// address ranges it can use when trying to extract one from
+ /// the valid (non-NULL) symbol context classes.
+ ///
+ /// @param[in] range_idx
+ /// The address range index to grab. Since many functions and
+ /// blocks are not always contiguous, they may have more than
+ /// one address range.
+ ///
+ /// @param[in] use_inline_block_range
+ /// If \a scope has the eSymbolContextBlock bit set, and there
+ /// is a valid block in the symbol context, return the block
+ /// address range for the containing inline function block, not
+ /// the deepest most block. This allows us to extract information
+ /// for the address range of the inlined function block, not
+ /// the deepest lexical block.
+ ///
+ /// @param[out] range
+ /// An address range object that will be filled in if \b true
+ /// is returned.
+ ///
+ /// @return
+ /// \b True if this symbol context contains items that describe
+ /// an address range, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetAddressRange (uint32_t scope,
+ uint32_t range_idx,
+ bool use_inline_block_range,
+ AddressRange &range) const;
+
+
+ void
+ GetDescription(Stream *s,
+ lldb::DescriptionLevel level,
+ Target *target) const;
+
+ uint32_t
+ GetResolvedMask () const;
+
+
+ //------------------------------------------------------------------
+ /// Find a block that defines the function represented by this
+ /// symbol context.
+ ///
+ /// If this symbol context points to a block that is an inlined
+ /// function, or is contained within an inlined function, the block
+ /// that defines the inlined function is returned.
+ ///
+ /// If this symbol context has no block in it, or the block is not
+ /// itself an inlined function block or contained within one, we
+ /// return the top level function block.
+ ///
+ /// This is a handy function to call when you want to get the block
+ /// whose variable list will include the arguments for the function
+ /// that is represented by this symbol context (whether the function
+ /// is an inline function or not).
+ ///
+ /// @return
+ /// The block object pointer that defines the function that is
+ /// represented by this symbol context object, NULL otherwise.
+ //------------------------------------------------------------------
+ Block *
+ GetFunctionBlock ();
+
+
+ //------------------------------------------------------------------
+ /// If this symbol context represents a function that is a method,
+ /// return true and provide information about the method.
+ ///
+ /// @param[out] language
+ /// If \b true is returned, the language for the method.
+ ///
+ /// @param[out] is_instance_method
+ /// If \b true is returned, \b true if this is a instance method,
+ /// \b false if this is a static/class function.
+ ///
+ /// @param[out] language_object_name
+ /// If \b true is returned, the name of the artificial variable
+ /// for the language ("this" for C++, "self" for ObjC).
+ ///
+ /// @return
+ /// \b True if this symbol context represents a function that
+ /// is a method of a class, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetFunctionMethodInfo (lldb::LanguageType &language,
+ bool &is_instance_method,
+ ConstString &language_object_name);
+
+ //------------------------------------------------------------------
+ /// Find a name of the innermost function for the symbol context.
+ ///
+ /// For instance, if the symbol context contains an inlined block,
+ /// it will return the inlined function name.
+ ///
+ /// @param[in] prefer_mangled
+ /// if \btrue, then the mangled name will be returned if there
+ /// is one. Otherwise the unmangled name will be returned if it
+ /// is available.
+ ///
+ /// @return
+ /// The name of the function represented by this symbol context.
+ //------------------------------------------------------------------
+ ConstString
+ GetFunctionName (Mangled::NamePreference preference = Mangled::ePreferDemangled) const;
+
+
+ //------------------------------------------------------------------
+ /// Get the line entry that corresponds to the function.
+ ///
+ /// If the symbol context contains an inlined block, the line entry
+ /// for the start address of the inlined function will be returned,
+ /// otherwise the line entry for the start address of the function
+ /// will be returned. This can be used after doing a
+ /// Module::FindFunctions(...) or ModuleList::FindFunctions(...)
+ /// call in order to get the correct line table information for
+ /// the symbol context.
+ /// it will return the inlined function name.
+ ///
+ /// @param[in] prefer_mangled
+ /// if \btrue, then the mangled name will be returned if there
+ /// is one. Otherwise the unmangled name will be returned if it
+ /// is available.
+ ///
+ /// @return
+ /// The name of the function represented by this symbol context.
+ //------------------------------------------------------------------
+ LineEntry
+ GetFunctionStartLineEntry () const;
+
+ //------------------------------------------------------------------
+ /// Find the block containing the inlined block that contains this block.
+ ///
+ /// For instance, if the symbol context contains an inlined block,
+ /// it will return the inlined function name.
+ ///
+ /// @param[in] curr_frame_pc
+ /// The address within the block of this object.
+ ///
+ /// @param[out] next_frame_sc
+ /// A new symbol context that does what the title says it does.
+ ///
+ /// @param[out] next_frame_addr
+ /// This is what you should report as the PC in \a next_frame_sc.
+ ///
+ /// @return
+ /// \b true if this SymbolContext specifies a block contained in an
+ /// inlined block. If this returns \b true, \a next_frame_sc and
+ /// \a next_frame_addr will be filled in correctly.
+ //------------------------------------------------------------------
+ bool
+ GetParentOfInlinedScope (const Address &curr_frame_pc,
+ SymbolContext &next_frame_sc,
+ Address &inlined_frame_addr) const;
+
+ //------------------------------------------------------------------
+ // Member variables
+ //------------------------------------------------------------------
+ lldb::TargetSP target_sp; ///< The Target for a given query
+ lldb::ModuleSP module_sp; ///< The Module for a given query
+ CompileUnit * comp_unit; ///< The CompileUnit for a given query
+ Function * function; ///< The Function for a given query
+ Block * block; ///< The Block for a given query
+ LineEntry line_entry; ///< The LineEntry for a given query
+ Symbol * symbol; ///< The Symbol for a given query
+};
+
+
+class SymbolContextSpecifier
+{
+public:
+ typedef enum SpecificationType
+ {
+ eNothingSpecified = 0,
+ eModuleSpecified = 1 << 0,
+ eFileSpecified = 1 << 1,
+ eLineStartSpecified = 1 << 2,
+ eLineEndSpecified = 1 << 3,
+ eFunctionSpecified = 1 << 4,
+ eClassOrNamespaceSpecified = 1 << 5,
+ eAddressRangeSpecified = 1 << 6
+ } SpecificationType;
+
+ // This one produces a specifier that matches everything...
+ SymbolContextSpecifier (const lldb::TargetSP& target_sp);
+
+ ~SymbolContextSpecifier();
+
+ bool
+ AddSpecification (const char *spec_string, SpecificationType type);
+
+ bool
+ AddLineSpecification (uint32_t line_no, SpecificationType type);
+
+ void
+ Clear();
+
+ bool
+ SymbolContextMatches(SymbolContext &sc);
+
+ bool
+ AddressMatches(lldb::addr_t addr);
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level) const;
+
+private:
+ lldb::TargetSP m_target_sp;
+ std::string m_module_spec;
+ lldb::ModuleSP m_module_sp;
+ std::unique_ptr<FileSpec> m_file_spec_ap;
+ size_t m_start_line;
+ size_t m_end_line;
+ std::string m_function_spec;
+ std::string m_class_name;
+ std::unique_ptr<AddressRange> m_address_range_ap;
+ uint32_t m_type; // Or'ed bits from SpecificationType
+
+};
+
+//----------------------------------------------------------------------
+/// @class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h"
+/// @brief Defines a list of symbol context objects.
+///
+/// This class provides a common structure that can be used to contain
+/// the result of a query that can contain a multiple results. Examples
+/// of such queries include:
+/// @li Looking up a function by name.
+/// @li Finding all addressses for a specified file and line number.
+//----------------------------------------------------------------------
+class SymbolContextList
+{
+public:
+ //------------------------------------------------------------------
+ /// Default constructor.
+ ///
+ /// Initialize with an empty list.
+ //------------------------------------------------------------------
+ SymbolContextList ();
+
+ //------------------------------------------------------------------
+ /// Destructor.
+ //------------------------------------------------------------------
+ ~SymbolContextList ();
+
+ //------------------------------------------------------------------
+ /// Append a new symbol context to the list.
+ ///
+ /// @param[in] sc
+ /// A symbol context to append to the list.
+ //------------------------------------------------------------------
+ void
+ Append (const SymbolContext& sc);
+
+ void
+ Append (const SymbolContextList& sc_list);
+
+ bool
+ AppendIfUnique (const SymbolContext& sc,
+ bool merge_symbol_into_function);
+
+ bool
+ MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc,
+ uint32_t start_idx = 0,
+ uint32_t stop_idx = UINT32_MAX);
+
+ uint32_t
+ AppendIfUnique (const SymbolContextList& sc_list,
+ bool merge_symbol_into_function);
+ //------------------------------------------------------------------
+ /// Clear the object's state.
+ ///
+ /// Clears the symbol context list.
+ //------------------------------------------------------------------
+ void
+ Clear();
+
+ //------------------------------------------------------------------
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of each symbol context in
+ /// the list to the supplied stream \a s.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object descripton.
+ //------------------------------------------------------------------
+ void
+ Dump(Stream *s, Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Get accessor for a symbol context at index \a idx.
+ ///
+ /// Dump a description of the contents of each symbol context in
+ /// the list to the supplied stream \a s.
+ ///
+ /// @param[in] idx
+ /// The zero based index into the symbol context list.
+ ///
+ /// @param[out] sc
+ /// A reference to the symbol context to fill in.
+ ///
+ /// @return
+ /// Returns \b true if \a idx was a valid index into this
+ /// symbol context list and \a sc was filled in, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ bool
+ GetContextAtIndex(size_t idx, SymbolContext& sc) const;
+
+ //------------------------------------------------------------------
+ /// Direct reference accessor for a symbol context at index \a idx.
+ ///
+ /// The index \a idx must be a valid index, no error checking will
+ /// be done to ensure that it is valid.
+ ///
+ /// @param[in] idx
+ /// The zero based index into the symbol context list.
+ ///
+ /// @return
+ /// A const reference to the symbol context to fill in.
+ //------------------------------------------------------------------
+ SymbolContext&
+ operator [] (size_t idx)
+ {
+ return m_symbol_contexts[idx];
+ }
+
+ const SymbolContext&
+ operator [] (size_t idx) const
+ {
+ return m_symbol_contexts[idx];
+ }
+
+ //------------------------------------------------------------------
+ /// Get accessor for the last symbol context in the list.
+ ///
+ /// @param[out] sc
+ /// A reference to the symbol context to fill in.
+ ///
+ /// @return
+ /// Returns \b true if \a sc was filled in, \b false if the
+ /// list is empty.
+ //------------------------------------------------------------------
+ bool
+ GetLastContext(SymbolContext& sc) const;
+
+ bool
+ RemoveContextAtIndex (size_t idx);
+ //------------------------------------------------------------------
+ /// Get accessor for a symbol context list size.
+ ///
+ /// @return
+ /// Returns the number of symbol context objects in the list.
+ //------------------------------------------------------------------
+ uint32_t
+ GetSize() const;
+
+ uint32_t
+ NumLineEntriesWithLine (uint32_t line) const;
+
+ void
+ GetDescription(Stream *s,
+ lldb::DescriptionLevel level,
+ Target *target) const;
+
+protected:
+ typedef std::vector<SymbolContext> collection; ///< The collection type for the list.
+
+ //------------------------------------------------------------------
+ // Member variables.
+ //------------------------------------------------------------------
+ collection m_symbol_contexts; ///< The list of symbol contexts.
+};
+
+bool operator== (const SymbolContext& lhs, const SymbolContext& rhs);
+bool operator!= (const SymbolContext& lhs, const SymbolContext& rhs);
+
+bool operator== (const SymbolContextList& lhs, const SymbolContextList& rhs);
+bool operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_SymbolContext_h_
diff --git a/include/lldb/Symbol/SymbolContextScope.h b/include/lldb/Symbol/SymbolContextScope.h
new file mode 100644
index 000000000000..693cc0131e27
--- /dev/null
+++ b/include/lldb/Symbol/SymbolContextScope.h
@@ -0,0 +1,137 @@
+//===-- SymbolContextScope.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_SymbolContextScope_h_
+#define liblldb_SymbolContextScope_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class SymbolContextScope SymbolContextScope.h "lldb/Symbol/SymbolContextScope.h"
+/// @brief Inherit from this if your object is part of a symbol context
+/// and can reconstruct its symbol context.
+///
+/// Many objects that are part of a symbol context that have pointers
+/// back to parent objects that own them. Any members of a symbol
+/// context that, once they are built, will not go away, can inherit
+/// from this pure virtual class and can then reconstruct their symbol
+/// context without having to keep a complete SymbolContext object in
+/// the object.
+///
+/// Examples of these objects include:
+/// @li Module
+/// @li CompileUnit
+/// @li Function
+/// @li Block
+/// @li Symbol
+///
+/// Other objects can store a "SymbolContextScope *" using any pointers
+/// to one of the above objects. This allows clients to hold onto a
+/// pointer that uniquely will identify a symbol context. Those clients
+/// can then always reconstruct the symbol context using the pointer, or
+/// use it to uniquely identify a symbol context for an object.
+///
+/// Example objects include that currently use "SymbolContextScope *"
+/// objects include:
+/// @li Variable objects that can reconstruct where they are scoped
+/// by making sure the SymbolContextScope * comes from the scope
+/// in which the variable was declared. If a variable is a global,
+/// the appropriate CompileUnit * will be used when creating the
+/// variable. A static function variables, can the Block scope
+/// in which the variable is defined. Function arguments can use
+/// the Function object as their scope. The SymbolFile parsers
+/// will set these correctly as the variables are parsed.
+/// @li Type objects that know exactly in which scope they
+/// originated much like the variables above.
+/// @li StackID objects that are able to know that if the CFA
+/// (stack pointer at the beginning of a function) and the
+/// start PC for the function/symbol and the SymbolContextScope
+/// pointer (a unique pointer that identifies a symbol context
+/// location) match within the same thread, that the stack
+/// frame is the same as the previous stack frame.
+///
+/// Objects that adhere to this protocol can reconstruct enough of a
+/// symbol context to allow functions that take a symbol context to be
+/// called. Lists can also be created using a SymbolContextScope* and
+/// and object pairs that allow large collections of objects to be
+/// passed around with minimal overhead.
+//----------------------------------------------------------------------
+class SymbolContextScope
+{
+public:
+ virtual
+ ~SymbolContextScope () {}
+
+ //------------------------------------------------------------------
+ /// Reconstruct the object's symbolc context into \a sc.
+ ///
+ /// The object should fill in as much of the SymbolContext as it
+ /// can so function calls that require a symbol context can be made
+ /// for the given object.
+ ///
+ /// @param[out] sc
+ /// A symbol context object pointer that gets filled in.
+ //------------------------------------------------------------------
+ virtual void
+ CalculateSymbolContext (SymbolContext *sc) = 0;
+
+
+ virtual lldb::ModuleSP
+ CalculateSymbolContextModule ()
+ {
+ return lldb::ModuleSP();
+ }
+
+ virtual CompileUnit *
+ CalculateSymbolContextCompileUnit ()
+ {
+ return NULL;
+ }
+
+ virtual Function *
+ CalculateSymbolContextFunction ()
+ {
+ return NULL;
+ }
+
+ virtual Block *
+ CalculateSymbolContextBlock ()
+ {
+ return NULL;
+ }
+
+ virtual Symbol *
+ CalculateSymbolContextSymbol ()
+ {
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Dump the object's symbolc context to the stream \a s.
+ ///
+ /// The object should dump its symbol context to the stream \a s.
+ /// This function is widely used in the DumpDebug and verbose output
+ /// for lldb objets.
+ ///
+ /// @param[in] s
+ /// The stream to which to dump the object's symbol context.
+ //------------------------------------------------------------------
+ virtual void
+ DumpSymbolContext (Stream *s) = 0;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_SymbolContextScope_h_
diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h
new file mode 100644
index 000000000000..5b774e3a7d13
--- /dev/null
+++ b/include/lldb/Symbol/SymbolFile.h
@@ -0,0 +1,167 @@
+//===-- SymbolFile.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_SymbolFile_h_
+#define liblldb_SymbolFile_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/ClangNamespaceDecl.h"
+#include "lldb/Symbol/Type.h"
+
+namespace lldb_private {
+
+class SymbolFile :
+ public PluginInterface
+{
+public:
+ //------------------------------------------------------------------
+ // Symbol file ability bits.
+ //
+ // Each symbol file can claim to support one or more symbol file
+ // abilities. These get returned from SymbolFile::GetAbilities().
+ // These help us to determine which plug-in will be best to load
+ // the debug information found in files.
+ //------------------------------------------------------------------
+ enum Abilities
+ {
+ CompileUnits = (1u << 0),
+ LineTables = (1u << 1),
+ Functions = (1u << 2),
+ Blocks = (1u << 3),
+ GlobalVariables = (1u << 4),
+ LocalVariables = (1u << 5),
+ VariableTypes = (1u << 6),
+ kAllAbilities =((1u << 7) - 1u)
+ };
+
+ static SymbolFile *
+ FindPlugin (ObjectFile* obj_file);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFile(ObjectFile* obj_file) :
+ m_obj_file(obj_file),
+ m_abilities(0),
+ m_calculated_abilities(false)
+ {
+ }
+
+ virtual
+ ~SymbolFile()
+ {
+ }
+
+ //------------------------------------------------------------------
+ /// Get a mask of what this symbol file supports for the object file
+ /// that it was constructed with.
+ ///
+ /// Each symbol file gets to respond with a mask of abilities that
+ /// it supports for each object file. This happens when we are
+ /// trying to figure out which symbol file plug-in will get used
+ /// for a given object file. The plug-in that resoonds with the
+ /// best mix of "SymbolFile::Abilities" bits set, will get chosen to
+ /// be the symbol file parser. This allows each plug-in to check for
+ /// sections that contain data a symbol file plug-in would need. For
+ /// example the DWARF plug-in requires DWARF sections in a file that
+ /// contain debug information. If the DWARF plug-in doesn't find
+ /// these sections, it won't respond with many ability bits set, and
+ /// we will probably fall back to the symbol table SymbolFile plug-in
+ /// which uses any information in the symbol table. Also, plug-ins
+ /// might check for some specific symbols in a symbol table in the
+ /// case where the symbol table contains debug information (STABS
+ /// and COFF). Not a lot of work should happen in these functions
+ /// as the plug-in might not get selected due to another plug-in
+ /// having more abilities. Any initialization work should be saved
+ /// for "void SymbolFile::InitializeObject()" which will get called
+ /// on the SymbolFile object with the best set of abilities.
+ ///
+ /// @return
+ /// A uint32_t mask containing bits from the SymbolFile::Abilities
+ /// enumeration. Any bits that are set represent an ability that
+ /// this symbol plug-in can parse from the object file.
+ ///------------------------------------------------------------------
+ uint32_t GetAbilities ()
+ {
+ if (!m_calculated_abilities)
+ {
+ m_abilities = CalculateAbilities();
+ m_calculated_abilities = true;
+ }
+
+ return m_abilities;
+ }
+
+ virtual uint32_t CalculateAbilities() = 0;
+
+ //------------------------------------------------------------------
+ /// Initialize the SymbolFile object.
+ ///
+ /// The SymbolFile object with the best set of abilities (detected
+ /// in "uint32_t SymbolFile::GetAbilities()) will have this function
+ /// called if it is chosen to parse an object file. More complete
+ /// initialization can happen in this function which will get called
+ /// prior to any other functions in the SymbolFile protocol.
+ //------------------------------------------------------------------
+ virtual void InitializeObject() {}
+
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
+ // Approach 1 - iterator
+ virtual uint32_t GetNumCompileUnits() = 0;
+ virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) = 0;
+
+ virtual lldb::LanguageType ParseCompileUnitLanguage (const SymbolContext& sc) = 0;
+ virtual size_t ParseCompileUnitFunctions (const SymbolContext& sc) = 0;
+ virtual bool ParseCompileUnitLineTable (const SymbolContext& sc) = 0;
+ virtual bool ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) = 0;
+ virtual size_t ParseFunctionBlocks (const SymbolContext& sc) = 0;
+ virtual size_t ParseTypes (const SymbolContext& sc) = 0;
+ virtual size_t ParseVariablesForContext (const SymbolContext& sc) = 0;
+ virtual Type* ResolveTypeUID (lldb::user_id_t type_uid) = 0;
+ virtual bool ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) = 0;
+ virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) { return NULL; }
+ virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) { return NULL; }
+ virtual uint32_t ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) = 0;
+ virtual uint32_t ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) = 0;
+ virtual uint32_t FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables) = 0;
+ virtual uint32_t FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) = 0;
+ virtual uint32_t FindFunctions (const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list) = 0;
+ virtual uint32_t FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) = 0;
+ virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types) = 0;
+// virtual uint32_t FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) = 0;
+ virtual TypeList * GetTypeList ();
+ virtual size_t GetTypes (lldb_private::SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) = 0;
+ virtual ClangASTContext &
+ GetClangASTContext ();
+ virtual ClangNamespaceDecl
+ FindNamespace (const SymbolContext& sc,
+ const ConstString &name,
+ const ClangNamespaceDecl *parent_namespace_decl) = 0;
+
+ ObjectFile* GetObjectFile() { return m_obj_file; }
+ const ObjectFile* GetObjectFile() const { return m_obj_file; }
+
+protected:
+ ObjectFile* m_obj_file; // The object file that symbols can be extracted from.
+ uint32_t m_abilities;
+ bool m_calculated_abilities;
+private:
+ DISALLOW_COPY_AND_ASSIGN (SymbolFile);
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_SymbolFile_h_
diff --git a/include/lldb/Symbol/SymbolVendor.h b/include/lldb/Symbol/SymbolVendor.h
new file mode 100644
index 000000000000..0eeea4eb466b
--- /dev/null
+++ b/include/lldb/Symbol/SymbolVendor.h
@@ -0,0 +1,207 @@
+//===-- SymbolVendor.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_SymbolVendor_h_
+#define liblldb_SymbolVendor_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/ClangNamespaceDecl.h"
+#include "lldb/Symbol/TypeList.h"
+
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// The symbol vendor class is designed to abstract the process of
+// searching for debug information for a given module. Platforms can
+// subclass this class and provide extra ways to find debug information.
+// Examples would be a subclass that would allow for locating a stand
+// alone debug file, parsing debug maps, or runtime data in the object
+// files. A symbol vendor can use multiple sources (SymbolFile
+// objects) to provide the information and only parse as deep as needed
+// in order to provide the information that is requested.
+//----------------------------------------------------------------------
+class SymbolVendor :
+ public ModuleChild,
+ public PluginInterface
+{
+public:
+ static SymbolVendor*
+ FindPlugin (const lldb::ModuleSP &module_sp,
+ Stream *feedback_strm);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolVendor(const lldb::ModuleSP &module_sp);
+
+ virtual
+ ~SymbolVendor();
+
+ void
+ AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp);
+
+ virtual void
+ Dump(Stream *s);
+
+ virtual lldb::LanguageType
+ ParseCompileUnitLanguage (const SymbolContext& sc);
+
+ virtual size_t
+ ParseCompileUnitFunctions (const SymbolContext& sc);
+
+ virtual bool
+ ParseCompileUnitLineTable (const SymbolContext& sc);
+
+ virtual bool
+ ParseCompileUnitSupportFiles (const SymbolContext& sc,
+ FileSpecList& support_files);
+
+ virtual size_t
+ ParseFunctionBlocks (const SymbolContext& sc);
+
+ virtual size_t
+ ParseTypes (const SymbolContext& sc);
+
+ virtual size_t
+ ParseVariablesForContext (const SymbolContext& sc);
+
+ virtual Type*
+ ResolveTypeUID(lldb::user_id_t type_uid);
+
+ virtual uint32_t
+ ResolveSymbolContext (const Address& so_addr,
+ uint32_t resolve_scope,
+ SymbolContext& sc);
+
+ virtual uint32_t
+ ResolveSymbolContext (const FileSpec& file_spec,
+ uint32_t line,
+ bool check_inlines,
+ uint32_t resolve_scope,
+ SymbolContextList& sc_list);
+
+ virtual size_t
+ FindGlobalVariables (const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ bool append,
+ size_t max_matches,
+ VariableList& variables);
+
+ virtual size_t
+ FindGlobalVariables (const RegularExpression& regex,
+ bool append,
+ size_t max_matches,
+ VariableList& variables);
+
+ virtual size_t
+ FindFunctions (const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ uint32_t name_type_mask,
+ bool include_inlines,
+ bool append,
+ SymbolContextList& sc_list);
+
+ virtual size_t
+ FindFunctions (const RegularExpression& regex,
+ bool include_inlines,
+ bool append,
+ SymbolContextList& sc_list);
+
+ virtual size_t
+ FindTypes (const SymbolContext& sc,
+ const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ bool append,
+ size_t max_matches,
+ TypeList& types);
+
+ virtual ClangNamespaceDecl
+ FindNamespace (const SymbolContext& sc,
+ const ConstString &name,
+ const ClangNamespaceDecl *parent_namespace_decl);
+
+ virtual size_t
+ GetNumCompileUnits();
+
+ virtual bool
+ SetCompileUnitAtIndex (size_t cu_idx,
+ const lldb::CompUnitSP &cu_sp);
+
+ virtual lldb::CompUnitSP
+ GetCompileUnitAtIndex(size_t idx);
+
+ TypeList&
+ GetTypeList()
+ {
+ return m_type_list;
+ }
+
+ const TypeList&
+ GetTypeList() const
+ {
+ return m_type_list;
+ }
+
+ virtual size_t
+ GetTypes (SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ TypeList &type_list);
+
+ SymbolFile *
+ GetSymbolFile()
+ {
+ return m_sym_file_ap.get();
+ }
+
+ // Get module unified section list symbol table.
+ virtual Symtab *
+ GetSymtab ();
+
+ // Clear module unified section list symbol table.
+ virtual void
+ ClearSymtab ();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual ConstString
+ GetPluginName();
+
+ virtual uint32_t
+ GetPluginVersion();
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from SymbolVendor can see and modify these
+ //------------------------------------------------------------------
+ typedef std::vector<lldb::CompUnitSP> CompileUnits;
+ typedef CompileUnits::iterator CompileUnitIter;
+ typedef CompileUnits::const_iterator CompileUnitConstIter;
+
+ TypeList m_type_list; // Uniqued types for all parsers owned by this module
+ CompileUnits m_compile_units; // The current compile units
+ lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in case it isn't the same as the module object file (debug symbols in a separate file)
+ std::unique_ptr<SymbolFile> m_sym_file_ap; // A single symbol file. Subclasses can add more of these if needed.
+
+private:
+ //------------------------------------------------------------------
+ // For SymbolVendor only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (SymbolVendor);
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_SymbolVendor_h_
diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h
new file mode 100644
index 000000000000..666c3b5686b9
--- /dev/null
+++ b/include/lldb/Symbol/Symtab.h
@@ -0,0 +1,160 @@
+//===-- Symtab.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_Symtab_h_
+#define liblldb_Symtab_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/Symbol.h"
+
+namespace lldb_private {
+
+class Symtab
+{
+public:
+ typedef std::vector<uint32_t> IndexCollection;
+ typedef UniqueCStringMap<uint32_t> NameToIndexMap;
+
+ typedef enum Debug {
+ eDebugNo, // Not a debug symbol
+ eDebugYes, // A debug symbol
+ eDebugAny
+ } Debug;
+
+ typedef enum Visibility {
+ eVisibilityAny,
+ eVisibilityExtern,
+ eVisibilityPrivate
+ } Visibility;
+
+ Symtab(ObjectFile *objfile);
+ ~Symtab();
+
+ void Reserve (size_t count);
+ Symbol * Resize (size_t count);
+ uint32_t AddSymbol(const Symbol& symbol);
+ size_t GetNumSymbols() const;
+ void Dump(Stream *s, Target *target, SortOrder sort_type);
+ void Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const;
+ uint32_t GetIndexForSymbol (const Symbol *symbol) const;
+ Mutex & GetMutex ()
+ {
+ return m_mutex;
+ }
+ Symbol * FindSymbolByID (lldb::user_id_t uid) const;
+ Symbol * SymbolAtIndex (size_t idx);
+ const Symbol * SymbolAtIndex (size_t idx) const;
+ Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx);
+ uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
+ uint32_t AppendSymbolIndexesWithTypeAndFlagsValue (lldb::SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
+ uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
+ uint32_t AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& matches);
+ uint32_t AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches);
+ uint32_t AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, lldb::SymbolType symbol_type, std::vector<uint32_t>& matches);
+ uint32_t AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches);
+ uint32_t AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regex, lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes);
+ uint32_t AppendSymbolIndexesMatchingRegExAndType (const RegularExpression &regex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes);
+ size_t FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes);
+ size_t FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes);
+ size_t FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes);
+ Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility);
+ Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes);
+ Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr);
+ size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list);
+ void CalculateSymbolSizes ();
+
+ void SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const;
+
+ static void DumpSymbolHeader (Stream *s);
+
+
+ void Finalize ()
+ {
+ // Shrink to fit the symbols so we don't waste memory
+ if (m_symbols.capacity() > m_symbols.size())
+ {
+ collection new_symbols (m_symbols.begin(), m_symbols.end());
+ m_symbols.swap (new_symbols);
+ }
+ }
+
+ void AppendSymbolNamesToMap (const IndexCollection &indexes,
+ bool add_demangled,
+ bool add_mangled,
+ NameToIndexMap &name_to_index_map) const;
+
+protected:
+ typedef std::vector<Symbol> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+ typedef RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> FileRangeToIndexMap;
+ void InitNameIndexes ();
+ void InitAddressIndexes ();
+
+ ObjectFile * m_objfile;
+ collection m_symbols;
+ FileRangeToIndexMap m_file_addr_to_index;
+ UniqueCStringMap<uint32_t> m_name_to_index;
+ UniqueCStringMap<uint32_t> m_basename_to_index;
+ UniqueCStringMap<uint32_t> m_method_to_index;
+ UniqueCStringMap<uint32_t> m_selector_to_index;
+ mutable Mutex m_mutex; // Provide thread safety for this symbol table
+ bool m_file_addr_to_index_computed:1,
+ m_name_indexes_computed:1;
+private:
+
+ bool
+ CheckSymbolAtIndex (size_t idx, Debug symbol_debug_type, Visibility symbol_visibility) const
+ {
+ switch (symbol_debug_type)
+ {
+ case eDebugNo:
+ if (m_symbols[idx].IsDebug() == true)
+ return false;
+ break;
+
+ case eDebugYes:
+ if (m_symbols[idx].IsDebug() == false)
+ return false;
+ break;
+
+ case eDebugAny:
+ break;
+ }
+
+ switch (symbol_visibility)
+ {
+ case eVisibilityAny:
+ return true;
+
+ case eVisibilityExtern:
+ return m_symbols[idx].IsExternal();
+
+ case eVisibilityPrivate:
+ return !m_symbols[idx].IsExternal();
+ }
+ return false;
+ }
+
+ void
+ SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes,
+ SymbolContextList &sc_list);
+
+ DISALLOW_COPY_AND_ASSIGN (Symtab);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Symtab_h_
diff --git a/include/lldb/Symbol/TaggedASTType.h b/include/lldb/Symbol/TaggedASTType.h
new file mode 100644
index 000000000000..c44a5356f86d
--- /dev/null
+++ b/include/lldb/Symbol/TaggedASTType.h
@@ -0,0 +1,61 @@
+//===-- TaggedASTType.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_TaggedASTType_h_
+#define liblldb_TaggedASTType_h_
+
+#include "lldb/Symbol/ClangASTType.h"
+
+namespace lldb_private
+{
+
+// For cases in which there are multiple classes of types that are not
+// interchangeable, to allow static type checking.
+template <unsigned int C> class TaggedASTType : public ClangASTType
+{
+public:
+ TaggedASTType (const ClangASTType &clang_type) :
+ ClangASTType(clang_type)
+ {
+ }
+
+ TaggedASTType (lldb::clang_type_t type, clang::ASTContext *ast_context) :
+ ClangASTType(ast_context, type)
+ {
+ }
+
+ TaggedASTType (const TaggedASTType<C> &tw) :
+ ClangASTType(tw)
+ {
+ }
+
+ TaggedASTType () :
+ ClangASTType()
+ {
+ }
+
+ virtual
+ ~TaggedASTType()
+ {
+ }
+
+ TaggedASTType<C> &operator= (const TaggedASTType<C> &tw)
+ {
+ ClangASTType::operator= (tw);
+ return *this;
+ }
+};
+
+// Commonly-used tagged types, so code using them is interoperable
+typedef TaggedASTType<0> TypeFromParser;
+typedef TaggedASTType<1> TypeFromUser;
+
+}
+
+#endif
diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h
new file mode 100644
index 000000000000..50b22fe96b9d
--- /dev/null
+++ b/include/lldb/Symbol/Type.h
@@ -0,0 +1,596 @@
+//===-- Type.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_Type_h_
+#define liblldb_Type_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/Declaration.h"
+
+#include <set>
+
+namespace lldb_private {
+
+class SymbolFileType :
+ public std::enable_shared_from_this<SymbolFileType>,
+ public UserID
+ {
+ public:
+ SymbolFileType (SymbolFile &symbol_file, lldb::user_id_t uid) :
+ UserID (uid),
+ m_symbol_file (symbol_file)
+ {
+ }
+
+ ~SymbolFileType ()
+ {
+ }
+
+ Type *
+ operator->()
+ {
+ return GetType ();
+ }
+
+ Type *
+ GetType ();
+
+ protected:
+ SymbolFile &m_symbol_file;
+ lldb::TypeSP m_type_sp;
+ };
+
+class Type :
+ public std::enable_shared_from_this<Type>,
+ public UserID
+{
+public:
+ typedef enum EncodingDataTypeTag
+ {
+ eEncodingInvalid,
+ eEncodingIsUID, ///< This type is the type whose UID is m_encoding_uid
+ eEncodingIsConstUID, ///< This type is the type whose UID is m_encoding_uid with the const qualifier added
+ eEncodingIsRestrictUID, ///< This type is the type whose UID is m_encoding_uid with the restrict qualifier added
+ eEncodingIsVolatileUID, ///< This type is the type whose UID is m_encoding_uid with the volatile qualifier added
+ eEncodingIsTypedefUID, ///< This type is pointer to a type whose UID is m_encoding_uid
+ eEncodingIsPointerUID, ///< This type is pointer to a type whose UID is m_encoding_uid
+ eEncodingIsLValueReferenceUID, ///< This type is L value reference to a type whose UID is m_encoding_uid
+ eEncodingIsRValueReferenceUID, ///< This type is R value reference to a type whose UID is m_encoding_uid
+ eEncodingIsSyntheticUID
+ } EncodingDataType;
+
+ typedef enum ResolveStateTag
+ {
+ eResolveStateUnresolved = 0,
+ eResolveStateForward = 1,
+ eResolveStateLayout = 2,
+ eResolveStateFull = 3
+ } ResolveState;
+
+ Type (lldb::user_id_t uid,
+ SymbolFile* symbol_file,
+ const ConstString &name,
+ uint64_t byte_size,
+ SymbolContextScope *context,
+ lldb::user_id_t encoding_uid,
+ EncodingDataType encoding_uid_type,
+ const Declaration& decl,
+ const ClangASTType &clang_qual_type,
+ ResolveState clang_type_resolve_state);
+
+ // This makes an invalid type. Used for functions that return a Type when they
+ // get an error.
+ Type();
+
+ Type (const Type &rhs);
+
+ const Type&
+ operator= (const Type& rhs);
+
+ void
+ Dump(Stream *s, bool show_context);
+
+ void
+ DumpTypeName(Stream *s);
+
+
+ void
+ GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name);
+
+ SymbolFile *
+ GetSymbolFile()
+ {
+ return m_symbol_file;
+ }
+ const SymbolFile *
+ GetSymbolFile() const
+ {
+ return m_symbol_file;
+ }
+
+ TypeList*
+ GetTypeList();
+
+ const ConstString&
+ GetName();
+
+ uint64_t
+ GetByteSize();
+
+ uint32_t
+ GetNumChildren (bool omit_empty_base_classes);
+
+ bool
+ IsAggregateType ();
+
+ bool
+ IsValidType ()
+ {
+ return m_encoding_uid_type != eEncodingInvalid;
+ }
+
+ bool
+ IsTypedef ()
+ {
+ return m_encoding_uid_type == eEncodingIsTypedefUID;
+ }
+
+ lldb::TypeSP
+ GetTypedefType();
+
+ const ConstString &
+ GetName () const
+ {
+ return m_name;
+ }
+
+ ConstString
+ GetQualifiedName ();
+
+ void
+ DumpValue(ExecutionContext *exe_ctx,
+ Stream *s,
+ const DataExtractor &data,
+ uint32_t data_offset,
+ bool show_type,
+ bool show_summary,
+ bool verbose,
+ lldb::Format format = lldb::eFormatDefault);
+
+ bool
+ DumpValueInMemory(ExecutionContext *exe_ctx,
+ Stream *s,
+ lldb::addr_t address,
+ AddressType address_type,
+ bool show_types,
+ bool show_summary,
+ bool verbose);
+
+ bool
+ ReadFromMemory (ExecutionContext *exe_ctx,
+ lldb::addr_t address,
+ AddressType address_type,
+ DataExtractor &data);
+
+ bool
+ WriteToMemory (ExecutionContext *exe_ctx,
+ lldb::addr_t address,
+ AddressType address_type,
+ DataExtractor &data);
+
+ bool
+ GetIsDeclaration() const;
+
+ void
+ SetIsDeclaration(bool b);
+
+ bool
+ GetIsExternal() const;
+
+ void
+ SetIsExternal(bool b);
+
+ lldb::Format
+ GetFormat ();
+
+ lldb::Encoding
+ GetEncoding (uint64_t &count);
+
+ SymbolContextScope *
+ GetSymbolContextScope()
+ {
+ return m_context;
+ }
+ const SymbolContextScope *
+ GetSymbolContextScope() const
+ {
+ return m_context;
+ }
+ void
+ SetSymbolContextScope(SymbolContextScope *context)
+ {
+ m_context = context;
+ }
+
+ const lldb_private::Declaration &
+ GetDeclaration () const;
+
+ // Get the clang type, and resolve definitions for any
+ // class/struct/union/enum types completely.
+ ClangASTType
+ GetClangFullType ();
+
+ // Get the clang type, and resolve definitions enough so that the type could
+ // have layout performed. This allows ptrs and refs to class/struct/union/enum
+ // types remain forward declarations.
+ ClangASTType
+ GetClangLayoutType ();
+
+ // Get the clang type and leave class/struct/union/enum types as forward
+ // declarations if they haven't already been fully defined.
+ ClangASTType
+ GetClangForwardType ();
+
+ ClangASTContext &
+ GetClangASTContext ();
+
+ static int
+ Compare(const Type &a, const Type &b);
+
+ // From a fully qualified typename, split the type into the type basename
+ // and the remaining type scope (namespaces/classes).
+ static bool
+ GetTypeScopeAndBasename (const char* &name_cstr,
+ std::string &scope,
+ std::string &basename,
+ lldb::TypeClass &type_class);
+ void
+ SetEncodingType (Type *encoding_type)
+ {
+ m_encoding_type = encoding_type;
+ }
+
+ uint32_t
+ GetEncodingMask ();
+
+ ClangASTType
+ CreateClangTypedefType (Type *typedef_type, Type *base_type);
+
+ bool
+ IsRealObjCClass();
+
+ bool
+ IsCompleteObjCClass()
+ {
+ return m_flags.is_complete_objc_class;
+ }
+
+ void
+ SetIsCompleteObjCClass(bool is_complete_objc_class)
+ {
+ m_flags.is_complete_objc_class = is_complete_objc_class;
+ }
+
+protected:
+ ConstString m_name;
+ SymbolFile *m_symbol_file;
+ SymbolContextScope *m_context; // The symbol context in which this type is defined
+ Type *m_encoding_type;
+ lldb::user_id_t m_encoding_uid;
+ EncodingDataType m_encoding_uid_type;
+ uint64_t m_byte_size;
+ Declaration m_decl;
+ ClangASTType m_clang_type;
+
+ struct Flags {
+ ResolveState clang_type_resolve_state : 2;
+ bool is_complete_objc_class : 1;
+ } m_flags;
+
+ Type *
+ GetEncodingType ();
+
+ bool
+ ResolveClangType (ResolveState clang_type_resolve_state);
+};
+
+
+///
+/// Sometimes you can find the name of the type corresponding to an object, but we don't have debug
+/// information for it. If that is the case, you can return one of these objects, and then if it
+/// has a full type, you can use that, but if not at least you can print the name for informational
+/// purposes.
+///
+
+class TypeAndOrName
+{
+public:
+ TypeAndOrName ();
+ TypeAndOrName (lldb::TypeSP &type_sp);
+ TypeAndOrName (const char *type_str);
+ TypeAndOrName (const TypeAndOrName &rhs);
+ TypeAndOrName (ConstString &type_const_string);
+
+ TypeAndOrName &
+ operator= (const TypeAndOrName &rhs);
+
+ bool
+ operator==(const TypeAndOrName &other) const;
+
+ bool
+ operator!=(const TypeAndOrName &other) const;
+
+ ConstString GetName () const;
+
+ lldb::TypeSP
+ GetTypeSP () const
+ {
+ return m_type_sp;
+ }
+
+ void
+ SetName (const ConstString &type_name);
+
+ void
+ SetName (const char *type_name_cstr);
+
+ void
+ SetTypeSP (lldb::TypeSP type_sp);
+
+ bool
+ IsEmpty ();
+
+ bool
+ HasName ();
+
+ bool
+ HasTypeSP ();
+
+ void
+ Clear ();
+
+ operator
+ bool ()
+ {
+ return !IsEmpty();
+ }
+
+private:
+ lldb::TypeSP m_type_sp;
+ ConstString m_type_name;
+};
+
+// the two classes here are used by the public API as a backend to
+// the SBType and SBTypeList classes
+
+class TypeImpl
+{
+public:
+
+ TypeImpl() :
+ m_clang_ast_type(),
+ m_type_sp()
+ {
+ }
+
+ TypeImpl(const TypeImpl& rhs) :
+ m_clang_ast_type(rhs.m_clang_ast_type),
+ m_type_sp(rhs.m_type_sp)
+ {
+ }
+
+ TypeImpl(const lldb_private::ClangASTType& type);
+
+ TypeImpl(const lldb::TypeSP& type);
+
+ TypeImpl&
+ operator = (const TypeImpl& rhs);
+
+ bool
+ operator == (const TypeImpl& rhs)
+ {
+ return m_clang_ast_type == rhs.m_clang_ast_type && m_type_sp.get() == rhs.m_type_sp.get();
+ }
+
+ bool
+ operator != (const TypeImpl& rhs)
+ {
+ return m_clang_ast_type != rhs.m_clang_ast_type || m_type_sp.get() != rhs.m_type_sp.get();
+ }
+
+ bool
+ IsValid()
+ {
+ return m_type_sp.get() != NULL || m_clang_ast_type.IsValid();
+ }
+
+ const lldb_private::ClangASTType &
+ GetClangASTType() const
+ {
+ return m_clang_ast_type;
+ }
+
+ clang::ASTContext*
+ GetASTContext();
+
+ lldb::clang_type_t
+ GetOpaqueQualType();
+
+ lldb::TypeSP
+ GetTypeSP ()
+ {
+ return m_type_sp;
+ }
+
+ ConstString
+ GetName ();
+
+ bool
+ GetDescription (lldb_private::Stream &strm,
+ lldb::DescriptionLevel description_level);
+
+ void
+ SetType (const lldb::TypeSP &type_sp);
+
+private:
+ ClangASTType m_clang_ast_type;
+ lldb::TypeSP m_type_sp;
+};
+
+class TypeListImpl
+{
+public:
+ TypeListImpl() :
+ m_content()
+ {
+ }
+
+ void
+ Append (const lldb::TypeImplSP& type)
+ {
+ m_content.push_back(type);
+ }
+
+ class AppendVisitor
+ {
+ public:
+ AppendVisitor(TypeListImpl &type_list) :
+ m_type_list(type_list)
+ {
+ }
+
+ void
+ operator() (const lldb::TypeImplSP& type)
+ {
+ m_type_list.Append(type);
+ }
+
+ private:
+ TypeListImpl &m_type_list;
+ };
+
+ void
+ Append (const lldb_private::TypeList &type_list);
+
+ lldb::TypeImplSP
+ GetTypeAtIndex(size_t idx)
+ {
+ lldb::TypeImplSP type_sp;
+ if (idx < GetSize())
+ type_sp = m_content[idx];
+ return type_sp;
+ }
+
+ size_t
+ GetSize()
+ {
+ return m_content.size();
+ }
+
+private:
+ std::vector<lldb::TypeImplSP> m_content;
+};
+
+class TypeMemberImpl
+{
+public:
+ TypeMemberImpl () :
+ m_type_impl_sp (),
+ m_bit_offset (0),
+ m_name (),
+ m_bitfield_bit_size (0),
+ m_is_bitfield (false)
+
+ {
+ }
+
+ TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp,
+ uint64_t bit_offset,
+ const ConstString &name,
+ uint32_t bitfield_bit_size = 0,
+ bool is_bitfield = false) :
+ m_type_impl_sp (type_impl_sp),
+ m_bit_offset (bit_offset),
+ m_name (name),
+ m_bitfield_bit_size (bitfield_bit_size),
+ m_is_bitfield (is_bitfield)
+ {
+ }
+
+ TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp,
+ uint64_t bit_offset):
+ m_type_impl_sp (type_impl_sp),
+ m_bit_offset (bit_offset),
+ m_name (),
+ m_bitfield_bit_size (0),
+ m_is_bitfield (false)
+ {
+ if (m_type_impl_sp)
+ m_name = m_type_impl_sp->GetName();
+ }
+
+ const lldb::TypeImplSP &
+ GetTypeImpl ()
+ {
+ return m_type_impl_sp;
+ }
+
+ const ConstString &
+ GetName () const
+ {
+ return m_name;
+ }
+
+ uint64_t
+ GetBitOffset () const
+ {
+ return m_bit_offset;
+ }
+
+ uint32_t
+ GetBitfieldBitSize () const
+ {
+ return m_bitfield_bit_size;
+ }
+
+ void
+ SetBitfieldBitSize (uint32_t bitfield_bit_size)
+ {
+ m_bitfield_bit_size = bitfield_bit_size;
+ }
+
+ bool
+ GetIsBitfield () const
+ {
+ return m_is_bitfield;
+ }
+
+ void
+ SetIsBitfield (bool is_bitfield)
+ {
+ m_is_bitfield = is_bitfield;
+ }
+
+protected:
+ lldb::TypeImplSP m_type_impl_sp;
+ uint64_t m_bit_offset;
+ ConstString m_name;
+ uint32_t m_bitfield_bit_size; // Bit size for bitfield members only
+ bool m_is_bitfield;
+};
+
+
+} // namespace lldb_private
+
+#endif // liblldb_Type_h_
+
diff --git a/include/lldb/Symbol/TypeList.h b/include/lldb/Symbol/TypeList.h
new file mode 100644
index 000000000000..9c74db6bf1f4
--- /dev/null
+++ b/include/lldb/Symbol/TypeList.h
@@ -0,0 +1,88 @@
+//===-- TypeList.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_TypeList_h_
+#define liblldb_TypeList_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Symbol/Type.h"
+#include <map>
+
+namespace lldb_private {
+
+class TypeList
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ TypeList();
+
+ virtual
+ ~TypeList();
+
+ void
+ Clear();
+
+ void
+ Dump(Stream *s, bool show_context);
+
+// lldb::TypeSP
+// FindType(lldb::user_id_t uid);
+
+ TypeList
+ FindTypes(const ConstString &name);
+
+ void
+ Insert (const lldb::TypeSP& type);
+
+ bool
+ InsertUnique (const lldb::TypeSP& type);
+
+ uint32_t
+ GetSize() const;
+
+ lldb::TypeSP
+ GetTypeAtIndex(uint32_t idx);
+
+ void
+ ForEach (std::function <bool(const lldb::TypeSP &type_sp)> const &callback) const;
+
+ void
+ ForEach (std::function <bool(lldb::TypeSP &type_sp)> const &callback);
+
+ bool
+ RemoveTypeWithUID (lldb::user_id_t uid);
+
+ void
+ RemoveMismatchedTypes (const char *qualified_typename,
+ bool exact_match);
+
+ void
+ RemoveMismatchedTypes (const std::string &type_scope,
+ const std::string &type_basename,
+ lldb::TypeClass type_class,
+ bool exact_match);
+
+ void
+ RemoveMismatchedTypes (lldb::TypeClass type_class);
+
+private:
+ typedef std::multimap<lldb::user_id_t, lldb::TypeSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ collection m_types;
+
+ DISALLOW_COPY_AND_ASSIGN (TypeList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_TypeList_h_
diff --git a/include/lldb/Symbol/TypeVendor.h b/include/lldb/Symbol/TypeVendor.h
new file mode 100644
index 000000000000..559b21eeb95a
--- /dev/null
+++ b/include/lldb/Symbol/TypeVendor.h
@@ -0,0 +1,61 @@
+//===-- TypeVendor.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_TypeVendor_h_
+#define liblldb_TypeVendor_h_
+
+#include "lldb/Core/ClangForward.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// The type vendor class is intended as a generic interface to search
+// for Clang types that are not necessarily backed by a specific symbol
+// file.
+//----------------------------------------------------------------------
+class TypeVendor
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ TypeVendor()
+ {
+ }
+
+ virtual
+ ~TypeVendor()
+ {
+ }
+
+ virtual uint32_t
+ FindTypes (const ConstString &name,
+ bool append,
+ uint32_t max_matches,
+ std::vector <ClangASTType> &types) = 0;
+
+ virtual clang::ASTContext *
+ GetClangASTContext () = 0;
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from TypeVendor can see and modify these
+ //------------------------------------------------------------------
+
+private:
+ //------------------------------------------------------------------
+ // For TypeVendor only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (TypeVendor);
+};
+
+
+} // namespace lldb_private
+
+#endif
diff --git a/include/lldb/Symbol/UnwindPlan.h b/include/lldb/Symbol/UnwindPlan.h
new file mode 100644
index 000000000000..6fc5ce042357
--- /dev/null
+++ b/include/lldb/Symbol/UnwindPlan.h
@@ -0,0 +1,499 @@
+#ifndef liblldb_UnwindPlan_h
+#define liblldb_UnwindPlan_h
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ConstString.h"
+
+#include <map>
+#include <vector>
+
+namespace lldb_private {
+
+// The UnwindPlan object specifies how to unwind out of a function - where
+// this function saves the caller's register values before modifying them
+// (for non-volatile aka saved registers) and how to find this frame's
+// Canonical Frame Address (CFA).
+
+// Most commonly, registers are saved on the stack, offset some bytes from
+// the Canonical Frame Address, or CFA, which is the starting address of
+// this function's stack frame (the CFA is same as the eh_frame's CFA,
+// whatever that may be on a given architecture).
+// The CFA address for the stack frame does not change during
+// the lifetime of the function.
+
+// Internally, the UnwindPlan is structured as a vector of register locations
+// organized by code address in the function, showing which registers have been
+// saved at that point and where they are saved.
+// It can be thought of as the expanded table form of the DWARF CFI
+// encoded information.
+
+// Other unwind information sources will be converted into UnwindPlans before
+// being added to a FuncUnwinders object. The unwind source may be
+// an eh_frame FDE, a DWARF debug_frame FDE, or assembly language based
+// prologue analysis.
+// The UnwindPlan is the canonical form of this information that the unwinder
+// code will use when walking the stack.
+
+class UnwindPlan {
+public:
+
+ class Row {
+ public:
+ class RegisterLocation
+ {
+ public:
+
+ enum RestoreType
+ {
+ unspecified, // not specified, we may be able to assume this
+ // is the same register. gcc doesn't specify all
+ // initial values so we really don't know...
+ undefined, // reg is not available, e.g. volatile reg
+ same, // reg is unchanged
+ atCFAPlusOffset, // reg = deref(CFA + offset)
+ isCFAPlusOffset, // reg = CFA + offset
+ inOtherRegister, // reg = other reg
+ atDWARFExpression, // reg = deref(eval(dwarf_expr))
+ isDWARFExpression // reg = eval(dwarf_expr)
+ };
+
+ RegisterLocation() :
+ m_type(unspecified),
+ m_location()
+ {
+ }
+
+ bool
+ operator == (const RegisterLocation& rhs) const;
+
+ bool
+ operator != (const RegisterLocation &rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ void
+ SetUnspecified()
+ {
+ m_type = unspecified;
+ }
+
+ void
+ SetUndefined()
+ {
+ m_type = undefined;
+ }
+
+ void
+ SetSame()
+ {
+ m_type = same;
+ }
+
+ bool
+ IsSame () const
+ {
+ return m_type == same;
+ }
+
+ bool
+ IsUnspecified () const
+ {
+ return m_type == unspecified;
+ }
+
+ bool
+ IsCFAPlusOffset () const
+ {
+ return m_type == isCFAPlusOffset;
+ }
+
+ bool
+ IsAtCFAPlusOffset () const
+ {
+ return m_type == atCFAPlusOffset;
+ }
+
+ bool
+ IsInOtherRegister () const
+ {
+ return m_type == inOtherRegister;
+ }
+
+ bool
+ IsAtDWARFExpression () const
+ {
+ return m_type == atDWARFExpression;
+ }
+
+ bool
+ IsDWARFExpression () const
+ {
+ return m_type == isDWARFExpression;
+ }
+
+ void
+ SetAtCFAPlusOffset (int32_t offset)
+ {
+ m_type = atCFAPlusOffset;
+ m_location.offset = offset;
+ }
+
+ void
+ SetIsCFAPlusOffset (int32_t offset)
+ {
+ m_type = isCFAPlusOffset;
+ m_location.offset = offset;
+ }
+
+ void
+ SetInRegister (uint32_t reg_num)
+ {
+ m_type = inOtherRegister;
+ m_location.reg_num = reg_num;
+ }
+
+ uint32_t
+ GetRegisterNumber () const
+ {
+ if (m_type == inOtherRegister)
+ return m_location.reg_num;
+ return LLDB_INVALID_REGNUM;
+ }
+
+ RestoreType
+ GetLocationType () const
+ {
+ return m_type;
+ }
+
+ int32_t
+ GetOffset () const
+ {
+ if (m_type == atCFAPlusOffset || m_type == isCFAPlusOffset)
+ return m_location.offset;
+ return 0;
+ }
+
+ void
+ GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const
+ {
+ if (m_type == atDWARFExpression || m_type == isDWARFExpression)
+ {
+ *opcodes = m_location.expr.opcodes;
+ len = m_location.expr.length;
+ }
+ else
+ {
+ *opcodes = NULL;
+ len = 0;
+ }
+ }
+
+ void
+ SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len);
+
+ void
+ SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len);
+
+ const uint8_t *
+ GetDWARFExpressionBytes ()
+ {
+ if (m_type == atDWARFExpression || m_type == isDWARFExpression)
+ return m_location.expr.opcodes;
+ return NULL;
+ }
+
+ int
+ GetDWARFExpressionLength ()
+ {
+ if (m_type == atDWARFExpression || m_type == isDWARFExpression)
+ return m_location.expr.length;
+ return 0;
+ }
+
+ void
+ Dump (Stream &s,
+ const UnwindPlan* unwind_plan,
+ const UnwindPlan::Row* row,
+ Thread* thread,
+ bool verbose) const;
+
+ private:
+ RestoreType m_type; // How do we locate this register?
+ union
+ {
+ // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset
+ int32_t offset;
+ // For m_type == inOtherRegister
+ uint32_t reg_num; // The register number
+ // For m_type == atDWARFExpression or m_type == isDWARFExpression
+ struct {
+ const uint8_t *opcodes;
+ uint16_t length;
+ } expr;
+ } m_location;
+ };
+
+ public:
+ Row ();
+
+ Row (const UnwindPlan::Row& rhs) :
+ m_offset (rhs.m_offset),
+ m_cfa_reg_num (rhs.m_cfa_reg_num),
+ m_cfa_offset (rhs.m_cfa_offset),
+ m_register_locations (rhs.m_register_locations)
+ {
+ }
+
+ bool
+ operator == (const Row &rhs) const;
+
+ bool
+ GetRegisterInfo (uint32_t reg_num, RegisterLocation& register_location) const;
+
+ void
+ SetRegisterInfo (uint32_t reg_num, const RegisterLocation register_location);
+
+ lldb::addr_t
+ GetOffset() const
+ {
+ return m_offset;
+ }
+
+ void
+ SetOffset(lldb::addr_t offset)
+ {
+ m_offset = offset;
+ }
+
+ void
+ SlideOffset(lldb::addr_t offset)
+ {
+ m_offset += offset;
+ }
+
+ uint32_t
+ GetCFARegister () const
+ {
+ return m_cfa_reg_num;
+ }
+
+ bool
+ SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num,
+ int32_t offset,
+ bool can_replace);
+
+ bool
+ SetRegisterLocationToIsCFAPlusOffset (uint32_t reg_num,
+ int32_t offset,
+ bool can_replace);
+
+ bool
+ SetRegisterLocationToUndefined (uint32_t reg_num,
+ bool can_replace,
+ bool can_replace_only_if_unspecified);
+
+ bool
+ SetRegisterLocationToUnspecified (uint32_t reg_num,
+ bool can_replace);
+
+ bool
+ SetRegisterLocationToRegister (uint32_t reg_num,
+ uint32_t other_reg_num,
+ bool can_replace);
+
+ bool
+ SetRegisterLocationToSame (uint32_t reg_num,
+ bool must_replace);
+
+
+
+ void
+ SetCFARegister (uint32_t reg_num);
+
+ int32_t
+ GetCFAOffset () const
+ {
+ return m_cfa_offset;
+ }
+
+ void
+ SetCFAOffset (int32_t offset)
+ {
+ m_cfa_offset = offset;
+ }
+
+ void
+ Clear ();
+
+ void
+ Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, lldb::addr_t base_addr) const;
+
+ protected:
+ typedef std::map<uint32_t, RegisterLocation> collection;
+ lldb::addr_t m_offset; // Offset into the function for this row
+ uint32_t m_cfa_reg_num; // The Call Frame Address register number
+ int32_t m_cfa_offset; // The offset from the CFA for this row
+ collection m_register_locations;
+ }; // class Row
+
+public:
+
+ typedef std::shared_ptr<Row> RowSP;
+
+ UnwindPlan (lldb::RegisterKind reg_kind) :
+ m_row_list (),
+ m_plan_valid_address_range (),
+ m_register_kind (reg_kind),
+ m_return_addr_register (LLDB_INVALID_REGNUM),
+ m_source_name (),
+ m_plan_is_sourced_from_compiler (eLazyBoolCalculate),
+ m_plan_is_valid_at_all_instruction_locations (eLazyBoolCalculate)
+ {
+ }
+
+ ~UnwindPlan ()
+ {
+ }
+
+ void
+ Dump (Stream& s, Thread* thread, lldb::addr_t base_addr) const;
+
+ void
+ AppendRow (const RowSP& row_sp);
+
+ // Returns a pointer to the best row for the given offset into the function's instructions.
+ // If offset is -1 it indicates that the function start is unknown - the final row in the UnwindPlan is returned.
+ // In practice, the UnwindPlan for a function with no known start address will be the architectural default
+ // UnwindPlan which will only have one row.
+ UnwindPlan::RowSP
+ GetRowForFunctionOffset (int offset) const;
+
+ lldb::RegisterKind
+ GetRegisterKind () const
+ {
+ return m_register_kind;
+ }
+
+ void
+ SetRegisterKind (lldb::RegisterKind kind)
+ {
+ m_register_kind = kind;
+ }
+
+ void
+ SetReturnAddressRegister (uint32_t regnum)
+ {
+ m_return_addr_register = regnum;
+ }
+
+ uint32_t
+ GetReturnAddressRegister (void)
+ {
+ return m_return_addr_register;
+ }
+
+ uint32_t
+ GetInitialCFARegister () const
+ {
+ if (m_row_list.empty())
+ return LLDB_INVALID_REGNUM;
+ return m_row_list.front()->GetCFARegister();
+ }
+
+ // This UnwindPlan may not be valid at every address of the function span.
+ // For instance, a FastUnwindPlan will not be valid at the prologue setup
+ // instructions - only in the body of the function.
+ void
+ SetPlanValidAddressRange (const AddressRange& range);
+
+ const AddressRange &
+ GetAddressRange () const
+ {
+ return m_plan_valid_address_range;
+ }
+
+ bool
+ PlanValidAtAddress (Address addr);
+
+ bool
+ IsValidRowIndex (uint32_t idx) const;
+
+ const UnwindPlan::RowSP
+ GetRowAtIndex (uint32_t idx) const;
+
+ const UnwindPlan::RowSP
+ GetLastRow () const;
+
+ lldb_private::ConstString
+ GetSourceName () const;
+
+ void
+ SetSourceName (const char *);
+
+ // Was this UnwindPlan emitted by a compiler?
+ lldb_private::LazyBool
+ GetSourcedFromCompiler () const
+ {
+ return m_plan_is_sourced_from_compiler;
+ }
+
+ // Was this UnwindPlan emitted by a compiler?
+ void
+ SetSourcedFromCompiler (lldb_private::LazyBool from_compiler)
+ {
+ m_plan_is_sourced_from_compiler = from_compiler;
+ }
+
+ // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites,
+ // e.g. for exception handling.
+ lldb_private::LazyBool
+ GetUnwindPlanValidAtAllInstructions () const
+ {
+ return m_plan_is_valid_at_all_instruction_locations;
+ }
+
+ // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites,
+ // e.g. for exception handling.
+ void
+ SetUnwindPlanValidAtAllInstructions (lldb_private::LazyBool valid_at_all_insn)
+ {
+ m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn;
+ }
+
+ int
+ GetRowCount () const;
+
+ void
+ Clear()
+ {
+ m_row_list.clear();
+ m_plan_valid_address_range.Clear();
+ m_register_kind = lldb::eRegisterKindDWARF;
+ m_source_name.Clear();
+ }
+
+ const RegisterInfo *
+ GetRegisterInfo (Thread* thread, uint32_t reg_num) const;
+
+private:
+
+
+ typedef std::vector<RowSP> collection;
+ collection m_row_list;
+ AddressRange m_plan_valid_address_range;
+ lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers are in terms of - will need to be
+ // translated to lldb native reg nums at unwind time
+ uint32_t m_return_addr_register; // The register that has the return address for the caller frame
+ // e.g. the lr on arm
+ lldb_private::ConstString m_source_name; // for logging, where this UnwindPlan originated from
+ lldb_private::LazyBool m_plan_is_sourced_from_compiler;
+ lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations;
+}; // class UnwindPlan
+
+} // namespace lldb_private
+
+#endif //liblldb_UnwindPlan_h
diff --git a/include/lldb/Symbol/UnwindTable.h b/include/lldb/Symbol/UnwindTable.h
new file mode 100644
index 000000000000..cefb91eb371a
--- /dev/null
+++ b/include/lldb/Symbol/UnwindTable.h
@@ -0,0 +1,69 @@
+//===-- Symtab.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_UnwindTable_h
+#define liblldb_UnwindTable_h
+
+#include <map>
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// A class which holds all the FuncUnwinders objects for a given ObjectFile.
+// The UnwindTable is populated with FuncUnwinders objects lazily during
+// the debug session.
+
+class UnwindTable
+{
+public:
+ UnwindTable(ObjectFile& objfile);
+ ~UnwindTable();
+
+ lldb_private::DWARFCallFrameInfo *
+ GetEHFrameInfo ();
+
+ lldb::FuncUnwindersSP
+ GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc);
+
+// Normally when we create a new FuncUnwinders object we track it in this UnwindTable so it can
+// be reused later. But for the target modules show-unwind we want to create brand new
+// UnwindPlans for the function of interest - so ignore any existing FuncUnwinders for that
+// function and don't add this new one to our UnwindTable.
+// This FuncUnwinders object does have a reference to the UnwindTable but the lifetime of this
+// uncached FuncUnwinders is expected to be short so in practice this will not be a problem.
+ lldb::FuncUnwindersSP
+ GetUncachedFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc);
+
+private:
+ void
+ Dump (Stream &s);
+
+ void Initialize ();
+
+ typedef std::map<lldb::addr_t, lldb::FuncUnwindersSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ ObjectFile& m_object_file;
+ collection m_unwinds;
+
+ bool m_initialized; // delay some initialization until ObjectFile is set up
+
+ UnwindAssembly* m_assembly_profiler;
+
+ DWARFCallFrameInfo* m_eh_frame;
+
+ DISALLOW_COPY_AND_ASSIGN (UnwindTable);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_UnwindTable_h
diff --git a/include/lldb/Symbol/Variable.h b/include/lldb/Symbol/Variable.h
new file mode 100644
index 000000000000..07295d090ee6
--- /dev/null
+++ b/include/lldb/Symbol/Variable.h
@@ -0,0 +1,184 @@
+//===-- Variable.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_Variable_h_
+#define liblldb_Variable_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/Mangled.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Symbol/Declaration.h"
+
+namespace lldb_private {
+
+class Variable : public UserID
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ Variable (lldb::user_id_t uid,
+ const char *name,
+ const char *mangled, // The mangled variable name for variables in namespaces
+ const lldb::SymbolFileTypeSP &symfile_type_sp,
+ lldb::ValueType scope,
+ SymbolContextScope *owner_scope,
+ Declaration* decl,
+ const DWARFExpression& location,
+ bool external,
+ bool artificial);
+
+ virtual
+ ~Variable();
+
+ void
+ Dump(Stream *s, bool show_context) const;
+
+ bool
+ DumpDeclaration (Stream *s,
+ bool show_fullpaths,
+ bool show_module);
+
+ const Declaration&
+ GetDeclaration() const
+ {
+ return m_declaration;
+ }
+
+ const ConstString&
+ GetName() const;
+
+ SymbolContextScope *
+ GetSymbolContextScope() const
+ {
+ return m_owner_scope;
+ }
+
+ // Since a variable can have a basename "i" and also a mangled
+ // named "_ZN12_GLOBAL__N_11iE" and a demangled mangled name
+ // "(anonymous namespace)::i", this function will allow a generic match
+ // function that can be called by commands and expression parsers to make
+ // sure we match anything we come across.
+ bool
+ NameMatches (const ConstString &name) const
+ {
+ if (m_name == name)
+ return true;
+ return m_mangled.NameMatches (name);
+ }
+
+ bool
+ NameMatches (const RegularExpression& regex) const;
+
+ Type *
+ GetType();
+
+ lldb::ValueType
+ GetScope() const
+ {
+ return m_scope;
+ }
+
+ bool
+ IsExternal() const
+ {
+ return m_external;
+ }
+
+ bool
+ IsArtificial() const
+ {
+ return m_artificial;
+ }
+
+ DWARFExpression &
+ LocationExpression()
+ {
+ return m_location;
+ }
+
+ const DWARFExpression &
+ LocationExpression() const
+ {
+ return m_location;
+ }
+
+ bool
+ DumpLocationForAddress (Stream *s,
+ const Address &address);
+
+ size_t
+ MemorySize() const;
+
+ void
+ CalculateSymbolContext (SymbolContext *sc);
+
+ bool
+ IsInScope (StackFrame *frame);
+
+ bool
+ LocationIsValidForFrame (StackFrame *frame);
+
+ bool
+ LocationIsValidForAddress (const Address &address);
+
+ bool
+ GetLocationIsConstantValueData () const
+ {
+ return m_loc_is_const_data;
+ }
+
+ void
+ SetLocationIsConstantValueData (bool b)
+ {
+ m_loc_is_const_data = b;
+ }
+
+ typedef size_t (*GetVariableCallback) (void *baton,
+ const char *name,
+ VariableList &var_list);
+
+
+ static Error
+ GetValuesForVariableExpressionPath (const char *variable_expr_path,
+ ExecutionContextScope *scope,
+ GetVariableCallback callback,
+ void *baton,
+ VariableList &variable_list,
+ ValueObjectList &valobj_list);
+
+ static size_t
+ AutoComplete (const ExecutionContext &exe_ctx,
+ const char *name,
+ StringList &matches,
+ bool &word_complete);
+
+protected:
+ ConstString m_name; // The basename of the variable (no namespaces)
+ Mangled m_mangled; // The mangled name of the variable
+ lldb::SymbolFileTypeSP m_symfile_type_sp; // The type pointer of the variable (int, struct, class, etc)
+ lldb::ValueType m_scope; // global, parameter, local
+ SymbolContextScope *m_owner_scope; // The symbol file scope that this variable was defined in
+ Declaration m_declaration; // Declaration location for this item.
+ DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate()
+ uint8_t m_external:1, // Visible outside the containing compile unit?
+ m_artificial:1, // Non-zero if the variable is not explicitly declared in source
+ m_loc_is_const_data:1; // The m_location expression contains the constant variable value data, not a DWARF location
+private:
+ Variable(const Variable& rhs);
+ Variable& operator=(const Variable& rhs);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Variable_h_
diff --git a/include/lldb/Symbol/VariableList.h b/include/lldb/Symbol/VariableList.h
new file mode 100644
index 000000000000..2ce6146f4627
--- /dev/null
+++ b/include/lldb/Symbol/VariableList.h
@@ -0,0 +1,95 @@
+//===-- VariableList.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_VariableList_h_
+#define liblldb_VariableList_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/Variable.h"
+
+namespace lldb_private {
+
+class VariableList
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+// VariableList(const SymbolContext &symbol_context);
+ VariableList();
+ virtual ~VariableList();
+
+ void
+ AddVariable (const lldb::VariableSP &var_sp);
+
+ bool
+ AddVariableIfUnique (const lldb::VariableSP &var_sp);
+
+ void
+ AddVariables (VariableList *variable_list);
+
+ void
+ Clear();
+
+ void
+ Dump(Stream *s, bool show_context) const;
+
+ lldb::VariableSP
+ GetVariableAtIndex(size_t idx) const;
+
+ lldb::VariableSP
+ RemoveVariableAtIndex (size_t idx);
+
+ lldb::VariableSP
+ FindVariable (const ConstString& name);
+
+ uint32_t
+ FindVariableIndex (const lldb::VariableSP &var_sp);
+
+ // Returns the actual number of unique variables that were added to the
+ // list. "total_matches" will get updated with the actualy number of
+ // matches that were found regardless of whether they were unique or not
+ // to allow for error conditions when nothing is found, versus conditions
+ // where any varaibles that match "regex" were already in "var_list".
+ size_t
+ AppendVariablesIfUnique (const RegularExpression& regex,
+ VariableList &var_list,
+ size_t& total_matches);
+
+ size_t
+ AppendVariablesWithScope (lldb::ValueType type,
+ VariableList &var_list,
+ bool if_unique = true);
+
+ uint32_t
+ FindIndexForVariable (Variable* variable);
+
+ size_t
+ MemorySize() const;
+
+ size_t
+ GetSize() const;
+
+protected:
+ typedef std::vector<lldb::VariableSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ collection m_variables;
+private:
+ //------------------------------------------------------------------
+ // For VariableList only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (VariableList);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_VariableList_h_
diff --git a/include/lldb/Symbol/VerifyDecl.h b/include/lldb/Symbol/VerifyDecl.h
new file mode 100644
index 000000000000..228e635652e6
--- /dev/null
+++ b/include/lldb/Symbol/VerifyDecl.h
@@ -0,0 +1,20 @@
+//===-- VerifyDecl.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_VariableList_h_
+#define lldb_VariableList_h_
+
+#include "lldb/Core/ClangForward.h"
+
+namespace lldb_private
+{
+ void VerifyDecl (clang::Decl *decl);
+}
+
+#endif