diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 6a03514b9626..10b123e20638 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -853,13 +853,36 @@ ClangASTContext::AddMethodToCXXRecordType CXXMethodDecl *cxx_method_decl = NULL; DeclarationName decl_name (&identifier_table->get(name)); + + DeclarationNameInfo decl_name_info (decl_name, SourceLocation()); + const bool is_implicitly_declared = false; - if (name[0] == '~' || decl_name == record_decl->getDeclName()) + clang::Type *method_type(method_qual_type.getTypePtr()); + + if (method_type == NULL) + return NULL; + + FunctionProtoType *method_function_prototype (dyn_cast(method_type)); + + if (!method_function_prototype) + return NULL; + + unsigned int num_params = method_function_prototype->getNumArgs(); + + if (name[0] == '~') + { + cxx_method_decl = CXXDestructorDecl::Create (*ast_context, + cxx_record_decl, + decl_name_info, + method_qual_type, + is_inline, + is_implicitly_declared); + } + else if (decl_name == record_decl->getDeclName()) { - bool is_implicitly_declared = false; cxx_method_decl = CXXConstructorDecl::Create (*ast_context, cxx_record_decl, - DeclarationNameInfo (decl_name, SourceLocation()), + decl_name_info, method_qual_type, NULL, // TypeSourceInfo * is_explicit, @@ -867,15 +890,33 @@ ClangASTContext::AddMethodToCXXRecordType is_implicitly_declared); } else - { - cxx_method_decl = CXXMethodDecl::Create (*ast_context, - cxx_record_decl, - DeclarationNameInfo (decl_name, SourceLocation()), - method_qual_type, - NULL, // TypeSourceInfo * - is_static, - SC_None, - is_inline); + { + // TODO: verify this is an ok way to see if this is a C++ conversion + // operator. I am currently checking for "operator " following by a valid + // first character of a type name (A-Z, a-z, or _)... + if ((num_params == 0) && + (::strstr(name, "operator ") == name) && + (::isalpha(name[9]) || name[9] == '_')) + { + cxx_method_decl = CXXConversionDecl::Create (*ast_context, + cxx_record_decl, + decl_name_info, + method_qual_type, + NULL, // TypeSourceInfo * + is_inline, + is_explicit); + } + else + { + cxx_method_decl = CXXMethodDecl::Create (*ast_context, + cxx_record_decl, + decl_name_info, + method_qual_type, + NULL, // TypeSourceInfo * + is_static, + SC_None, + is_inline); + } } @@ -885,17 +926,6 @@ ClangASTContext::AddMethodToCXXRecordType cxx_method_decl->setVirtualAsWritten (is_virtual); // Populate the method decl with parameter decls - clang::Type *method_type(method_qual_type.getTypePtr()); - - if (method_type == NULL) - return NULL; - - FunctionProtoType *method_function_prototype (dyn_cast(method_type)); - - if (!method_function_prototype) - return NULL; - - unsigned int num_params = method_function_prototype->getNumArgs(); ParmVarDecl *params[num_params]; diff --git a/lldb/test/class_types/main.cpp b/lldb/test/class_types/main.cpp index 36885f429130..1766ef0ba2bc 100644 --- a/lldb/test/class_types/main.cpp +++ b/lldb/test/class_types/main.cpp @@ -7,6 +7,22 @@ // //===----------------------------------------------------------------------===// +class Conversion +{ +public: + Conversion (int i) : + m_i (i) + {} + + operator bool() + { + return m_i != 0; + } + +private: + int m_i; +}; + class A { public: @@ -103,5 +119,8 @@ main (int argc, char const *argv[]) A a(12); B b(22,33); C c(44,55,66); - return b.GetIntegerB() - a.GetInteger() + c.GetInteger(); + Conversion conv(1); + if (conv) + return b.GetIntegerB() - a.GetInteger() + c.GetInteger(); + return 0; }