summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2012-02-04 08:49:35 +0000
committerSean Callanan <scallanan@apple.com>2012-02-04 08:49:35 +0000
commit5b26f27f465676684f9440f02ac4e84a252f5bbb (patch)
tree573b886fcfcf80d6be527eaf3444361b51a7466e
parentbdce3885c4e1c1b96d30cf76d005d661401fbe03 (diff)
downloadbcm5719-llvm-5b26f27f465676684f9440f02ac4e84a252f5bbb.tar.gz
bcm5719-llvm-5b26f27f465676684f9440f02ac4e84a252f5bbb.zip
I have brought LLDB up-to-date with top of tree
LLVM/Clang. This brings in several fixes, including: - Improvements in the Just-In-Time compiler's allocation of memory: the JIT now allocates memory in chunks of sections, improving its ability to generate relocations. I have revamped the RecordingMemoryManager to reflect these changes, as well as to get the memory allocation and data copying out fo the ClangExpressionParser code. Jim Grosbach wrote the updates to the JIT on the LLVM side. - A new ExternalASTSource interface to allow LLDB to report accurate structure layout information to Clang. Previously we could only report the sizes of fields, not their offsets. This meant that if data structures included field alignment directives, we could not communicate the necessary alignment to Clang and accesses to the data would fail. Now we can (and I have update the relevant test case). Thanks to Doug Gregor for implementing the Clang side of this fix. - The way Objective-C interfaces are completed by Clang has been made consistent with RecordDecls; with help from Doug Gregor and Greg Clayton I have ensured that this still works. - I have eliminated all local LLVM and Clang patches, committing the ones that are still relevant to LLVM and Clang as needed. I have tested the changes extensively locally, but please let me know if they cause any trouble for you. llvm-svn: 149775
-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