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 { +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_ 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 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 +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("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(parser_type.GetTypeSystem()); if (ast == nullptr) @@ -328,8 +330,15 @@ if (target == nullptr) return false; - TypeFromUser user_type = + llvm::Expected 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,7 +367,6 @@ 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) @@ -366,13 +374,15 @@ 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 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: 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;