[Lldb-commits] [lldb] r278670 - Fix expression evaluation with operator new

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Mon Aug 15 07:32:33 PDT 2016


Author: labath
Date: Mon Aug 15 09:32:32 2016
New Revision: 278670

URL: http://llvm.org/viewvc/llvm-project?rev=278670&view=rev
Log:
Fix expression evaluation with operator new

Summary:
referencing a user-defined operator new was triggering an assert in clang because we were
registering the function name as string "operator new", instead of using the special operator
enum, which clang has for this purpose. Method operators already had code to handle this, and now
I extend this to cover free standing operator functions as well. Test included.

Reviewers: spyffe

Subscribers: sivachandra, paulherman, lldb-commits

Differential Revision: http://reviews.llvm.org/D17856

Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/global_operators/main.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=278670&r1=278669&r2=278670&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Mon Aug 15 09:32:32 2016
@@ -390,10 +390,9 @@ public:
     static clang::DeclContext *
     GetAsDeclContext (clang::ObjCMethodDecl *objc_method_decl);
 
-    
     static bool
-    CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, 
-                                               uint32_t num_params);
+    CheckOverloadedOperatorKindParameterCount(bool is_method, clang::OverloadedOperatorKind op_kind,
+                                              uint32_t num_params);
 
     bool
     FieldIsBitfield (clang::FieldDecl* field,
@@ -1188,6 +1187,9 @@ public:
         return clang::QualType();
     }
 
+    clang::DeclarationName
+    GetDeclarationName(const char *name, const CompilerType &function_clang_type);
+
 protected:
     //------------------------------------------------------------------
     // Classes that inherit from ClangASTContext can see and modify these

Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py?rev=278670&r1=278669&r2=278670&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py Mon Aug 15 09:32:32 2016
@@ -10,8 +10,7 @@ class TestCppGlobalOperators(TestBase):
     
     mydir = TestBase.compute_mydir(__file__)
     
-    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
-    def test_with_run_command(self):
+    def prepare_executable_and_get_frame(self):
         self.build()
 
         # Get main source file
@@ -42,8 +41,11 @@ class TestCppGlobalOperators(TestBase):
         self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
         thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
 
-        # Check if global operators are evaluated 
-        frame = thread.GetSelectedFrame()
+        return thread.GetSelectedFrame()
+
+    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
+    def test_equals_operator(self):
+        frame = self.prepare_executable_and_get_frame()
 
         test_result = frame.EvaluateExpression("operator==(s1, s2)")
         self.assertTrue(test_result.IsValid() and test_result.GetValue() == "false", "operator==(s1, s2) = false")
@@ -53,3 +55,25 @@ class TestCppGlobalOperators(TestBase):
 
         test_result = frame.EvaluateExpression("operator==(s2, s3)")
         self.assertTrue(test_result.IsValid() and test_result.GetValue() == "false", "operator==(s2, s3) = false")
+
+    def do_new_test(self, frame, expr, expected_value_name):
+        """Evaluate a new expression, and check its result"""
+
+        expected_value = frame.FindValue(expected_value_name, lldb.eValueTypeVariableGlobal)
+        self.assertTrue(expected_value.IsValid())
+
+        expected_value_addr = expected_value.AddressOf()
+        self.assertTrue(expected_value_addr.IsValid())
+
+        got = frame.EvaluateExpression(expr)
+        self.assertTrue(got.IsValid())
+        self.assertEqual(got.GetValueAsUnsigned(), expected_value_addr.GetValueAsUnsigned())
+        got_type = got.GetType()
+        self.assertTrue(got_type.IsPointerType())
+        self.assertEqual(got_type.GetPointeeType().GetName(), "Struct")
+
+    def test_operator_new(self):
+        frame = self.prepare_executable_and_get_frame()
+
+        self.do_new_test(frame, "new Struct()", "global_new_buf")
+        self.do_new_test(frame, "new(new_tag) Struct()", "tagged_new_buf")

Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/global_operators/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/global_operators/main.cpp?rev=278670&r1=278669&r2=278670&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/global_operators/main.cpp (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/global_operators/main.cpp Mon Aug 15 09:32:32 2016
@@ -1,3 +1,10 @@
+#include <new>
+
+struct new_tag_t
+{
+};
+new_tag_t new_tag;
+
 struct Struct {
 	int value;
 };
@@ -6,6 +13,25 @@ bool operator==(const Struct &a, const S
 	return a.value == b.value;
 }
 
+typedef char buf_t[sizeof(Struct)];
+buf_t global_new_buf, tagged_new_buf;
+
+// This overrides global operator new
+// This function and the following does not actually allocate memory. We are merely
+// trying to make sure it is getting called.
+void *
+operator new(std::size_t count)
+{
+    return &global_new_buf;
+}
+
+// A custom allocator
+void *
+operator new(std::size_t count, const new_tag_t &)
+{
+    return &tagged_new_buf;
+}
+
 int main() {
 	Struct s1, s2, s3;
 	s1.value = 3;

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp?rev=278670&r1=278669&r2=278670&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp Mon Aug 15 09:32:32 2016
@@ -2081,13 +2081,10 @@ ClangExpressionDeclMap::AddOneFunction (
                             StreamString ss;
                             
                             function->DumpSymbolContext(&ss);
-                            
+
                             log->Printf("  CEDM::FEVD[%u] Imported decl for function %s (description %s), returned %s",
-                                        current_id,
-                                        copied_function_decl->getName().str().c_str(),
-                                        ss.GetData(),
+                                        current_id, copied_function_decl->getNameAsString().c_str(), ss.GetData(),
                                         ast_dumper.GetCString());
-                            
                         }
                         
                         context.AddNamedDecl(copied_function_decl);

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=278670&r1=278669&r2=278670&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Mon Aug 15 09:32:32 2016
@@ -131,6 +131,241 @@ GetASTMap()
     return *g_map_ptr;
 }
 
+static bool
+IsOperator(const char *name, clang::OverloadedOperatorKind &op_kind)
+{
+    if (name == nullptr || name[0] == '\0')
+        return false;
+
+#define OPERATOR_PREFIX "operator"
+#define OPERATOR_PREFIX_LENGTH (sizeof(OPERATOR_PREFIX) - 1)
+
+    const char *post_op_name = nullptr;
+
+    bool no_space = true;
+
+    if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
+        return false;
+
+    post_op_name = name + OPERATOR_PREFIX_LENGTH;
+
+    if (post_op_name[0] == ' ')
+    {
+        post_op_name++;
+        no_space = false;
+    }
+
+#undef OPERATOR_PREFIX
+#undef OPERATOR_PREFIX_LENGTH
+
+    // This is an operator, set the overloaded operator kind to invalid
+    // in case this is a conversion operator...
+    op_kind = clang::NUM_OVERLOADED_OPERATORS;
+
+    switch (post_op_name[0])
+    {
+        default:
+            if (no_space)
+                return false;
+            break;
+        case 'n':
+            if (no_space)
+                return false;
+            if (strcmp(post_op_name, "new") == 0)
+                op_kind = clang::OO_New;
+            else if (strcmp(post_op_name, "new[]") == 0)
+                op_kind = clang::OO_Array_New;
+            break;
+
+        case 'd':
+            if (no_space)
+                return false;
+            if (strcmp(post_op_name, "delete") == 0)
+                op_kind = clang::OO_Delete;
+            else if (strcmp(post_op_name, "delete[]") == 0)
+                op_kind = clang::OO_Array_Delete;
+            break;
+
+        case '+':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Plus;
+            else if (post_op_name[2] == '\0')
+            {
+                if (post_op_name[1] == '=')
+                    op_kind = clang::OO_PlusEqual;
+                else if (post_op_name[1] == '+')
+                    op_kind = clang::OO_PlusPlus;
+            }
+            break;
+
+        case '-':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Minus;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '=':
+                        op_kind = clang::OO_MinusEqual;
+                        break;
+                    case '-':
+                        op_kind = clang::OO_MinusMinus;
+                        break;
+                    case '>':
+                        op_kind = clang::OO_Arrow;
+                        break;
+                }
+            }
+            else if (post_op_name[3] == '\0')
+            {
+                if (post_op_name[2] == '*')
+                    op_kind = clang::OO_ArrowStar;
+                break;
+            }
+            break;
+
+        case '*':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Star;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_StarEqual;
+            break;
+
+        case '/':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Slash;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_SlashEqual;
+            break;
+
+        case '%':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Percent;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_PercentEqual;
+            break;
+
+        case '^':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Caret;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_CaretEqual;
+            break;
+
+        case '&':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Amp;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '=':
+                        op_kind = clang::OO_AmpEqual;
+                        break;
+                    case '&':
+                        op_kind = clang::OO_AmpAmp;
+                        break;
+                }
+            }
+            break;
+
+        case '|':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Pipe;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '=':
+                        op_kind = clang::OO_PipeEqual;
+                        break;
+                    case '|':
+                        op_kind = clang::OO_PipePipe;
+                        break;
+                }
+            }
+            break;
+
+        case '~':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Tilde;
+            break;
+
+        case '!':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Exclaim;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_ExclaimEqual;
+            break;
+
+        case '=':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Equal;
+            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+                op_kind = clang::OO_EqualEqual;
+            break;
+
+        case '<':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Less;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '<':
+                        op_kind = clang::OO_LessLess;
+                        break;
+                    case '=':
+                        op_kind = clang::OO_LessEqual;
+                        break;
+                }
+            }
+            else if (post_op_name[3] == '\0')
+            {
+                if (post_op_name[2] == '=')
+                    op_kind = clang::OO_LessLessEqual;
+            }
+            break;
+
+        case '>':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Greater;
+            else if (post_op_name[2] == '\0')
+            {
+                switch (post_op_name[1])
+                {
+                    case '>':
+                        op_kind = clang::OO_GreaterGreater;
+                        break;
+                    case '=':
+                        op_kind = clang::OO_GreaterEqual;
+                        break;
+                }
+            }
+            else if (post_op_name[1] == '>' && post_op_name[2] == '=' && post_op_name[3] == '\0')
+            {
+                op_kind = clang::OO_GreaterGreaterEqual;
+            }
+            break;
+
+        case ',':
+            if (post_op_name[1] == '\0')
+                op_kind = clang::OO_Comma;
+            break;
+
+        case '(':
+            if (post_op_name[1] == ')' && post_op_name[2] == '\0')
+                op_kind = clang::OO_Call;
+            break;
+
+        case '[':
+            if (post_op_name[1] == ']' && post_op_name[2] == '\0')
+                op_kind = clang::OO_Subscript;
+            break;
+    }
+
+    return true;
+}
 
 clang::AccessSpecifier
 ClangASTContext::ConvertAccessTypeToAccessSpecifier (AccessType access)
@@ -1524,23 +1759,26 @@ ClangASTContext::CreateClassTemplateSpec
 }
 
 static inline bool
-check_op_param (uint32_t op_kind, bool unary, bool binary, uint32_t num_params)
+check_op_param(bool is_method, clang::OverloadedOperatorKind op_kind, bool unary, bool binary, uint32_t num_params)
 {
     // Special-case call since it can take any number of operands
     if(op_kind == OO_Call)
         return true;
     
     // The parameter count doesn't include "this"
-    if (num_params == 0)
-        return unary;
+    if (is_method)
+        ++num_params;
     if (num_params == 1)
+        return unary;
+    if (num_params == 2)
         return binary;
     else 
     return false;
 }
 
 bool
-ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, uint32_t num_params)
+ClangASTContext::CheckOverloadedOperatorKindParameterCount(bool is_method, clang::OverloadedOperatorKind op_kind,
+                                                           uint32_t num_params)
 {
     switch (op_kind)
     {
@@ -1553,8 +1791,10 @@ ClangASTContext::CheckOverloadedOperator
     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);
+
+#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly)                                          \
+    case OO_##Name:                                                                                                    \
+        return check_op_param(is_method, op_kind, Unary, Binary, num_params);
     switch (op_kind)
     {
 #include "clang/Basic/OperatorKinds.def"
@@ -1965,6 +2205,35 @@ ClangASTContext::GetOpaqueCompilerType(c
 
 #pragma mark Function Types
 
+clang::DeclarationName
+ClangASTContext::GetDeclarationName(const char *name, const CompilerType &function_clang_type)
+{
+    if (!name || !name[0])
+        return clang::DeclarationName();
+
+    clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
+    if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS)
+        return DeclarationName(&getASTContext()->Idents.get(name)); // Not operator, but a regular function.
+
+    // Check the number of operator parameters. Sometimes we have
+    // seen bad DWARF that doesn't correctly describe operators and
+    // if we try to create a method and add it to the class, clang
+    // will assert and crash, so we need to make sure things are
+    // acceptable.
+    clang::QualType method_qual_type(ClangUtil::GetQualType(function_clang_type));
+    const clang::FunctionProtoType *function_type =
+        llvm::dyn_cast<clang::FunctionProtoType>(method_qual_type.getTypePtr());
+    if (function_type == nullptr)
+        return clang::DeclarationName();
+
+    const bool is_method = false;
+    const unsigned int num_params = function_type->getNumParams();
+    if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(is_method, op_kind, num_params))
+        return clang::DeclarationName();
+
+    return getASTContext()->DeclarationNames.getCXXOperatorName(op_kind);
+}
+
 FunctionDecl *
 ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx,
                                             const char *name,
@@ -1981,20 +2250,10 @@ ClangASTContext::CreateFunctionDeclarati
     const bool hasWrittenPrototype = true;
     const bool isConstexprSpecified = false;
 
-    if (name && name[0])
-    {
-        func_decl = FunctionDecl::Create(
-            *ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(&ast->Idents.get(name)),
-            ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline,
-            hasWrittenPrototype, isConstexprSpecified);
-    }
-    else
-    {
-        func_decl =
-            FunctionDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), DeclarationName(),
-                                 ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage,
-                                 is_inline, hasWrittenPrototype, isConstexprSpecified);
-    }
+    clang::DeclarationName declarationName = GetDeclarationName(name, function_clang_type);
+    func_decl = FunctionDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName,
+                                     ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage,
+                                     is_inline, hasWrittenPrototype, isConstexprSpecified);
     if (func_decl)
         decl_ctx->addDecl (func_decl);
     
@@ -7382,222 +7641,6 @@ ClangASTContext::GetTypeForFormatters (v
     return CompilerType();
 }
 
-static bool
-IsOperator (const char *name, clang::OverloadedOperatorKind &op_kind)
-{
-    if (name == nullptr || name[0] == '\0')
-        return false;
-    
-#define OPERATOR_PREFIX "operator"
-#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
-    
-    const char *post_op_name = nullptr;
-    
-    bool no_space = true;
-    
-    if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
-        return false;
-    
-    post_op_name = name + OPERATOR_PREFIX_LENGTH;
-    
-    if (post_op_name[0] == ' ')
-    {
-        post_op_name++;
-        no_space = false;
-    }
-    
-#undef OPERATOR_PREFIX
-#undef OPERATOR_PREFIX_LENGTH
-    
-    // This is an operator, set the overloaded operator kind to invalid
-    // in case this is a conversion operator...
-    op_kind = clang::NUM_OVERLOADED_OPERATORS;
-    
-    switch (post_op_name[0])
-    {
-        default:
-            if (no_space)
-                return false;
-            break;
-        case 'n':
-            if (no_space)
-                return false;
-            if  (strcmp (post_op_name, "new") == 0)
-                op_kind = clang::OO_New;
-            else if (strcmp (post_op_name, "new[]") == 0)
-                op_kind = clang::OO_Array_New;
-            break;
-            
-        case 'd':
-            if (no_space)
-                return false;
-            if (strcmp (post_op_name, "delete") == 0)
-                op_kind = clang::OO_Delete;
-            else if (strcmp (post_op_name, "delete[]") == 0)
-                op_kind = clang::OO_Array_Delete;
-            break;
-            
-        case '+':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Plus;
-            else if (post_op_name[2] == '\0')
-            {
-                if (post_op_name[1] == '=')
-                    op_kind = clang::OO_PlusEqual;
-                else if (post_op_name[1] == '+')
-                    op_kind = clang::OO_PlusPlus;
-            }
-            break;
-            
-        case '-':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Minus;
-            else if (post_op_name[2] == '\0')
-            {
-                switch (post_op_name[1])
-                {
-                    case '=': op_kind = clang::OO_MinusEqual; break;
-                    case '-': op_kind = clang::OO_MinusMinus; break;
-                    case '>': op_kind = clang::OO_Arrow; break;
-                }
-            }
-            else if (post_op_name[3] == '\0')
-            {
-                if (post_op_name[2] == '*')
-                    op_kind = clang::OO_ArrowStar; break;
-            }
-            break;
-            
-        case '*':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Star;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_StarEqual;
-            break;
-            
-        case '/':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Slash;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_SlashEqual;
-            break;
-            
-        case '%':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Percent;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_PercentEqual;
-            break;
-            
-            
-        case '^':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Caret;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_CaretEqual;
-            break;
-            
-        case '&':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Amp;
-            else if (post_op_name[2] == '\0')
-            {
-                switch (post_op_name[1])
-                {
-                    case '=': op_kind = clang::OO_AmpEqual; break;
-                    case '&': op_kind = clang::OO_AmpAmp; break;
-                }
-            }
-            break;
-            
-        case '|':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Pipe;
-            else if (post_op_name[2] == '\0')
-            {
-                switch (post_op_name[1])
-                {
-                    case '=': op_kind = clang::OO_PipeEqual; break;
-                    case '|': op_kind = clang::OO_PipePipe; break;
-                }
-            }
-            break;
-            
-        case '~':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Tilde;
-            break;
-            
-        case '!':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Exclaim;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_ExclaimEqual;
-            break;
-            
-        case '=':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Equal;
-            else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
-                op_kind = clang::OO_EqualEqual;
-            break;
-            
-        case '<':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Less;
-            else if (post_op_name[2] == '\0')
-            {
-                switch (post_op_name[1])
-                {
-                    case '<': op_kind = clang::OO_LessLess; break;
-                    case '=': op_kind = clang::OO_LessEqual; break;
-                }
-            }
-            else if (post_op_name[3] == '\0')
-            {
-                if (post_op_name[2] == '=')
-                    op_kind = clang::OO_LessLessEqual;
-            }
-            break;
-            
-        case '>':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Greater;
-            else if (post_op_name[2] == '\0')
-            {
-                switch (post_op_name[1])
-                {
-                    case '>': op_kind = clang::OO_GreaterGreater; break;
-                    case '=': op_kind = clang::OO_GreaterEqual; break;
-                }
-            }
-            else if (post_op_name[1] == '>' &&
-                     post_op_name[2] == '=' &&
-                     post_op_name[3] == '\0')
-            {
-                op_kind = clang::OO_GreaterGreaterEqual;
-            }
-            break;
-            
-        case ',':
-            if (post_op_name[1] == '\0')
-                op_kind = clang::OO_Comma;
-            break;
-            
-        case '(':
-            if (post_op_name[1] == ')' && post_op_name[2] == '\0')
-                op_kind = clang::OO_Call;
-            break;
-            
-        case '[':
-            if (post_op_name[1] == ']' && post_op_name[2] == '\0')
-                op_kind = clang::OO_Subscript;
-            break;
-    }
-    
-    return true;
-}
-
 clang::EnumDecl *
 ClangASTContext::GetAsEnumDecl (const CompilerType& type)
 {
@@ -7982,7 +8025,8 @@ ClangASTContext::AddMethodToCXXRecordTyp
                 // if we try to create a method and add it to the class, clang
                 // will assert and crash, so we need to make sure things are
                 // acceptable.
-                if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
+                const bool is_method = true;
+                if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount(is_method, op_kind, num_params))
                     return nullptr;
                 cxx_method_decl = clang::CXXMethodDecl::Create (*getASTContext(),
                                                                 cxx_record_decl,




More information about the lldb-commits mailing list