summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Expression/ClangASTSource.h61
-rw-r--r--lldb/include/lldb/Expression/ClangExpressionDeclMap.h4
-rw-r--r--lldb/include/lldb/Expression/ClangExpressionVariable.h17
-rw-r--r--lldb/include/lldb/Expression/ClangPersistentVariables.h3
-rw-r--r--lldb/include/lldb/Expression/RecordingMemoryManager.h140
-rw-r--r--lldb/include/lldb/Symbol/ClangASTImporter.h3
-rw-r--r--lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h9
-rw-r--r--lldb/scripts/build-llvm.pl4
-rw-r--r--lldb/scripts/clang.DebuggerCastResultToId.diff25
-rw-r--r--lldb/scripts/clang.complete-type-being-converted.diff14
-rw-r--r--lldb/scripts/clang.complete-type-being-laid-out.diff15
-rw-r--r--lldb/scripts/clang.complete-type-ivar-lookup.diff19
-rw-r--r--lldb/scripts/clang.instantiate-complete-type.diff15
-rw-r--r--lldb/scripts/clang.is-being-completed-from-lexical-storage.diff78
-rw-r--r--lldb/scripts/clang.require-complete-type.diff75
-rw-r--r--lldb/scripts/llvm.communicate-triple.diff199
-rw-r--r--lldb/scripts/llvm.delete-target-machine.diff12
-rw-r--r--lldb/source/Expression/ClangASTSource.cpp323
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp19
-rw-r--r--lldb/source/Expression/ClangExpressionParser.cpp71
-rw-r--r--lldb/source/Expression/ClangPersistentVariables.cpp14
-rw-r--r--lldb/source/Expression/IRForTarget.cpp5
-rw-r--r--lldb/source/Expression/IRInterpreter.cpp13
-rw-r--r--lldb/source/Expression/RecordingMemoryManager.cpp226
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp97
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp89
-rw-r--r--lldb/source/Symbol/ClangASTImporter.cpp69
-rw-r--r--lldb/source/Symbol/ClangASTType.cpp11
-rw-r--r--lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp21
-rw-r--r--lldb/test/lang/c/bitfields/TestBitfields.py8
-rw-r--r--lldb/test/lang/c/bitfields/main.c5
31 files changed, 979 insertions, 685 deletions
diff --git a/lldb/include/lldb/Expression/ClangASTSource.h b/lldb/include/lldb/Expression/ClangASTSource.h
index 3e5ae3d740e..b9e71d97d80 100644
--- a/lldb/include/lldb/Expression/ClangASTSource.h
+++ b/lldb/include/lldb/Expression/ClangASTSource.h
@@ -121,6 +121,47 @@ public:
llvm::SmallVectorImpl<clang::Decl*> &Decls);
//------------------------------------------------------------------
+ /// Specify the layout of the contents of a RecordDecl.
+ ///
+ /// @param[in] Record
+ /// The record (in the parser's AST context) that needs to be
+ /// laid out.
+ ///
+ /// @param[out] Size
+ /// The total size of the record in bits.
+ ///
+ /// @param[out] Alignment
+ /// The alignment of the record in bits.
+ ///
+ /// @param[in] FieldOffsets
+ /// A map that must be populated with pairs of the record's
+ /// fields (in the parser's AST context) and their offsets
+ /// (measured in bits).
+ ///
+ /// @param[in] BaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ concrete base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// @param[in] VirtualBaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ virtual base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// @return
+ /// True <=> the layout is valid.
+ //-----------------------------------------------------------------
+ bool
+ layoutRecordType(const clang::RecordDecl *Record,
+ uint64_t &Size,
+ uint64_t &Alignment,
+ llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets);
+
+ //------------------------------------------------------------------
/// Complete a TagDecl.
///
/// @param[in] Tag
@@ -233,6 +274,22 @@ public:
{
return m_original.CompleteType(Class);
}
+
+ bool
+ layoutRecordType(const clang::RecordDecl *Record,
+ uint64_t &Size,
+ uint64_t &Alignment,
+ llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets)
+ {
+ return m_original.layoutRecordType(Record,
+ Size,
+ Alignment,
+ FieldOffsets,
+ BaseOffsets,
+ VirtualBaseOffsets);
+ }
void StartTranslationUnit (clang::ASTConsumer *Consumer)
{
@@ -301,7 +358,7 @@ protected:
FindObjCMethodDecls (NameSearchContext &context);
//------------------------------------------------------------------
- /// Find all Objective-C properties with a given name.
+ /// Find all Objective-C properties and ivars with a given name.
///
/// @param[in] context
/// The NameSearchContext that can construct Decls for this name.
@@ -309,7 +366,7 @@ protected:
/// is the containing object.
//------------------------------------------------------------------
void
- FindObjCPropertyDecls (NameSearchContext &context);
+ FindObjCPropertyAndIvarDecls (NameSearchContext &context);
//------------------------------------------------------------------
/// A wrapper for ClangASTContext::CopyType that sets a flag that
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
index 3e0058db0da..71df587c2d7 100644
--- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
+++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
@@ -503,6 +503,10 @@ public:
bool transient,
bool maybe_make_load);
+
+ void
+ RemoveResultVariable (const ConstString &name);
+
//------------------------------------------------------------------
/// [Used by CommandObjectExpression] Materialize the entire struct
/// at a given address, which should be aligned as specified by
diff --git a/lldb/include/lldb/Expression/ClangExpressionVariable.h b/lldb/include/lldb/Expression/ClangExpressionVariable.h
index cdc2b7a72c1..21a1b63ae69 100644
--- a/lldb/include/lldb/Expression/ClangExpressionVariable.h
+++ b/lldb/include/lldb/Expression/ClangExpressionVariable.h
@@ -375,8 +375,6 @@ public:
m_variables.push_back(var_sp);
return var_sp;
}
-
-
lldb::ClangExpressionVariableSP
CreateVariable (ExecutionContextScope *exe_scope,
@@ -394,6 +392,21 @@ public:
}
void
+ RemoveVariable (lldb::ClangExpressionVariableSP var_sp)
+ {
+ for (std::vector<lldb::ClangExpressionVariableSP>::iterator vi = m_variables.begin(), ve = m_variables.end();
+ vi != ve;
+ ++vi)
+ {
+ if (vi->get() == var_sp.get())
+ {
+ m_variables.erase(vi);
+ return;
+ }
+ }
+ }
+
+ void
Clear()
{
m_variables.clear();
diff --git a/lldb/include/lldb/Expression/ClangPersistentVariables.h b/lldb/include/lldb/Expression/ClangPersistentVariables.h
index 2dff7ef41b8..6d9dae95473 100644
--- a/lldb/include/lldb/Expression/ClangPersistentVariables.h
+++ b/lldb/include/lldb/Expression/ClangPersistentVariables.h
@@ -52,6 +52,9 @@ public:
//----------------------------------------------------------------------
ConstString
GetNextPersistentVariableName ();
+
+ void
+ RemovePersistentVariable (lldb::ClangExpressionVariableSP variable);
void
RegisterPersistentType (const ConstString &name,
diff --git a/lldb/include/lldb/Expression/RecordingMemoryManager.h b/lldb/include/lldb/Expression/RecordingMemoryManager.h
index d70ff38e63f..b6bf61f3683 100644
--- a/lldb/include/lldb/Expression/RecordingMemoryManager.h
+++ b/lldb/include/lldb/Expression/RecordingMemoryManager.h
@@ -152,6 +152,43 @@ public:
/// Allocated space.
//------------------------------------------------------------------
virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
+
+ //------------------------------------------------------------------
+ /// Allocate space for executable code, and add it to the
+ /// m_spaceBlocks map
+ ///
+ /// @param[in] Size
+ /// The size of the area.
+ ///
+ /// @param[in] Alignment
+ /// The required alignment of the area.
+ ///
+ /// @param[in] SectionID
+ /// A unique identifier for the section.
+ ///
+ /// @return
+ /// Allocated space.
+ //------------------------------------------------------------------
+ virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID);
+
+ //------------------------------------------------------------------
+ /// Allocate space for data, and add it to the m_spaceBlocks map
+ ///
+ /// @param[in] Size
+ /// The size of the area.
+ ///
+ /// @param[in] Alignment
+ /// The required alignment of the area.
+ ///
+ /// @param[in] SectionID
+ /// A unique identifier for the section.
+ ///
+ /// @return
+ /// Allocated space.
+ //------------------------------------------------------------------
+ virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID);
//------------------------------------------------------------------
/// Allocate space for a global variable, and add it to the
@@ -246,7 +283,7 @@ public:
}
//------------------------------------------------------------------
- /// [Convenience method for ClangExpression] Look up the object in
+ /// [Convenience method for ClangExpressionParser] Look up the object in
/// m_address_map that contains a given address, find where it was
/// copied to, and return the remote address at the same offset into
/// the copied entity
@@ -261,7 +298,7 @@ public:
GetRemoteAddressForLocal (lldb::addr_t local_address);
//------------------------------------------------------------------
- /// [Convenience method for ClangExpression] Look up the object in
+ /// [Convenience method for ClangExpressionParser] Look up the object in
/// m_address_map that contains a given address, find where it was
/// copied to, and return its address range in the target process
///
@@ -271,61 +308,82 @@ public:
/// @return
/// The range of the containing object in the target process.
//------------------------------------------------------------------
- std::pair <lldb::addr_t, lldb::addr_t>
+ typedef std::pair <lldb::addr_t, uintptr_t> AddrRange;
+ AddrRange
GetRemoteRangeForLocal (lldb::addr_t local_address);
+
+ //------------------------------------------------------------------
+ /// [Convenience method for ClangExpressionParser] Commit all allocations
+ /// to the process and record where they were stored.
+ ///
+ /// @param[in] process
+ /// The process to allocate memory in.
+ ///
+ /// @return
+ /// True <=> all allocations were performed successfully.
+ /// This method will attempt to free allocated memory if the
+ /// operation fails.
+ //------------------------------------------------------------------
+ bool
+ CommitAllocations (Process &process);
+
+ //------------------------------------------------------------------
+ /// [Convenience method for ClangExpressionParser] Write the contents
+ /// of all allocations to the process.
+ ///
+ /// @param[in] local_address
+ /// The process containing the allocations.
+ ///
+ /// @return
+ /// True <=> all allocations were performed successfully.
+ //------------------------------------------------------------------
+ bool
+ WriteData (Process &process);
private:
std::auto_ptr<JITMemoryManager> m_default_mm_ap; ///< The memory allocator to use in actually creating space. All calls are passed through to it.
- std::map<uint8_t *, uint8_t *> m_functions; ///< A map from function base addresses to their end addresses.
- std::map<uint8_t *, intptr_t> m_spaceBlocks; ///< A map from the base addresses of generic allocations to their sizes.
- std::map<uint8_t *, unsigned> m_stubs; ///< A map from the base addresses of stubs to their sizes.
- std::map<uint8_t *, uintptr_t> m_globals; ///< A map from the base addresses of globals to their sizes.
- std::map<uint8_t *, uint8_t *> m_exception_tables; ///< A map from the base addresses of exception tables to their end addresses.
lldb::LogSP m_log; ///< The log to use when printing log messages. May be NULL.
//----------------------------------------------------------------------
- /// @class LocalToRemoteAddressRange RecordingMemoryManager.h "lldb/Expression/RecordingMemoryManager.h"
- /// @brief A record of an allocated region that has been copied into the target
+ /// @class Allocation RecordingMemoryManager.h "lldb/Expression/RecordingMemoryManager.h"
+ /// @brief A record of a region that has been allocated by the JIT.
///
/// The RecordingMemoryManager makes records of all regions that need copying;
- /// then, ClangExpression copies these regions into the target. It records
- /// what was copied where in records of type LocalToRemoteAddressRange.
+ /// upon requests, it allocates and
//----------------------------------------------------------------------
- struct LocalToRemoteAddressRange
+ struct Allocation
{
- lldb::addr_t m_local_start; ///< The base address of the local allocation
- size_t m_size; ///< The size of the allocation
- lldb::addr_t m_remote_start; ///< The base address of the remote allocation
-
+ lldb::addr_t m_remote_allocation;///< The (unaligned) base for the remote allocation
+ lldb::addr_t m_remote_start; ///< The base address of the remote allocation
+ uintptr_t m_local_start; ///< The base address of the local allocation
+ uintptr_t m_size; ///< The size of the allocation
+ unsigned m_section_id; ///< The ID of the section
+ unsigned m_alignment; ///< The required alignment for the allocation
+ bool m_executable; ///< True <=> the allocation must be executable in the target
+ bool m_allocated; ///< True <=> the allocation has been propagated to the target
+
+ static const unsigned eSectionIDNone = (unsigned)-1;
+
//------------------------------------------------------------------
/// Constructor
//------------------------------------------------------------------
- LocalToRemoteAddressRange (lldb::addr_t lstart, size_t size, lldb::addr_t rstart) :
- m_local_start (lstart),
- m_size (size),
- m_remote_start (rstart)
- {}
-
+ Allocation () :
+ m_remote_allocation(0),
+ m_remote_start(0),
+ m_local_start(0),
+ m_size(0),
+ m_section_id(eSectionIDNone),
+ m_alignment(0),
+ m_executable(false),
+ m_allocated(false)
+ {
+ }
+
+ void dump (lldb::LogSP log);
};
- //------------------------------------------------------------------
- /// Add a range to the list of copied ranges.
- ///
- /// @param[in] lstart
- /// The base address of the local allocation.
- ///
- /// @param[in] size
- /// The size of the allocation.
- ///
- /// @param[in] rstart
- /// The base address of the remote allocation.
- //------------------------------------------------------------------
- void
- AddToLocalToRemoteMap (lldb::addr_t lstart, size_t size, lldb::addr_t rstart);
-
- std::vector<LocalToRemoteAddressRange> m_address_map; ///< The base address of the remote allocation
-
- friend class ClangExpressionParser;
+ typedef std::vector<Allocation> AllocationList;
+ AllocationList m_allocations; ///< The base address of the remote allocation
};
} // namespace lldb_private
diff --git a/lldb/include/lldb/Symbol/ClangASTImporter.h b/lldb/include/lldb/Symbol/ClangASTImporter.h
index 1e1dd53c187..ef831448f89 100644
--- a/lldb/include/lldb/Symbol/ClangASTImporter.h
+++ b/lldb/include/lldb/Symbol/ClangASTImporter.h
@@ -57,6 +57,9 @@ public:
DeportDecl (clang::ASTContext *dst_ctx,
clang::ASTContext *src_ctx,
clang::Decl *decl);
+
+ void
+ CompleteDecl (clang::Decl *decl);
bool
CompleteTagDecl (clang::TagDecl *decl);
diff --git a/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h b/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h
index 42422376285..d37f10fa57d 100644
--- a/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h
+++ b/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h
@@ -122,7 +122,14 @@ public:
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,
diff --git a/lldb/scripts/build-llvm.pl b/lldb/scripts/build-llvm.pl
index 93ac565061b..0646519589e 100644
--- a/lldb/scripts/build-llvm.pl
+++ b/lldb/scripts/build-llvm.pl
@@ -21,8 +21,8 @@ our ($llvm_clang_basename, $llvm_clang_dirname) = fileparse ($llvm_clang_outfile
our $llvm_configuration = $ENV{LLVM_CONFIGURATION};
-our $llvm_revision = "146622";
-our $clang_revision = "146622";
+our $llvm_revision = "149773";
+our $clang_revision = "149773";
our $SRCROOT = "$ENV{SRCROOT}";
our $llvm_dstroot_zip = "$SRCROOT/llvm.zip";
diff --git a/lldb/scripts/clang.DebuggerCastResultToId.diff b/lldb/scripts/clang.DebuggerCastResultToId.diff
deleted file mode 100644
index 01fe8a2f064..00000000000
--- a/lldb/scripts/clang.DebuggerCastResultToId.diff
+++ /dev/null
@@ -1,25 +0,0 @@
-Index: include/clang/Basic/LangOptions.def
-===================================================================
---- include/clang/Basic/LangOptions.def (revision 146622)
-+++ include/clang/Basic/LangOptions.def (working copy)
-@@ -121,6 +121,7 @@
- BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden default visibility for inline C++ methods")
- BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
- BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
-+BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type")
- BENIGN_LANGOPT(AddressSanitizer , 1, 0, "AddressSanitizer enabled")
-
- BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
-Index: lib/Sema/SemaExprCXX.cpp
-===================================================================
---- lib/Sema/SemaExprCXX.cpp (revision 146622)
-+++ lib/Sema/SemaExprCXX.cpp (working copy)
-@@ -4675,7 +4675,7 @@
- return ExprError();
-
- // Top-level message sends default to 'id' when we're in a debugger.
-- if (getLangOptions().DebuggerSupport &&
-+ if (getLangOptions().DebuggerCastResultToId &&
- FullExpr.get()->getType() == Context.UnknownAnyTy &&
- isa<ObjCMessageExpr>(FullExpr.get())) {
- FullExpr = forceUnknownAnyToType(FullExpr.take(), Context.getObjCIdType());
diff --git a/lldb/scripts/clang.complete-type-being-converted.diff b/lldb/scripts/clang.complete-type-being-converted.diff
deleted file mode 100644
index 8c01fa1161a..00000000000
--- a/lldb/scripts/clang.complete-type-being-converted.diff
+++ /dev/null
@@ -1,14 +0,0 @@
-Index: lib/CodeGen/CodeGenTypes.cpp
-===================================================================
---- lib/CodeGen/CodeGenTypes.cpp (revision 146622)
-+++ lib/CodeGen/CodeGenTypes.cpp (working copy)
-@@ -113,6 +113,9 @@
- static bool
- isSafeToConvert(const RecordDecl *RD, CodeGenTypes &CGT,
- llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) {
-+ if (RD->hasExternalLexicalStorage() && !RD->getDefinition())
-+ RD->getASTContext().getExternalSource()->CompleteType(const_cast<RecordDecl*>(RD));
-+
- // If we have already checked this type (maybe the same type is used by-value
- // multiple times in multiple structure fields, don't check again.
- if (!AlreadyChecked.insert(RD)) return true;
diff --git a/lldb/scripts/clang.complete-type-being-laid-out.diff b/lldb/scripts/clang.complete-type-being-laid-out.diff
deleted file mode 100644
index 388ac5484f9..00000000000
--- a/lldb/scripts/clang.complete-type-being-laid-out.diff
+++ /dev/null
@@ -1,15 +0,0 @@
-Index: lib/AST/RecordLayoutBuilder.cpp
-===================================================================
---- lib/AST/RecordLayoutBuilder.cpp (revision 146622)
-+++ lib/AST/RecordLayoutBuilder.cpp (working copy)
-@@ -2062,6 +2062,10 @@
- // as soon as we begin to parse the definition. That definition is
- // not a complete definition (which is what isDefinition() tests)
- // until we *finish* parsing the definition.
-+
-+ if (D->hasExternalLexicalStorage() && !D->getDefinition())
-+ getExternalSource()->CompleteType(const_cast<RecordDecl*>(D));
-+
- D = D->getDefinition();
- assert(D && "Cannot get layout of forward declarations!");
- assert(D->isCompleteDefinition() && "Cannot layout type before complete!");
diff --git a/lldb/scripts/clang.complete-type-ivar-lookup.diff b/lldb/scripts/clang.complete-type-ivar-lookup.diff
deleted file mode 100644
index 81db76942ef..00000000000
--- a/lldb/scripts/clang.complete-type-ivar-lookup.diff
+++ /dev/null
@@ -1,19 +0,0 @@
-Index: lib/AST/DeclObjC.cpp
-===================================================================
---- lib/AST/DeclObjC.cpp (revision 146622)
-+++ lib/AST/DeclObjC.cpp (working copy)
-@@ -244,11 +244,11 @@
-
- ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
- ObjCInterfaceDecl *&clsDeclared) {
-- if (ExternallyCompleted)
-- LoadExternalDefinition();
--
- ObjCInterfaceDecl* ClassDecl = this;
- while (ClassDecl != NULL) {
-+ if (ClassDecl->ExternallyCompleted)
-+ ClassDecl->LoadExternalDefinition();
-+
- if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
- clsDeclared = ClassDecl;
- return I;
diff --git a/lldb/scripts/clang.instantiate-complete-type.diff b/lldb/scripts/clang.instantiate-complete-type.diff
deleted file mode 100644
index fd25244e642..00000000000
--- a/lldb/scripts/clang.instantiate-complete-type.diff
+++ /dev/null
@@ -1,15 +0,0 @@
-Index: lib/Sema/SemaTemplateInstantiate.cpp
-===================================================================
---- lib/Sema/SemaTemplateInstantiate.cpp (revision 145552)
-+++ lib/Sema/SemaTemplateInstantiate.cpp (working copy)
-@@ -1683,6 +1683,10 @@
- TemplateSpecializationKind TSK,
- bool Complain) {
- bool Invalid = false;
-+
-+ RequireCompleteType(Pattern->getLocation(),
-+ QualType(Pattern->getTypeForDecl(), 0),
-+ diag::err_incomplete_type);
-
- CXXRecordDecl *PatternDef
- = cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
diff --git a/lldb/scripts/clang.is-being-completed-from-lexical-storage.diff b/lldb/scripts/clang.is-being-completed-from-lexical-storage.diff
deleted file mode 100644
index 4a973a5be93..00000000000
--- a/lldb/scripts/clang.is-being-completed-from-lexical-storage.diff
+++ /dev/null
@@ -1,78 +0,0 @@
-Index: lib/AST/ASTImporter.cpp
-===================================================================
---- lib/AST/ASTImporter.cpp (revision 146622)
-+++ lib/AST/ASTImporter.cpp (working copy)
-@@ -2300,7 +2300,8 @@
-
- if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
- if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
-- if (!D->isCompleteDefinition() || IsStructuralMatch(D, FoundDef)) {
-+ if (FoundDef->isBeingCompletedFromLexicalStorage() ||
-+ !D->isCompleteDefinition() || IsStructuralMatch(D, FoundDef)) {
- // The record types structurally match, or the "from" translation
- // unit only had a forward declaration anyway; call it the same
- // function.
-Index: lib/AST/Decl.cpp
-===================================================================
---- lib/AST/Decl.cpp (revision 146622)
-+++ lib/AST/Decl.cpp (working copy)
-@@ -2421,8 +2421,14 @@
- ExternalASTSource::Deserializing TheFields(Source);
-
- SmallVector<Decl*, 64> Decls;
-- LoadedFieldsFromExternalStorage = true;
-- switch (Source->FindExternalLexicalDeclsBy<FieldDecl>(this, Decls)) {
-+ LoadedFieldsFromExternalStorage = true;
-+
-+ setIsBeingCompletedFromLexicalStorage(true);
-+ ExternalLoadResult LoadResult =
-+ Source->FindExternalLexicalDeclsBy<FieldDecl>(this, Decls);
-+ setIsBeingCompletedFromLexicalStorage(false);
-+
-+ switch (LoadResult) {
- case ELR_Success:
- break;
-
-Index: include/clang/AST/DeclBase.h
-===================================================================
---- include/clang/AST/DeclBase.h (revision 146622)
-+++ include/clang/AST/DeclBase.h (working copy)
-@@ -836,6 +836,12 @@
- /// storage that contains additional declarations that are visible
- /// in this context.
- mutable unsigned ExternalVisibleStorage : 1;
-+
-+ /// \brief True if this declaration context is currently having
-+ /// declarations added from its external lexical storage. This flag
-+ /// is intended to prevent One Definition Rule checking as the
-+ /// declarations are imported.
-+ mutable unsigned IsBeingCompletedFromLexicalStorage : 1;
-
- /// \brief Pointer to the data structure used to lookup declarations
- /// within this context (or a DependentStoredDeclsMap if this is a
-@@ -863,8 +869,8 @@
-
- DeclContext(Decl::Kind K)
- : DeclKind(K), ExternalLexicalStorage(false),
-- ExternalVisibleStorage(false), LookupPtr(0), FirstDecl(0),
-- LastDecl(0) { }
-+ ExternalVisibleStorage(false), IsBeingCompletedFromLexicalStorage(false),
-+ LookupPtr(0), FirstDecl(0), LastDecl(0) { }
-
- public:
- ~DeclContext();
-@@ -1368,6 +1374,14 @@
- ExternalVisibleStorage = ES;
- }
-
-+ bool isBeingCompletedFromLexicalStorage() const {
-+ return IsBeingCompletedFromLexicalStorage;
-+ }
-+
-+ void setIsBeingCompletedFromLexicalStorage(bool IBC) const {
-+ IsBeingCompletedFromLexicalStorage = IBC;
-+ }
-+
- /// \brief Determine whether the given declaration is stored in the list of
- /// declarations lexically within this context.
- bool isDeclInLexicalTraversal(const Decl *D) const {
diff --git a/lldb/scripts/clang.require-complete-type.diff b/lldb/scripts/clang.require-complete-type.diff
deleted file mode 100644
index a99e127de53..00000000000
--- a/lldb/scripts/clang.require-complete-type.diff
+++ /dev/null
@@ -1,75 +0,0 @@
-Index: lib/Sema/SemaType.cpp
-===================================================================
---- lib/Sema/SemaType.cpp (revision 145552)
-+++ lib/Sema/SemaType.cpp (working copy)
-@@ -4065,6 +4065,34 @@
- if (!T->isIncompleteType())
- return false;
-
-+ const TagType *Tag = T->getAs<TagType>();
-+ const ObjCInterfaceType *IFace = 0;
-+
-+ if (Tag) {
-+ // Avoid diagnosing invalid decls as incomplete.
-+ if (Tag->getDecl()->isInvalidDecl())
-+ return true;
-+
-+ // Give the external AST source a chance to complete the type.
-+ if (Tag->getDecl()->hasExternalLexicalStorage()) {
-+ Context.getExternalSource()->CompleteType(Tag->getDecl());
-+ if (!Tag->isIncompleteType())
-+ return false;
-+ }
-+ }
-+ else if ((IFace = T->getAs<ObjCInterfaceType>())) {
-+ // Avoid diagnosing invalid decls as incomplete.
-+ if (IFace->getDecl()->isInvalidDecl())
-+ return true;
-+
-+ // Give the external AST source a chance to complete the type.
-+ if (IFace->getDecl()->hasExternalLexicalStorage()) {
-+ Context.getExternalSource()->CompleteType(IFace->getDecl());
-+ if (!IFace->isIncompleteType())
-+ return false;
-+ }
-+ }
-+
- // If we have a class template specialization or a class member of a
- // class template specialization, or an array with known size of such,
- // try to instantiate it.
-@@ -4096,35 +4124,7 @@
-
- if (diag == 0)
- return true;
--
-- const TagType *Tag = T->getAs<TagType>();
-- const ObjCInterfaceType *IFace = 0;
--
-- if (Tag) {
-- // Avoid diagnosing invalid decls as incomplete.
-- if (Tag->getDecl()->isInvalidDecl())
-- return true;
--
-- // Give the external AST source a chance to complete the type.
-- if (Tag->getDecl()->hasExternalLexicalStorage()) {
-- Context.getExternalSource()->CompleteType(Tag->getDecl());
-- if (!Tag->isIncompleteType())
-- return false;
-- }
-- }
-- else if ((IFace = T->getAs<ObjCInterfaceType>())) {
-- // Avoid diagnosing invalid decls as incomplete.
-- if (IFace->getDecl()->isInvalidDecl())
-- return true;
-
-- // Give the external AST source a chance to complete the type.
-- if (IFace->getDecl()->hasExternalLexicalStorage()) {
-- Context.getExternalSource()->CompleteType(IFace->getDecl());
-- if (!IFace->isIncompleteType())
-- return false;
-- }
-- }
--
- // We have an incomplete type. Produce a diagnostic.
- Diag(Loc, PD) << T;
-
diff --git a/lldb/scripts/llvm.communicate-triple.diff b/lldb/scripts/llvm.communicate-triple.diff
deleted file mode 100644
index 3c833aa8d85..00000000000
--- a/lldb/scripts/llvm.communicate-triple.diff
+++ /dev/null
@@ -1,199 +0,0 @@
-Index: lib/MC/MCDisassembler/EDOperand.cpp
-===================================================================
---- lib/MC/MCDisassembler/EDOperand.cpp (revision 146622)
-+++ lib/MC/MCDisassembler/EDOperand.cpp (working copy)
-@@ -30,8 +30,10 @@
- MCOpIndex(mcOpIndex) {
- unsigned int numMCOperands = 0;
-
-- if (Disassembler.Key.Arch == Triple::x86 ||
-- Disassembler.Key.Arch == Triple::x86_64) {
-+ Triple::ArchType arch = Disassembler.TgtTriple.getArch();
-+
-+ if (arch == Triple::x86 ||
-+ arch == Triple::x86_64) {
- uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
-
- switch (operandType) {
-@@ -54,8 +56,8 @@
- break;
- }
- }
-- else if (Disassembler.Key.Arch == Triple::arm ||
-- Disassembler.Key.Arch == Triple::thumb) {
-+ else if (arch == Triple::arm ||
-+ arch == Triple::thumb) {
- uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
-
- switch (operandType) {
-@@ -126,7 +128,9 @@
- void *arg) {
- uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
-
-- switch (Disassembler.Key.Arch) {
-+ Triple::ArchType arch = Disassembler.TgtTriple.getArch();
-+
-+ switch (arch) {
- default:
- return -1;
- case Triple::x86:
-@@ -168,7 +172,7 @@
-
- unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
-
-- if (segmentReg != 0 && Disassembler.Key.Arch == Triple::x86_64) {
-+ if (segmentReg != 0 && arch == Triple::x86_64) {
- unsigned fsID = Disassembler.registerIDWithName("FS");
- unsigned gsID = Disassembler.registerIDWithName("GS");
-
-Index: lib/MC/MCDisassembler/EDDisassembler.cpp
-===================================================================
---- lib/MC/MCDisassembler/EDDisassembler.cpp (revision 146622)
-+++ lib/MC/MCDisassembler/EDDisassembler.cpp (working copy)
-@@ -98,16 +98,23 @@
-
- EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
- AssemblySyntax syntax) {
-+ const char *triple = tripleFromArch(arch);
-+ return getDisassembler(StringRef(triple), syntax);
-+}
-+
-+EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
-+ AssemblySyntax syntax) {
- CPUKey key;
-- key.Arch = arch;
-+ key.Triple = str.str();
- key.Syntax = syntax;
-
- EDDisassembler::DisassemblerMap_t::iterator i = sDisassemblers.find(key);
--
-+
- if (i != sDisassemblers.end()) {
-- return i->second;
-- } else {
-- EDDisassembler* sdd = new EDDisassembler(key);
-+ return i->second;
-+ }
-+ else {
-+ EDDisassembler *sdd = new EDDisassembler(key);
- if (!sdd->valid()) {
- delete sdd;
- return NULL;
-@@ -119,10 +126,7 @@
- }
-
- return NULL;
--}
--
--EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
-- AssemblySyntax syntax) {
-+
- return getDisassembler(Triple(str).getArch(), syntax);
- }
-
-@@ -130,21 +134,20 @@
- Valid(false),
- HasSemantics(false),
- ErrorStream(nulls()),
-- Key(key) {
-- const char *triple = tripleFromArch(key.Arch);
--
-- if (!triple)
-+ Key(key),
-+ TgtTriple(key.Triple.c_str()) {
-+ if (TgtTriple.getArch() == Triple::InvalidArch)
- return;
-
-- LLVMSyntaxVariant = getLLVMSyntaxVariant(key.Arch, key.Syntax);
-+ LLVMSyntaxVariant = getLLVMSyntaxVariant(TgtTriple.getArch(), key.Syntax);
-
- if (LLVMSyntaxVariant < 0)
- return;
-
-- std::string tripleString(triple);
-+ std::string tripleString(key.Triple);
- std::string errorString;
-
-- Tgt = TargetRegistry::lookupTarget(tripleString,
-+ Tgt = TargetRegistry::lookupTarget(key.Triple,
- errorString);
-
- if (!Tgt)
-@@ -263,7 +266,7 @@
- RegRMap[registerName] = registerIndex;
- }
-
-- switch (Key.Arch) {
-+ switch (TgtTriple.getArch()) {
- default:
- break;
- case Triple::x86:
-@@ -331,7 +334,7 @@
- const std::string &str) {
- int ret = 0;
-
-- switch (Key.Arch) {
-+ switch (TgtTriple.getArch()) {
- default:
- return -1;
- case Triple::x86:
-@@ -356,8 +359,7 @@
- context, *streamer,
- *AsmInfo));
-
-- StringRef triple = tripleFromArch(Key.Arch);
-- OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(triple, "", ""));
-+ OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(Key.Triple.c_str(), "", ""));
- OwningPtr<MCTargetAsmParser>
- TargetParser(Tgt->createMCAsmParser(*STI, *genericParser));
-
-Index: lib/MC/MCDisassembler/EDDisassembler.h
-===================================================================
---- lib/MC/MCDisassembler/EDDisassembler.h (revision 146622)
-+++ lib/MC/MCDisassembler/EDDisassembler.h (working copy)
-@@ -25,6 +25,7 @@
-
- #include <map>
- #include <set>
-+#include <string>
- #include <vector>
-
- namespace llvm {
-@@ -74,21 +75,21 @@
- /// pair
- struct CPUKey {
- /// The architecture type
-- llvm::Triple::ArchType Arch;
-+ std::string Triple;
-
- /// The assembly syntax
- AssemblySyntax Syntax;
-
- /// operator== - Equality operator
- bool operator==(const CPUKey &key) const {
-- return (Arch == key.Arch &&
-+ return (Triple == key.Triple &&
- Syntax == key.Syntax);
- }
-
- /// operator< - Less-than operator
- bool operator<(const CPUKey &key) const {
-- return ((Arch < key.Arch) ||
-- ((Arch == key.Arch) && Syntax < (key.Syntax)));
-+ return ((Triple < key.Triple) ||
-+ ((Triple == key.Triple) && Syntax < (key.Syntax)));
- }
- };
-
-@@ -126,8 +127,10 @@
- /// The stream to write errors to
- llvm::raw_ostream &ErrorStream;
-
-- /// The architecture/syntax pair for the current architecture
-+ /// The triple/syntax pair for the current architecture
- CPUKey Key;
-+ /// The Triple fur the current architecture
-+ Triple TgtTriple;
- /// The LLVM target corresponding to the disassembler
- const llvm::Target *Tgt;
- /// The assembly information for the target architecture
diff --git a/lldb/scripts/llvm.delete-target-machine.diff b/lldb/scripts/llvm.delete-target-machine.diff
deleted file mode 100644
index 25dec6639ea..00000000000
--- a/lldb/scripts/llvm.delete-target-machine.diff
+++ /dev/null
@@ -1,12 +0,0 @@
-Index: lib/ExecutionEngine/MCJIT/MCJIT.cpp
-===================================================================
---- lib/ExecutionEngine/MCJIT/MCJIT.cpp (revision 146622)
-+++ lib/ExecutionEngine/MCJIT/MCJIT.cpp (working copy)
-@@ -85,6 +85,7 @@
-
- MCJIT::~MCJIT() {
- delete MemMgr;
-+ delete TM;
- }
-
- void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp
index 162dfab2ef4..738b342d5e8 100644
--- a/lldb/source/Expression/ClangASTSource.cpp
+++ b/lldb/source/Expression/ClangASTSource.cpp
@@ -9,6 +9,7 @@
#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
@@ -448,7 +449,7 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
}
else if (isa<ObjCInterfaceDecl>(context.m_decl_context))
{
- FindObjCPropertyDecls(context);
+ FindObjCPropertyAndIvarDecls(context);
}
else if (!isa<TranslationUnitDecl>(context.m_decl_context))
{
@@ -499,6 +500,12 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
const char *name_unique_cstr = name.GetCString();
+ static ConstString id_name("id");
+ static ConstString Class_name("Class");
+
+ if (name == id_name || name == Class_name)
+ return;
+
if (name_unique_cstr == NULL)
return;
@@ -567,16 +574,10 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
}
}
- static ConstString id_name("id");
- static ConstString Class_name("Class");
-
do
{
TypeList types;
SymbolContext null_sc;
-
- if (name == id_name || name == Class_name)
- break;
if (module_sp && namespace_decl)
module_sp->FindTypes(null_sc, name, &namespace_decl, true, 1, types);
@@ -788,62 +789,308 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
}
}
+template <class D> class TaggedASTDecl {
+public:
+ TaggedASTDecl() : decl(NULL) { }
+ TaggedASTDecl(D *_decl) : decl(_decl) { }
+ bool IsValid() const { return (decl != NULL); }
+ bool IsInvalid() const { return !IsValid(); }
+ D *operator->() const { return decl; }
+ D *decl;
+};
+
+template <class D2, template <class D> class TD, class D1>
+TD<D2>
+DynCast(TD<D1> source)
+{
+ return TD<D2> (dyn_cast<D2>(source.decl));
+}
+
+template <class D = Decl> class DeclFromParser;
+template <class D = Decl> class DeclFromUser;
+
+template <class D> class DeclFromParser : public TaggedASTDecl<D> {
+public:
+ DeclFromParser() : TaggedASTDecl<D>() { }
+ DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) { }
+
+ DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
+};
+
+template <class D> class DeclFromUser : public TaggedASTDecl<D> {
+public:
+ DeclFromUser() : TaggedASTDecl<D>() { }
+ DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) { }
+
+ DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
+};
+
+template <class D>
+DeclFromUser<D>
+DeclFromParser<D>::GetOrigin(ClangASTImporter *importer)
+{
+ DeclFromUser <> origin_decl;
+ importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
+ if (origin_decl.IsInvalid())
+ return DeclFromUser<D>();
+ return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
+}
+
+template <class D>
+DeclFromParser<D>
+DeclFromUser<D>::Import(ClangASTImporter *importer, ASTContext &dest_ctx)
+{
+ DeclFromParser <> parser_generic_decl(importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
+ if (parser_generic_decl.IsInvalid())
+ return DeclFromParser<D>();
+ return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
+}
+
void
-ClangASTSource::FindObjCPropertyDecls (NameSearchContext &context)
+ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
{
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
- const ObjCInterfaceDecl *iface_decl = cast<ObjCInterfaceDecl>(context.m_decl_context);
- Decl *orig_decl;
- ASTContext *orig_ast_ctx;
-
- m_ast_importer->ResolveDeclOrigin(iface_decl, &orig_decl, &orig_ast_ctx);
+ DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context));
+ DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer));
- if (!orig_decl)
+ if (origin_iface_decl.IsInvalid())
return;
- ObjCInterfaceDecl *orig_iface_decl = dyn_cast<ObjCInterfaceDecl>(orig_decl);
+ std::string name_str = context.m_decl_name.getAsString();
+ StringRef name(name_str.c_str());
+ IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name));
- if (!orig_iface_decl)
- return;
+ if (log)
+ log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'",
+ current_id,
+ m_ast_context,
+ parser_iface_decl->getNameAsString().c_str(),
+ name_str.c_str());
- if (!ClangASTContext::GetCompleteDecl(orig_ast_ctx, orig_iface_decl))
- return;
+ DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier));
- std::string property_name_str = context.m_decl_name.getAsString();
- StringRef property_name(property_name_str.c_str());
- ObjCPropertyDecl *property_decl = orig_iface_decl->FindPropertyDeclaration(&orig_ast_ctx->Idents.get(property_name));
+ if (origin_property_decl.IsValid())
+ {
+ DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(m_ast_importer, *m_ast_context));
+ if (parser_property_decl.IsValid())
+ {
+ if (log)
+ {
+ ASTDumper dumper((Decl*)parser_property_decl.decl);
+ log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
+ }
+
+ context.AddNamedDecl(parser_property_decl.decl);
+ }
+ }
+
+ DeclFromUser<ObjCIvarDecl> origin_ivar_decl(origin_iface_decl->getIvarDecl(&name_identifier));
+
+ if (origin_ivar_decl.IsValid())
+ {
+ DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(m_ast_importer, *m_ast_context));
+ if (parser_ivar_decl.IsValid())
+ {
+ if (log)
+ {
+ ASTDumper dumper((Decl*)parser_ivar_decl.decl);
+ log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
+ }
+
+ context.AddNamedDecl(parser_ivar_decl.decl);
+ }
+ }
+}
+
+typedef llvm::DenseMap <const FieldDecl *, uint64_t> FieldOffsetMap;
+typedef llvm::DenseMap <const CXXRecordDecl *, CharUnits> BaseOffsetMap;
+
+template <class D, class O>
+static bool
+ImportOffsetMap (llvm::DenseMap <const D*, O> &destination_map,
+ llvm::DenseMap <const D*, O> &source_map,
+ ClangASTImporter *importer,
+ ASTContext &dest_ctx)
+{
+ typedef llvm::DenseMap <const D*, O> MapType;
+
+ for (typename MapType::iterator fi = source_map.begin(), fe = source_map.end();
+ fi != fe;
+ ++fi)
+ {
+ DeclFromUser <D> user_decl(const_cast<D*>(fi->first));
+ DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx));
+ if (parser_decl.IsInvalid())
+ return false;
+ destination_map.insert(std::pair<const D *, O>(parser_decl.decl, fi->second));
+ }
+
+ return true;
+}
+
+template <bool IsVirtual> bool ExtractBaseOffsets (const ASTRecordLayout &record_layout,
+ DeclFromUser<const CXXRecordDecl> &record,
+ BaseOffsetMap &base_offsets)
+{
+ for (CXXRecordDecl::base_class_const_iterator
+ bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()),
+ be = (IsVirtual ? record->vbases_end() : record->bases_end());
+ bi != be;
+ ++bi)
+ {
+ if (!IsVirtual && bi->isVirtual())
+ continue;
+
+ const clang::Type *origin_base_type = bi->getType().getTypePtr();
+ const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>();
+
+ if (!origin_base_record_type)
+ return false;
+
+ DeclFromUser <RecordDecl> origin_base_record(origin_base_record_type->getDecl());
+
+ if (origin_base_record.IsInvalid())
+ return false;
+
+ DeclFromUser <CXXRecordDecl> origin_base_cxx_record(DynCast<CXXRecordDecl>(origin_base_record));
+
+ if (origin_base_cxx_record.IsInvalid())
+ return false;
+
+ CharUnits base_offset;
+
+ if (IsVirtual)
+ base_offset = record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
+ else
+ base_offset = record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
+
+ base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset));
+ }
+
+ return true;
+}
+
+bool
+ClangASTSource::layoutRecordType(const RecordDecl *record,
+ uint64_t &size,
+ uint64_t &alignment,
+ FieldOffsetMap &field_offsets,
+ BaseOffsetMap &base_offsets,
+ BaseOffsetMap &virtual_base_offsets)
+{
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
+
+ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ if (!record->getNameAsString().compare("PseudoObjectExprBitfields"))
+ fprintf(stderr, "THIS IS THE ONE!");
if (log)
- log->Printf("ClangASTSource::FindObjCPropertyDecls[%d] on (ASTContext*)%p for property '%s.%s'",
- current_id,
+ {
+ log->Printf("LayoutRecordType[%u] on (RecordDecl*)%p [name = '%s']",
+ current_id,
m_ast_context,
- iface_decl->getNameAsString().c_str(),
- property_name_str.c_str());
+ record->getNameAsString().c_str());
+ }
- if (!property_decl)
- return;
- Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, orig_ast_ctx, property_decl);
+ DeclFromParser <const RecordDecl> parser_record(record);
+ DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer));
- if (!copied_decl)
- return;
+ if (origin_record.IsInvalid())
+ return false;
+
+ FieldOffsetMap origin_field_offsets;
+ BaseOffsetMap origin_base_offsets;
+ BaseOffsetMap origin_virtual_base_offsets;
- ObjCPropertyDecl *copied_property_decl = dyn_cast<ObjCPropertyDecl>(copied_decl);
+ const ASTRecordLayout &record_layout(origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
- if (!copied_property_decl)
- return;
+ int field_idx = 0;
+
+ for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end();
+ fi != fe;
+ ++fi)
+ {
+ uint64_t field_offset = record_layout.getFieldOffset(field_idx);
+
+ origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
+
+ field_idx++;
+ }
+
+ ASTContext &parser_ast_context(record->getASTContext());
+
+ DeclFromUser <const CXXRecordDecl> origin_cxx_record(DynCast<const CXXRecordDecl>(origin_record));
+
+ if (origin_cxx_record.IsValid())
+ {
+ if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record, origin_base_offsets) ||
+ !ExtractBaseOffsets<true>(record_layout, origin_cxx_record, origin_virtual_base_offsets))
+ return false;
+ }
+
+ if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer, parser_ast_context) ||
+ !ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer, parser_ast_context) ||
+ !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer, parser_ast_context))
+ return false;
+
+ size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
+ alignment = record_layout.getAlignment().getQuantity() * m_ast_context->getCharWidth();
if (log)
{
- ASTDumper dumper((Decl*)copied_property_decl);
- log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
+ log->Printf("LRT[%u] returned:", current_id);
+ log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id, origin_record.decl);
+ log->Printf("LRT[%u] Size = %lld", current_id, size);
+ log->Printf("LRT[%u] Alignment = %lld", current_id, alignment);
+ log->Printf("LRT[%u] Fields:", current_id);
+ for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end();
+ fi != fe;
+ ++fi)
+ {
+ log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %lld bits",
+ current_id,
+ *fi,
+ fi->getNameAsString().c_str(),
+ field_offsets[*fi]);
+ }
+ DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record);
+ if (parser_cxx_record.IsValid())
+ {
+ log->Printf("LRT[%u] Bases:", current_id);
+ for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end();
+ bi != be;
+ ++bi)
+ {
+ bool is_virtual = bi->isVirtual();
+
+ QualType base_type = bi->getType();
+ const RecordType *base_record_type = base_type->getAs<RecordType>();
+ DeclFromParser <RecordDecl> base_record(base_record_type->getDecl());
+ DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record);
+
+ log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %lld chars",
+ current_id,
+ (is_virtual ? "Virtual " : ""),
+ base_cxx_record.decl,
+ base_cxx_record.decl->getNameAsString().c_str(),
+ (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity() :
+ base_offsets[base_cxx_record.decl].getQuantity()));
+ }
+ }
+ else
+ {
+ log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id);
+ }
}
-
- context.AddNamedDecl(copied_property_decl);
+
+ return true;
}
void
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index 128db9c5753..19c3c0e5ced 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -415,7 +415,8 @@ ClangExpressionDeclMap::CompleteResultVariable (lldb::ClangExpressionVariableSP
const size_t pvar_byte_size = pvar_sp->GetByteSize();
uint8_t *pvar_data = pvar_sp->GetValueBytes();
- ReadTarget(pvar_data, value, pvar_byte_size);
+ if (!ReadTarget(pvar_data, value, pvar_byte_size))
+ return false;
pvar_sp->m_flags &= ~(ClangExpressionVariable::EVNeedsFreezeDry);
}
@@ -425,6 +426,16 @@ ClangExpressionDeclMap::CompleteResultVariable (lldb::ClangExpressionVariableSP
return true;
}
+void
+ClangExpressionDeclMap::RemoveResultVariable
+(
+ const ConstString &name
+)
+{
+ ClangExpressionVariableSP pvar_sp = m_parser_vars->m_persistent_vars->GetVariable(name);
+ m_parser_vars->m_persistent_vars->RemovePersistentVariable(pvar_sp);
+}
+
bool
ClangExpressionDeclMap::AddPersistentVariable
(
@@ -2322,6 +2333,12 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
if (name_unique_cstr == NULL)
return;
+ static ConstString id_name("id");
+ static ConstString Class_name("Class");
+
+ if (name == id_name || name == Class_name)
+ return;
+
// Only look for functions by name out in our symbols if the function
// doesn't start with our phony prefix of '$'
Target *target = m_parser_vars->m_exe_ctx->GetTargetPtr();
diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp
index 625b03e28a2..958d18b5a40 100644
--- a/lldb/source/Expression/ClangExpressionParser.cpp
+++ b/lldb/source/Expression/ClangExpressionParser.cpp
@@ -172,8 +172,7 @@ static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
// If there are any AST files to merge, create a frontend action
// adaptor to perform the merge.
if (!CI.getFrontendOpts().ASTMergeFiles.empty())
- Act = new ASTMergeAction(Act, &CI.getFrontendOpts().ASTMergeFiles[0],
- CI.getFrontendOpts().ASTMergeFiles.size());
+ Act = new ASTMergeAction(Act, CI.getFrontendOpts().ASTMergeFiles);
return Act;
}
@@ -492,12 +491,7 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr,
error_stream,
function_name.c_str());
- if (!ir_for_target.runOnModule(*module))
- {
- err.SetErrorToGenericError();
- err.SetErrorString("Couldn't prepare the expression for execution in the target");
- return err;
- }
+ ir_for_target.runOnModule(*module);
Error &interpreter_error(ir_for_target.getInterpreterError());
@@ -519,6 +513,7 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr,
err.SetErrorString("Execution needed to run in the target, but the target can't be run");
else
err.SetErrorStringWithFormat("Interpreting the expression locally failed: %s", interpreter_error.AsCString());
+
return err;
}
@@ -629,58 +624,9 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr,
err.SetErrorString("Couldn't write the JIT compiled code into the target because there is no target");
return err;
}
-
- // Look over the regions allocated for the function compiled. The JIT
- // tries to allocate the functions & stubs close together, so we should try to
- // write them that way too...
- // For now I only write functions with no stubs, globals, exception tables,
- // etc. So I only need to write the functions.
-
- size_t alloc_size = 0;
-
- std::map<uint8_t *, uint8_t *>::iterator fun_pos = jit_memory_manager->m_functions.begin();
- std::map<uint8_t *, uint8_t *>::iterator fun_end = jit_memory_manager->m_functions.end();
-
- for (; fun_pos != fun_end; ++fun_pos)
- {
- size_t mem_size = fun_pos->second - fun_pos->first;
- if (log)
- log->Printf ("JIT memory: [%p - %p) size = %zu", fun_pos->first, fun_pos->second, mem_size);
- alloc_size += mem_size;
- }
-
- Error alloc_error;
- func_allocation_addr = process->AllocateMemory (alloc_size,
- lldb::ePermissionsReadable|lldb::ePermissionsExecutable,
- alloc_error);
-
- if (func_allocation_addr == LLDB_INVALID_ADDRESS)
- {
- err.SetErrorToGenericError();
- err.SetErrorStringWithFormat("Couldn't allocate memory for the JITted function: %s", alloc_error.AsCString("unknown error"));
- return err;
- }
-
- lldb::addr_t cursor = func_allocation_addr;
-
- for (fun_pos = jit_memory_manager->m_functions.begin(); fun_pos != fun_end; fun_pos++)
- {
- lldb::addr_t lstart = (lldb::addr_t) (*fun_pos).first;
- lldb::addr_t lend = (lldb::addr_t) (*fun_pos).second;
- size_t size = lend - lstart;
- Error write_error;
-
- if (process->WriteMemory(cursor, (void *) lstart, size, write_error) != size)
- {
- err.SetErrorToGenericError();
- err.SetErrorStringWithFormat("Couldn't copy JIT code for function into the target: %s", write_error.AsCString("unknown error"));
- return err;
- }
-
- jit_memory_manager->AddToLocalToRemoteMap (lstart, size, cursor);
- cursor += size;
- }
+ jit_memory_manager->CommitAllocations(*process);
+ jit_memory_manager->WriteData(*process);
std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end();
@@ -690,7 +636,8 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr,
if (!(*pos).m_name.compare(function_name.c_str()))
{
- func_end = jit_memory_manager->GetRemoteRangeForLocal ((*pos).m_local_addr).second;
+ RecordingMemoryManager::AddrRange func_range = jit_memory_manager->GetRemoteRangeForLocal((*pos).m_local_addr);
+ func_end = func_range.first + func_range.second;
func_addr = (*pos).m_remote_addr;
}
}
@@ -766,7 +713,7 @@ ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &ex
}
if (log)
- log->Printf("Function's code range is [0x%llx-0x%llx]", func_range.first, func_range.second);
+ log->Printf("Function's code range is [0x%llx+0x%llx]", func_range.first, func_range.second);
Target *target = exe_ctx.GetTargetPtr();
if (!target)
@@ -775,7 +722,7 @@ ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &ex
ret.SetErrorString("Couldn't find the target");
}
- lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second - func_remote_addr, 0));
+ lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));
Process *process = exe_ctx.GetProcessPtr();
Error err;
diff --git a/lldb/source/Expression/ClangPersistentVariables.cpp b/lldb/source/Expression/ClangPersistentVariables.cpp
index 3da9dc8c365..db062d2e20b 100644
--- a/lldb/source/Expression/ClangPersistentVariables.cpp
+++ b/lldb/source/Expression/ClangPersistentVariables.cpp
@@ -46,6 +46,20 @@ ClangPersistentVariables::CreatePersistentVariable (ExecutionContextScope *exe_s
return var_sp;
}
+void
+ClangPersistentVariables::RemovePersistentVariable (lldb::ClangExpressionVariableSP variable)
+{
+ RemoveVariable(variable);
+
+ const char *name = variable->GetName().AsCString();
+
+ if (*name != '$')
+ return;
+ name++;
+
+ if (strtoul(name, NULL, 0) == m_next_persistent_variable_id - 1)
+ m_next_persistent_variable_id--;
+}
ConstString
ClangPersistentVariables::GetNextPersistentVariableName ()
diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp
index 15ba25038af..5cd17083f98 100644
--- a/lldb/source/Expression/IRForTarget.cpp
+++ b/lldb/source/Expression/IRForTarget.cpp
@@ -2669,6 +2669,11 @@ IRForTarget::runOnModule (Module &llvm_module)
return true;
}
+ if (m_execution_policy == lldb_private::eExecutionPolicyNever) {
+ m_decl_map->RemoveResultVariable(m_result_name);
+ return false;
+ }
+
if (log && log->GetVerbose())
{
std::string s;
diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp
index a7ca4c86581..741f27ea329 100644
--- a/lldb/source/Expression/IRInterpreter.cpp
+++ b/lldb/source/Expression/IRInterpreter.cpp
@@ -873,6 +873,7 @@ static const char *memory_allocation_error = "Interpreter couldn't allo
static const char *memory_write_error = "Interpreter couldn't write to memory";
static const char *memory_read_error = "Interpreter couldn't read from memory";
static const char *infinite_loop_error = "Interpreter ran for too many cycles";
+static const char *bad_result_error = "Result of expression is in bad memory";
bool
IRInterpreter::supportsFunction (Function &llvm_function,
@@ -1524,7 +1525,17 @@ IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result,
return true;
GlobalValue *result_value = llvm_module.getNamedValue(result_name.GetCString());
- return frame.ConstructResult(result, result_value, result_name, result_type, llvm_module);
+
+ if (!frame.ConstructResult(result, result_value, result_name, result_type, llvm_module))
+ {
+ if (log)
+ log->Printf("Couldn't construct the expression's result");
+ err.SetErrorToGenericError();
+ err.SetErrorString(bad_result_error);
+ return false;
+ }
+
+ return true;
}
case Instruction::Store:
{
diff --git a/lldb/source/Expression/RecordingMemoryManager.cpp b/lldb/source/Expression/RecordingMemoryManager.cpp
index de14fe4f285..3d0cda32745 100644
--- a/lldb/source/Expression/RecordingMemoryManager.cpp
+++ b/lldb/source/Expression/RecordingMemoryManager.cpp
@@ -43,8 +43,7 @@ uint8_t *
RecordingMemoryManager::startFunctionBody(const llvm::Function *F,
uintptr_t &ActualSize)
{
- uint8_t *return_value = m_default_mm_ap->startFunctionBody(F, ActualSize);
- return return_value;
+ return m_default_mm_ap->startFunctionBody(F, ActualSize);
}
uint8_t *
@@ -52,7 +51,21 @@ RecordingMemoryManager::allocateStub(const llvm::GlobalValue* F, unsigned StubSi
unsigned Alignment)
{
uint8_t *return_value = m_default_mm_ap->allocateStub(F, StubSize, Alignment);
- m_stubs.insert (std::pair<uint8_t *,unsigned>(return_value, StubSize));
+
+ Allocation allocation;
+ allocation.m_size = StubSize;
+ allocation.m_alignment = Alignment;
+ allocation.m_local_start = (uintptr_t)return_value;
+
+ if (m_log)
+ {
+ m_log->Printf("RecordingMemoryManager::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
+ F, StubSize, Alignment, return_value);
+ allocation.dump(m_log);
+ }
+
+ m_allocations.push_back(allocation);
+
return return_value;
}
@@ -61,31 +74,96 @@ RecordingMemoryManager::endFunctionBody(const llvm::Function *F, uint8_t *Functi
uint8_t *FunctionEnd)
{
m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd);
- if (m_log)
- m_log->Printf("Adding [%p-%p] to m_functions",
- FunctionStart, FunctionEnd);
- m_functions.insert(std::pair<uint8_t *, uint8_t *>(FunctionStart, FunctionEnd));
}
uint8_t *
RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
{
uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment);
+
+ Allocation allocation;
+ allocation.m_size = Size;
+ allocation.m_alignment = Alignment;
+ allocation.m_local_start = (uintptr_t)return_value;
+
if (m_log)
- m_log->Printf("RecordingMemoryManager::allocateSpace(Size=0x%llx, Alignment=%u) = %p",
+ {
+ m_log->Printf("RecordingMemoryManager::allocateSpace(Size=%llu, Alignment=%u) = %p",
(uint64_t)Size, Alignment, return_value);
- m_spaceBlocks.insert (std::pair<uint8_t *, intptr_t>(return_value, Size));
+ allocation.dump(m_log);
+ }
+
+ m_allocations.push_back(allocation);
+
+ return return_value;
+}
+
+uint8_t *
+RecordingMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID)
+{
+ uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID);
+
+ Allocation allocation;
+ allocation.m_size = Size;
+ allocation.m_alignment = Alignment;
+ allocation.m_local_start = (uintptr_t)return_value;
+ allocation.m_section_id = SectionID;
+ allocation.m_executable = true;
+
+ if (m_log)
+ {
+ m_log->Printf("RecordingMemoryManager::allocateCodeSection(Size=0x%llx, Alignment=%u, SectionID=%u) = %p",
+ (uint64_t)Size, Alignment, SectionID, return_value);
+ allocation.dump(m_log);
+ }
+
+ m_allocations.push_back(allocation);
+
return return_value;
}
uint8_t *
+RecordingMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID)
+{
+ uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID);
+
+ Allocation allocation;
+ allocation.m_size = Size;
+ allocation.m_alignment = Alignment;
+ allocation.m_local_start = (uintptr_t)return_value;
+ allocation.m_section_id = SectionID;
+
+ if (m_log)
+ {
+ m_log->Printf("RecordingMemoryManager::allocateDataSection(Size=0x%llx, Alignment=%u, SectionID=%u) = %p",
+ (uint64_t)Size, Alignment, SectionID, return_value);
+ allocation.dump(m_log);
+ }
+
+ m_allocations.push_back(allocation);
+
+ return return_value;
+}
+
+uint8_t *
RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
{
uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment);
+
+ Allocation allocation;
+ allocation.m_size = Size;
+ allocation.m_alignment = Alignment;
+ allocation.m_local_start = (uintptr_t)return_value;
+
if (m_log)
+ {
m_log->Printf("RecordingMemoryManager::allocateGlobal(Size=0x%llx, Alignment=%u) = %p",
(uint64_t)Size, Alignment, return_value);
- m_globals.insert (std::pair<uint8_t *, uintptr_t>(return_value, Size));
+ allocation.dump(m_log);
+ }
+
+ m_allocations.push_back(allocation);
+
return return_value;
}
@@ -99,8 +177,7 @@ uint8_t*
RecordingMemoryManager::startExceptionTable(const llvm::Function* F,
uintptr_t &ActualSize)
{
- uint8_t *return_value = m_default_mm_ap->startExceptionTable(F, ActualSize);
- return return_value;
+ return m_default_mm_ap->startExceptionTable(F, ActualSize);
}
void
@@ -108,7 +185,6 @@ RecordingMemoryManager::endExceptionTable(const llvm::Function *F, uint8_t *Tabl
uint8_t *TableEnd, uint8_t* FrameRegister)
{
m_default_mm_ap->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
- m_exception_tables.insert (std::pair<uint8_t *, uint8_t *>(TableStart, TableEnd));
}
void
@@ -120,43 +196,125 @@ RecordingMemoryManager::deallocateExceptionTable(void *ET)
lldb::addr_t
RecordingMemoryManager::GetRemoteAddressForLocal (lldb::addr_t local_address)
{
- std::vector<LocalToRemoteAddressRange>::iterator pos, end = m_address_map.end();
- for (pos = m_address_map.begin(); pos < end; pos++)
+ for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
+ ai != ae;
+ ++ai)
{
- lldb::addr_t lstart = (*pos).m_local_start;
- if (local_address >= lstart && local_address < lstart + (*pos).m_size)
- {
- return (*pos).m_remote_start + (local_address - lstart);
- }
+ if (local_address >= ai->m_local_start &&
+ local_address < ai->m_local_start + ai->m_size)
+ return ai->m_remote_start + (local_address - ai->m_local_start);
}
+
return LLDB_INVALID_ADDRESS;
}
-std::pair <lldb::addr_t, lldb::addr_t>
+RecordingMemoryManager::AddrRange
RecordingMemoryManager::GetRemoteRangeForLocal (lldb::addr_t local_address)
{
- std::vector<LocalToRemoteAddressRange>::iterator pos, end = m_address_map.end();
+ for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
+ ai != ae;
+ ++ai)
+ {
+ if (local_address >= ai->m_local_start &&
+ local_address < ai->m_local_start + ai->m_size)
+ return AddrRange(ai->m_remote_start, ai->m_size);
+ }
+
+ return AddrRange (0, 0);
+}
+
+bool
+RecordingMemoryManager::CommitAllocations (Process &process)
+{
+ bool ret = true;
+
+ for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
+ ai != ae;
+ ++ai)
+ {
+ if (ai->m_allocated)
+ continue;
+
+ lldb_private::Error err;
+
+ ai->m_remote_allocation = process.AllocateMemory(
+ ai->m_size + ai->m_alignment - 1,
+ ai->m_executable ? (lldb::ePermissionsReadable | lldb::ePermissionsExecutable)
+ : (lldb::ePermissionsReadable | lldb::ePermissionsWritable),
+ err);
+
+ uint64_t mask = ai->m_alignment - 1;
+
+ ai->m_remote_start = (ai->m_remote_allocation + mask) & (~mask);
+
+ if (!err.Success())
+ {
+ ret = false;
+ break;
+ }
+
+ ai->m_allocated = true;
+
+ if (m_log)
+ {
+ m_log->Printf("RecordingMemoryManager::CommitAllocations() committed an allocation");
+ ai->dump(m_log);
+ }
+ }
+
+ if (!ret)
+ {
+ for (AllocationList::iterator ai = m_allocations.end(), ae = m_allocations.end();
+ ai != ae;
+ ++ai)
+ {
+ if (ai->m_allocated)
+ process.DeallocateMemory(ai->m_remote_start);
+ }
+ }
- for (pos = m_address_map.begin(); pos < end; ++pos)
+ return ret;
+}
+
+bool
+RecordingMemoryManager::WriteData (Process &process)
+{
+ for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
+ ai != ae;
+ ++ai)
{
- lldb::addr_t lstart = pos->m_local_start;
- lldb::addr_t lend = lstart + pos->m_size;
+ if (!ai->m_allocated)
+ return false;
- if (local_address >= lstart && local_address < lend)
+ lldb_private::Error err;
+
+ if (process.WriteMemory(ai->m_remote_start,
+ (void*)ai->m_local_start,
+ ai->m_size,
+ err) != ai->m_size ||
+ !err.Success())
+ return false;
+
+ if (m_log)
{
- return std::pair <lldb::addr_t, lldb::addr_t> (pos->m_remote_start, pos->m_remote_start + pos->m_size);
+ m_log->Printf("RecordingMemoryManager::CommitAllocations() wrote an allocation");
+ ai->dump(m_log);
}
}
- return std::pair <lldb::addr_t, lldb::addr_t> (0, 0);
+ return true;
}
-void
-RecordingMemoryManager::AddToLocalToRemoteMap (lldb::addr_t lstart, size_t size, lldb::addr_t rstart)
+void
+RecordingMemoryManager::Allocation::dump (lldb::LogSP log)
{
- if (m_log)
- m_log->Printf("Adding local [0x%llx-0x%llx], remote [0x%llx-0x%llx] to local->remote map", lstart, lstart + size, rstart, rstart + size);
+ if (!log)
+ return;
- m_address_map.push_back (LocalToRemoteAddressRange(lstart, size, rstart));
+ log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d)",
+ (unsigned long long)m_local_start,
+ (unsigned long long)m_size,
+ (unsigned long long)m_remote_start,
+ (unsigned)m_alignment,
+ (unsigned)m_section_id);
}
-
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index cd622260199..6bb3e083492 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -79,9 +79,20 @@ using namespace lldb;
using namespace lldb_private;
static inline bool
-DW_TAG_is_function_tag (dw_tag_t tag)
+child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
{
- return tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine;
+ switch (tag)
+ {
+ default:
+ break;
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ return true;
+ }
+ return false;
}
static AccessType
@@ -1475,10 +1486,41 @@ SymbolFileDWARF::ParseChildMembers
encoding_uid);
}
- if (member_byte_offset != UINT32_MAX)
+ if (member_byte_offset != UINT32_MAX || bit_size != 0)
{
- // Set the field offset in bits
- layout_info.field_offsets.insert(std::make_pair(field_decl, member_byte_offset * 8));
+ /////////////////////////////////////////////////////////////
+ // How to locate a field given the DWARF debug information
+ //
+ // AT_byte_size indicates the size of the word in which the
+ // bit offset must be interpreted.
+ //
+ // AT_data_member_location indicates the byte offset of the
+ // word from the base address of the structure.
+ //
+ // AT_bit_offset indicates how many bits into the word
+ // (according to the host endianness) the low-order bit of
+ // the field starts. AT_bit_offset can be negative.
+ //
+ // AT_bit_size indicates the size of the field in bits.
+ /////////////////////////////////////////////////////////////
+
+ ByteOrder object_endian = GetObjectFile()->GetModule()->GetArchitecture().GetDefaultEndian();
+
+ uint64_t total_bit_offset = 0;
+
+ total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
+
+ if (object_endian == eByteOrderLittle)
+ {
+ total_bit_offset += byte_size * 8;
+ total_bit_offset -= (bit_offset + bit_size);
+ }
+ else
+ {
+ total_bit_offset += bit_offset;
+ }
+
+ layout_info.field_offsets.insert(std::make_pair(field_decl, total_bit_offset));
}
if (prop_name != NULL)
{
@@ -1646,7 +1688,7 @@ SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Type*
SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* die, bool assert_not_being_parsed)
-{
+{
if (die != NULL)
{
LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
@@ -1677,7 +1719,7 @@ SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry
decl_ctx_die->GetOffset());
Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed);
- if (DW_TAG_is_function_tag(die->Tag()))
+ if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag()))
{
if (log)
GetObjectFile()->GetModule()->LogMessage (log.get(),
@@ -1907,8 +1949,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
}
}
-#if 0
- // Disable assisted layout until we get the clang side hooked up
+
if (!layout_info.field_offsets.empty())
{
if (type)
@@ -1944,7 +1985,6 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
}
}
-#endif
}
ast.CompleteTagDeclarationDefinition (clang_type);
return clang_type;
@@ -4053,7 +4093,7 @@ SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugIn
DWARFDIECollection decl_ctx_1;
DWARFDIECollection decl_ctx_2;
die1->GetDeclContextDIEs (this, cu1, decl_ctx_1);
- die1->GetDeclContextDIEs (this, cu2, decl_ctx_2);
+ die2->GetDeclContextDIEs (this, cu2, decl_ctx_2);
const size_t count1 = decl_ctx_1.Size();
const size_t count2 = decl_ctx_2.Size();
if (count1 != count2)
@@ -4079,7 +4119,7 @@ SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugIn
decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
const char *name1 = decl_ctx_die1->GetName(this, cu1);
- const char *name2 = decl_ctx_die1->GetName(this, cu2);
+ const char *name2 = decl_ctx_die2->GetName(this, cu2);
// If the string was from a DW_FORM_strp, then the pointer will often
// be the same!
if (name1 != name2)
@@ -4231,16 +4271,40 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
if (type_is_new_ptr)
*type_is_new_ptr = false;
+
+ static int depth = -1;
+
+ class DepthTaker {
+ public:
+ DepthTaker (int &depth) : m_depth(depth) { ++m_depth; }
+ ~DepthTaker () { --m_depth; }
+ int &m_depth;
+ } depth_taker(depth);
AccessType accessibility = eAccessNone;
if (die != NULL)
{
LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
if (log)
- GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s'",
- die->GetOffset(),
+ {
+ const DWARFDebugInfoEntry *context_die;
+ clang::DeclContext *context = GetClangDeclContextContainingDIE (dwarf_cu, die, &context_die);
+
+ std::string name_storage;
+
+ const char* qual_name = die->GetQualifiedName(this,
+ dwarf_cu,
+ name_storage);
+
+ GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (depth = %d, die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s '%s'='%s')",
+ depth,
+ die->GetOffset(),
+ context,
+ context_die->GetOffset(),
DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
+ die->GetName(this, dwarf_cu),
+ qual_name);
+ }
//
// LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
// if (log && dwarf_cu)
@@ -5010,6 +5074,9 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
if (type_name_cstr)
{
+ if (die->GetOffset() == 0xaeaba)
+ fprintf(stderr, "This is the one!");
+
bool type_handled = false;
if (tag == DW_TAG_subprogram)
{
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 0449902a193..23fcd55735f 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -82,6 +82,15 @@ GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
switch (type_class)
{
+ case clang::Type::ConstantArray:
+ {
+ const clang::ArrayType *array_type = dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
+
+ if (array_type)
+ return GetCompleteQualType (ast, array_type->getElementType());
+ }
+ break;
+
case clang::Type::Record:
case clang::Type::Enum:
{
@@ -124,8 +133,10 @@ GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
// because it only supports TagDecl objects right now...
if (class_interface_decl)
{
- bool is_forward_decl = class_interface_decl->isForwardDecl();
- if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
+ if (class_interface_decl->getDefinition())
+ return true;
+
+ if (class_interface_decl->hasExternalLexicalStorage())
{
if (ast)
{
@@ -133,15 +144,12 @@ GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
if (external_ast_source)
{
external_ast_source->CompleteType (class_interface_decl);
- is_forward_decl = class_interface_decl->isForwardDecl();
+ return !objc_class_type->isIncompleteType();
}
}
- return is_forward_decl == false;
}
- return true;
- }
- else
return false;
+ }
}
}
break;
@@ -568,7 +576,7 @@ public:
{
if (m_log)
{
- llvm::SmallVectorImpl<char> diag_str(10);
+ llvm::SmallVector<char, 32> diag_str(10);
info.FormatDiagnostic(diag_str);
diag_str.push_back('\0');
m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
@@ -1231,6 +1239,10 @@ ClangASTContext::CreateClassTemplateDecl (DeclContext *decl_ctx,
{
if (access_type != eAccessNone)
class_template_decl->setAccess (ConvertAccessTypeToAccessSpecifier (access_type));
+
+ //if (TagDecl *ctx_tag_decl = dyn_cast<TagDecl>(decl_ctx))
+ // CompleteTagDeclarationDefinition(GetTypeForDecl(ctx_tag_decl));
+
decl_ctx->addDecl (class_template_decl);
#ifdef LLDB_CONFIGURATION_DEBUG
@@ -1575,6 +1587,18 @@ check_op_param (uint32_t op_kind, bool unary, bool binary, uint32_t num_params)
bool
ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, uint32_t num_params)
{
+ switch (op_kind)
+ {
+ default:
+ break;
+ // C++ standard allows any number of arguments to new/delete
+ case OO_New:
+ case OO_Array_New:
+ case OO_Delete:
+ case OO_Array_Delete:
+ return true;
+ }
+
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) case OO_##Name: return check_op_param (op_kind, Unary, Binary, num_params);
switch (op_kind)
{
@@ -2033,8 +2057,9 @@ ClangASTContext::CreateObjCClass
decl_ctx,
SourceLocation(),
&ast->Idents.get(name),
+ NULL,
SourceLocation(),
- isForwardDecl,
+ /*isForwardDecl,*/
isInternal);
return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
@@ -3759,7 +3784,7 @@ ClangASTContext::GetChildClangTypeAtIndex
}
// We have a pointer to an simple type
- if (idx == 0)
+ if (idx == 0 && GetCompleteQualType(ast, pointee_type))
{
std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
assert(clang_type_info.first % 8 == 0);
@@ -4706,7 +4731,13 @@ ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *d
return namespace_decl;
}
- namespace_decl = NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), &identifier_info);
+ namespace_decl = NamespaceDecl::Create(*ast,
+ decl_ctx,
+ false,
+ SourceLocation(),
+ SourceLocation(),
+ &identifier_info,
+ NULL);
decl_ctx->addDecl (namespace_decl);
}
@@ -4718,7 +4749,13 @@ ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *d
if (namespace_decl)
return namespace_decl;
- namespace_decl = NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), NULL);
+ namespace_decl = NamespaceDecl::Create(*ast,
+ decl_ctx,
+ false,
+ SourceLocation(),
+ SourceLocation(),
+ NULL,
+ NULL);
translation_unit_decl->setAnonymousNamespace (namespace_decl);
translation_unit_decl->addDecl (namespace_decl);
assert (namespace_decl == translation_unit_decl->getAnonymousNamespace());
@@ -4731,7 +4768,13 @@ ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *d
namespace_decl = parent_namespace_decl->getAnonymousNamespace();
if (namespace_decl)
return namespace_decl;
- namespace_decl = NamespaceDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), NULL);
+ namespace_decl = NamespaceDecl::Create(*ast,
+ decl_ctx,
+ false,
+ SourceLocation(),
+ SourceLocation(),
+ NULL,
+ NULL);
parent_namespace_decl->setAnonymousNamespace (namespace_decl);
parent_namespace_decl->addDecl (namespace_decl);
assert (namespace_decl == parent_namespace_decl->getAnonymousNamespace());
@@ -4906,6 +4949,17 @@ ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
return true;
}
}
+
+ const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(t);
+ if (object_type)
+ {
+ ObjCInterfaceDecl *interface_decl = object_type->getInterface();
+ if (interface_decl)
+ {
+ interface_decl->startDefinition();
+ return true;
+ }
+ }
}
}
return false;
@@ -4931,9 +4985,8 @@ ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
if (objc_class_type)
{
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- class_interface_decl->completedForwardDecl();
+ // ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+ // class_interface_decl->completeDefinition();
}
const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
@@ -6064,7 +6117,7 @@ ClangASTContext::GetCompleteDecl (clang::ASTContext *ast,
}
else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
{
- if (!objc_interface_decl->isForwardDecl())
+ if (objc_interface_decl->getDefinition())
return true;
if (!objc_interface_decl->hasExternalLexicalStorage())
@@ -6072,7 +6125,7 @@ ClangASTContext::GetCompleteDecl (clang::ASTContext *ast,
ast_source->CompleteType(objc_interface_decl);
- return !objc_interface_decl->isForwardDecl();
+ return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
}
else
{
diff --git a/lldb/source/Symbol/ClangASTImporter.cpp b/lldb/source/Symbol/ClangASTImporter.cpp
index dc7f5688f5c..6f6dcd4abd6 100644
--- a/lldb/source/Symbol/ClangASTImporter.cpp
+++ b/lldb/source/Symbol/ClangASTImporter.cpp
@@ -137,6 +137,43 @@ ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx,
return result;
}
+void
+ClangASTImporter::CompleteDecl (clang::Decl *decl)
+{
+ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ log->Printf(" [ClangASTImporter] CompleteDecl called on (%sDecl*)%p",
+ decl->getDeclKindName(),
+ decl);
+
+ if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl))
+ {
+ if (!interface_decl->getDefinition())
+ {
+ interface_decl->startDefinition();
+ CompleteObjCInterfaceDecl(interface_decl);
+ }
+ }
+ else if (ObjCProtocolDecl *protocol_decl = dyn_cast<ObjCProtocolDecl>(protocol_decl))
+ {
+ if (!protocol_decl->getDefinition())
+ protocol_decl->startDefinition();
+ }
+ else if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl))
+ {
+ if (!tag_decl->getDefinition() && !tag_decl->isBeingDefined())
+ {
+ tag_decl->startDefinition();
+ CompleteTagDecl(tag_decl);
+ tag_decl->setCompleteDefinition(true);
+ }
+ }
+ else {
+ assert (0 && "CompleteDecl called on a Decl that can't be completed");
+ }
+}
+
bool
ClangASTImporter::CompleteTagDecl (clang::TagDecl *decl)
{
@@ -310,14 +347,26 @@ void
ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from)
{
ASTImporter::Imported(from, to);
+
+ ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to);
+
+ /*
+ if (to_objc_interface)
+ to_objc_interface->startDefinition();
+
+ CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);
+ if (to_cxx_record)
+ to_cxx_record->startDefinition();
+ */
+
ImportDefinition(from);
-
+
// If we're dealing with an Objective-C class, ensure that the inheritance has
// been set up correctly. The ASTImporter may not do this correctly if the
// class was originally sourced from symbols.
- if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to))
+ if (to_objc_interface)
{
do
{
@@ -346,6 +395,9 @@ ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from
if (!imported_from_superclass)
break;
+ if (!to_objc_interface->hasDefinition())
+ to_objc_interface->startDefinition();
+
to_objc_interface->setSuperClass(imported_from_superclass);
}
while (0);
@@ -366,6 +418,10 @@ clang::Decl
to,
from_named_decl->getName().str().c_str(),
from);
+
+ if (!strcmp(from->getDeclKindName(), "ClassTemplateSpecialization") &&
+ !from_named_decl->getName().str().compare("rebind"))
+ fprintf(stderr, "This is the one!");
}
else
{
@@ -464,17 +520,14 @@ clang::Decl
to_interface_decl->setHasExternalLexicalStorage();
to_interface_decl->setHasExternalVisibleStorage();
-
- if (to_interface_decl->isForwardDecl())
- to_interface_decl->completedForwardDecl();
-
- to_interface_decl->setExternallyCompleted();
+
+ /*to_interface_decl->setExternallyCompleted();*/
if (log)
log->Printf(" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s",
(to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
(to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
- (to_interface_decl->isForwardDecl() ? " Forward" : ""));
+ (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
}
return clang::ASTImporter::Imported(from, to);
diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp
index 6e9c05a053c..ea9ab99186c 100644
--- a/lldb/source/Symbol/ClangASTType.cpp
+++ b/lldb/source/Symbol/ClangASTType.cpp
@@ -1232,8 +1232,9 @@ ClangASTType::IsDefined (clang_type_t clang_type)
if (objc_class_type)
{
clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- if (class_interface_decl->isForwardDecl())
- return false;
+ if (class_interface_decl)
+ return class_interface_decl->getDefinition() != NULL;
+ return false;
}
}
return true;
@@ -1667,8 +1668,12 @@ ClangASTType::ReadFromMemory
// context (which Module it came from)
return false;
}
+
+ if (!ClangASTContext::GetCompleteType(ast_context, clang_type))
+ return false;
+
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
-
+
const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
if (data.GetByteSize() < byte_size)
{
diff --git a/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp b/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp
index 04c85798ebf..314408daa7b 100644
--- a/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp
+++ b/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp
@@ -134,3 +134,24 @@ ClangExternalASTSourceCallbacks::CompleteType (ObjCInterfaceDecl *objc_decl)
if (m_callback_objc_decl)
m_callback_objc_decl (m_callback_baton, objc_decl);
}
+
+bool
+ClangExternalASTSourceCallbacks::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)
+{
+ if (m_callback_layout_record_type)
+ return m_callback_layout_record_type(m_callback_baton,
+ Record,
+ Size,
+ Alignment,
+ FieldOffsets,
+ BaseOffsets,
+ VirtualBaseOffsets);
+
+ return false;
+}
+
diff --git a/lldb/test/lang/c/bitfields/TestBitfields.py b/lldb/test/lang/c/bitfields/TestBitfields.py
index 34fe7420a31..ef83139e4f3 100644
--- a/lldb/test/lang/c/bitfields/TestBitfields.py
+++ b/lldb/test/lang/c/bitfields/TestBitfields.py
@@ -66,7 +66,7 @@ class BitfieldsTestCase(TestBase):
substrs = ['(uint32_t:1) b1 = 1',
'(uint32_t:2) b2 = 3',
'(uint32_t:3) b3 = 7',
- '(uint32_t:4) b4 = 15',
+ '(uint32_t) b4 = 15',
'(uint32_t:5) b5 = 31',
'(uint32_t:6) b6 = 63',
'(uint32_t:7) b7 = 127',
@@ -78,7 +78,7 @@ class BitfieldsTestCase(TestBase):
substrs = ['(uint32_t:1) b1 = 1',
'(uint32_t:2) b2 = 3',
'(uint32_t:3) b3 = 7',
- '(uint32_t:4) b4 = 15',
+ '(uint32_t) b4 = 15',
'(uint32_t:5) b5 = 31',
'(uint32_t:6) b6 = 63',
'(uint32_t:7) b7 = 127',
@@ -113,8 +113,8 @@ class BitfieldsTestCase(TestBase):
self.DebugSBValue(bits)
self.assertTrue(bits.GetTypeName() == "Bits" and
bits.GetNumChildren() == 8 and
- bits.GetByteSize() == 4,
- "(Bits)bits with byte size of 4 and 8 children")
+ bits.GetByteSize() == 32,
+ "(Bits)bits with byte size of 32 and 8 children")
# Notice the pattern of int(b1.GetValue(), 0). We pass a base of 0
# so that the proper radix is determined based on the contents of the
diff --git a/lldb/test/lang/c/bitfields/main.c b/lldb/test/lang/c/bitfields/main.c
index 8d4116b2278..00d455ceab7 100644
--- a/lldb/test/lang/c/bitfields/main.c
+++ b/lldb/test/lang/c/bitfields/main.c
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include <stdint.h>
+#include <stdio.h>
int main (int argc, char const *argv[])
{
struct Bits
@@ -14,13 +15,15 @@ int main (int argc, char const *argv[])
uint32_t b1 : 1,
b2 : 2,
b3 : 3,
- b4 : 4,
+ b4 __attribute__ ((align(16))),
b5 : 5,
b6 : 6,
b7 : 7,
four : 4;
};
+ printf("%lu", sizeof(struct Bits));
+
struct Bits bits;
int i;
for (i=0; i<(1<<1); i++)
OpenPOWER on IntegriCloud