diff options
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionDeclMap.h | 10 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionVariable.h | 3 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/ClangASTContext.h | 9 | ||||
-rw-r--r-- | lldb/source/Expression/ClangASTSource.cpp | 6 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 75 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionParser.cpp | 12 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTContext.cpp | 6 | ||||
-rw-r--r-- | lldb/test/alias_tests/TestAliases.py | 4 | ||||
-rw-r--r-- | lldb/test/expression_command/test/TestExprs.py | 38 |
9 files changed, 131 insertions, 32 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index d3e641aee57..627827c3687 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -85,6 +85,16 @@ public: WillParse (ExecutionContext &exe_ctx); //------------------------------------------------------------------ + /// [Used by ClangExpressionParser] For each variable that had an unknown + /// type at the beginning of parsing, determine its final type now. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ + bool + ResolveUnknownTypes(); + + //------------------------------------------------------------------ /// Disable the state needed for parsing and IR transformation. //------------------------------------------------------------------ void diff --git a/lldb/include/lldb/Expression/ClangExpressionVariable.h b/lldb/include/lldb/Expression/ClangExpressionVariable.h index 4c3263dbe9d..86c01290138 100644 --- a/lldb/include/lldb/Expression/ClangExpressionVariable.h +++ b/lldb/include/lldb/Expression/ClangExpressionVariable.h @@ -223,7 +223,8 @@ public: EVNeedsAllocation = 1 << 2, ///< Space for this variable has yet to be allocated in the target process EVIsFreezeDried = 1 << 3, ///< This variable's authoritative version is in m_frozen_sp (for example, for statically-computed results) EVNeedsFreezeDry = 1 << 4, ///< Copy from m_live_sp to m_frozen_sp during dematerialization - EVKeepInTarget = 1 << 5 ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it + EVKeepInTarget = 1 << 5, ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it + EVUnknownType = 1 << 6 ///< This is a symbol of unknown type, and the type must be resolved after parsing is complete }; uint16_t m_flags; // takes elements of Flags diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h index b389de9c03d..337ea8186e0 100644 --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -159,6 +159,15 @@ public: lldb::clang_type_t GetBuiltInType_objc_Class(); + + static lldb::clang_type_t + GetUnknownAnyType(clang::ASTContext *ast); + + lldb::clang_type_t + GetUnknownAnyType() + { + return ClangASTContext::GetUnknownAnyType(getASTContext()); + } lldb::clang_type_t GetBuiltInType_objc_selector(); diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index f3526a70f7b..d91f2f1069e 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -232,9 +232,9 @@ NameSearchContext::AddGenericFunDecl() proto_info.Variadic = true; - QualType generic_function_type(m_ast_source.m_ast_context.getFunctionType (m_ast_source.m_ast_context.getSizeType(), // result - NULL, // argument types - 0, // number of arguments + QualType generic_function_type(m_ast_source.m_ast_context.getFunctionType (m_ast_source.m_ast_context.UnknownAnyTy, // result + NULL, // argument types + 0, // number of arguments proto_info)); return AddFunDecl(generic_function_type.getAsOpaquePtr()); diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 6c7b2a87dff..b2fe2da3e66 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -1295,8 +1295,15 @@ ClangExpressionDeclMap::DoMaterializeOneVariable } if (log) - log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType()); - + { + StreamString my_stream_string; + + ClangASTType::DumpTypeDescription (type.GetASTContext(), + type.GetOpaqueQualType(), + &my_stream_string); + + log->Printf("%s %s with type %s", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), my_stream_string.GetString().c_str()); + } if (!location_value.get()) { @@ -2095,13 +2102,13 @@ ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, clang::ASTContext *scratch_ast_context = m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext(); - TypeFromUser user_type (ClangASTContext::GetVoidPtrType(scratch_ast_context, false), + TypeFromUser user_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(scratch_ast_context, true)), scratch_ast_context); - TypeFromParser parser_type (ClangASTContext::GetVoidPtrType(context.GetASTContext(), false), + TypeFromParser parser_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(context.GetASTContext(), true)), context.GetASTContext()); - NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(parser_type.GetASTContext(), parser_type.GetOpaqueQualType())); + NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType()); std::string decl_name(context.m_decl_name.getAsString()); ConstString entity_name(decl_name.c_str()); @@ -2111,7 +2118,6 @@ ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, m_parser_vars->m_exe_ctx->process->GetByteOrder(), m_parser_vars->m_exe_ctx->process->GetAddressByteSize())); assert (entity.get()); - entity->EnableParserVars(); std::auto_ptr<Value> symbol_location(new Value); @@ -2123,11 +2129,13 @@ ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, symbol_location->GetScalar() = symbol_load_addr; symbol_location->SetValueType(Value::eValueTypeLoadAddress); + entity->EnableParserVars(); entity->m_parser_vars->m_parser_type = parser_type; entity->m_parser_vars->m_named_decl = var_decl; entity->m_parser_vars->m_llvm_value = NULL; entity->m_parser_vars->m_lldb_value = symbol_location.release(); entity->m_parser_vars->m_lldb_sym = &symbol; + //entity->m_flags |= ClangExpressionVariable::EVUnknownType; if (log) { @@ -2147,6 +2155,61 @@ ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, } } +bool +ClangExpressionDeclMap::ResolveUnknownTypes() +{ + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + clang::ASTContext *scratch_ast_context = m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext(); + + for (size_t index = 0, num_entities = m_found_entities.GetSize(); + index < num_entities; + ++index) + { + ClangExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index); + + if (entity->m_flags & ClangExpressionVariable::EVUnknownType) + { + const NamedDecl *named_decl = entity->m_parser_vars->m_named_decl; + const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl); + + if (!var_decl) + { + if (log) + log->Printf("Entity of unknown type does not have a VarDecl"); + return false; + } + + if (log) + { + std::string var_decl_print_string; + llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string); + var_decl->print(var_decl_print_stream); + var_decl_print_stream.flush(); + + log->Printf("Variable of unknown type now has Decl %s", var_decl_print_string.c_str()); + } + + QualType var_type = var_decl->getType(); + TypeFromParser parser_type(var_type.getAsOpaquePtr(), &var_decl->getASTContext()); + + lldb::clang_type_t copied_type = ClangASTContext::CopyType(scratch_ast_context, &var_decl->getASTContext(), var_type.getAsOpaquePtr()); + + TypeFromUser user_type(copied_type, scratch_ast_context); + + entity->m_parser_vars->m_lldb_value->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType()); + entity->m_parser_vars->m_parser_type = parser_type; + + entity->SetClangAST(user_type.GetASTContext()); + entity->SetClangType(user_type.GetOpaqueQualType()); + + entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType); + } + } + + return true; +} + void ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context, const RegisterInfo *reg_info) diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp index 51654626fcd..028f99ab7e2 100644 --- a/lldb/source/Expression/ClangExpressionParser.cpp +++ b/lldb/source/Expression/ClangExpressionParser.cpp @@ -17,6 +17,7 @@ #include "lldb/Core/StreamString.h" #include "lldb/Expression/ClangASTSource.h" #include "lldb/Expression/ClangExpression.h" +#include "lldb/Expression/ClangExpressionDeclMap.h" #include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Expression/IRForTarget.h" #include "lldb/Expression/IRToDWARF.h" @@ -352,7 +353,7 @@ ClangExpressionParser::Parse (Stream &stream) ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), m_compiler->getASTContext()); diag_buf->EndSourceFile(); - + TextDiagnosticBuffer::const_iterator diag_iterator; int num_errors = 0; @@ -377,6 +378,15 @@ ClangExpressionParser::Parse (Stream &stream) ++diag_iterator) stream.Printf("note: %s\n", (*diag_iterator).second.c_str()); + if (!num_errors) + { + if (m_expr.DeclMap() && !m_expr.DeclMap()->ResolveUnknownTypes()) + { + stream.Printf("error: Couldn't infer the type of a variable\n"); + num_errors++; + } + } + return num_errors; } diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 40f0124acbe..cc9ea13112b 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -897,6 +897,12 @@ ClangASTContext::GetBuiltInType_objc_selector() } clang_type_t +ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast) +{ + return ast->UnknownAnyTy.getAsOpaquePtr(); +} + +clang_type_t ClangASTContext::GetCStringType (bool is_const) { QualType char_type(getASTContext()->CharTy); diff --git a/lldb/test/alias_tests/TestAliases.py b/lldb/test/alias_tests/TestAliases.py index e30fe15a104..ae79875ac41 100644 --- a/lldb/test/alias_tests/TestAliases.py +++ b/lldb/test/alias_tests/TestAliases.py @@ -94,8 +94,8 @@ class AliasTestCase(TestBase): self.expect ("run", patterns = [ "Process .* launched: .*a.out" ]) - self.expect (r'''expression printf("\x68\x65\x6c\x6c\x6f\n")''', - substrs = [ "(unsigned long) $", + self.expect (r'''expression (int) printf("\x68\x65\x6c\x6c\x6f\n")''', + substrs = [ "(int) $", "= 6" ]) self.expect ("hello", diff --git a/lldb/test/expression_command/test/TestExprs.py b/lldb/test/expression_command/test/TestExprs.py index b3dc440c2b0..9c056c59e21 100644 --- a/lldb/test/expression_command/test/TestExprs.py +++ b/lldb/test/expression_command/test/TestExprs.py @@ -182,36 +182,36 @@ class BasicExprCommandsTestCase(TestBase): substrs = ['(char) $', "'a'"]) - # runCmd: expression printf ("\n\n\tHello there!\n") - # output: (unsigned long) $1 = 16 - self.expect(r'''expression printf ("\n\n\tHello there!\n")''', - substrs = ['(unsigned long) $', + # runCmd: expression (int) printf ("\n\n\tHello there!\n") + # output: (int) $1 = 16 + self.expect(r'''expression (int) printf ("\n\n\tHello there!\n")''', + substrs = ['(int) $', '16']) - # runCmd: expression printf("\t\x68\n") - # output: (unsigned long) $2 = 3 - self.expect(r'''expression printf("\t\x68\n")''', - substrs = ['(unsigned long) $', + # runCmd: expression (int) printf("\t\x68\n") + # output: (int) $2 = 3 + self.expect(r'''expression (int) printf("\t\x68\n")''', + substrs = ['(int) $', '3']) - # runCmd: expression printf("\"\n") - # output: (unsigned long) $3 = 2 - self.expect(r'''expression printf("\"\n")''', - substrs = ['(unsigned long) $', + # runCmd: expression (int) printf("\"\n") + # output: (int) $3 = 2 + self.expect(r'''expression (int) printf("\"\n")''', + substrs = ['(int) $', '2']) - # runCmd: expression printf("'\n") - # output: (unsigned long) $4 = 2 - self.expect(r'''expression printf("'\n")''', - substrs = ['(unsigned long) $', + # runCmd: expression (int) printf("'\n") + # output: (int) $4 = 2 + self.expect(r'''expression (int) printf("'\n")''', + substrs = ['(int) $', '2']) - # runCmd: command alias print_hi expression printf ("\n\tHi!\n") + # runCmd: command alias print_hi expression (int) printf ("\n\tHi!\n") # output: - self.runCmd(r'''command alias print_hi expression printf ("\n\tHi!\n")''') + self.runCmd(r'''command alias print_hi expression (int) printf ("\n\tHi!\n")''') # This fails currently. self.expect('print_hi', - substrs = ['(unsigned long) $', + substrs = ['(int) $', '6']) |