summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointResolverName.h8
-rw-r--r--lldb/include/lldb/lldb-enumerations.h20
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj2
-rw-r--r--lldb/scripts/build-llvm.pl2
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverName.cpp95
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.cpp25
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp34
7 files changed, 153 insertions, 33 deletions
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h
index 4cfd2458dd6..9d5e68ecc07 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h
@@ -63,6 +63,14 @@ public:
protected:
ConstString m_func_name;
+ // "m_basename_filter" is used to filter results after searching for
+ // "m_func_name" first. This is used when we are asked to set a breakpoint
+ // at "foo::bar::baz" (C++ function in namespace or in a class). For
+ // "foo::bar::baz" we will place "baz" into m_func_name and search for all
+ // matching basename and methods that match "baz", then we will filter the
+ // results by checking if the demangled name contains "m_basename_filter"
+ // which would be set to "foo::bar::baz".
+ std::string m_basename_filter;
uint32_t m_func_name_type_mask; // See FunctionNameType
ConstString m_class_name; // FIXME: Not used yet. The idea would be to stop on methods of this class.
RegularExpression m_regex;
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index c3f7f39a2a7..3f5553eab74 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -412,15 +412,17 @@ typedef enum ArchitectureType
typedef enum FunctionNameType
{
eFunctionNameTypeNone = 0u,
- eFunctionNameTypeFull = (1u << 1),// The function name.
- // For C this is the same as just the name of the function
- // For C++ this is the demangled version of the mangled name.
- // For ObjC this is the full function signature with the + or
- // - and the square brackets and the class and selector
- eFunctionNameTypeBase = (1u << 2),// The function name only, no namespaces or arguments and no class
- // methods or selectors will be searched.
- eFunctionNameTypeMethod = (1u << 3),// Find function by method name (C++) with no namespace or arguments
- eFunctionNameTypeSelector = (1u << 4) // Find function by selector name (ObjC) names
+ eFunctionNameTypeAuto = (1u << 1), // Automatically figure out which FunctionNameType
+ // bits to set based on the function name.
+ eFunctionNameTypeFull = (1u << 2), // The function name.
+ // For C this is the same as just the name of the function
+ // For C++ this is the demangled version of the mangled name.
+ // For ObjC this is the full function signature with the + or
+ // - and the square brackets and the class and selector
+ eFunctionNameTypeBase = (1u << 3), // The function name only, no namespaces or arguments and no class
+ // methods or selectors will be searched.
+ eFunctionNameTypeMethod = (1u << 4), // Find function by method name (C++) with no namespace or arguments
+ eFunctionNameTypeSelector = (1u << 5), // Find function by selector name (ObjC) names
} FunctionNameType;
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index 0d7a9e58bd3..516bb859d2f 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -2964,7 +2964,7 @@
"$(LLVM_BUILD_DIR)",
);
LLVM_BUILD_DIR = "$(SRCROOT)/llvm";
- LLVM_CONFIGURATION = Release;
+ LLVM_CONFIGURATION = "Debug+Asserts";
OTHER_CFLAGS = (
"-DFOR_DYLD=0",
"-DSUPPORT_REMOTE_UNWINDING",
diff --git a/lldb/scripts/build-llvm.pl b/lldb/scripts/build-llvm.pl
index 86b3d9f4984..a9db7648b68 100644
--- a/lldb/scripts/build-llvm.pl
+++ b/lldb/scripts/build-llvm.pl
@@ -91,7 +91,7 @@ if (-l $llvm_dstroot)
# LLVM in the "lldb" root is a symlink which indicates we are using a
# standard LLVM build directory where everything is built into the
# same folder
- create_single_llvm_arhive_for_arch ($llvm_dstroot, 0);
+ create_single_llvm_arhive_for_arch ($llvm_dstroot, 1);
my $llvm_dstroot_archive = "$llvm_dstroot/$llvm_clang_basename";
push @llvm_clang_slices, $llvm_dstroot_archive;
create_dstroot_file ($llvm_clang_basename, $llvm_clang_dirname, \@llvm_clang_slices, $llvm_clang_basename);
diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp
index f25910de565..5431db0c230 100644
--- a/lldb/source/Breakpoint/BreakpointResolverName.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp
@@ -29,12 +29,54 @@ BreakpointResolverName::BreakpointResolverName
Breakpoint::MatchType type
) :
BreakpointResolver (bkpt),
- m_func_name (func_name),
+ m_func_name (),
+ m_basename_filter (),
m_func_name_type_mask (func_name_type_mask),
m_class_name (),
m_regex (),
m_match_type (type)
{
+ if (func_name_type_mask == eFunctionNameTypeAuto)
+ {
+ if ((::strchr (func_name, '(' ) != NULL) ||
+ (::strstr (func_name, "-[") == func_name) ||
+ (::strstr (func_name, "+[") == func_name))
+ {
+ // We have a name that contains an open parens, or starts with
+ // "+[" or "-[", so this looks like a complete function prototype
+ m_func_name_type_mask = eFunctionNameTypeFull;
+ }
+ else
+ {
+ // We don't have a full function name, but we might have a partial
+ // function basename with namespaces or classes
+ if (::strstr (func_name, "::") != NULL)
+ {
+ // Keep the full name in "m_basename_filter"
+ m_basename_filter = func_name;
+ // Now set "m_func_name" to just the function basename
+ m_func_name.SetCString(m_basename_filter.c_str() + m_basename_filter.rfind("::") + 2);
+ // We have a name with a double colon which means we have a
+ // function name that is a C++ method or a function in a C++
+ // namespace
+ m_func_name_type_mask = eFunctionNameTypeBase | eFunctionNameTypeMethod;
+ }
+ else if (::strstr (func_name, ":") != NULL)
+ {
+ // Single colon => selector
+ m_func_name_type_mask = eFunctionNameTypeSelector;
+ }
+ else
+ {
+ // just a basename by default
+ m_func_name_type_mask = eFunctionNameTypeBase;
+ }
+ }
+ }
+
+ if (!m_func_name)
+ m_func_name.SetCString(func_name);
+
if (m_match_type == Breakpoint::Regexp)
{
if (!m_regex.Compile (m_func_name.AsCString()))
@@ -137,6 +179,53 @@ BreakpointResolverName::SearchCallback
break;
}
+ if (!m_basename_filter.empty())
+ {
+ // Filter out any matches whose names don't contain the basename filter
+ const char *basename_filter = m_basename_filter.c_str();
+ if (func_list.GetSize())
+ {
+ bool remove = false;
+ for (i = 0; i < func_list.GetSize(); remove = false)
+ {
+ if (func_list.GetContextAtIndex(i, sc) == false)
+ remove = true;
+ else if (sc.function == NULL)
+ remove = true;
+ else if (::strstr (sc.function->GetName().AsCString(), basename_filter) == NULL)
+ remove = true;
+
+ if (remove)
+ {
+ func_list.RemoveContextAtIndex(i);
+ continue;
+ }
+ i++;
+ }
+ }
+
+ if (sym_list.GetSize())
+ {
+ bool remove = false;
+ for (i = 0; i < sym_list.GetSize(); remove = false)
+ {
+ if (sym_list.GetContextAtIndex(i, sc) == false)
+ remove = true;
+ else if (sc.symbol == NULL)
+ remove = true;
+ else if (::strstr (sc.symbol->GetName().AsCString(), basename_filter) == NULL)
+ remove = true;
+
+ if (remove)
+ {
+ sym_list.RemoveContextAtIndex(i);
+ continue;
+ }
+ i++;
+ }
+ }
+ }
+
// Remove any duplicates between the funcion list and the symbol list
if (func_list.GetSize())
{
@@ -242,8 +331,10 @@ BreakpointResolverName::GetDescription (Stream *s)
{
if (m_match_type == Breakpoint::Regexp)
s->Printf("regex = '%s'", m_regex.GetText());
- else
+ else if (m_basename_filter.empty())
s->Printf("name = '%s'", m_func_name.AsCString());
+ else
+ s->Printf("name = '%s'", m_basename_filter.c_str());
}
void
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index e7cf0a8bb95..a9d1615dfca 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -104,7 +104,7 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
"Set the breakpoint by address, at the specified address."},
{ LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "Set the breakpoint by function name - for C++ this means namespaces and arguments will be ignored." },
+ "Set the breakpoint by function name." },
{ LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
"Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguemnts, and "
@@ -119,6 +119,9 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_7, true, "func-regex", 'r', required_argument, NULL, 0, eArgTypeRegularExpression,
"Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
+ { LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
+ "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored)." },
+
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -157,11 +160,16 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, cons
m_line_num = Args::StringToUInt32 (option_arg, 0);
break;
- case 'n':
+ case 'b':
m_func_name = option_arg;
m_func_name_type_mask |= eFunctionNameTypeBase;
break;
+ case 'n':
+ m_func_name = option_arg;
+ m_func_name_type_mask |= eFunctionNameTypeAuto;
+ break;
+
case 'F':
m_func_name = option_arg;
m_func_name_type_mask |= eFunctionNameTypeFull;
@@ -391,17 +399,8 @@ CommandObjectBreakpointSet::Execute
uint32_t name_type_mask = m_options.m_func_name_type_mask;
if (name_type_mask == 0)
- {
-
- if (m_options.m_func_name.find('(') != std::string::npos ||
- m_options.m_func_name.find("-[") == 0 ||
- m_options.m_func_name.find("+[") == 0)
- name_type_mask |= eFunctionNameTypeFull;
- else
- name_type_mask |= eFunctionNameTypeBase;
- }
-
-
+ name_type_mask = eFunctionNameTypeAuto;
+
if (use_module)
{
for (int i = 0; i < num_modules; ++i)
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index e741cc099ee..ed16d0c5685 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -3099,7 +3099,22 @@ ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
unsigned NumPositiveBits = 1;
unsigned NumNegativeBits = 0;
- enum_decl->completeDefinition(enum_decl->getIntegerType(), enum_decl->getIntegerType(), NumPositiveBits, NumNegativeBits);
+ ASTContext *ast_context = getASTContext();
+
+ QualType promotion_qual_type;
+ // If the enum integer type is less than an integer in bit width,
+ // then we must promote it to an integer size.
+ if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy))
+ {
+ if (enum_decl->getIntegerType()->isSignedIntegerType())
+ promotion_qual_type = ast_context->IntTy;
+ else
+ promotion_qual_type = ast_context->UnsignedIntTy;
+ }
+ else
+ promotion_qual_type = enum_decl->getIntegerType();
+
+ enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
return true;
}
}
@@ -3117,12 +3132,17 @@ ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *nam
// like maybe filling in the SourceLocation with it...
ASTContext *ast_context = getASTContext();
assert (ast_context != NULL);
- EnumDecl *enum_decl = EnumDecl::Create(*ast_context,
- ast_context->getTranslationUnitDecl(),
- SourceLocation(),
- name && name[0] ? &ast_context->Idents.get(name) : NULL,
- SourceLocation(),
- NULL);
+
+ // TODO: ask about these...
+// const bool IsScoped = false;
+// const bool IsFixed = false;
+
+ EnumDecl *enum_decl = EnumDecl::Create (*ast_context,
+ ast_context->getTranslationUnitDecl(),
+ SourceLocation(),
+ name && name[0] ? &ast_context->Idents.get(name) : NULL,
+ SourceLocation(),
+ NULL); //IsScoped, IsFixed);
if (enum_decl)
{
// TODO: check if we should be setting the promotion type too?
OpenPOWER on IntegriCloud