/// \brief Parse \p Input as line sample. /// /// \param Input input line. /// \param IsCallsite true if the line represents an inlined callsite. /// \param Depth the depth of the inline stack. /// \param NumSamples total samples of the line/inlined callsite. /// \param LineOffset line offset to the start of the function. /// \param Discriminator discriminator of the line. /// \param TargetCountMap map from indirect call target to count. /// /// returns true if parsing is successful. static bool ParseLine(const StringRef &Input, bool &IsCallsite, unsigned &Depth, unsigned &NumSamples, unsigned &LineOffset, unsigned &Discriminator, StringRef &CalleeName, DenseMap<StringRef, unsigned> &TargetCountMap) { for (Depth = 0; Input[Depth] == ' '; Depth++) ; if (Depth == 0) return false; size_t n1 = Input.find(':'); StringRef Loc = Input.substr(Depth, n1 - Depth); size_t n2 = Loc.find('.'); if (n2 == StringRef::npos) { if (Loc.getAsInteger(10, LineOffset)) return false; Discriminator = 0; } else { if (Loc.substr(0, n2).getAsInteger(10, LineOffset)) return false; if (Loc.substr(n2 + 1).getAsInteger(10, Discriminator)) return false; } StringRef Rest = Input.substr(n1 + 2); if (Rest[0] >= '0' && Rest[0] <= '9') { IsCallsite = false; size_t n3 = Rest.find(' '); if (n3 == StringRef::npos) { if (Rest.getAsInteger(10, NumSamples)) return false; } else { if (Rest.substr(0, n3).getAsInteger(10, NumSamples)) return false; } while (n3 != StringRef::npos) { n3 += Rest.substr(n3).find_first_not_of(' '); Rest = Rest.substr(n3); n3 = Rest.find(' '); StringRef pair = Rest; if (n3 != StringRef::npos) { pair = Rest.substr(0, n3); } int n4 = pair.find(':'); unsigned count; if (pair.substr(n4 + 1).getAsInteger(10, count)) return false; TargetCountMap[pair.substr(0, n4)] = count; } } else { IsCallsite = true; int n3 = Rest.find_last_of(':'); CalleeName = Rest.substr(0, n3); if (Rest.substr(n3 + 1).getAsInteger(10, NumSamples)) return false; } return true; }
Error LLVMOutputStyle::dumpStreamData() { uint32_t StreamCount = File.getNumStreams(); StringRef DumpStreamStr = opts::raw::DumpStreamDataIdx; uint32_t DumpStreamNum; if (DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum)) return Error::success(); if (DumpStreamNum >= StreamCount) return make_error<RawError>(raw_error_code::no_stream); auto S = MappedBlockStream::createIndexedStream(DumpStreamNum, File); if (!S) return S.takeError(); codeview::StreamReader R(**S); while (R.bytesRemaining() > 0) { ArrayRef<uint8_t> Data; uint32_t BytesToReadInBlock = std::min( R.bytesRemaining(), static_cast<uint32_t>(File.getBlockSize())); if (auto EC = R.readBytes(Data, BytesToReadInBlock)) return EC; P.printBinaryBlock( "Data", StringRef(reinterpret_cast<const char *>(Data.begin()), Data.size())); } return Error::success(); }
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; }
/// Get an unsigned integer, including error checks. static unsigned getInt(StringRef R) { unsigned Result; bool error = R.getAsInteger(10, Result); (void)error; if (error) report_fatal_error("not a number, or does not fit in an unsigned int"); return Result; }
static void dumpStreamData(ScopedPrinter &P, PDBFile &File) { uint32_t StreamCount = File.getNumStreams(); StringRef DumpStreamStr = opts::DumpStreamData; uint32_t DumpStreamNum; if (DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum) || DumpStreamNum >= StreamCount) return; uint32_t StreamBytesRead = 0; uint32_t StreamSize = File.getStreamByteSize(DumpStreamNum); auto StreamBlocks = File.getStreamBlockList(DumpStreamNum); for (uint32_t StreamBlockAddr : StreamBlocks) { uint32_t BytesLeftToReadInStream = StreamSize - StreamBytesRead; if (BytesLeftToReadInStream == 0) break; uint32_t BytesToReadInBlock = std::min( BytesLeftToReadInStream, static_cast<uint32_t>(File.getBlockSize())); auto StreamBlockData = File.getBlockData(StreamBlockAddr, BytesToReadInBlock); outs() << StreamBlockData; StreamBytesRead += StreamBlockData.size(); } }
void Decompiler::decompile(unsigned Address) { std::vector<unsigned> Children; Children.push_back(Address); do { Function* CurFunc = decompileFunction(Children.back()); Children.pop_back(); if (CurFunc == NULL) { continue; } // Scan Current Function for children (should probably record children // during decompile...) for (Function::iterator BI = CurFunc->begin(), BE = CurFunc->end(); BI != BE; ++BI) { for (BasicBlock::iterator I = BI->begin(), E = BI->end(); I != E; ++I) { CallInst *CI = dyn_cast<CallInst>(I); if (CI == NULL || !CI->getCalledFunction()->hasFnAttribute("Address")) { continue; } StringRef AddrStr = CI->getCalledFunction()->getFnAttribute("Address").getValueAsString(); uint64_t Addr; AddrStr.getAsInteger(10, Addr); DEBUG(outs() << "Read Address as: " << format("%1" PRIx64, Addr) << ", " << AddrStr << "\n"); StringRef FName = Dis->getFunctionName(Addr); Function *NF = Mod->getFunction(FName); if (Addr != 0 && (NF == NULL || NF->empty())) { Children.push_back(Addr); } } } } while (Children.size() != 0); // While there are children, decompile }
/// \brief Attempt to read the lock file with the given name, if it exists. /// /// \param LockFileName The name of the lock file to read. /// /// \returns The process ID of the process that owns this lock file Optional<std::pair<std::string, int> > LockFileManager::readLockFile(StringRef LockFileName) { // Check whether the lock file exists. If not, clearly there's nothing // to read, so we just return. if (!sys::fs::exists(LockFileName)) return None; // Read the owning host and PID out of the lock file. If it appears that the // owning process is dead, the lock file is invalid. OwningPtr<MemoryBuffer> MB; if (MemoryBuffer::getFile(LockFileName, MB)) return None; StringRef Hostname; StringRef PIDStr; std::tie(Hostname, PIDStr) = getToken(MB->getBuffer(), " "); PIDStr = PIDStr.substr(PIDStr.find_first_not_of(" ")); int PID; if (!PIDStr.getAsInteger(10, PID)) return std::make_pair(std::string(Hostname), PID); // Delete the lock file. It's invalid anyway. sys::fs::remove(LockFileName); return None; }
// parser<unsigned long long> implementation // bool parser<unsigned long long>::parse(Option &O, StringRef ArgName, StringRef Arg, unsigned long long &Value){ if (Arg.getAsInteger(0, Value)) return O.error("'" + Arg + "' value invalid for uint argument!"); return false; }
IntegerConstantExpr::IntegerConstantExpr(ASTContext &C, SMLoc Loc, StringRef Data) : ConstantExpr(IntegerConstant, C.IntegerTy, Loc) { llvm::APSInt Val(64); Data.getAsInteger(10, Val); Num.setValue(C, Val); }
/// \brief Attempt to read the lock file with the given name, if it exists. /// /// \param LockFileName The name of the lock file to read. /// /// \returns The process ID of the process that owns this lock file Optional<std::pair<std::string, int> > LockFileManager::readLockFile(StringRef LockFileName) { // Read the owning host and PID out of the lock file. If it appears that the // owning process is dead, the lock file is invalid. std::unique_ptr<MemoryBuffer> MB; if (MemoryBuffer::getFile(LockFileName, MB)) { sys::fs::remove(LockFileName); return None; } StringRef Hostname; StringRef PIDStr; std::tie(Hostname, PIDStr) = getToken(MB->getBuffer(), " "); PIDStr = PIDStr.substr(PIDStr.find_first_not_of(" ")); int PID; if (!PIDStr.getAsInteger(10, PID)) { auto Owner = std::make_pair(std::string(Hostname), PID); if (processStillExecuting(Owner.first, Owner.second)) return Owner; } // Delete the lock file. It's invalid anyway. sys::fs::remove(LockFileName); return None; }
typename llvm::enable_if_c<std::numeric_limits<T>::is_integer, bool>::type getAs(const llvm::yaml::ScalarNode *SN, T &Result) { SmallString<4> Storage; StringRef Value = SN->getValue(Storage); if (Value.getAsInteger(0, Result)) return false; return true; }
static Optional<int> parseDevirtPassName(StringRef Name) { if (!Name.consume_front("devirt<") || !Name.consume_back(">")) return None; int Count; if (Name.getAsInteger(0, Count) || Count <= 0) return None; return Count; }
unsigned ArchiveMemberHeader::getGID() const { unsigned Ret; StringRef Group = StringRef(ArMemHdr->GID, sizeof(ArMemHdr->GID)).rtrim(' '); if (Group.empty()) return 0; if (Group.getAsInteger(10, Ret)) llvm_unreachable("GID time not a decimal number."); return Ret; }
/// isValidGCCRegisterName - Returns whether the passed in string /// is a valid register name according to GCC. This is used by Sema for /// inline asm statements. bool TargetInfo::isValidGCCRegisterName(StringRef Name) const { if (Name.empty()) return false; const char * const *Names; unsigned NumNames; // Get rid of any register prefix. Name = removeGCCRegisterPrefix(Name); if (Name.empty()) return false; getGCCRegNames(Names, NumNames); // If we have a number it maps to an entry in the register name array. if (isDigit(Name[0])) { int n; if (!Name.getAsInteger(0, n)) return n >= 0 && (unsigned)n < NumNames; } // Check register names. for (unsigned i = 0; i < NumNames; i++) { if (Name == Names[i]) return true; } // Check any additional names that we have. const AddlRegName *AddlNames; unsigned NumAddlNames; getGCCAddlRegNames(AddlNames, NumAddlNames); for (unsigned i = 0; i < NumAddlNames; i++) for (unsigned j = 0; j < llvm::array_lengthof(AddlNames[i].Names); j++) { if (!AddlNames[i].Names[j]) break; // Make sure the register that the additional name is for is within // the bounds of the register names from above. if (AddlNames[i].Names[j] == Name && AddlNames[i].RegNum < NumNames) return true; } // Now check aliases. const GCCRegAlias *Aliases; unsigned NumAliases; getGCCRegAliases(Aliases, NumAliases); for (unsigned i = 0; i < NumAliases; i++) { for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) { if (!Aliases[i].Aliases[j]) break; if (Aliases[i].Aliases[j] == Name) return true; } } return false; }
/// \brief Load samples from a text file. /// /// The file is divided in two segments: /// /// Symbol table (represented with the string "symbol table") /// Number of symbols in the table /// symbol 1 /// symbol 2 /// ... /// symbol N /// /// Function body profiles /// function1:total_samples:total_head_samples:number_of_locations /// location_offset_1: number_of_samples /// location_offset_2: number_of_samples /// ... /// location_offset_N: number_of_samples /// /// Function names must be mangled in order for the profile loader to /// match them in the current translation unit. /// /// Since this is a flat profile, a function that shows up more than /// once gets all its samples aggregated across all its instances. /// TODO - flat profiles are too imprecise to provide good optimization /// opportunities. Convert them to context-sensitive profile. /// /// This textual representation is useful to generate unit tests and /// for debugging purposes, but it should not be used to generate /// profiles for large programs, as the representation is extremely /// inefficient. void SampleProfile::loadText() { ExternalProfileTextLoader Loader(Filename); // Read the symbol table. StringRef Line = Loader.readLine(); if (Line != "symbol table") Loader.reportParseError("Expected 'symbol table', found " + Line); int NumSymbols; Line = Loader.readLine(); if (Line.getAsInteger(10, NumSymbols)) Loader.reportParseError("Expected a number, found " + Line); for (int I = 0; I < NumSymbols; I++) { StringRef FName = Loader.readLine(); FunctionProfile &FProfile = Profiles[FName]; FProfile.BodySamples.clear(); FProfile.TotalSamples = 0; FProfile.TotalHeadSamples = 0; } // Read the profile of each function. Since each function may be // mentioned more than once, and we are collecting flat profiles, // accumulate samples as we parse them. Regex HeadRE("^([^:]+):([0-9]+):([0-9]+):([0-9]+)$"); Regex LineSample("^([0-9]+): ([0-9]+)$"); while (!Loader.atEOF()) { SmallVector<StringRef, 4> Matches; Line = Loader.readLine(); if (!HeadRE.match(Line, &Matches)) Loader.reportParseError("Expected 'mangled_name:NUM:NUM:NUM', found " + Line); assert(Matches.size() == 5); StringRef FName = Matches[1]; unsigned NumSamples, NumHeadSamples, NumSampledLines; Matches[2].getAsInteger(10, NumSamples); Matches[3].getAsInteger(10, NumHeadSamples); Matches[4].getAsInteger(10, NumSampledLines); FunctionProfile &FProfile = Profiles[FName]; FProfile.TotalSamples += NumSamples; FProfile.TotalHeadSamples += NumHeadSamples; BodySampleMap &SampleMap = FProfile.BodySamples; unsigned I; for (I = 0; I < NumSampledLines && !Loader.atEOF(); I++) { Line = Loader.readLine(); if (!LineSample.match(Line, &Matches)) Loader.reportParseError("Expected 'NUM: NUM', found " + Line); assert(Matches.size() == 3); unsigned LineOffset, NumSamples; Matches[1].getAsInteger(10, LineOffset); Matches[2].getAsInteger(10, NumSamples); SampleMap[LineOffset] += NumSamples; } if (I < NumSampledLines) Loader.reportParseError("Unexpected end of file"); } }
// Parses -z max-page-size=<value> static bool parseMaxPageSize(StringRef opt, uint64_t &val) { size_t equalPos = opt.find('='); if (equalPos == 0 || equalPos == StringRef::npos) return false; StringRef value = opt.substr(equalPos + 1); val = 0; if (value.getAsInteger(0, val) || !val) return false; return true; }
static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { unsigned flags = 0; // If a valid numerical value is set for the section flag, use it verbatim if (!flagsStr.getAsInteger(0, flags)) return flags; for (char i : flagsStr) { switch (i) { case 'a': flags |= ELF::SHF_ALLOC; break; case 'e': flags |= ELF::SHF_EXCLUDE; break; case 'x': flags |= ELF::SHF_EXECINSTR; break; case 'w': flags |= ELF::SHF_WRITE; break; case 'o': flags |= ELF::SHF_LINK_ORDER; break; case 'M': flags |= ELF::SHF_MERGE; break; case 'S': flags |= ELF::SHF_STRINGS; break; case 'T': flags |= ELF::SHF_TLS; break; case 'c': flags |= ELF::XCORE_SHF_CP_SECTION; break; case 'd': flags |= ELF::XCORE_SHF_DP_SECTION; break; case 'y': flags |= ELF::SHF_ARM_PURECODE; break; case 'G': flags |= ELF::SHF_GROUP; break; case '?': *UseLastGroup = true; break; default: return -1U; } } return flags; }
void ArrayOrderPass::perform(std::unique_ptr<MutableFile> &f) { auto definedAtoms = f->definedAtoms(); // Move sections need to be sorted into the separate continious group. // That reduces a number of sorting elements and simplifies conditions // in the sorting predicate. auto last = std::stable_partition(definedAtoms.begin(), definedAtoms.end(), [](const DefinedAtom *atom) { if (atom->sectionChoice() != DefinedAtom::sectionCustomRequired) return false; StringRef name = atom->customSectionName(); return name.startswith(".init_array") || name.startswith(".fini_array"); }); std::stable_sort(definedAtoms.begin(), last, [](const DefinedAtom *left, const DefinedAtom *right) { StringRef leftSec = left->customSectionName(); StringRef rightSec = right->customSectionName(); // Drop the front dot from the section name and get // an optional section's number starting after the second dot. StringRef leftNum = leftSec.drop_front().rsplit('.').second; StringRef rightNum = rightSec.drop_front().rsplit('.').second; // Sort {.init_array, .fini_array}[.<num>] sections // according to their number. Sections without optional // numer suffix should go last. uint32_t leftPriority = std::numeric_limits<uint32_t>::max(); if (!leftNum.empty()) leftNum.getAsInteger(10, leftPriority); uint32_t rightPriority = std::numeric_limits<uint32_t>::max(); if (!rightNum.empty()) rightNum.getAsInteger(10, rightPriority); return leftPriority < rightPriority; }); }
StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const { assert(isValidGCCRegisterName(Name) && "Invalid register passed in"); // Get rid of any register prefix. Name = removeGCCRegisterPrefix(Name); const char * const *Names; unsigned NumNames; getGCCRegNames(Names, NumNames); // First, check if we have a number. if (isdigit(Name[0])) { int n; if (!Name.getAsInteger(0, n)) { assert(n >= 0 && (unsigned)n < NumNames && "Out of bounds register number!"); return Names[n]; } } // Check any additional names that we have. const AddlRegName *AddlNames; unsigned NumAddlNames; getGCCAddlRegNames(AddlNames, NumAddlNames); for (unsigned i = 0; i < NumAddlNames; i++) for (unsigned j = 0; j < llvm::array_lengthof(AddlNames[i].Names); j++) { if (!AddlNames[i].Names[j]) break; // Make sure the register that the additional name is for is within // the bounds of the register names from above. if (AddlNames[i].Names[j] == Name && AddlNames[i].RegNum < NumNames) return Name; } // Now check aliases. const GCCRegAlias *Aliases; unsigned NumAliases; getGCCRegAliases(Aliases, NumAliases); for (unsigned i = 0; i < NumAliases; i++) { for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) { if (!Aliases[i].Aliases[j]) break; if (Aliases[i].Aliases[j] == Name) return Aliases[i].Register; } } return Name; }
/// Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, OffsetOption &Val) { if (Arg == "") { Val.Val = 0; Val.HasValue = false; Val.IsRequested = true; return false; } if (Arg.getAsInteger(0, Val.Val)) return O.error("'" + Arg + "' value invalid for integer argument!"); Val.HasValue = true; Val.IsRequested = true; return false; }
static unsigned getIntegerAttribute(const Function &F, const char *Name, unsigned Default) { Attribute A = F.getFnAttribute(Name); unsigned Result = Default; if (A.isStringAttribute()) { StringRef Str = A.getValueAsString(); if (Str.getAsInteger(0, Result)) { LLVMContext &Ctx = F.getContext(); Ctx.emitError("can't parse shader type"); } } return Result; }
int getIntegerAttribute(const Function &F, StringRef Name, int Default) { Attribute A = F.getFnAttribute(Name); int Result = Default; if (A.isStringAttribute()) { StringRef Str = A.getValueAsString(); if (Str.getAsInteger(0, Result)) { LLVMContext &Ctx = F.getContext(); Ctx.emitError("can't parse integer attribute " + Name); } } return Result; }
AMDGPUMachineFunction::AMDGPUMachineFunction(const MachineFunction &MF) : MachineFunctionInfo() { ShaderType = ShaderType::COMPUTE; LDSSize = 0; AttributeSet Set = MF.getFunction()->getAttributes(); Attribute A = Set.getAttribute(AttributeSet::FunctionIndex, ShaderTypeAttribute); if (A.isStringAttribute()) { StringRef Str = A.getValueAsString(); if (Str.getAsInteger(0, ShaderType)) llvm_unreachable("Can't parse shader type!"); } }
std::vector<uint8_t> ScriptParserBase::parseHex(StringRef S) { std::vector<uint8_t> Hex; while (!S.empty()) { StringRef B = S.substr(0, 2); S = S.substr(2); uint8_t H; if (B.getAsInteger(16, H)) { setError("not a hexadecimal value: " + B); return {}; } Hex.push_back(H); } return Hex; }
Optional<Version> Version::parseVersionString(StringRef VersionString, SourceLoc Loc, DiagnosticEngine *Diags) { Version TheVersion; SmallString<16> digits; llvm::raw_svector_ostream OS(digits); SmallVector<std::pair<StringRef, SourceRange>, 5> SplitComponents; // Skip over quote character in string literal. if (VersionString.empty()) { if (Diags) Diags->diagnose(Loc, diag::empty_version_string); return None; } splitVersionComponents(SplitComponents, VersionString, Loc, Diags); uint64_t ComponentNumber; bool isValidVersion = true; for (size_t i = 0; i < SplitComponents.size(); ++i) { StringRef SplitComponent; SourceRange Range; std::tie(SplitComponent, Range) = SplitComponents[i]; // Version components can't be empty. if (SplitComponent.empty()) { if (Diags) Diags->diagnose(Range.Start, diag::empty_version_component); isValidVersion = false; continue; } // All other version components must be numbers. if (!SplitComponent.getAsInteger(10, ComponentNumber)) { TheVersion.Components.push_back(ComponentNumber); continue; } else { if (Diags) Diags->diagnose(Range.Start, diag::version_component_not_number); isValidVersion = false; } } return isValidVersion ? Optional<Version>(TheVersion) : None; }
Optional<unsigned> HexagonToolChain::getSmallDataThreshold( const ArgList &Args) { StringRef Gn = ""; if (Arg *A = Args.getLastArg(options::OPT_G)) { Gn = A->getValue(); } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic, options::OPT_fPIC)) { Gn = "0"; } unsigned G; if (!Gn.getAsInteger(10, G)) return G; return None; }
static std::map<void *, uint64_t> applySpecificSectionMappings(RuntimeDyldChecker &Checker) { std::map<void*, uint64_t> SpecificMappings; for (StringRef Mapping : SpecificSectionMappings) { size_t EqualsIdx = Mapping.find_first_of("="); StringRef SectionIDStr = Mapping.substr(0, EqualsIdx); size_t ComaIdx = Mapping.find_first_of(","); if (ComaIdx == StringRef::npos) { errs() << "Invalid section specification '" << Mapping << "'. Should be '<file name>,<section name>=<addr>'\n"; exit(1); } StringRef FileName = SectionIDStr.substr(0, ComaIdx); StringRef SectionName = SectionIDStr.substr(ComaIdx + 1); uint64_t OldAddrInt; std::string ErrorMsg; std::tie(OldAddrInt, ErrorMsg) = Checker.getSectionAddr(FileName, SectionName, true); if (ErrorMsg != "") { errs() << ErrorMsg; exit(1); } void* OldAddr = reinterpret_cast<void*>(static_cast<uintptr_t>(OldAddrInt)); StringRef NewAddrStr = Mapping.substr(EqualsIdx + 1); uint64_t NewAddr; if (NewAddrStr.getAsInteger(0, NewAddr)) { errs() << "Invalid section address in mapping: " << Mapping << "\n"; exit(1); } Checker.getRTDyld().mapSectionAddress(OldAddr, NewAddr); SpecificMappings[OldAddr] = NewAddr; } return SpecificMappings; }
static bool ByteArrayFromString(ByteArrayTy &ByteArray, StringRef &Str, SourceMgr &SM) { while (!Str.empty()) { // Strip horizontal whitespace. if (size_t Pos = Str.find_first_not_of(" \t\r")) { Str = Str.substr(Pos); continue; } // If this is the end of a line or start of a comment, remove the rest of // the line. if (Str[0] == '\n' || Str[0] == '#') { // Strip to the end of line if we already processed any bytes on this // line. This strips the comment and/or the \n. if (Str[0] == '\n') { Str = Str.substr(1); } else { Str = Str.substr(Str.find_first_of('\n')); if (!Str.empty()) Str = Str.substr(1); } continue; } // 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.clear(); continue; } ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data())); Str = Str.substr(Next); } return false; }
bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const { // The only supported expression is @LINE([\+-]\d+)? if (!Expr.startswith("@LINE")) return false; Expr = Expr.substr(StringRef("@LINE").size()); int Offset = 0; if (!Expr.empty()) { if (Expr[0] == '+') Expr = Expr.substr(1); else if (Expr[0] != '-') return false; if (Expr.getAsInteger(10, Offset)) return false; } Value = llvm::itostr(LineNumber + Offset); return true; }
int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal, const CheckerBase *C, bool SearchInParents) { SmallString<10> StrBuf; llvm::raw_svector_ostream OS(StrBuf); OS << DefaultVal; StringRef V = C ? getCheckerOption(C->getTagDescription(), Name, OS.str(), SearchInParents) : StringRef(Config.insert(std::make_pair(Name, OS.str())) .first->second); int Res = DefaultVal; bool b = V.getAsInteger(10, Res); assert(!b && "analyzer-config option should be numeric"); (void)b; return Res; }