Example #1
0
static unsigned CountNumOperands(StringRef AsmString) {
  unsigned NumOps = 0;
  std::pair<StringRef, StringRef> ASM = AsmString.split(' ');

  while (!ASM.second.empty()) {
    ++NumOps;
    ASM = ASM.second.split(' ');
  }

  return NumOps;
}
Example #2
0
static std::pair<StringRef, unsigned>
getPassNameAndInstanceNum(StringRef PassName) {
  StringRef Name, InstanceNumStr;
  std::tie(Name, InstanceNumStr) = PassName.split(',');

  unsigned InstanceNum = 0;
  if (!InstanceNumStr.empty() && InstanceNumStr.getAsInteger(10, InstanceNum))
    report_fatal_error("invalid pass instance specifier " + PassName);

  return std::make_pair(Name, InstanceNum);
}
Example #3
0
static unsigned CountResultNumOperands(StringRef AsmString) {
  unsigned NumOps = 0;
  std::pair<StringRef, StringRef> ASM = AsmString.split('\t');

  if (!ASM.second.empty()) {
    size_t I = ASM.second.find('{');
    StringRef Str = ASM.second;
    if (I != StringRef::npos)
      Str = ASM.second.substr(I, ASM.second.find('|', I));

    ASM = Str.split(' ');

    do {
      ++NumOps;
      ASM = ASM.second.split(' ');
    } while (!ASM.second.empty());
  }

  return NumOps;
}
Example #4
0
void CVTypeDumperImpl::visitUnionType(TypeLeafKind Leaf, const UnionType *Union,
                                      ArrayRef<uint8_t> LeafData) {
  W.printNumber("MemberCount", Union->MemberCount);
  uint16_t Props = Union->Properties;
  W.printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
  printTypeIndex("FieldList", Union->FieldList);
  uint64_t SizeOf;
  if (!decodeUIntLeaf(LeafData, SizeOf))
    return parseError();
  W.printNumber("SizeOf", SizeOf);
  StringRef LeafChars = getBytesAsCharacters(LeafData);
  StringRef LinkageName;
  std::tie(Name, LinkageName) = LeafChars.split('\0');
  W.printString("Name", Name);
  if (Props & uint16_t(ClassOptions::HasUniqueName)) {
    LinkageName = LinkageName.split('\0').first;
    if (LinkageName.empty())
      return parseError();
    W.printString("LinkageName", LinkageName);
  }
}
Example #5
0
 bool TryFindProgram(StringRef Names, std::string &ProgramPath) {
   raw_string_ostream Log(LogBuffer);
   SmallVector<StringRef, 8> parts;
   Names.split(parts, "|");
   for (auto Name : parts) {
     ProgramPath = sys::FindProgramByName(Name);
     if (!ProgramPath.empty())
       return true;
     Log << "  Tried '" << Name << "'\n";
   }
   return false;
 }
Example #6
0
void RewriteUtils::indentAfterNewLine(StringRef Str,
                                      std::string &NewStr,
                                      const std::string &IndentStr)
{
  SmallVector<StringRef, 20> StrVec;
  Str.split(StrVec, "\n"); 
  NewStr = "";
  for(SmallVector<StringRef, 20>::iterator I = StrVec.begin(), 
      E = StrVec.end(); I != E; ++I) {
    NewStr += ((*I).str() + "\n" + IndentStr);
  }
}
static bool getModuleInterfaceInfo(ASTContext &Ctx,
                                   StringRef ModuleName,
                                   Optional<StringRef> Group,
                                 SwiftInterfaceGenContext::Implementation &Impl,
                                   std::string &ErrMsg) {
  Module *&Mod = Impl.Mod;
  SourceTextInfo &Info = Impl.Info;

  if (ModuleName.empty()) {
    ErrMsg = "Module name is empty";
    return true;
  }

  // Get the (sub)module to generate.
  Mod = getModuleByFullName(Ctx, ModuleName);
  if (!Mod) {
    ErrMsg = "Could not load module: ";
    ErrMsg += ModuleName;
    return true;
  }

  std::vector<StringRef> SplitModuleName;
  while (!ModuleName.empty()) {
    StringRef SubModuleName;
    std::tie(SubModuleName, ModuleName) = ModuleName.split('.');
    SplitModuleName.push_back(SubModuleName);
  }
  assert(!SplitModuleName.empty());

  // FIXME: If this is a submodule, get its top-level module, which will be the
  // DeclContext for all of its Decls since we don't have first-class submodules.
  if (SplitModuleName.size() > 1) {
    Mod = getModuleByFullName(Ctx, SplitModuleName[0]);
    if (!Mod) {
      ErrMsg = "Could not load module: ";
      ErrMsg += ModuleName;
      return true;
    }
  }

  PrintOptions Options = PrintOptions::printInterface();
  ModuleTraversalOptions TraversalOptions = None; // Don't print submodules.
  SmallString<128> Text;
  llvm::raw_svector_ostream OS(Text);
  AnnotatingPrinter Printer(Info, OS);
  printSubmoduleInterface(Mod, SplitModuleName, Group,
                          TraversalOptions,
                          Printer, Options, false);

  Info.Text = OS.str();
  return false;
}
Example #8
0
// Decode ARM features from string like +[no]featureA+[no]featureB+...
static bool DecodeARMFeatures(const Driver &D, StringRef text,
                              std::vector<StringRef> &Features) {
  SmallVector<StringRef, 8> Split;
  text.split(Split, StringRef("+"), -1, false);

  for (StringRef Feature : Split) {
    StringRef FeatureName = llvm::ARM::getArchExtFeature(Feature);
    if (!FeatureName.empty())
      Features.push_back(FeatureName);
    else
      return false;
  }
  return true;
}
Example #9
0
static WeightedFile parseWeightedFile(const StringRef &WeightedFilename) {
  StringRef WeightStr, FileName;
  std::tie(WeightStr, FileName) = WeightedFilename.split(',');

  uint64_t Weight;
  if (WeightStr.getAsInteger(10, Weight) || Weight < 1)
    exitWithError("Input weight must be a positive integer.");

  if (!sys::fs::exists(FileName))
    exitWithErrorCode(make_error_code(errc::no_such_file_or_directory),
                      FileName);

  return WeightedFile(FileName, Weight);
}
Example #10
0
/// print -  Print source files with collected line count information.
void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const {
  for (StringMap<LineData>::const_iterator I = LineInfo.begin(),
         E = LineInfo.end(); I != E; ++I) {
    StringRef Filename = I->first();
    OwningPtr<MemoryBuffer> Buff;
    if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
      errs() << Filename << ": " << ec.message() << "\n";
      return;
    }
    StringRef AllLines = Buff->getBuffer();

    std::string CovFilename = Filename.str() + ".llcov";
    std::string ErrorInfo;
    raw_fd_ostream OS(CovFilename.c_str(), ErrorInfo);
    if (!ErrorInfo.empty())
      errs() << ErrorInfo << "\n";

    OS << "        -:    0:Source:" << Filename << "\n";
    OS << "        -:    0:Graph:" << GCNOFile << "\n";
    OS << "        -:    0:Data:" << GCDAFile << "\n";
    OS << "        -:    0:Runs:" << RunCount << "\n";
    OS << "        -:    0:Programs:" << ProgramCount << "\n";

    const LineData &Line = I->second;
    for (uint32_t i = 0; !AllLines.empty(); ++i) {
      LineData::const_iterator BlocksIt = Line.find(i);

      // Add up the block counts to form line counts.
      if (BlocksIt != Line.end()) {
        const BlockVector &Blocks = BlocksIt->second;
        uint64_t LineCount = 0;
        for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
               I != E; ++I) {
          LineCount += (*I)->getCount();
        }
        if (LineCount == 0)
          OS << "    #####:";
        else
          OS << format("%9" PRIu64 ":", LineCount);
      } else {
        OS << "        -:";
      }
      std::pair<StringRef, StringRef> P = AllLines.split('\n');
      OS << format("%5u:", i+1) << P.first << "\n";
      AllLines = P.second;
    }
  }
}
Example #11
0
// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
static bool DecodeAArch64Features(const Driver &D, StringRef text,
                                  std::vector<StringRef> &Features) {
  SmallVector<StringRef, 8> Split;
  text.split(Split, StringRef("+"), -1, false);

  for (StringRef Feature : Split) {
    StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
    if (!FeatureName.empty())
      Features.push_back(FeatureName);
    else if (Feature == "neon" || Feature == "noneon")
      D.Diag(clang::diag::err_drv_no_neon_modifier);
    else
      return false;
  }
  return true;
}
// Append a #define line to Buf for Macro.  Macro should be of the form XXX,
// in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
// "#define XXX Y z W".  To get a #define with no value, use "XXX=".
static void DefineBuiltinMacro(MacroBuilder &Builder, StringRef Macro,
                               DiagnosticsEngine &Diags) {
  std::pair<StringRef, StringRef> MacroPair = Macro.split('=');
  StringRef MacroName = MacroPair.first;
  StringRef MacroBody = MacroPair.second;
  if (MacroName.size() != Macro.size()) {
    // Per GCC -D semantics, the macro ends at \n if it exists.
    StringRef::size_type End = MacroBody.find_first_of("\n\r");
    if (End != StringRef::npos)
      Diags.Report(diag::warn_fe_macro_contains_embedded_newline)
        << MacroName;
    Builder.defineMacro(MacroName, MacroBody.substr(0, End));
  } else {
    // Push "macroname 1".
    Builder.defineMacro(Macro);
  }
}
Example #13
0
bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
  // If the pipeline just consists of the word 'default' just replace the AA
  // manager with our default one.
  if (PipelineText == "default") {
    AA = buildDefaultAAPipeline();
    return true;
  }

  while (!PipelineText.empty()) {
    StringRef Name;
    std::tie(Name, PipelineText) = PipelineText.split(',');
    if (!parseAAPassName(AA, Name))
      return false;
  }

  return true;
}
Example #14
0
unsigned Pattern::ComputeMatchDistance(StringRef Buffer,
                              const StringMap<StringRef> &VariableTable) const {
  // Just compute the number of matching characters. For regular expressions, we
  // just compare against the regex itself and hope for the best.
  //
  // FIXME: One easy improvement here is have the regex lib generate a single
  // example regular expression which matches, and use that as the example
  // string.
  StringRef ExampleString(FixedStr);
  if (ExampleString.empty())
    ExampleString = RegExStr;

  // Only compare up to the first line in the buffer, or the string size.
  StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
  BufferPrefix = BufferPrefix.split('\n').first;
  return BufferPrefix.edit_distance(ExampleString);
}
/// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at
/// \p WriteTo - 1.
void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile,
                                          unsigned &WriteFrom, unsigned WriteTo,
                                          StringRef LocalEOL, int &Line,
                                          bool EnsureNewline) {
  if (WriteTo <= WriteFrom)
    return;
  if (&FromFile == PredefinesBuffer) {
    // Ignore the #defines of the predefines buffer.
    WriteFrom = WriteTo;
    return;
  }

  // If we would output half of a line ending, advance one character to output
  // the whole line ending.  All buffers are null terminated, so looking ahead
  // one byte is safe.
  if (LocalEOL.size() == 2 &&
      LocalEOL[0] == (FromFile.getBufferStart() + WriteTo)[-1] &&
      LocalEOL[1] == (FromFile.getBufferStart() + WriteTo)[0])
    WriteTo++;

  StringRef TextToWrite(FromFile.getBufferStart() + WriteFrom,
                        WriteTo - WriteFrom);

  if (MainEOL == LocalEOL) {
    OS << TextToWrite;
    // count lines manually, it's faster than getPresumedLoc()
    Line += TextToWrite.count(LocalEOL);
    if (EnsureNewline && !TextToWrite.endswith(LocalEOL))
      OS << MainEOL;
  } else {
    // Output the file one line at a time, rewriting the line endings as we go.
    StringRef Rest = TextToWrite;
    while (!Rest.empty()) {
      StringRef LineText;
      std::tie(LineText, Rest) = Rest.split(LocalEOL);
      OS << LineText;
      Line++;
      if (!Rest.empty())
        OS << MainEOL;
    }
    if (TextToWrite.endswith(LocalEOL) || EnsureNewline)
      OS << MainEOL;
  }
  WriteFrom = WriteTo;
}
Example #16
0
void SubtargetFeatureInfo::emitComputeAvailableFeatures(
    StringRef TargetName, StringRef ClassName,
    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
    raw_ostream &OS) {
  OS << "uint64_t " << TargetName << ClassName << "::\n"
     << "ComputeAvailableFeatures(const FeatureBitset& FB) const {\n";
  OS << "  uint64_t Features = 0;\n";
  for (const auto &SF : SubtargetFeatures) {
    const SubtargetFeatureInfo &SFI = SF.second;

    OS << "  if (";
    std::string CondStorage =
        SFI.TheDef->getValueAsString("AssemblerCondString");
    StringRef Conds = CondStorage;
    std::pair<StringRef, StringRef> Comma = Conds.split(',');
    bool First = true;
    do {
      if (!First)
        OS << " && ";

      bool Neg = false;
      StringRef Cond = Comma.first;
      if (Cond[0] == '!') {
        Neg = true;
        Cond = Cond.substr(1);
      }

      OS << "(";
      if (Neg)
        OS << "!";
      OS << "FB[" << TargetName << "::" << Cond << "])";

      if (Comma.second.empty())
        break;

      First = false;
      Comma = Comma.second.split(',');
    } while (true);

    OS << ")\n";
    OS << "    Features |= " << SFI.getEnumName() << ";\n";
  }
  OS << "  return Features;\n";
  OS << "}\n\n";
}
Example #17
0
/// Parse a stringified Swift declaration name, e.g. "init(frame:)".
StringRef swift::parseDeclName(StringRef name,
                               SmallVectorImpl<StringRef> &argumentLabels,
                               bool &isFunctionName) {
  if (name.empty()) return "";

  if (name.back() != ')') {
    isFunctionName = false;
    if (Lexer::isIdentifier(name) && name != "_")
      return name;

    return "";
  }

  isFunctionName = true;

  StringRef BaseName, Parameters;
  std::tie(BaseName, Parameters) = name.split('(');
  if (!Lexer::isIdentifier(BaseName) || BaseName == "_")
    return "";

  if (Parameters.empty())
    return "";
  Parameters = Parameters.drop_back(); // ')'

  if (Parameters.empty())
    return BaseName;

  if (Parameters.back() != ':')
    return "";

  do {
    StringRef NextParam;
    std::tie(NextParam, Parameters) = Parameters.split(':');

    if (!Lexer::isIdentifier(NextParam))
      return "";
    if (NextParam == "_")
      argumentLabels.push_back("");
    else
      argumentLabels.push_back(NextParam);
  } while (!Parameters.empty());

  return BaseName;
}
Example #18
0
bool
LLDBServerUtilities::SetupLogging(const std::string& log_file,
	                              const StringRef& log_channels,
	                              uint32_t log_options)
{
    lldb::StreamSP log_stream_sp;
    if (log_file.empty())
    {
        log_stream_sp.reset(new StreamFile(stdout, false));
    }
    else
    {
        uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate |
                           File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
        if (!(log_options & LLDB_LOG_OPTION_APPEND))
            options |= File::eOpenOptionTruncate;

        log_stream_sp.reset(new StreamFile(log_file.c_str(), options));
    }

    SmallVector<StringRef, 32> channel_array;
    log_channels.split(channel_array, ":");
    for (auto channel_with_categories : channel_array)
    {
        StreamString error_stream;
        Args channel_then_categories(channel_with_categories);
        std::string channel(channel_then_categories.GetArgumentAtIndex(0));
        channel_then_categories.Shift (); // Shift off the channel

        bool success = Log::EnableLogChannel(log_stream_sp,
                                             log_options,
                                             channel.c_str(),
                                             channel_then_categories.GetConstArgumentVector(),
                                             error_stream);
        if (!success)
        {
            fprintf(stderr, "Unable to open log file '%s' for channel \"%s\"\n",
                    log_file.c_str(),
                    channel_with_categories.str().c_str());
            return false;
        }
    }
    return true;
}
Example #19
0
void formatErrorString(StringRef FormatString, ArrayRef<std::string> Args,
                       llvm::raw_ostream &OS) {
  while (!FormatString.empty()) {
    std::pair<StringRef, StringRef> Pieces = FormatString.split("$");
    OS << Pieces.first.str();
    if (Pieces.second.empty()) break;

    const char Next = Pieces.second.front();
    FormatString = Pieces.second.drop_front();
    if (Next >= '0' && Next <= '9') {
      const unsigned Index = Next - '0';
      if (Index < Args.size()) {
        OS << Args[Index];
      } else {
        OS << "<Argument_Not_Provided>";
      }
    }
  }
}
Example #20
0
/// \brief Parse the simulator version define:
/// __IPHONE_OS_VERSION_MIN_REQUIRED=([0-9])([0-9][0-9])([0-9][0-9])
// and return the grouped values as integers, e.g:
//   __IPHONE_OS_VERSION_MIN_REQUIRED=40201
// will return Major=4, Minor=2, Micro=1.
static bool GetVersionFromSimulatorDefine(StringRef define,
                                          unsigned &Major, unsigned &Minor,
                                          unsigned &Micro) {
  assert(define.startswith(SimulatorVersionDefineName()));
  StringRef name, version;
  llvm::tie(name, version) = define.split('=');
  if (version.empty())
    return false;
  std::string verstr = version.str();
  char *end;
  unsigned num = (unsigned) strtol(verstr.c_str(), &end, 10);
  if (*end != '\0')
    return false;
  Major = num / 10000;
  num = num % 10000;
  Minor = num / 100;
  Micro = num % 100;
  return true;
}
Example #21
0
void StringRef::split(SmallVectorImpl<StringRef> &A,
                      StringRef Separators, int MaxSplit,
                      bool KeepEmpty) const {
  StringRef rest = *this;

  // rest.data() is used to distinguish cases like "a," that splits into
  // "a" + "" and "a" that splits into "a" + 0.
  for (int splits = 0;
       rest.data() != NULL && (MaxSplit < 0 || splits < MaxSplit);
       ++splits) {
    std::pair<StringRef, StringRef> p = rest.split(Separators);

    if (KeepEmpty || p.first.size() != 0)
      A.push_back(p.first);
    rest = p.second;
  }
  // If we have a tail left, add it.
  if (rest.data() != NULL && (rest.size() != 0 || KeepEmpty))
    A.push_back(rest);
}
Example #22
0
static void parseInputFilenamesFile(MemoryBuffer *Buffer,
                                    WeightedFileVector &WFV) {
  if (!Buffer)
    return;

  SmallVector<StringRef, 8> Entries;
  StringRef Data = Buffer->getBuffer();
  Data.split(Entries, '\n', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
  for (const StringRef &FileWeightEntry : Entries) {
    StringRef SanitizedEntry = FileWeightEntry.trim(" \t\v\f\r");
    // Skip comments.
    if (SanitizedEntry.startswith("#"))
      continue;
    // If there's no comma, it's an unweighted profile.
    else if (SanitizedEntry.find(',') == StringRef::npos)
      addWeightedInput(WFV, {SanitizedEntry, 1});
    else
      addWeightedInput(WFV, parseWeightedFile(SanitizedEntry));
  }
}
// Determine whether we use the vector ABI.
static bool UsesVectorABI(StringRef CPU, StringRef FS) {
  // We use the vector ABI whenever the vector facility is avaiable.
  // This is the case by default if CPU is z13 or later, and can be
  // overridden via "[+-]vector" feature string elements.
  bool VectorABI = true;
  if (CPU.empty() || CPU == "generic" ||
      CPU == "z10" || CPU == "z196" || CPU == "zEC12")
    VectorABI = false;

  SmallVector<StringRef, 3> Features;
  FS.split(Features, ',', -1, false /* KeepEmpty */);
  for (auto &Feature : Features) {
    if (Feature == "vector" || Feature == "+vector")
      VectorABI = true;
    if (Feature == "-vector")
      VectorABI = false;
  }

  return VectorABI;
}
Example #24
0
/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
/// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is
/// provided, or to nullptr otherwise.
std::string aarch64::getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
  std::string CPU;
  // If we have -mcpu, use that.
  if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
    StringRef Mcpu = A->getValue();
    CPU = Mcpu.split("+").first.lower();
  }

  // Handle CPU name is 'native'.
  if (CPU == "native")
    return llvm::sys::getHostCPUName();
  else if (CPU.size())
    return CPU;

  // Make sure we pick "cyclone" if -arch is used.
  // FIXME: Should this be picked by checking the target triple instead?
  if (Args.getLastArg(options::OPT_arch))
    return "cyclone";

  return "generic";
}
Example #25
0
StringRef llvm::codeview::getSymbolName(CVSymbol Sym) {
  if (Sym.kind() == SymbolKind::S_CONSTANT) {
    // S_CONSTANT is preceded by an APSInt, which has a variable length.  So we
    // have to do a full deserialization.
    BinaryStreamReader Reader(Sym.content(), llvm::support::little);
    // The container doesn't matter for single records.
    SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile);
    ConstantSym Const(SymbolKind::S_CONSTANT);
    cantFail(Mapping.visitSymbolBegin(Sym));
    cantFail(Mapping.visitKnownRecord(Sym, Const));
    cantFail(Mapping.visitSymbolEnd(Sym));
    return Const.Name;
  }

  int Offset = getSymbolNameOffset(Sym);
  if (Offset == -1)
    return StringRef();

  StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
  return StringData.split('\0').first;
}
Example #26
0
Type ASTBuilder::createTupleType(ArrayRef<Type> eltTypes,
                                 StringRef labels,
                                 bool isVariadic) {
  // Just bail out on variadic tuples for now.
  if (isVariadic) return Type();

  SmallVector<TupleTypeElt, 4> elements;
  elements.reserve(eltTypes.size());
  for (auto eltType : eltTypes) {
    Identifier label;
    if (!labels.empty()) {
      auto split = labels.split(' ');
      if (!split.first.empty())
        label = Ctx.getIdentifier(split.first);
      labels = split.second;
    }
    elements.emplace_back(eltType, label);
  }

  return TupleType::get(elements, Ctx);
}
Example #27
0
static Flavor parseProgname(StringRef Progname) {
#if __APPLE__
  // Use Darwin driver for "ld" on Darwin.
  if (Progname == "ld")
    return Darwin;
#endif

#if LLVM_ON_UNIX
  // Use GNU driver for "ld" on other Unix-like system.
  if (Progname == "ld")
    return Gnu;
#endif

  // Progname may be something like "lld-gnu". Parse it.
  SmallVector<StringRef, 3> V;
  Progname.split(V, "-");
  for (StringRef S : V)
    if (Flavor F = getFlavor(S))
      return F;
  return Invalid;
}
Example #28
0
std::string FormatErrorString(StringRef FormatString,
                              ArrayRef<std::string> Args) {
  std::string Out;
  while (!FormatString.empty()) {
    std::pair<StringRef, StringRef> Pieces = FormatString.split("$");
    Out += Pieces.first.str();
    if (Pieces.second.empty()) break;

    const char Next = Pieces.second.front();
    FormatString = Pieces.second.drop_front();
    if (Next >= '0' && Next <= '9') {
      const unsigned Index = Next - '0';
      if (Index < Args.size()) {
        Out += Args[Index];
      } else {
        Out += "<Argument_Not_Provided>";
      }
    }
  }
  return Out;
}
Example #29
0
/// InsertText - Insert the specified string at the specified location in the
/// original buffer.
bool Rewriter::InsertText(SourceLocation Loc, StringRef Str,
                          bool InsertAfter, bool indentNewLines) {
  if (!isRewritable(Loc)) return true;
  FileID FID;
  unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);

  SmallString<128> indentedStr;
  if (indentNewLines && Str.find('\n') != StringRef::npos) {
    StringRef MB = SourceMgr->getBufferData(FID);

    unsigned lineNo = SourceMgr->getLineNumber(FID, StartOffs) - 1;
    const SrcMgr::ContentCache *
        Content = SourceMgr->getSLocEntry(FID).getFile().getContentCache();
    unsigned lineOffs = Content->SourceLineCache[lineNo];

    // Find the whitespace at the start of the line.
    StringRef indentSpace;
    {
      unsigned i = lineOffs;
      while (isWhitespace(MB[i]))
        ++i;
      indentSpace = MB.substr(lineOffs, i-lineOffs);
    }

    SmallVector<StringRef, 4> lines;
    Str.split(lines, "\n");

    for (unsigned i = 0, e = lines.size(); i != e; ++i) {
      indentedStr += lines[i];
      if (i < e-1) {
        indentedStr += '\n';
        indentedStr += indentSpace;
      }
    }
    Str = indentedStr.str();
  }

  getEditBuffer(FID).InsertText(StartOffs, Str, InsertAfter);
  return false;
}
Example #30
0
static std::vector<StringRef> getSearchPaths(opt::InputArgList *Args,
                                             StringSaver &Saver) {
  std::vector<StringRef> Ret;
  // Add current directory as first item of the search path.
  Ret.push_back("");

  // Add /libpath flags.
  for (auto *Arg : Args->filtered(OPT_libpath))
    Ret.push_back(Arg->getValue());

  // Add $LIB.
  Optional<std::string> EnvOpt = sys::Process::GetEnv("LIB");
  if (!EnvOpt.hasValue())
    return Ret;
  StringRef Env = Saver.save(*EnvOpt);
  while (!Env.empty()) {
    StringRef Path;
    std::tie(Path, Env) = Env.split(';');
    Ret.push_back(Path);
  }
  return Ret;
}