vsk updated this revision to Diff 136450.
vsk added a comment.

> The problem with your RETURN_IF_UNEXPECTED macro is that it make it 
> impossible to put a breakpoint only on the "type was invalid case." To catch 
> that happening while debugging you'd have to write a conditional breakpoint 
> that also checks the error.

Yes, we'd need a conditional breakpoint if more than one InvalidTypeError 
instance is created (otherwise we'd just break on the constructor). While I 
hope we never have to deal with that, I'm happy to keep things more explicit 
for now.


https://reviews.llvm.org/D43912

Files:
  include/lldb/Symbol/CompilerType.h
  source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
  source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
  source/Symbol/CompilerType.cpp

Index: source/Symbol/CompilerType.cpp
===================================================================
--- source/Symbol/CompilerType.cpp
+++ source/Symbol/CompilerType.cpp
@@ -1080,3 +1080,5 @@
   return lhs.GetTypeSystem() != rhs.GetTypeSystem() ||
          lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType();
 }
+
+char lldb_private::InvalidTypeError::ID;
Index: source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
===================================================================
--- source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -625,10 +625,11 @@
   ///     The type as it appears in the source context.
   ///
   /// @return
-  ///     Returns the moved type, or an empty type if there was a problem.
+  ///     Returns the moved type, or an error.
   //------------------------------------------------------------------
-  TypeFromUser DeportType(ClangASTContext &target, ClangASTContext &source,
-                          TypeFromParser parser_type);
+  llvm::Expected<TypeFromUser> DeportType(ClangASTContext &target,
+                                          ClangASTContext &source,
+                                          TypeFromParser parser_type);
 
   ClangASTContext *GetClangASTContext();
 };
Index: source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
===================================================================
--- source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -277,9 +277,10 @@
   return ret;
 }
 
-TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
-                                                ClangASTContext &source,
-                                                TypeFromParser parser_type) {
+llvm::Expected<TypeFromUser>
+ClangExpressionDeclMap::DeportType(ClangASTContext &target,
+                                   ClangASTContext &source,
+                                   TypeFromParser parser_type) {
   assert (&target == m_target->GetScratchClangASTContext());
   assert ((TypeSystem*)&source == parser_type.GetTypeSystem());
   assert (source.getASTContext() == m_ast_context);
@@ -302,10 +303,10 @@
         source_file,
         clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType()));
     return TypeFromUser(exported_type.getAsOpaquePtr(), &target);
-  } else {
-    lldbassert(0 && "No mechanism for deporting a type!");
-    return TypeFromUser();
   }
+
+  lldbassert(0 && "No mechanism for deporting a type!");
+  return llvm::make_error<InvalidTypeError>("Could not deport type");
 }
 
 bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
@@ -315,6 +316,7 @@
                                                    bool is_lvalue) {
   assert(m_parser_vars.get());
 
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
   ClangASTContext *ast =
       llvm::dyn_cast_or_null<ClangASTContext>(parser_type.GetTypeSystem());
   if (ast == nullptr)
@@ -328,8 +330,15 @@
     if (target == nullptr)
       return false;
 
-    TypeFromUser user_type =
+    llvm::Expected<TypeFromUser> user_type_or_err =
         DeportType(*target->GetScratchClangASTContext(), *ast, parser_type);
+    if (!user_type_or_err) {
+      LLDB_LOG_ERROR(log, user_type_or_err.takeError(), "{0}");
+      return false;
+    }
+    TypeFromUser &user_type = *user_type_or_err;
+    assert(user_type.IsValid() &&
+           "Persistent variable's type wasn't copied successfully");
 
     uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
         user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
@@ -358,21 +367,22 @@
     return true;
   }
 
-  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
   ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
   Target *target = exe_ctx.GetTargetPtr();
   if (target == NULL)
     return false;
 
   ClangASTContext *context(target->GetScratchClangASTContext());
 
-  TypeFromUser user_type = DeportType(*context, *ast, parser_type);
-
-  if (!user_type.GetOpaqueQualType()) {
-    if (log)
-      log->Printf("Persistent variable's type wasn't copied successfully");
+  llvm::Expected<TypeFromUser> user_type_or_err =
+      DeportType(*context, *ast, parser_type);
+  if (!user_type_or_err) {
+    LLDB_LOG_ERROR(log, user_type_or_err.takeError(), "{0}");
     return false;
   }
+  TypeFromUser &user_type = *user_type_or_err;
+  assert(user_type.IsValid() &&
+         "Persistent variable's type wasn't copied successfully");
 
   if (!m_parser_vars->m_target_info.IsValid())
     return false;
Index: include/lldb/Symbol/CompilerType.h
===================================================================
--- include/lldb/Symbol/CompilerType.h
+++ include/lldb/Symbol/CompilerType.h
@@ -21,6 +21,7 @@
 #include "lldb/Core/ClangForward.h"
 #include "lldb/lldb-private.h"
 #include "llvm/ADT/APSInt.h"
+#include "llvm/Support/Error.h"
 
 namespace lldb_private {
 
@@ -441,6 +442,23 @@
   CompilerType type;
 };
 
+/// A force-checked error used to describe type construction failures.
+class InvalidTypeError : public llvm::ErrorInfo<InvalidTypeError> {
+public:
+  static char ID;
+  std::string Reason;
+
+  InvalidTypeError(llvm::StringRef Reason) : Reason(Reason) {}
+
+  void log(llvm::raw_ostream &OS) const override {
+    OS << "Invalid type: " << Reason;
+  }
+
+  std::error_code convertToErrorCode() const override {
+    return std::make_error_code(std::errc::invalid_argument);
+  }
+};
+
 } // namespace lldb_private
 
 #endif // liblldb_CompilerType_h_
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to