Beispiel #1
0
std::string quoteArg(llvm::StringRef arg) {
  if (!needsQuotes(arg))
    return arg;

  std::string quotedArg;
  quotedArg.reserve(3 + 2 * arg.size()); // worst case

  quotedArg.push_back('"');

  const size_t argLength = arg.size();
  for (size_t i = 0; i < argLength; ++i) {
    if (arg[i] == '"') {
      // Escape all preceding backslashes (if any).
      // Note that we *don't* need to escape runs of backslashes that don't
      // precede a double quote! See MSDN:
      // http://msdn.microsoft.com/en-us/library/17w5ykft%28v=vs.85%29.aspx
      quotedArg.append(countPrecedingBackslashes(arg, i), '\\');

      // Escape the double quote.
      quotedArg.push_back('\\');
    }

    quotedArg.push_back(arg[i]);
  }

  // Make sure our final double quote doesn't get escaped by a trailing
  // backslash.
  quotedArg.append(countPrecedingBackslashes(arg, argLength), '\\');
  quotedArg.push_back('"');

  return quotedArg;
}
Beispiel #2
0
void
StringLiteral::setString(ASTContext &C, llvm::StringRef Str) {
  char *AStrData = new (C, 1) char[Str.size()];
  memcpy(AStrData, Str.data(), Str.size());
  StrData = AStrData;
  ByteLength = Str.size();
}
Beispiel #3
0
    static bool writeFile(llvm::StringRef file_name, llvm::StringRef data) {
        std::error_code error_code;
        llvm::raw_fd_ostream file(file_name, error_code, llvm::sys::fs::F_RW);
        if (error_code)
            return false;

        int uncompressed_size = data.size();
        // Write the uncompressed size to the beginning of the file as a simple checksum.
        // It looks like each lz4 block has its own data checksum, but we need to also
        // make sure that we have all the blocks that we expected.
        // In particular, without this, an empty file seems to be a valid lz4 stream.
        file.write(reinterpret_cast<const char*>(&uncompressed_size), 4);

        LZ4F_preferences_t preferences;
        memset(&preferences, 0, sizeof(preferences));
        preferences.frameInfo.contentChecksumFlag = contentChecksumEnabled;
        preferences.frameInfo.contentSize = data.size();

        std::vector<char> compressed;
        size_t max_size = LZ4F_compressFrameBound(data.size(), &preferences);
        compressed.resize(max_size);
        size_t compressed_size = LZ4F_compressFrame(&compressed[0], max_size, data.data(), data.size(), &preferences);
        if (LZ4F_isError(compressed_size))
            return false;
        file.write(compressed.data(), compressed_size);
        return true;
    }
Beispiel #4
0
std::size_t WireEncoder::GetStringSize(llvm::StringRef str) const {
  if (m_proto_rev < 0x0300u) {
    std::size_t len = str.size();
    if (len > 0xffff) len = 0xffff; // Limited to 64K length; truncate
    return 2 + len;
  }
  return SizeUleb128(str.size()) + str.size();
}
void PythonString::SetString(llvm::StringRef string) {
#if PY_MAJOR_VERSION >= 3
  PyObject *unicode = PyUnicode_FromStringAndSize(string.data(), string.size());
  PythonObject::Reset(PyRefType::Owned, unicode);
#else
  PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
  PythonObject::Reset(PyRefType::Owned, str);
#endif
}
void ClangDocBitcodeWriter::emitRecord(llvm::StringRef Str, RecordId ID) {
  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
  assert(RecordIdNameMap[ID].Abbrev == &StringAbbrev &&
         "Abbrev type mismatch.");
  if (!prepRecordData(ID, !Str.empty()))
    return;
  assert(Str.size() < (1U << BitCodeConstants::StringLengthSize));
  Record.push_back(Str.size());
  Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Str);
}
static void EscapeBackticks(llvm::StringRef str, std::string &dst) {
  dst.clear();
  dst.reserve(str.size());

  for (size_t i = 0, e = str.size(); i != e; ++i) {
    char c = str[i];
    if (c == '`') {
      if (i == 0 || str[i - 1] != '\\')
        dst += '\\';
    }
    dst += c;
  }
}
InclusionDirective::InclusionDirective(PreprocessingRecord &PPRec,
                                       InclusionKind Kind, 
                                       llvm::StringRef FileName, 
                                       bool InQuotes, const FileEntry *File, 
                                       SourceRange Range)
  : PreprocessingDirective(InclusionDirectiveKind, Range), 
    InQuotes(InQuotes), Kind(Kind), File(File) 
{ 
  char *Memory 
    = (char*)PPRec.Allocate(FileName.size() + 1, llvm::alignOf<char>());
  memcpy(Memory, FileName.data(), FileName.size());
  Memory[FileName.size()] = 0;
  this->FileName = llvm::StringRef(Memory, FileName.size());
}
static bool IsValidBasename(const llvm::StringRef &basename) {
  // Check that the basename matches with the following regular expression or is
  // an operator name:
  // "^~?([A-Za-z_][A-Za-z_0-9]*)(<.*>)?$"
  // We are using a hand written implementation because it is significantly more
  // efficient then
  // using the general purpose regular expression library.
  size_t idx = 0;
  if (basename.size() > 0 && basename[0] == '~')
    idx = 1;

  if (basename.size() <= idx)
    return false; // Empty string or "~"

  if (!std::isalpha(basename[idx]) && basename[idx] != '_')
    return false; // First charater (after removing the possible '~'') isn't in
                  // [A-Za-z_]

  // Read all characters matching [A-Za-z_0-9]
  ++idx;
  while (idx < basename.size()) {
    if (!std::isalnum(basename[idx]) && basename[idx] != '_')
      break;
    ++idx;
  }

  // We processed all characters. It is a vaild basename.
  if (idx == basename.size())
    return true;

  // Check for basename with template arguments
  // TODO: Improve the quality of the validation with validating the template
  // arguments
  if (basename[idx] == '<' && basename.back() == '>')
    return true;

  // Check if the basename is a vaild C++ operator name
  if (!basename.startswith("operator"))
    return false;

  static RegularExpression g_operator_regex(
      llvm::StringRef("^(operator)( "
                      "?)([A-Za-z_][A-Za-z_0-9]*|\\(\\)|"
                      "\\[\\]|[\\^<>=!\\/"
                      "*+-]+)(<.*>)?(\\[\\])?$"));
  std::string basename_str(basename.str());
  return g_operator_regex.Execute(basename_str, nullptr);
}
void TemplightProtobufReader::loadDictionaryEntry(llvm::StringRef aSubBuffer) {
  // Set default values:
  std::string name = "";
  llvm::SmallVector<std::size_t,8> markers;
  
  while ( aSubBuffer.size() ) {
    unsigned int cur_wire = llvm::protobuf::loadVarInt(aSubBuffer);
    switch( cur_wire ) {
      case llvm::protobuf::getStringWire<1>::value:
        name = llvm::protobuf::loadString(aSubBuffer);
        break;
      case llvm::protobuf::getVarIntWire<2>::value:
        markers.push_back(llvm::protobuf::loadVarInt(aSubBuffer));
        break;
      default:
        llvm::protobuf::skipData(aSubBuffer, cur_wire);
        break;
    }
  }
  
  std::string::iterator it_name = std::find(name.begin(), name.end(), '\0');
  llvm::SmallVector<std::size_t,8>::iterator it_mark = markers.begin();
  while ( ( it_name != name.end() ) && ( it_mark != markers.end() ) ) {
    std::size_t offset = it_name - name.begin();
    name.replace(it_name, it_name + 1, templateNameMap[*it_mark]);
    it_name = std::find(name.begin() + offset, name.end(), '\0');
    ++it_mark;
  }
  
  templateNameMap.push_back(name);
  
}
void TemplightProtobufReader::loadTemplateName(llvm::StringRef aSubBuffer) {
  // Set default values:
  LastBeginEntry.Name = "";
  
  while ( aSubBuffer.size() ) {
    unsigned int cur_wire = llvm::protobuf::loadVarInt(aSubBuffer);
    switch( cur_wire ) {
      case llvm::protobuf::getStringWire<1>::value:
        LastBeginEntry.Name = llvm::protobuf::loadString(aSubBuffer);
        break;
      case llvm::protobuf::getStringWire<2>::value: {
        LastBeginEntry.Name = llvm::protobuf::loadString(aSubBuffer);
        llvm::SmallVector<char,32> UBuf;
        if ( llvm::zlib::uncompress(LastBeginEntry.Name, UBuf, LastBeginEntry.Name.size() * 2) 
                == llvm::zlib::StatusOK )
          LastBeginEntry.Name.assign(UBuf.begin(), UBuf.end());
        else
          LastBeginEntry.Name = "";
        break;
      }
      case llvm::protobuf::getVarIntWire<3>::value: {
        LastBeginEntry.Name = templateNameMap[llvm::protobuf::loadVarInt(aSubBuffer)];
        break;
      }
      default:
        llvm::protobuf::skipData(aSubBuffer, cur_wire);
        break;
    }
  }
  
}
Beispiel #12
0
bool ReverseFindMatchingChars(const llvm::StringRef &s,
                              const llvm::StringRef &left_right_chars,
                              size_t &left_pos, size_t &right_pos,
                              size_t pos = llvm::StringRef::npos) {
  assert(left_right_chars.size() == 2);
  left_pos = llvm::StringRef::npos;
  const char left_char = left_right_chars[0];
  const char right_char = left_right_chars[1];
  pos = s.find_last_of(left_right_chars, pos);
  if (pos == llvm::StringRef::npos || s[pos] == left_char)
    return false;
  right_pos = pos;
  uint32_t depth = 1;
  while (pos > 0 && depth > 0) {
    pos = s.find_last_of(left_right_chars, pos);
    if (pos == llvm::StringRef::npos)
      return false;
    if (s[pos] == left_char) {
      if (--depth == 0) {
        left_pos = pos;
        return left_pos < right_pos;
      }
    } else if (s[pos] == right_char) {
      ++depth;
    }
  }
  return false;
}
Beispiel #13
0
size_t DiagnosticManager::PutString(DiagnosticSeverity severity,
                                    llvm::StringRef str) {
    if (str.empty())
        return 0;
    AddDiagnostic(str, severity, eDiagnosticOriginLLDB);
    return str.size();
}
static inline void StripSpaces(llvm::StringRef &Str)
{
    while (!Str.empty() && isspace(Str[0]))
        Str = Str.substr(1);
    while (!Str.empty() && isspace(Str.back()))
        Str = Str.substr(0, Str.size()-1);
}
Beispiel #15
0
std::string Context::getThunkTarget(llvm::StringRef MangledName) {
  if (!isThunkSymbol(MangledName))
    return std::string();

  if (isMangledName(MangledName)) {
    // The targets of those thunks not derivable from the mangling.
    if (MangledName.endswith("TR") ||
        MangledName.endswith("Tr") ||
        MangledName.endswith("TW") )
      return std::string();

    if (MangledName.endswith("fC")) {
      std::string target = MangledName.str();
      target[target.size() - 1] = 'c';
      return target;
    }

    return MangledName.substr(0, MangledName.size() - 2).str();
  }
  // Old mangling.
  assert(MangledName.startswith("_T"));
  StringRef Remaining = MangledName.substr(2);
  if (Remaining.startswith("PA_"))
    return Remaining.substr(3).str();
  if (Remaining.startswith("PAo_"))
    return Remaining.substr(4).str();
  assert(Remaining.startswith("To") || Remaining.startswith("TO"));
  return std::string("_T") + Remaining.substr(2).str();
}
bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
                                          StringExtractorGDBRemote &response) {
  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
  if (log)
    log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);

  // we want to lock down packet sending while we continue
  Lock lock(*this, true);

  if (log)
    log->Printf(
        "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
        __FUNCTION__, int(payload.size()), payload.data());

  if (SendPacketNoLock(payload) != PacketResult::Success)
    return false;

  OnRunPacketSent(true);

  // wait for the response to the vCont
  if (ReadPacket(response, llvm::None, false) == PacketResult::Success) {
    if (response.IsOKResponse())
      return true;
  }

  return false;
}
Beispiel #17
0
/**
 * Write raw bytes to the buffer.
 *
 * @param buffer StringRef to the buffer to read the bytes from.
 * @return The number of bytes actually written into the port.
 */
int SerialPort::Write(llvm::StringRef buffer) {
  int32_t status = 0;
  int retVal = HAL_WriteSerial(static_cast<HAL_SerialPort>(m_port),
                               buffer.data(), buffer.size(), &status);
  wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
  return retVal;
}
GDBRemoteCommunication::PacketResult
GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
    llvm::StringRef payload, StringExtractorGDBRemote &response) {
  PacketResult packet_result = SendPacketNoLock(payload);
  if (packet_result != PacketResult::Success)
    return packet_result;

  const size_t max_response_retries = 3;
  for (size_t i = 0; i < max_response_retries; ++i) {
    packet_result = ReadPacket(response, GetPacketTimeout(), true);
    // Make sure we received a response
    if (packet_result != PacketResult::Success)
      return packet_result;
    // Make sure our response is valid for the payload that was sent
    if (response.ValidateResponse())
      return packet_result;
    // Response says it wasn't valid
    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
    if (log)
      log->Printf(
          "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
          int(payload.size()), payload.data(), response.GetStringRef().c_str(),
          (i == (max_response_retries - 1))
              ? "using invalid response and giving up"
              : "ignoring response and waiting for another");
  }
  return packet_result;
}
Beispiel #19
0
/// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
/// "unknown-pragmas" to have the specified mapping.  This returns true and
/// ignores the request if "Group" was unknown, false otherwise.
bool DiagnosticIDs::setDiagnosticGroupMapping(llvm::StringRef Group,
                                              diag::Mapping Map,
                                              SourceLocation Loc,
                                              Diagnostic &Diag) const {
  assert((Loc.isValid() ||
          Diag.DiagStatePoints.empty() ||
          Diag.DiagStatePoints.back().Loc.isInvalid()) &&
         "Loc should be invalid only when the mapping comes from command-line");
  assert((Loc.isInvalid() || Diag.DiagStatePoints.empty() ||
          Diag.DiagStatePoints.back().Loc.isInvalid() ||
          !Diag.SourceMgr->isBeforeInTranslationUnit(Loc,
                                            Diag.DiagStatePoints.back().Loc)) &&
         "Source location of new mapping is before the previous one!");

  WarningOption Key = { Group.size(), Group.data(), 0, 0 };
  const WarningOption *Found =
  std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
                   WarningOptionCompare);
  if (Found == OptionTable + OptionTableSize ||
      Found->getName() != Group)
    return true;  // Option not found.

  MapGroupMembers(Found, Map, Loc, Diag);
  return false;
}
Beispiel #20
0
// Compute the edit distance between the two given strings.
unsigned StringRef::edit_distance(llvm::StringRef Other,
                                  bool AllowReplacements,
                                  unsigned MaxEditDistance) {
  return llvm::ComputeEditDistance(
      llvm::ArrayRef<char>(data(), size()),
      llvm::ArrayRef<char>(Other.data(), Other.size()),
      AllowReplacements, MaxEditDistance);
}
Beispiel #21
0
// Compute the edit distance between the two given strings.
unsigned StringRef::edit_distance(llvm::StringRef Other,
                                  bool AllowReplacements,
                                  unsigned MaxEditDistance) const {
  return llvm::ComputeEditDistance(
      makeArrayRef(data(), size()),
      makeArrayRef(Other.data(), Other.size()),
      AllowReplacements, MaxEditDistance);
}
Beispiel #22
0
 Type *vaListType() override {
   // We need to pass the actual va_list type for correct mangling. Simply
   // using TypeIdentifier here is a bit wonky but works, as long as the name
   // is actually available in the scope (this is what DMD does, so if a better
   // solution is found there, this should be adapted).
   static const llvm::StringRef ident = "__va_list";
   return (createTypeIdentifier(Loc(), Identifier::idPool(ident.data(), ident.size())));
 }
/// HandleComment - Hook into the preprocessor and extract comments containing
///  expected errors and warnings.
bool VerifyDiagnosticConsumer::HandleComment(Lexer &PP, const SourceLocation& CommentBegin, const llvm::StringRef &C) {
  const llvm::SourceMgr &SM = PP.getSourceManager();

  // If this comment is for a different source manager, ignore it.
  if (SrcManager && &SM != SrcManager)
    return false;

  if (C.empty())
    return false;

  // Fold any "\<EOL>" sequences
  size_t loc = C.find('\\');
  if (loc == StringRef::npos) {
    ParseDirective(C, &ED, SM, &PP, CommentBegin, Status);
    return false;
  }

  std::string C2;
  C2.reserve(C.size());

  for (size_t last = 0;; loc = C.find('\\', last)) {
    if (loc == StringRef::npos || loc == C.size()) {
      C2 += C.substr(last);
      break;
    }
    C2 += C.substr(last, loc-last);
    last = loc + 1;

    if (C[last] == '\n' || C[last] == '\r') {
      ++last;

      // Escape \r\n  or \n\r, but not \n\n.
      if (last < C.size())
        if (C[last] == '\n' || C[last] == '\r')
          if (C[last] != C[last-1])
            ++last;
    } else {
      // This was just a normal backslash.
      C2 += '\\';
    }
  }

  if (!C2.empty())
    ParseDirective(C2, &ED, SM, &PP, CommentBegin, Status);
  return false;
}
lldb::OptionValueSP
OptionValueArray::GetSubValue(const ExecutionContext *exe_ctx,
                              llvm::StringRef name, bool will_modify,
                              Status &error) const {
  if (name.empty() || name.front() != '[') {
    error.SetErrorStringWithFormat(
      "invalid value path '%s', %s values only support '[<index>]' subvalues "
      "where <index> is a positive or negative array index",
      name.str().c_str(), GetTypeAsCString());
    return nullptr;
  }

  name = name.drop_front();
  llvm::StringRef index, sub_value;
  std::tie(index, sub_value) = name.split(']');
  if (index.size() == name.size()) {
    // Couldn't find a closing bracket
    return nullptr;
  }

  const size_t array_count = m_values.size();
  int32_t idx = 0;
  if (index.getAsInteger(0, idx))
    return nullptr;

  uint32_t new_idx = UINT32_MAX;
  if (idx < 0) {
    // Access from the end of the array if the index is negative
    new_idx = array_count - idx;
  } else {
    // Just a standard index
    new_idx = idx;
  }

  if (new_idx < array_count) {
    if (m_values[new_idx]) {
      if (!sub_value.empty())
        return m_values[new_idx]->GetSubValue(exe_ctx, sub_value,
                                              will_modify, error);
      else
        return m_values[new_idx];
    }
  } else {
    if (array_count == 0)
      error.SetErrorStringWithFormat(
          "index %i is not valid for an empty array", idx);
    else if (idx > 0)
      error.SetErrorStringWithFormat(
          "index %i out of range, valid values are 0 through %" PRIu64,
          idx, (uint64_t)(array_count - 1));
    else
      error.SetErrorStringWithFormat("negative index %i out of range, "
                                      "valid values are -1 through "
                                      "-%" PRIu64,
                                      idx, (uint64_t)array_count);
  }
  return OptionValueSP();
}
Beispiel #25
0
bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
                       char *&ResultPtr, const UTF8 *&ErrorPtr) {
  assert(WideCharWidth == 1 || WideCharWidth == 2 || WideCharWidth == 4);
  ConversionResult result = conversionOK;
  // Copy the character span over.
  if (WideCharWidth == 1) {
    const UTF8 *Pos = reinterpret_cast<const UTF8*>(Source.begin());
    if (!isLegalUTF8String(&Pos, reinterpret_cast<const UTF8*>(Source.end()))) {
      result = sourceIllegal;
      ErrorPtr = Pos;
    } else {
      memcpy(ResultPtr, Source.data(), Source.size());
      ResultPtr += Source.size();
    }
  } else if (WideCharWidth == 2) {
    const UTF8 *sourceStart = (const UTF8*)Source.data();
    // FIXME: Make the type of the result buffer correct instead of
    // using reinterpret_cast.
    UTF16 *targetStart = reinterpret_cast<UTF16*>(ResultPtr);
    ConversionFlags flags = strictConversion;
    result = ConvertUTF8toUTF16(
        &sourceStart, sourceStart + Source.size(),
        &targetStart, targetStart + Source.size(), flags);
    if (result == conversionOK)
      ResultPtr = reinterpret_cast<char*>(targetStart);
    else
      ErrorPtr = sourceStart;
  } else if (WideCharWidth == 4) {
    const UTF8 *sourceStart = (const UTF8*)Source.data();
    // FIXME: Make the type of the result buffer correct instead of
    // using reinterpret_cast.
    UTF32 *targetStart = reinterpret_cast<UTF32*>(ResultPtr);
    ConversionFlags flags = strictConversion;
    result = ConvertUTF8toUTF32(
        &sourceStart, sourceStart + Source.size(),
        &targetStart, targetStart + Source.size(), flags);
    if (result == conversionOK)
      ResultPtr = reinterpret_cast<char*>(targetStart);
    else
      ErrorPtr = sourceStart;
  }
  assert((result != targetExhausted)
         && "ConvertUTF8toUTFXX exhausted target buffer");
  return result == conversionOK;
}
MCLDDirectory::MCLDDirectory(llvm::StringRef pName)
  : Directory(), m_Name(pName.data(), pName.size()) {
  Directory::m_Path.assign(pName.str());

  if (!Directory::m_Path.empty())
    m_bInSysroot = ('=' == Directory::m_Path.native()[0]);

  Directory::m_Path.m_append_separator_if_needed();
  if (m_bInSysroot)
    Directory::m_Path.native().erase(Directory::m_Path.native().begin());
  else
    detail::open_dir(*this);
}
Beispiel #27
0
  int MetaProcessor::process(llvm::StringRef input_line,
                             Interpreter::CompilationResult& compRes,
                             Value* result,
                             bool disableValuePrinting /* = false */) {
    if (result)
      *result = Value();
    compRes = Interpreter::kSuccess;
    int expectedIndent = m_InputValidator->getExpectedIndent();

    if (expectedIndent)
      compRes = Interpreter::kMoreInputExpected;

    if (input_line.empty() ||
        (input_line.size() == 1 && input_line.front() == '\n')) {
      // just a blank line, nothing to do.
      return expectedIndent;
    }

    //  Check for and handle meta commands.
    m_MetaParser->enterNewInputLine(input_line);
    MetaSema::ActionResult actionResult = MetaSema::AR_Success;
    if (!m_InputValidator->inBlockComment() &&
         m_MetaParser->isMetaCommand(actionResult, result)) {

      if (m_MetaParser->isQuitRequested())
        return -1;

      if (actionResult != MetaSema::AR_Success)
        compRes = Interpreter::kFailure;
       // ExpectedIndent might have changed after meta command.
       return m_InputValidator->getExpectedIndent();
    }

    // Check if the current statement is now complete. If not, return to
    // prompt for more.
    if (m_InputValidator->validate(input_line) == InputValidator::kIncomplete) {
      compRes = Interpreter::kMoreInputExpected;
      return m_InputValidator->getExpectedIndent();
    }

    //  We have a complete statement, compile and execute it.
    std::string input;
    m_InputValidator->reset(&input);
    // if (m_Options.RawInput)
    //   compResLocal = m_Interp.declare(input);
    // else
    compRes = m_Interp.process(input, result, /*Transaction*/ nullptr,
                               disableValuePrinting);

    return 0;
  }
Beispiel #28
0
void WireEncoder::WriteString(llvm::StringRef str) {
  // length
  std::size_t len = str.size();
  if (m_proto_rev < 0x0300u) {
    if (len > 0xffff) len = 0xffff; // Limited to 64K length; truncate
    Write16(len);
  } else
    WriteUleb128(len);

  // contents
  Reserve(len);
  std::memcpy(m_cur, str.data(), len);
  m_cur += len;
}
Beispiel #29
0
static void mangleNameInPlace(InternedString& id, llvm::StringRef private_name, InternedStringPool& interned_strings) {
    if (!private_name.size())
        return;

    int len = id.s().size();
    if (len < 2 || id.s()[0] != '_' || id.s()[1] != '_')
        return;

    if ((id.s()[len - 2] == '_' && id.s()[len - 1] == '_') || id.s().find('.') != std::string::npos)
        return;

    assert(private_name.data()[private_name.size()] == '\0');
    const char* p = private_name.data();
    while (*p == '_') {
        p++;
        len--;
    }
    if (*p == '\0')
        return;

    // TODO add a twine interface to interned strings?
    id = interned_strings.get("_" + std::string(p) + std::string(id.s()));
}
lldb::OptionValueSP
OptionValueDictionary::GetSubValue(const ExecutionContext *exe_ctx,
                                   llvm::StringRef name, bool will_modify,
                                   Status &error) const {
  lldb::OptionValueSP value_sp;
  if (name.empty())
    return nullptr;

  llvm::StringRef left, temp;
  std::tie(left, temp) = name.split('[');
  if (left.size() == name.size()) {
    error.SetErrorStringWithFormat("invalid value path '%s', %s values only "
      "support '[<key>]' subvalues where <key> "
      "a string value optionally delimited by "
      "single or double quotes",
      name.str().c_str(), GetTypeAsCString());
    return nullptr;
  }
  assert(!temp.empty());

  llvm::StringRef key, quote_char;

  if (temp[0] == '\"' || temp[0] == '\'') {
    quote_char = temp.take_front();
    temp = temp.drop_front();
  }

  llvm::StringRef sub_name;
  std::tie(key, sub_name) = temp.split(']');

  if (!key.consume_back(quote_char) || key.empty()) {
    error.SetErrorStringWithFormat("invalid value path '%s', "
      "key names must be formatted as ['<key>'] where <key> "
      "is a string that doesn't contain quotes and the quote"
      " char is optional", name.str().c_str());
    return nullptr;
  }

  value_sp = GetValueForKey(ConstString(key));
  if (!value_sp) {
    error.SetErrorStringWithFormat(
      "dictionary does not contain a value for the key name '%s'",
      key.str().c_str());
    return nullptr;
  }

  if (sub_name.empty())
    return value_sp;
  return value_sp->GetSubValue(exe_ctx, sub_name, will_modify, error);
}