Files
clang-p2996/lldb/tools/lldb-mi/MICmdCmdSymbol.cpp
Kate Stone b9c1b51e45 *** This commit represents a complete reformatting of the LLDB source code
*** to conform to clang-format’s LLVM style.  This kind of mass change has
*** two obvious implications:

Firstly, merging this particular commit into a downstream fork may be a huge
effort.  Alternatively, it may be worth merging all changes up to this commit,
performing the same reformatting operation locally, and then discarding the
merge for this particular commit.  The commands used to accomplish this
reformatting were as follows (with current working directory as the root of
the repository):

    find . \( -iname "*.c" -or -iname "*.cpp" -or -iname "*.h" -or -iname "*.mm" \) -exec clang-format -i {} +
    find . -iname "*.py" -exec autopep8 --in-place --aggressive --aggressive {} + ;

The version of clang-format used was 3.9.0, and autopep8 was 1.2.4.

Secondly, “blame” style tools will generally point to this commit instead of
a meaningful prior commit.  There are alternatives available that will attempt
to look through this change and find the appropriate prior commit.  YMMV.

llvm-svn: 280751
2016-09-06 20:57:50 +00:00

269 lines
9.9 KiB
C++

//===-- MICmdCmdSymbol.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Overview: CMICmdCmdSymbolListLines implementation.
// Third Party Headers:
#include "lldb/API/SBCommandInterpreter.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Regex.h"
// In-house headers:
#include "MICmdArgValFile.h"
#include "MICmdCmdSymbol.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueList.h"
#include "MICmnMIValueTuple.h"
//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdSymbolListLines constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdSymbolListLines::CMICmdCmdSymbolListLines()
: m_constStrArgNameFile("file") {
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "symbol-list-lines";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdSymbolListLines::CreateSelf;
}
//++
//------------------------------------------------------------------------------------
// Details: CMICmdCmdSymbolListLines destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdSymbolListLines::~CMICmdCmdSymbolListLines() {}
//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The parses the command line
// options
// arguments to extract values for each of those arguments.
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdSymbolListLines::ParseArgs() {
m_setCmdArgs.Add(new CMICmdArgValFile(m_constStrArgNameFile, true, true));
return ParseValidateCmdOptions();
}
//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command does work in this
// function.
// The command is likely to communicate with the LLDB SBDebugger in
// here.
// Synopsis: -symbol-list-lines file
// Ref:
// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Symbol-Query.html#GDB_002fMI-Symbol-Query
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdSymbolListLines::Execute() {
CMICMDBASE_GETOPTION(pArgFile, File, m_constStrArgNameFile);
const CMIUtilString &strFilePath(pArgFile->GetValue());
const CMIUtilString strCmd(CMIUtilString::Format(
"source info --file \"%s\"", strFilePath.AddSlashes().c_str()));
CMICmnLLDBDebugSessionInfo &rSessionInfo(
CMICmnLLDBDebugSessionInfo::Instance());
const lldb::ReturnStatus rtn =
rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(
strCmd.c_str(), m_lldbResult);
MIunused(rtn);
return MIstatus::success;
}
//++
//------------------------------------------------------------------------------------
// Details: Helper function for parsing the header returned from lldb for the
// command:
// target modules dump line-table <file>
// where the header is of the format:
// Line table for /path/to/file in `/path/to/module
// Args: input - (R) Input string to parse.
// file - (W) String representing the file.
// Return: bool - True = input was parsed successfully, false = input could not
// be parsed.
// Throws: None.
//--
static bool ParseLLDBLineAddressHeader(const char *input, CMIUtilString &file) {
// Match LineEntry using regex.
static llvm::Regex g_lineentry_header_regex(llvm::StringRef(
"^ *Lines found for file (.+) in compilation unit (.+) in `(.+)$"));
// ^1=file ^2=cu
// ^3=module
llvm::SmallVector<llvm::StringRef, 4> match;
const bool ok = g_lineentry_header_regex.match(input, &match);
if (ok)
file = match[1];
return ok;
}
//++
//------------------------------------------------------------------------------------
// Details: Helper function for parsing a line entry returned from lldb for the
// command:
// target modules dump line-table <file>
// where the line entry is of the format:
// 0x0000000100000e70: /path/to/file:3002[:4]
// addr file line column(opt)
// Args: input - (R) Input string to parse.
// addr - (W) String representing the pc address.
// file - (W) String representing the file.
// line - (W) String representing the line.
// Return: bool - True = input was parsed successfully, false = input could not
// be parsed.
// Throws: None.
//--
static bool ParseLLDBLineAddressEntry(const char *input, CMIUtilString &addr,
CMIUtilString &file,
CMIUtilString &line) {
// Note: Ambiguities arise because the column is optional, and
// because : can appear in filenames or as a byte in a multibyte
// UTF8 character. We keep those cases to a minimum by using regex
// to work on the string from both the left and right, so that what
// is remains is assumed to be the filename.
// Match LineEntry using regex.
static llvm::Regex g_lineentry_nocol_regex(llvm::StringRef(
"^ *\\[(0x[0-9a-fA-F]+)-(0x[0-9a-fA-F]+)\\): (.+):([0-9]+)$"));
static llvm::Regex g_lineentry_col_regex(llvm::StringRef(
"^ *\\[(0x[0-9a-fA-F]+)-(0x[0-9a-fA-F]+)\\): (.+):([0-9]+):[0-9]+$"));
// ^1=start ^2=end ^3=f ^4=line
// ^5=:col(opt)
llvm::SmallVector<llvm::StringRef, 6> match;
// First try matching the LineEntry with the column,
// then try without the column.
const bool ok = g_lineentry_col_regex.match(input, &match) ||
g_lineentry_nocol_regex.match(input, &match);
if (ok) {
addr = match[1];
file = match[3];
line = match[4];
}
return ok;
}
//++
//------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record
// Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdSymbolListLines::Acknowledge() {
if (m_lldbResult.GetErrorSize() > 0) {
const char *pLldbErr = m_lldbResult.GetError();
const CMIUtilString strMsg(CMIUtilString(pLldbErr).StripCRAll());
const CMICmnMIValueConst miValueConst(strMsg);
const CMICmnMIValueResult miValueResult("message", miValueConst);
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
miValueResult);
m_miResultRecord = miRecordResult;
} else {
CMIUtilString::VecString_t vecLines;
const CMIUtilString strLldbMsg(m_lldbResult.GetOutput());
const MIuint nLines(strLldbMsg.SplitLines(vecLines));
// Parse the file from the header.
const CMIUtilString &rWantFile(vecLines[0]);
CMIUtilString strWantFile;
if (!ParseLLDBLineAddressHeader(rWantFile.c_str(), strWantFile)) {
// Unexpected error - parsing failed.
// MI print "%s^error,msg=\"Command '-symbol-list-lines'. Error: Line
// address header is absent or has an unknown format.\""
const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
MIRSRC(IDS_CMD_ERR_SOME_ERROR), m_cmdData.strMiCmd.c_str(),
"Line address header is absent or has an unknown format."));
const CMICmnMIValueResult miValueResult("msg", miValueConst);
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
// Parse the line address entries.
CMICmnMIValueList miValueList(true);
for (MIuint i = 1; i < nLines; ++i) {
// String looks like:
// 0x0000000100000e70: /path/to/file:3[:4]
const CMIUtilString &rLine(vecLines[i]);
CMIUtilString strAddr;
CMIUtilString strFile;
CMIUtilString strLine;
if (!ParseLLDBLineAddressEntry(rLine.c_str(), strAddr, strFile, strLine))
continue;
const CMICmnMIValueConst miValueConst(strAddr);
const CMICmnMIValueResult miValueResult("pc", miValueConst);
CMICmnMIValueTuple miValueTuple(miValueResult);
const CMICmnMIValueConst miValueConst2(strLine);
const CMICmnMIValueResult miValueResult2("line", miValueConst2);
miValueTuple.Add(miValueResult2);
miValueList.Add(miValueTuple);
}
// MI print "%s^done,lines=[{pc=\"%d\",line=\"%d\"}...]"
const CMICmnMIValueResult miValueResult("lines", miValueList);
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
miValueResult);
m_miResultRecord = miRecordResult;
}
return MIstatus::success;
}
//++
//------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The
// factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase *CMICmdCmdSymbolListLines::CreateSelf() {
return new CMICmdCmdSymbolListLines();
}