summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Expression/ClangExpressionDeclMap.h10
-rw-r--r--lldb/include/lldb/Expression/ClangExpressionVariable.h3
-rw-r--r--lldb/include/lldb/Symbol/ClangASTContext.h9
-rw-r--r--lldb/source/Expression/ClangASTSource.cpp6
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp75
-rw-r--r--lldb/source/Expression/ClangExpressionParser.cpp12
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp6
-rw-r--r--lldb/test/alias_tests/TestAliases.py4
-rw-r--r--lldb/test/expression_command/test/TestExprs.py38
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'])
OpenPOWER on IntegriCloud