Modified the expression parser's class wrapper to
support reporting "this" as a templated class. The
expression parser wraps expressions in C++ methods
as methods with the signature
$__lldb_class::$__lldb_expr(...)
and previously responded to clang's queries about
$__lldb_class with the type of *this. This didn't
work if *this was a ClassTemplateSpecializationDecl
because ClassTemplateSpecializationDecls can't be
the result of simple name queries.
Instead what we do now is respond that $__lldb_class
is a typedef and that the target of the typedef is
the (potentially templated) type of *this. That is
much more robust.
Thanks to John McCall for key insights.
<rdar://problem/10987183>
llvm-svn: 174153
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index ce6404d..21fc0fd 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -2650,7 +2650,6 @@
if (method_decl)
{
-
clang::CXXRecordDecl *class_decl = method_decl->getParent();
QualType class_qual_type(class_decl->getTypeForDecl(), 0);
@@ -2664,7 +2663,28 @@
log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString());
}
- AddOneType(context, class_user_type, current_id, true);
+ TypeFromParser class_type = CopyClassType(class_user_type, current_id);
+
+ if (!class_type.IsValid())
+ return;
+
+ TypeSourceInfo *type_source_info = m_ast_context->CreateTypeSourceInfo(QualType::getFromOpaquePtr(class_type.GetOpaqueQualType()));
+
+ if (!type_source_info)
+ return;
+
+ TypedefDecl *typedef_decl = TypedefDecl::Create(*m_ast_context,
+ m_ast_context->getTranslationUnitDecl(),
+ SourceLocation(),
+ SourceLocation(),
+ context.m_decl_name.getAsIdentifierInfo(),
+ type_source_info);
+
+
+ if (!typedef_decl)
+ return;
+
+ context.AddNamedDecl(typedef_decl);
if (method_decl->isInstance())
{
@@ -2715,7 +2735,7 @@
TypeFromUser class_user_type (class_type.getAsOpaquePtr(),
this_type->GetClangAST());
- AddOneType(context, class_user_type, current_id, false);
+ AddOneType(context, class_user_type, current_id);
TypeFromUser this_user_type(this_type->GetClangFullType(),
@@ -2774,7 +2794,7 @@
log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
}
- AddOneType(context, class_user_type, current_id, false);
+ AddOneType(context, class_user_type, current_id);
if (method_decl->isInstanceMethod())
{
@@ -2841,7 +2861,7 @@
TypeFromUser class_user_type (class_type.getAsOpaquePtr(),
self_type->GetClangAST());
- AddOneType(context, class_user_type, current_id, false);
+ AddOneType(context, class_user_type, current_id);
TypeFromUser self_user_type(self_type->GetClangFullType(),
self_type->GetClangAST());
@@ -3605,28 +3625,26 @@
}
}
-void
-ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
- TypeFromUser &ut,
- unsigned int current_id,
- bool add_method)
+TypeFromParser
+ClangExpressionDeclMap::CopyClassType(TypeFromUser &ut,
+ unsigned int current_id)
{
ASTContext *parser_ast_context = m_ast_context;
ASTContext *user_ast_context = ut.GetASTContext();
-
+
void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
if (!copied_type)
{
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- if (log)
- log->Printf("ClangExpressionDeclMap::AddOneType - Couldn't import the type");
- return;
+ if (log)
+ log->Printf("ClangExpressionDeclMap::CopyClassType - Couldn't import the type");
+
+ return TypeFromParser();
}
-
- if (add_method && ClangASTContext::IsAggregateType(copied_type) && ClangASTContext::GetCompleteType (parser_ast_context, copied_type))
+
+ if (ClangASTContext::IsAggregateType(copied_type) && ClangASTContext::GetCompleteType (parser_ast_context, copied_type))
{
void *args[1];
@@ -3659,5 +3677,28 @@
is_artificial);
}
+ return TypeFromParser(copied_type, parser_ast_context);
+}
+
+void
+ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
+ TypeFromUser &ut,
+ unsigned int current_id)
+{
+ ASTContext *parser_ast_context = m_ast_context;
+ ASTContext *user_ast_context = ut.GetASTContext();
+
+ void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
+
+ if (!copied_type)
+ {
+ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ log->Printf("ClangExpressionDeclMap::AddOneType - Couldn't import the type");
+
+ return;
+ }
+
context.AddTypeDecl(copied_type);
}
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 169a32f..a5c6b1a 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -1309,8 +1309,8 @@
// With templated classes, we say that a class is templated with
// specializations, but that the bare class has no functions.
- template_cxx_decl->startDefinition();
- template_cxx_decl->completeDefinition();
+ //template_cxx_decl->startDefinition();
+ //template_cxx_decl->completeDefinition();
class_template_decl = ClassTemplateDecl::Create (*ast,
decl_ctx, // What decl context do we use here? TU? The actual decl context?
@@ -1356,6 +1356,8 @@
template_param_infos.args.size(),
NULL);
+ class_template_specialization_decl->setSpecializationKind(TSK_ExplicitSpecialization);
+
return class_template_specialization_decl;
}