aboutsummaryrefslogtreecommitdiff
path: root/source/Symbol/ClangASTImporter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Symbol/ClangASTImporter.cpp')
-rw-r--r--source/Symbol/ClangASTImporter.cpp267
1 files changed, 248 insertions, 19 deletions
diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp
index 141937072c73..6be10602d998 100644
--- a/source/Symbol/ClangASTImporter.cpp
+++ b/source/Symbol/ClangASTImporter.cpp
@@ -7,16 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "llvm/Support/raw_ostream.h"
+#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/ClangASTImporter.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "llvm/Support/raw_ostream.h"
using namespace lldb_private;
using namespace clang;
@@ -347,6 +348,211 @@ ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx,
return result;
}
+bool
+ClangASTImporter::CanImport(const CompilerType &type)
+{
+ if (!ClangUtil::IsClangType(type))
+ return false;
+
+ // TODO: remove external completion BOOL
+ // CompleteAndFetchChildren should get the Decl out and check for the
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ {
+ const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
+ return true;
+ }
+ }
+ break;
+
+ case clang::Type::Enum:
+ {
+ clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl)
+ {
+ if (ResolveDeclOrigin(enum_decl, NULL, NULL))
+ return true;
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ {
+ const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type)
+ {
+ clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added ASTContext
+ // because it only supports TagDecl objects right now...
+ if (class_interface_decl)
+ {
+ if (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
+ return true;
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return CanImport(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+
+ case clang::Type::Auto:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ return CanImport(CompilerType(
+ type.GetTypeSystem(), llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ return CanImport(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool
+ClangASTImporter::Import(const CompilerType &type)
+{
+ if (!ClangUtil::IsClangType(type))
+ return false;
+ // TODO: remove external completion BOOL
+ // CompleteAndFetchChildren should get the Decl out and check for the
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Record:
+ {
+ const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+ if (cxx_record_decl)
+ {
+ if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL))
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ break;
+
+ case clang::Type::Enum:
+ {
+ clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl();
+ if (enum_decl)
+ {
+ if (ResolveDeclOrigin(enum_decl, NULL, NULL))
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ break;
+
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ {
+ const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+ if (objc_class_type)
+ {
+ clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+ // We currently can't complete objective C types through the newly added ASTContext
+ // because it only supports TagDecl objects right now...
+ if (class_interface_decl)
+ {
+ if (ResolveDeclOrigin(class_interface_decl, NULL, NULL))
+ return CompleteAndFetchChildren(qual_type);
+ }
+ }
+ }
+ break;
+
+ case clang::Type::Typedef:
+ return Import(CompilerType(
+ type.GetTypeSystem(),
+ llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()));
+
+ case clang::Type::Auto:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::AutoType>(qual_type)->getDeducedType().getAsOpaquePtr()));
+
+ case clang::Type::Elaborated:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()));
+
+ case clang::Type::Paren:
+ return Import(CompilerType(type.GetTypeSystem(),
+ llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()));
+
+ default:
+ break;
+ }
+ return false;
+}
+
+bool
+ClangASTImporter::CompleteType(const CompilerType &compiler_type)
+{
+ if (!CanImport(compiler_type))
+ return false;
+
+ if (Import(compiler_type))
+ {
+ ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+ return true;
+ }
+
+ ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), false);
+ return false;
+}
+
+bool
+ClangASTImporter::LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
+{
+ RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find(record_decl);
+ bool success = false;
+ base_offsets.clear();
+ vbase_offsets.clear();
+ if (pos != m_record_decl_to_layout_map.end())
+ {
+ bit_size = pos->second.bit_size;
+ alignment = pos->second.alignment;
+ field_offsets.swap(pos->second.field_offsets);
+ base_offsets.swap(pos->second.base_offsets);
+ vbase_offsets.swap(pos->second.vbase_offsets);
+ m_record_decl_to_layout_map.erase(pos);
+ success = true;
+ }
+ else
+ {
+ bit_size = 0;
+ alignment = 0;
+ field_offsets.clear();
+ }
+ return success;
+}
+
+void
+ClangASTImporter::InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout)
+{
+ m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
+}
+
void
ClangASTImporter::CompleteDecl (clang::Decl *decl)
{
@@ -729,16 +935,21 @@ ClangASTImporter::Minion::ExecuteDeportWorkQueues ()
if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl))
{
if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
+ {
if (original_tag_decl->isCompleteDefinition())
+ {
ImportDefinitionTo(tag_decl, original_tag_decl);
+ tag_decl->setCompleteDefinition(true);
+ }
+ }
tag_decl->setHasExternalLexicalStorage(false);
tag_decl->setHasExternalVisibleStorage(false);
}
- else if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl))
+ else if (ObjCContainerDecl *container_decl = dyn_cast<ObjCContainerDecl>(decl))
{
- interface_decl->setHasExternalLexicalStorage(false);
- interface_decl->setHasExternalVisibleStorage(false);
+ container_decl->setHasExternalLexicalStorage(false);
+ container_decl->setHasExternalVisibleStorage(false);
}
to_context_md->m_origins.erase(decl);
@@ -753,8 +964,6 @@ 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();
@@ -766,12 +975,20 @@ ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from
*/
ImportDefinition(from);
+
+ if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to))
+ {
+ if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from))
+ {
+ to_tag->setCompleteDefinition(from_tag->isCompleteDefinition());
+ }
+ }
// 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 (to_objc_interface)
+ if (ObjCInterfaceDecl *to_objc_interface = dyn_cast<ObjCInterfaceDecl>(to))
{
do
{
@@ -949,20 +1166,32 @@ ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
to_namespace_decl->setHasExternalVisibleStorage();
}
- if (isa<ObjCInterfaceDecl>(from))
+ if (isa<ObjCContainerDecl>(from))
{
- ObjCInterfaceDecl *to_interface_decl = dyn_cast<ObjCInterfaceDecl>(to);
+ ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(to);
- to_interface_decl->setHasExternalLexicalStorage();
- to_interface_decl->setHasExternalVisibleStorage();
+ to_container_decl->setHasExternalLexicalStorage();
+ to_container_decl->setHasExternalVisibleStorage();
/*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->hasDefinition() ? " HasDefinition" : ""));
+ {
+ if (ObjCInterfaceDecl *to_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(to_container_decl))
+ {
+ log->Printf(" [ClangASTImporter] To is an ObjCInterfaceDecl - attributes %s%s%s",
+ (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+ (to_interface_decl->hasDefinition() ? " HasDefinition" : ""));
+ }
+ else
+ {
+ log->Printf(" [ClangASTImporter] To is an %sDecl - attributes %s%s",
+ ((Decl*)to_container_decl)->getDeclKindName(),
+ (to_container_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+ (to_container_decl->hasExternalVisibleStorage() ? " Visible" : ""));
+ }
+ }
}
return clang::ASTImporter::Imported(from, to);