[Lldb-commits] [lldb] r174153 - Modified the expression parser's class wrapper to

Sean Callanan scallanan at apple.com
Thu Jan 31 22:55:49 PST 2013


Author: spyffe
Date: Fri Feb  1 00:55:48 2013
New Revision: 174153

URL: http://llvm.org/viewvc/llvm-project?rev=174153&view=rev
Log:
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>

Modified:
    lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/test/lang/cpp/this/main.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=174153&r1=174152&r2=174153&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Fri Feb  1 00:55:48 2013
@@ -1017,16 +1017,23 @@ private:
     ///
     /// @param[in] type
     ///     The type that needs to be created.
-    ///
-    /// @param[in] add_method
-    ///     True if a method with signature void $__lldb_expr(void*)
-    ///     should be added to the C++ class type passed in
     //------------------------------------------------------------------
     void 
     AddOneType (NameSearchContext &context, 
                 TypeFromUser &type,
-                unsigned int current_id,
-                bool add_method);
+                unsigned int current_id);
+    
+    //------------------------------------------------------------------
+    /// Copy a C++ class type into the parser's AST context and add a
+    /// member function declaration to it for the expression.
+    ///
+    /// @param[in] type
+    ///     The type that needs to be created.
+    //------------------------------------------------------------------
+
+    TypeFromParser
+    CopyClassType(TypeFromUser &type,
+                  unsigned int current_id);
     
     //------------------------------------------------------------------
     /// Actually do the task of materializing or dematerializing the struct.

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=174153&r1=174152&r2=174153&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Fri Feb  1 00:55:48 2013
@@ -2650,7 +2650,6 @@ ClangExpressionDeclMap::FindExternalVisi
             
             if (method_decl)
             {
-            
                 clang::CXXRecordDecl *class_decl = method_decl->getParent();
                 
                 QualType class_qual_type(class_decl->getTypeForDecl(), 0);
@@ -2664,7 +2663,28 @@ ClangExpressionDeclMap::FindExternalVisi
                     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 @@ ClangExpressionDeclMap::FindExternalVisi
                         
                         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 @@ ClangExpressionDeclMap::FindExternalVisi
                     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 @@ ClangExpressionDeclMap::FindExternalVisi
                         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 @@ ClangExpressionDeclMap::AddOneFunction (
     }
 }
 
-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");
+            log->Printf("ClangExpressionDeclMap::CopyClassType - Couldn't import the type");
         
-        return;
+        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 @@ ClangExpressionDeclMap::AddOneType(NameS
                                                    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);
 }

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=174153&r1=174152&r2=174153&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Feb  1 00:55:48 2013
@@ -1309,8 +1309,8 @@ ClangASTContext::CreateClassTemplateDecl
 
     // 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 @@ ClangASTContext::CreateClassTemplateSpec
                                                                                                                    template_param_infos.args.size(),
                                                                                                                    NULL);
     
+    class_template_specialization_decl->setSpecializationKind(TSK_ExplicitSpecialization);
+    
     return class_template_specialization_decl;
 }
 

Modified: lldb/trunk/test/lang/cpp/this/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/this/main.cpp?rev=174153&r1=174152&r2=174153&view=diff
==============================================================================
--- lldb/trunk/test/lang/cpp/this/main.cpp (original)
+++ lldb/trunk/test/lang/cpp/this/main.cpp Fri Feb  1 00:55:48 2013
@@ -9,45 +9,45 @@
 
 #include <stdio.h>
 
-class A
+template <class T> class A
 {
 public:
-  void accessMember(int a);
-  int accessMemberConst() const;
+  void accessMember(T a);
+  T accessMemberConst() const;
   static int accessStaticMember();
 
-  void accessMemberInline(int a) __attribute__ ((always_inline))
+  void accessMemberInline(T a) __attribute__ ((always_inline))
   {
     m_a = a; // breakpoint 4
   }
 
-  int m_a;
+  T m_a;
   static int s_a;
 };
 
-int A::s_a = 5;
+template <class T> int A<T>::s_a = 5;
 
-void A::accessMember(int a)
+template <class T> void A<T>::accessMember(T a)
 {
   m_a = a; // breakpoint 1
 }
 
-int A::accessMemberConst() const
+template <class T> T A<T>::accessMemberConst() const
 {
   return m_a; // breakpoint 2
 }
 
-int A::accessStaticMember()
+template <class T> int A<T>::accessStaticMember()
 {
   return s_a; // breakpoint 3
 } 
 
 int main()
 {
-  A my_a;
+  A<int> my_a;
 
   my_a.accessMember(3);
   my_a.accessMemberConst();
-  A::accessStaticMember();
+  A<int>::accessStaticMember();
   my_a.accessMemberInline(5);
 }





More information about the lldb-commits mailing list