// Split S into linker script tokens. std::vector<StringRef> ScriptParserBase::tokenize(StringRef S) { std::vector<StringRef> Ret; for (;;) { S = skipSpace(S); if (S.empty()) return Ret; // Quoted token if (S.startswith("\"")) { size_t E = S.find("\"", 1); if (E == StringRef::npos) { error("unclosed quote"); return {}; } Ret.push_back(S.substr(1, E - 1)); S = S.substr(E + 1); continue; } // Unquoted token size_t Pos = S.find_first_not_of( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789_.$/\\~=+[]*?-:!<>"); // A character that cannot start a word (which is usually a // punctuation) forms a single character token. if (Pos == 0) Pos = 1; Ret.push_back(S.substr(0, Pos)); S = S.substr(Pos); } }
size_t camel_case::findWord(StringRef string, StringRef word) { assert(!word.empty()); assert(clang::isUppercase(word[0])); // Scan forward until we find the word as a complete word. size_t startingIndex = 0; while (true) { size_t index = string.find(word, startingIndex); if (index == StringRef::npos) return StringRef::npos; // If any of the following checks fail, we want to start searching // past the end of the match. (This assumes that the word doesn't // end with a prefix of itself, e.g. "LikeableLike".) startingIndex = index + word.size(); // We assume that we don't have to check if the match starts a new // word in the string. // If we find the word, check whether it's a valid match. StringRef suffix = string.substr(index); if (!suffix.empty() && clang::isLowercase(suffix[0])) continue; return index; } }
/// Parse an instruction mnemonic followed by its operands. bool PPCAsmParser:: ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, SmallVectorImpl<MCParsedAsmOperand*> &Operands) { // The first operand is the token for the instruction name. // If the instruction ends in a '.', we need to create a separate // token for it, to match what TableGen is doing. size_t Dot = Name.find('.'); StringRef Mnemonic = Name.slice(0, Dot); Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64())); if (Dot != StringRef::npos) { SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot); StringRef DotStr = Name.slice(Dot, StringRef::npos); Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64())); } // If there are no more operands then finish if (getLexer().is(AsmToken::EndOfStatement)) return false; // Parse the first operand if (ParseOperand(Operands)) return true; while (getLexer().isNot(AsmToken::EndOfStatement) && getLexer().is(AsmToken::Comma)) { // Consume the comma token getLexer().Lex(); // Parse the next operand if (ParseOperand(Operands)) return true; } return false; }
// Parses a symbol name in the form of <name>@<version> or <name>@@<version>. static std::pair<StringRef, uint16_t> getSymbolVersion(SymbolBody *B, int MaxVersionLen) { StringRef S = B->getName(); // MaxVersionLen was passed so that we don't need to scan // all characters in a symbol name. It is effective because // versions are usually short and symbol names can be very long. size_t Pos = S.find('@', std::max(0, int(S.size()) - MaxVersionLen - 2)); if (Pos == 0 || Pos == StringRef::npos) return {"", 0}; StringRef Name = S.substr(0, Pos); StringRef Verstr = S.substr(Pos + 1); if (Verstr.empty()) return {"", 0}; // '@@' in a symbol name means the default version. // It is usually the most recent one. bool IsDefault = (Verstr[0] == '@'); if (IsDefault) Verstr = Verstr.substr(1); for (VersionDefinition &V : Config->VersionDefinitions) { if (V.Name == Verstr) return {Name, IsDefault ? V.Id : (V.Id | VERSYM_HIDDEN)}; } // It is an error if the specified version was not defined. error("symbol " + S + " has undefined version " + Verstr); return {"", 0}; }
/// ParseCStringVector - Break INPUT up wherever one or more /// whitespace characters are found, and store the resulting tokens in /// OUTPUT. The tokens stored in OUTPUT are dynamically allocated /// using strdup(), so it is the caller's responsibility to free() /// them later. /// static void ParseCStringVector(std::vector<char *> &OutputVector, const char *Input) { // Characters which will be treated as token separators: StringRef Delims = " \v\f\t\r\n"; StringRef WorkStr(Input); while (!WorkStr.empty()) { // If the first character is a delimiter, strip them off. if (Delims.find(WorkStr[0]) != StringRef::npos) { size_t Pos = WorkStr.find_first_not_of(Delims); if (Pos == StringRef::npos) Pos = WorkStr.size(); WorkStr = WorkStr.substr(Pos); continue; } // Find position of first delimiter. size_t Pos = WorkStr.find_first_of(Delims); if (Pos == StringRef::npos) Pos = WorkStr.size(); // Everything from 0 to Pos is the next word to copy. char *NewStr = (char*)malloc(Pos+1); memcpy(NewStr, WorkStr.data(), Pos); NewStr[Pos] = 0; OutputVector.push_back(NewStr); WorkStr = WorkStr.substr(Pos); } }
ErrorOr<std::vector<MemoryBufferRef>> BinaryHolder::MapArchiveAndGetMemberBuffers( StringRef Filename, sys::TimePoint<std::chrono::seconds> Timestamp) { StringRef ArchiveFilename = Filename.substr(0, Filename.find('(')); auto ErrOrBuff = MemoryBuffer::getFileOrSTDIN(ArchiveFilename); if (auto Err = ErrOrBuff.getError()) return Err; if (Verbose) outs() << "\topened new archive '" << ArchiveFilename << "'\n"; changeBackingMemoryBuffer(std::move(*ErrOrBuff)); std::vector<MemoryBufferRef> ArchiveBuffers; auto ErrOrFat = object::MachOUniversalBinary::create( CurrentMemoryBuffer->getMemBufferRef()); if (!ErrOrFat) { consumeError(ErrOrFat.takeError()); // Not a fat binary must be a standard one. ArchiveBuffers.push_back(CurrentMemoryBuffer->getMemBufferRef()); } else { CurrentFatBinary = std::move(*ErrOrFat); CurrentFatBinaryName = ArchiveFilename; ArchiveBuffers = getMachOFatMemoryBuffers( CurrentFatBinaryName, *CurrentMemoryBuffer, *CurrentFatBinary); } for (auto MemRef : ArchiveBuffers) { auto ErrOrArchive = object::Archive::create(MemRef); if (!ErrOrArchive) return errorToErrorCode(ErrOrArchive.takeError()); CurrentArchives.push_back(std::move(*ErrOrArchive)); } return GetArchiveMemberBuffers(Filename, Timestamp); }
static std::string ParseCpu0Triple(StringRef TT, StringRef CPU) { std::string Cpu0ArchFeature; size_t DashPosition = 0; StringRef TheTriple; // Let's see if there is a dash, like cpu0-unknown-linux. DashPosition = TT.find('-'); if (DashPosition == StringRef::npos) { // No dash, we check the string size. TheTriple = TT.substr(0); } else { // We are only interested in substring before dash. TheTriple = TT.substr(0,DashPosition); } if (TheTriple == "cpu0" || TheTriple == "cpu0el") { if (CPU.empty() || CPU == "cpu032II") { Cpu0ArchFeature = "+cpu032II"; } else if (CPU == "cpu032I") { Cpu0ArchFeature = "+cpu032I"; } } return Cpu0ArchFeature; }
void StringRef::split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit, bool KeepEmpty) const { StringRef S = *this; // Count down from MaxSplit. When MaxSplit is -1, this will just split // "forever". This doesn't support splitting more than 2^31 times // intentionally; if we ever want that we can make MaxSplit a 64-bit integer // but that seems unlikely to be useful. while (MaxSplit-- != 0) { size_t Idx = S.find(Separator); if (Idx == npos) break; // Push this split. if (KeepEmpty || Idx > 0) A.push_back(S.slice(0, Idx)); // Jump forward. S = S.slice(Idx + 1, npos); } // Push the tail. if (KeepEmpty || !S.empty()) A.push_back(S); }
void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, const MCSymbol *Sym) const { SmallString<64> NameData("DW.ref."); // @LOCALMOD-BEGIN // The dwarf section label should not include the version suffix. // Strip it off here. StringRef Name = Sym->getName(); size_t atpos = Name.find("@"); if (atpos != StringRef::npos) Name = Name.substr(0, atpos); // @LOCALMOD-END NameData += Name; // @LOCALMOD MCSymbol *Label = getContext().GetOrCreateSymbol(NameData); Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); Streamer.EmitSymbolAttribute(Label, MCSA_Weak); StringRef Prefix = ".data."; NameData.insert(NameData.begin(), Prefix.begin(), Prefix.end()); unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; const MCSection *Sec = getContext().getELFSection(NameData, ELF::SHT_PROGBITS, Flags, SectionKind::getDataRel(), 0, Label->getName()); unsigned Size = TM.getDataLayout()->getPointerSize(); Streamer.SwitchSection(Sec); Streamer.EmitValueToAlignment(TM.getDataLayout()->getPointerABIAlignment()); Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); const MCExpr *E = MCConstantExpr::Create(Size, getContext()); Streamer.EmitELFSize(Label, E); Streamer.EmitLabel(Label); Streamer.EmitSymbolValue(Sym, Size); }
/// ParseDirectiveSymver /// ::= .symver foo, bar2@zed bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { StringRef Name; if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); if (getLexer().isNot(AsmToken::Comma)) return TokError("expected a comma"); // ARM assembly uses @ for a comment... // except when parsing the second parameter of the .symver directive. // Force the next symbol to allow @ in the identifier, which is // required for this directive and then reset it to its initial state. const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier(); getLexer().setAllowAtInIdentifier(true); Lex(); getLexer().setAllowAtInIdentifier(AllowAtInIdentifier); StringRef AliasName; if (getParser().parseIdentifier(AliasName)) return TokError("expected identifier in directive"); if (AliasName.find('@') == StringRef::npos) return TokError("expected a '@' in the name"); MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); const MCExpr *Value = MCSymbolRefExpr::Create(Sym, getContext()); getStreamer().EmitAssignment(Alias, Value); return false; }
// Find library file from search path. StringRef LinkerDriver::doFindLib(StringRef Filename) { // Add ".lib" to Filename if that has no file extension. bool hasExt = (Filename.find('.') != StringRef::npos); if (!hasExt) Filename = Alloc.save(Filename + ".lib"); return doFindFile(Filename); }
IntrusiveRefCntPtr<vfs::FileSystem> getFromYAMLString( StringRef Content, IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) { std::string VersionPlusContent("{\n 'version':0,\n"); VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos); return getFromYAMLRawString(VersionPlusContent, ExternalFS); }
SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error, SMRange SourceRange) { assert(SourceRange.isValid()); // Translate the location of the error from the location in the llvm IR string // to the corresponding location in the MIR file. auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start); unsigned Line = LineAndColumn.first + Error.getLineNo() - 1; unsigned Column = Error.getColumnNo(); StringRef LineStr = Error.getLineContents(); SMLoc Loc = Error.getLoc(); // Get the full line and adjust the column number by taking the indentation of // LLVM IR into account. for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E; L != E; ++L) { if (L.line_number() == Line) { LineStr = *L; Loc = SMLoc::getFromPointer(LineStr.data()); auto Indent = LineStr.find(Error.getLineContents()); if (Indent != StringRef::npos) Column += Indent; break; } } return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(), Error.getMessage(), LineStr, Error.getRanges(), Error.getFixIts()); }
/// \returns true if a placeholder was found. static bool findPlaceholder(StringRef Input, PlaceholderOccurrence &Occur) { while (true) { size_t Pos = Input.find("<#"); if (Pos == StringRef::npos) return false; const char *Begin = Input.begin() + Pos; const char *Ptr = Begin + 2; const char *End = Input.end(); for (; Ptr < End-1; ++Ptr) { if (*Ptr == '\n') break; if (Ptr[0] == '<' && Ptr[1] == '#') break; if (Ptr[0] == '#' && Ptr[1] == '>') { // Found it. Occur.FullPlaceholder = Input.substr(Pos, Ptr-Begin + 2); Occur.PlaceholderContent = Occur.FullPlaceholder.drop_front(2).drop_back(2); return true; } } // Try again. Input = Input.substr(Ptr - Input.begin()); } }
static bool ByteArrayFromString(ByteArrayTy &ByteArray, StringRef &Str, SourceMgr &SM) { while (SkipToToken(Str)) { // Handled by higher level if (Str[0] == '[' || Str[0] == ']') return false; // Get the current token. size_t Next = Str.find_first_of(" \t\n\r,#[]"); StringRef Value = Str.substr(0, Next); // Convert to a byte and add to the byte vector. unsigned ByteVal; if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) { // If we have an error, print it and skip to the end of line. SM.PrintMessage(SMLoc::getFromPointer(Value.data()), SourceMgr::DK_Error, "invalid input token"); Str = Str.substr(Str.find('\n')); ByteArray.first.clear(); ByteArray.second.clear(); continue; } ByteArray.first.push_back(ByteVal); ByteArray.second.push_back(Value.data()); Str = Str.substr(Next); } return false; }
BreakableToken::Split getCommentSplit(StringRef Text, unsigned ContentStartColumn, unsigned ColumnLimit) { if (ColumnLimit <= ContentStartColumn + 1) return BreakableToken::Split(StringRef::npos, 0); unsigned MaxSplit = ColumnLimit - ContentStartColumn + 1; StringRef::size_type SpaceOffset = Text.rfind(' ', MaxSplit); if (SpaceOffset == StringRef::npos || // Don't break at leading whitespace. Text.find_last_not_of(' ', SpaceOffset) == StringRef::npos) { // Make sure that we don't break at leading whitespace that // reaches past MaxSplit. StringRef::size_type FirstNonWhitespace = Text.find_first_not_of(" "); if (FirstNonWhitespace == StringRef::npos) // If the comment is only whitespace, we cannot split. return BreakableToken::Split(StringRef::npos, 0); SpaceOffset = Text.find(' ', std::max<unsigned>(MaxSplit, FirstNonWhitespace)); } if (SpaceOffset != StringRef::npos && SpaceOffset != 0) { StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim(); StringRef AfterCut = Text.substr(SpaceOffset).ltrim(); return BreakableToken::Split(BeforeCut.size(), AfterCut.begin() - BeforeCut.end()); } return BreakableToken::Split(StringRef::npos, 0); }
/// \brief Emits the comments that are stored in \p DC comment stream. /// Each comment in the comment stream must end with a newline. static void emitComments(LLVMDisasmContext *DC, formatted_raw_ostream &FormattedOS) { // Flush the stream before taking its content. DC->CommentStream.flush(); StringRef Comments = DC->CommentsToEmit.str(); // Get the default information for printing a comment. const MCAsmInfo *MAI = DC->getAsmInfo(); const char *CommentBegin = MAI->getCommentString(); unsigned CommentColumn = MAI->getCommentColumn(); bool IsFirst = true; while (!Comments.empty()) { if (!IsFirst) FormattedOS << '\n'; // Emit a line of comments. FormattedOS.PadToColumn(CommentColumn); size_t Position = Comments.find('\n'); FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position); // Move after the newline character. Comments = Comments.substr(Position+1); IsFirst = false; } FormattedOS.flush(); // Tell the comment stream that the vector changed underneath it. DC->CommentsToEmit.clear(); DC->CommentStream.resync(); }
void DiffConsumer::logf(const LogBuilder &Log) { header(); indent(); unsigned arg = 0; StringRef format = Log.getFormat(); while (true) { size_t percent = format.find('%'); if (percent == StringRef::npos) { out << format; break; } assert(format[percent] == '%'); if (percent > 0) out << format.substr(0, percent); switch (format[percent+1]) { case '%': out << '%'; break; case 'l': printValue(Log.getArgument(arg++), true); break; case 'r': printValue(Log.getArgument(arg++), false); break; default: llvm_unreachable("unknown format character"); } format = format.substr(percent+2); } out << '\n'; }
static std::string ParseMipsTriple(StringRef TT, StringRef CPU) { std::string MipsArchFeature; size_t DashPosition = 0; StringRef TheTriple; // Let's see if there is a dash, like mips-unknown-linux. DashPosition = TT.find('-'); if (DashPosition == StringRef::npos) { // No dash, we check the string size. TheTriple = TT.substr(0); } else { // We are only interested in substring before dash. TheTriple = TT.substr(0,DashPosition); } if (TheTriple == "mips" || TheTriple == "mipsel") { if (CPU.empty() || CPU == "mips32") { MipsArchFeature = "+mips32"; } else if (CPU == "mips32r2") { MipsArchFeature = "+mips32r2"; } } else { if (CPU.empty() || CPU == "mips64") { MipsArchFeature = "+mips64"; } else if (CPU == "mips64r2") { MipsArchFeature = "+mips64r2"; } } return MipsArchFeature; }
// Try to retrieve the function declaration and find the function parameter // types which are pointers/references to a non-pointer const. // We do not invalidate the corresponding argument regions. static void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs, const CallOrObjCMessage &Call) { const Decl *CallDecl = Call.getDecl(); if (!CallDecl) return; if (const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(CallDecl)) { const IdentifierInfo *II = FDecl->getIdentifier(); // List the cases, where the region should be invalidated even if the // argument is const. if (II) { StringRef FName = II->getName(); // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a // value into thread local storage. The value can later be retrieved with // 'void *ptheread_getspecific(pthread_key)'. So even thought the // parameter is 'const void *', the region escapes through the call. // - funopen - sets a buffer for future IO calls. // - ObjC functions that end with "NoCopy" can free memory, of the passed // in buffer. // - Many CF containers allow objects to escape through custom // allocators/deallocators upon container construction. // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can // be deallocated by NSMapRemove. // - Any call that has a callback as one of the arguments. if (FName == "pthread_setspecific" || FName == "funopen" || FName.endswith("NoCopy") || (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos)) || Call.isCFCGAllowingEscape(FName) || Call.hasNonZeroCallbackArg()) return; } for (unsigned Idx = 0, E = Call.getNumArgs(); Idx != E; ++Idx) { if (FDecl && Idx < FDecl->getNumParams()) { if (isPointerToConst(FDecl->getParamDecl(Idx))) PreserveArgs.insert(Idx); } } return; } if (const ObjCMethodDecl *MDecl = dyn_cast<ObjCMethodDecl>(CallDecl)) { assert(MDecl->param_size() <= Call.getNumArgs()); unsigned Idx = 0; if (Call.hasNonZeroCallbackArg()) return; for (clang::ObjCMethodDecl::param_const_iterator I = MDecl->param_begin(), E = MDecl->param_end(); I != E; ++I, ++Idx) { if (isPointerToConst(*I)) PreserveArgs.insert(Idx); } return; } }
/// \brief Format the given diagnostic text and place the result in the given /// buffer. static void formatDiagnosticText(StringRef InText, ArrayRef<DiagnosticArgument> Args, llvm::raw_ostream &Out) { while (!InText.empty()) { size_t Percent = InText.find('%'); if (Percent == StringRef::npos) { // Write the rest of the string; we're done. Out.write(InText.data(), InText.size()); break; } // Write the string up to (but not including) the %, then drop that text // (including the %). Out.write(InText.data(), Percent); InText = InText.substr(Percent + 1); // '%%' -> '%'. if (InText[0] == '%') { Out.write('%'); InText = InText.substr(1); continue; } // Parse an optional modifier. StringRef Modifier; { unsigned Length = 0; while (isalpha(InText[Length])) ++Length; Modifier = InText.substr(0, Length); InText = InText.substr(Length); } // Parse the optional argument list for a modifier, which is brace-enclosed. StringRef ModifierArguments; if (InText[0] == '{') { InText = InText.substr(1); ModifierArguments = skipToDelimiter(InText, '}'); } // Find the digit sequence. unsigned Length = 0; for (size_t N = InText.size(); Length != N; ++Length) { if (!isdigit(InText[Length])) break; } // Parse the digit sequence into an argument index. unsigned ArgIndex; bool Result = InText.substr(0, Length).getAsInteger(10, ArgIndex); assert(!Result && "Unparseable argument index value?"); (void)Result; assert(ArgIndex < Args.size() && "Out-of-range argument index"); InText = InText.substr(Length); // Convert the argument to a string. formatDiagnosticArgument(Modifier, ModifierArguments, Args, ArgIndex, Out); } }
static bool matchPassManager(StringRef PassID) { size_t prefix_pos = PassID.find('<'); if (prefix_pos == StringRef::npos) return false; StringRef Prefix = PassID.substr(0, prefix_pos); return Prefix.endswith("PassManager") || Prefix.endswith("PassAdaptor") || Prefix.endswith("AnalysisManagerProxy"); }
/// Parse the thinlto_prefix_replace option into the \p OldPrefix and /// \p NewPrefix strings, if it was specified. static void getThinLTOOldAndNewPrefix(std::string &OldPrefix, std::string &NewPrefix) { StringRef PrefixReplace = options::thinlto_prefix_replace; assert(PrefixReplace.empty() || PrefixReplace.find(";") != StringRef::npos); std::pair<StringRef, StringRef> Split = PrefixReplace.split(";"); OldPrefix = Split.first.str(); NewPrefix = Split.second.str(); }
// Print additional information about an address, if available. static void DumpAddress(uint64_t Address, ArrayRef<Section> Sections, MachOObject *MachOObj, raw_ostream &OS) { for (unsigned i = 0; i != Sections.size(); ++i) { uint64_t addr = Address-Sections[i].Address; if (Sections[i].Address <= Address && Sections[i].Address + Sections[i].Size > Address) { StringRef bytes = MachOObj->getData(Sections[i].Offset, Sections[i].Size); // Print constant strings. if (!strcmp(Sections[i].Name, "__cstring")) OS << '"' << bytes.substr(addr, bytes.find('\0', addr)) << '"'; // Print constant CFStrings. if (!strcmp(Sections[i].Name, "__cfstring")) OS << "@\"" << bytes.substr(addr, bytes.find('\0', addr)) << '"'; } } }
/// Match - Match the pattern string against the input buffer Buffer. This /// returns the position that is matched or npos if there is no match. If /// there is a match, the size of the matched string is returned in MatchLen. size_t Pattern::Match(StringRef Buffer, size_t &MatchLen, StringMap<StringRef> &VariableTable) const { // If this is a fixed string pattern, just match it now. if (!FixedStr.empty()) { MatchLen = FixedStr.size(); return Buffer.find(FixedStr); } // Regex match. // If there are variable uses, we need to create a temporary string with the // actual value. StringRef RegExToMatch = RegExStr; std::string TmpStr; if (!VariableUses.empty()) { TmpStr = RegExStr; unsigned InsertOffset = 0; for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) { StringMap<StringRef>::iterator it = VariableTable.find(VariableUses[i].first); // If the variable is undefined, return an error. if (it == VariableTable.end()) return StringRef::npos; // Look up the value and escape it so that we can plop it into the regex. std::string Value; AddFixedStringToRegEx(it->second, Value); // Plop it into the regex at the adjusted offset. TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset, Value.begin(), Value.end()); InsertOffset += Value.size(); } // Match the newly constructed regex. RegExToMatch = TmpStr; } SmallVector<StringRef, 4> MatchInfo; if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo)) return StringRef::npos; // Successful regex match. assert(!MatchInfo.empty() && "Didn't get any match"); StringRef FullMatch = MatchInfo[0]; // If this defines any variables, remember their values. for (unsigned i = 0, e = VariableDefs.size(); i != e; ++i) { assert(VariableDefs[i].second < MatchInfo.size() && "Internal paren error"); VariableTable[VariableDefs[i].first] = MatchInfo[VariableDefs[i].second]; } MatchLen = FullMatch.size(); return FullMatch.data()-Buffer.data(); }
// Try to find the first match in buffer for any prefix. If a valid match is // found, return that prefix and set its type and location. If there are almost // matches (e.g. the actual prefix string is found, but is not an actual check // string), but no valid match, return an empty string and set the position to // resume searching from. If no partial matches are found, return an empty // string and the location will be StringRef::npos. If one prefix is a substring // of another, the maximal match should be found. e.g. if "A" and "AA" are // prefixes then AA-CHECK: should match the second one. static StringRef FindFirstCandidateMatch(StringRef &Buffer, Check::CheckType &CheckTy, size_t &CheckLoc) { StringRef FirstPrefix; size_t FirstLoc = StringRef::npos; size_t SearchLoc = StringRef::npos; Check::CheckType FirstTy = Check::CheckNone; CheckTy = Check::CheckNone; CheckLoc = StringRef::npos; for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end(); I != E; ++I) { StringRef Prefix(*I); size_t PrefixLoc = Buffer.find(Prefix); if (PrefixLoc == StringRef::npos) continue; // Track where we are searching for invalid prefixes that look almost right. // We need to only advance to the first partial match on the next attempt // since a partial match could be a substring of a later, valid prefix. // Need to skip to the end of the word, otherwise we could end up // matching a prefix in a substring later. if (PrefixLoc < SearchLoc) SearchLoc = SkipWord(Buffer, PrefixLoc); // We only want to find the first match to avoid skipping some. if (PrefixLoc > FirstLoc) continue; // If one matching check-prefix is a prefix of another, choose the // longer one. if (PrefixLoc == FirstLoc && Prefix.size() < FirstPrefix.size()) continue; StringRef Rest = Buffer.drop_front(PrefixLoc); // Make sure we have actually found the prefix, and not a word containing // it. This should also prevent matching the wrong prefix when one is a // substring of another. if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1])) FirstTy = Check::CheckNone; else FirstTy = FindCheckType(Rest, Prefix); FirstLoc = PrefixLoc; FirstPrefix = Prefix; } // If the first prefix is invalid, we should continue the search after it. if (FirstTy == Check::CheckNone) { CheckLoc = SearchLoc; return ""; } CheckTy = FirstTy; CheckLoc = FirstLoc; return FirstPrefix; }
// Parses an argument of --defsym=<sym>=<sym> static bool parseDefsymAsAlias(StringRef opt, StringRef &sym, StringRef &target) { size_t equalPos = opt.find('='); if (equalPos == 0 || equalPos == StringRef::npos) return false; sym = opt.substr(0, equalPos); target = opt.substr(equalPos + 1); return !target.empty(); }
// Returns the line that the character S[Pos] is in. static StringRef getLine(StringRef S, size_t Pos) { size_t Begin = S.rfind('\n', Pos); size_t End = S.find('\n', Pos); Begin = (Begin == StringRef::npos) ? 0 : Begin + 1; if (End == StringRef::npos) End = S.size(); // rtrim for DOS-style newlines. return S.substr(Begin, End - Begin).rtrim(); }
bool TaskDebugBranchCheck::instru_fn(StringRef fn_name) { std::ifstream infile("functions.txt"); std::string line; while (std::getline(infile, line)) { if(fn_name.find(line) != StringRef::npos) return true; } return false; }
static void replaceObjcDeclarationsWithSwiftOnes(const Decl *D, StringRef Doc, raw_ostream &OS) { StringRef Open = "<Declaration>"; StringRef Close = "</Declaration>"; PrintOptions Options = PrintOptions::printQuickHelpDeclaration(); std::string S; llvm::raw_string_ostream SS(S); D->print(SS, Options); std::string Signature = SS.str(); auto OI = Doc.find(Open); auto CI = Doc.find(Close); if (StringRef::npos != OI && StringRef::npos != CI && CI > OI) OS << Doc.substr(0, OI) << Open << Signature << Close << Doc.substr(CI + Close.size()); else OS << Doc; }