static void ParseProgName(SmallVectorImpl<const char *> &ArgVector, std::set<std::string> &SavedStrings) { // Try to infer frontend type and default target from the program name by // comparing it against DriverSuffixes in order. // If there is a match, the function tries to identify a target as prefix. // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target // prefix "x86_64-linux". If such a target prefix is found, is gets added via // -target as implicit first argument. std::string ProgName =llvm::sys::path::stem(ArgVector[0]); #ifdef LLVM_ON_WIN32 // Transform to lowercase for case insensitive file systems. ProgName = StringRef(ProgName).lower(); #endif StringRef ProgNameRef = ProgName; const DriverSuffix *DS = FindDriverSuffix(ProgNameRef); if (!DS) { // Try again after stripping any trailing version number: // clang++3.5 -> clang++ ProgNameRef = ProgNameRef.rtrim("0123456789."); DS = FindDriverSuffix(ProgNameRef); } if (!DS) { // Try again after stripping trailing -component. // clang++-tot -> clang++ ProgNameRef = ProgNameRef.slice(0, ProgNameRef.rfind('-')); DS = FindDriverSuffix(ProgNameRef); } if (DS) { if (const char *Flag = DS->ModeFlag) { // Add Flag to the arguments. auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; ArgVector.insert(it, Flag); } StringRef::size_type LastComponent = ProgNameRef.rfind( '-', ProgNameRef.size() - strlen(DS->Suffix)); if (LastComponent == StringRef::npos) return; // Infer target from the prefix. StringRef Prefix = ProgNameRef.slice(0, LastComponent); std::string IgnoredError; if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; const char *arr[] = { "-target", GetStableCStr(SavedStrings, Prefix) }; ArgVector.insert(it, std::begin(arr), std::end(arr)); } } }
/// \brief Parse \p Input as function head. /// /// Parse one line of \p Input, and update function name in \p FName, /// function's total sample count in \p NumSamples, function's entry /// count in \p NumHeadSamples. /// /// \returns true if parsing is successful. static bool ParseHead(const StringRef &Input, StringRef &FName, unsigned &NumSamples, unsigned &NumHeadSamples) { if (Input[0] == ' ') return false; size_t n2 = Input.rfind(':'); size_t n1 = Input.rfind(':', n2 - 1); FName = Input.substr(0, n1); if (Input.substr(n1 + 1, n2 - n1 - 1).getAsInteger(10, NumSamples)) return false; if (Input.substr(n2 + 1).getAsInteger(10, NumHeadSamples)) return false; return true; }
static void insertArgsFromProgramName(StringRef ProgName, const DriverSuffix *DS, SmallVectorImpl<const char *> &ArgVector, std::set<std::string> &SavedStrings) { if (!DS) return; if (const char *Flag = DS->ModeFlag) { // Add Flag to the arguments. auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; ArgVector.insert(it, Flag); } StringRef::size_type LastComponent = ProgName.rfind( '-', ProgName.size() - strlen(DS->Suffix)); if (LastComponent == StringRef::npos) return; // Infer target from the prefix. StringRef Prefix = ProgName.slice(0, LastComponent); std::string IgnoredError; if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; const char *arr[] = { "-target", GetStableCStr(SavedStrings, Prefix) }; ArgVector.insert(it, std::begin(arr), std::end(arr)); } }
BOZConstantExpr::BOZConstantExpr(ASTContext &C, SMLoc Loc, StringRef Data) : ConstantExpr(BOZConstant, C.IntegerTy, Loc) { unsigned Radix = 0; switch (Data[0]) { case 'B': Kind = Binary; Radix = 2; break; case 'O': Kind = Octal; Radix = 8; break; case 'Z': case 'X': Kind = Hexadecimal; Radix = 16; break; } size_t LastQuote = Data.rfind(Data[1]); assert(LastQuote == StringRef::npos && "Invalid BOZ constant!"); llvm::StringRef NumStr = Data.slice(2, LastQuote); APInt Val; NumStr.getAsInteger(Radix, Val); Num.setValue(C, Val); }
void MinimalAction::ActOnImportSpec(SourceLocation PathLoc, StringRef ImportPath, IdentifierInfo *LocalName, bool IsLocal) { if (IsLocal) // FIXME: This should insert all exported symbols in ImportPath into the // current file's file scope. return; TypeNameInfoTable &TNIT = *getTable(TypeNameInfoTablePtr); if (LocalName) { // FIXME: This should insert all exported symbols in ImportPath into // LocalName's scope. TNIT.AddEntry(Action::IIT_Package, LocalName); TUScope->AddDecl(DeclPtrTy::make(LocalName)); return; } // FIXME: The right thing to do here is to load the package file pointed to // by ImportPath and get the `package` identifier used therein. As an // approximation, just grab the last path component off ImportPath. ImportPath = ImportPath.slice(1, ImportPath.size() - 1); // Strip "" size_t SlashPos = ImportPath.rfind('/'); if (SlashPos != StringRef::npos) ImportPath = ImportPath.substr(SlashPos + 1); TNIT.AddEntry(Action::IIT_Package, &Idents.get(ImportPath)); TUScope->AddDecl(DeclPtrTy::make(&Idents.get(ImportPath))); }
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); }
/// Turn an offset in Code into a [line, column] pair. Position clangd::offsetToPosition(StringRef Code, size_t Offset) { StringRef JustBefore = Code.substr(0, Offset); // FIXME: \r\n // FIXME: UTF-8 int Lines = JustBefore.count('\n'); int Cols = JustBefore.size() - JustBefore.rfind('\n') - 1; return {Lines, Cols}; }
bool Module::findPrimaryDefn() { StringRef primaryName = qname_; size_t dot = primaryName.rfind('.'); if (dot != primaryName.npos) { primaryName = primaryName.substr(dot + 1, primaryName.npos); } return IterableScope::lookupMember(primaryName, primaryDefs_, false); }
// Returns a whole line containing the current token. StringRef ScriptParserBase::getLine() { StringRef S = getCurrentMB().getBuffer(); StringRef Tok = Tokens[Pos - 1]; size_t Pos = S.rfind('\n', Tok.data() - S.data()); if (Pos != StringRef::npos) S = S.substr(Pos + 1); return S.substr(0, S.find_first_of("\r\n")); }
// If an input string is in the form of "foo.N" where N is a number, // return N. Otherwise, returns 65536, which is one greater than the // lowest priority. int elf::getPriority(StringRef S) { size_t Pos = S.rfind('.'); if (Pos == StringRef::npos) return 65536; int V; if (!to_integer(S.substr(Pos + 1), V, 10)) return 65536; return V; }
// 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(); }
void Module::setQualifiedName(StringRef qual) { qname_ = qual; size_t dot = qual.rfind('.'); if (dot == qual.npos) { name_ = moduleStrings_.intern(qual); packageName_.clear(); } else { name_ = moduleStrings_.intern(qual.substr(dot + 1, qual.npos)); packageName_ = qual.substr(0, dot); } }
Symbol symbol(StringRef QName) { Symbol Sym; Sym.ID = SymbolID(QName.str()); size_t Pos = QName.rfind("::"); if (Pos == StringRef::npos) { Sym.Name = QName; Sym.Scope = ""; } else { Sym.Name = QName.substr(Pos + 2); Sym.Scope = QName.substr(0, Pos + 2); } return Sym; }
BreakableToken::Split getStringSplit(StringRef Text, unsigned ContentStartColumn, unsigned ColumnLimit) { if (ColumnLimit <= ContentStartColumn) return BreakableToken::Split(StringRef::npos, 0); unsigned MaxSplit = ColumnLimit - ContentStartColumn; // FIXME: Reduce unit test case. if (Text.empty()) return BreakableToken::Split(StringRef::npos, 0); MaxSplit = std::min<unsigned>(MaxSplit, Text.size() - 1); StringRef::size_type SpaceOffset = Text.rfind(' ', MaxSplit); if (SpaceOffset != StringRef::npos && SpaceOffset != 0) return BreakableToken::Split(SpaceOffset + 1, 0); StringRef::size_type SlashOffset = Text.rfind('/', MaxSplit); if (SlashOffset != StringRef::npos && SlashOffset != 0) return BreakableToken::Split(SlashOffset + 1, 0); StringRef::size_type SplitPoint = getStartOfCharacter(Text, MaxSplit); if (SplitPoint == StringRef::npos || SplitPoint == 0) return BreakableToken::Split(StringRef::npos, 0); return BreakableToken::Split(SplitPoint, 0); }
bool ObjCRuntime::tryParse(StringRef input) { // Look for the last dash. std::size_t dash = input.rfind('-'); // We permit dashes in the runtime name, and we also permit the // version to be omitted, so if we see a dash not followed by a // digit then we need to ignore it. if (dash != StringRef::npos && dash + 1 != input.size() && (input[dash+1] < '0' || input[dash+1] > '9')) { dash = StringRef::npos; } // Everything prior to that must be a valid string name. Kind kind; StringRef runtimeName = input.substr(0, dash); Version = VersionTuple(0); if (runtimeName == "macosx") { kind = ObjCRuntime::MacOSX; } else if (runtimeName == "macosx-fragile") { kind = ObjCRuntime::FragileMacOSX; } else if (runtimeName == "ios") { kind = ObjCRuntime::iOS; } else if (runtimeName == "gnustep") { // If no version is specified then default to the most recent one that we // know about. Version = VersionTuple(1, 6); kind = ObjCRuntime::GNUstep; } else if (runtimeName == "gcc") { kind = ObjCRuntime::GCC; } else if (runtimeName == "objfw") { kind = ObjCRuntime::ObjFW; Version = VersionTuple(0, 8); } else if (runtimeName == "host") { kind = ObjCRuntime::Host; } else { return true; } TheKind = kind; if (dash != StringRef::npos) { StringRef verString = input.substr(dash + 1); if (Version.tryParse(verString)) return true; } if (kind == ObjCRuntime::ObjFW && Version > VersionTuple(0, 8)) Version = VersionTuple(0, 8); return false; }
// Path fits in a Ustar header if // // - Path is less than 100 characters long, or // - Path is in the form of "<prefix>/<name>" where <prefix> is less // than or equal to 155 characters long and <name> is less than 100 // characters long. Both <prefix> and <name> can contain extra '/'. // // If Path fits in a Ustar header, updates Prefix and Name and returns true. // Otherwise, returns false. static bool splitUstar(StringRef Path, StringRef &Prefix, StringRef &Name) { if (Path.size() < sizeof(UstarHeader::Name)) { Prefix = ""; Name = Path; return true; } size_t Sep = Path.rfind('/', sizeof(UstarHeader::Prefix) + 1); if (Sep == StringRef::npos) return false; if (Path.size() - Sep - 1 >= sizeof(UstarHeader::Name)) return false; Prefix = Path.substr(0, Sep); Name = Path.substr(Sep + 1); return true; }
StringRef AnalyzerOptions::getCheckerOption(StringRef CheckerName, StringRef OptionName, StringRef Default, bool SearchInParents) { // Search for a package option if the option for the checker is not specified // and search in parents is enabled. ConfigTable::const_iterator E = Config.end(); do { ConfigTable::const_iterator I = Config.find((Twine(CheckerName) + ":" + OptionName).str()); if (I != E) return StringRef(I->getValue()); size_t Pos = CheckerName.rfind('.'); if (Pos == StringRef::npos) return Default; CheckerName = CheckerName.substr(0, Pos); } while (!CheckerName.empty() && SearchInParents); return Default; }
bool NyuziAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) { size_t dotLoc = Name.find('.'); StringRef stem = Name.substr(0, dotLoc); Operands.push_back(NyuziOperand::createToken(stem, NameLoc)); if (dotLoc < Name.size()) { size_t dotLoc2 = Name.rfind('.'); if (dotLoc == dotLoc2) Operands.push_back( NyuziOperand::createToken(Name.substr(dotLoc), NameLoc)); else { Operands.push_back(NyuziOperand::createToken( Name.substr(dotLoc, dotLoc2 - dotLoc), NameLoc)); Operands.push_back( NyuziOperand::createToken(Name.substr(dotLoc2), NameLoc)); } } // If there are no more operands, then finish // XXX hash should start a comment, should the lexer just be consuming that? if (getLexer().is(AsmToken::EndOfStatement) || getLexer().is(AsmToken::Hash)) return false; // parse operands for (;;) { if (ParseOperand(Operands, stem)) return true; if (getLexer().isNot(AsmToken::Comma)) break; // Consume comma token getLexer().Lex(); } return false; }
bool swift::omitNeedlessWords(StringRef &baseName, MutableArrayRef<StringRef> argNames, StringRef firstParamName, OmissionTypeName resultType, OmissionTypeName contextType, ArrayRef<OmissionTypeName> paramTypes, bool returnsSelf, bool isProperty, const InheritedNameSet *allPropertyNames, StringScratchSpace &scratch) { bool anyChanges = false; /// Local function that lowercases all of the base names and /// argument names before returning. auto lowercaseAcronymsForReturn = [&] { StringRef newBaseName = toLowercaseWordAndAcronym(baseName, scratch); if (baseName.data() != newBaseName.data()) { baseName = newBaseName; anyChanges = true; } for (StringRef &argName : argNames) { StringRef newArgName = toLowercaseWordAndAcronym(argName, scratch); if (argName.data() != newArgName.data()) { argName = newArgName; anyChanges = true; } } return anyChanges; }; // If the result type matches the context, remove the context type from the // prefix of the name. bool resultTypeMatchesContext = returnsSelf || (resultType == contextType); if (resultTypeMatchesContext) { StringRef newBaseName = omitNeedlessWordsFromPrefix(baseName, contextType, scratch); if (newBaseName != baseName) { baseName = newBaseName; anyChanges = true; } } // Strip the context type from the base name of a method. if (!isProperty) { StringRef newBaseName = ::omitNeedlessWords(baseName, contextType, NameRole::BaseNameSelf, nullptr, scratch); if (newBaseName != baseName) { baseName = newBaseName; anyChanges = true; } } if (paramTypes.empty()) { if (resultTypeMatchesContext) { StringRef newBaseName = ::omitNeedlessWords( baseName, returnsSelf ? contextType : resultType, NameRole::Property, allPropertyNames, scratch); if (newBaseName != baseName) { baseName = newBaseName; anyChanges = true; } } return lowercaseAcronymsForReturn(); } // Omit needless words based on parameter types. for (unsigned i = 0, n = argNames.size(); i != n; ++i) { // If there is no corresponding parameter, there is nothing to // omit. if (i >= paramTypes.size()) continue; // Omit needless words based on the type of the parameter. NameRole role = i > 0 ? NameRole::SubsequentParameter : argNames[0].empty() ? NameRole::BaseName : NameRole::FirstParameter; // Omit needless words from the name. StringRef name = role == NameRole::BaseName ? baseName : argNames[i]; StringRef newName = ::omitNeedlessWords(name, paramTypes[i], role, role == NameRole::BaseName ? allPropertyNames : nullptr, scratch); // Did the name change? if (name != newName) anyChanges = true; // If the first parameter has a default argument, and there is a // preposition in the base name, split the base name at that preposition. if (role == NameRole::BaseName && argNames[0].empty() && paramTypes[0].hasDefaultArgument()) { // Scan backwards for a preposition. auto nameWords = camel_case::getWords(newName); auto nameWordRevIter = nameWords.rbegin(), nameWordRevIterEnd = nameWords.rend(); bool found = false, done = false; while (nameWordRevIter != nameWordRevIterEnd && !done) { switch (getPartOfSpeech(*nameWordRevIter)) { case PartOfSpeech::Preposition: found = true; done = true; break; case PartOfSpeech::Verb: case PartOfSpeech::Gerund: // Don't skip over verbs or gerunds. done = true; break; case PartOfSpeech::Unknown: ++nameWordRevIter; break; } } // If we found a split point that's not at the beginning of the // name, split there. if (found) { ++nameWordRevIter; unsigned splitPos = nameWordRevIter.base().getPosition(); if (splitPos > 0) { unsigned afterSplitPos = splitPos; // Create a first argument name with the remainder of the base name, // lowercased. If we would end up with a vacuous name, go // back and get the original. StringRef newArgName = newName.substr(afterSplitPos); if (isVacuousName(newArgName)) { size_t pos = name.rfind(newArgName); newArgName = name.substr(pos); } // If there is a leading "with" on the first argument, drop it. if (newArgName.size() > 4 && camel_case::sameWordIgnoreFirstCase( camel_case::getFirstWord(newArgName), "with")) { newArgName = newArgName.substr(4); } argNames[0] = toLowercaseWord(newArgName, scratch); // Update the base name by splitting at the preposition. newName = newName.substr(0, splitPos); anyChanges = true; } } } if (name == newName) continue; // Record this change. if (role == NameRole::BaseName) { baseName = newName; } else { argNames[i] = newName; } } return lowercaseAcronymsForReturn(); }
// Drop directory components and replace extension with ".exe". static std::string getOutputPath(StringRef Path) { auto P = Path.find_last_of("\\/"); StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1); return (S.substr(0, S.rfind('.')) + ".exe").str(); }