size_t StringRef::find_lower(StringRef Str, size_t From) const { StringRef This = substr(From); while (This.size() >= Str.size()) { if (This.startswith_lower(Str)) return From; This = This.drop_front(); ++From; } return npos; }
/// \returns Matched size. 0 means no match. static unsigned matchOption(const OptTable::Info *I, StringRef Str, bool IgnoreCase) { for (const char * const *Pre = I->Prefixes; *Pre != nullptr; ++Pre) { StringRef Prefix(*Pre); if (Str.startswith(Prefix)) { StringRef Rest = Str.substr(Prefix.size()); bool Matched = IgnoreCase ? Rest.startswith_lower(I->Name) : Rest.startswith(I->Name); if (Matched) return Prefix.size() + StringRef(I->Name).size(); } } return 0; }
/// Match a word within a name to a word within a type. static bool matchNameWordToTypeWord(StringRef nameWord, StringRef typeWord) { // If the name word is longer, there's no match. if (nameWord.size() > typeWord.size()) return false; // If the name word is shorter, try for a partial match. if (nameWord.size() < typeWord.size()) { // We can match the suffix of the type so long as everything preceding the // match is neither a lowercase letter nor a '_'. This ignores type // prefixes for acronyms, e.g., the 'NS' in 'NSURL'. if (typeWord.endswith_lower(nameWord) && !clang::isLowercase(typeWord[typeWord.size()-nameWord.size()])) { // Check that everything preceding the match is neither a lowercase letter // nor a '_'. for (unsigned i = 0, n = nameWord.size(); i != n; ++i) { if (clang::isLowercase(typeWord[i]) || typeWord[i] == '_') return false; } return true; } // We can match a prefix so long as everything following the match is // a number. if (typeWord.startswith_lower(nameWord)) { for (unsigned i = nameWord.size(), n = typeWord.size(); i != n; ++i) { if (!clang::isDigit(typeWord[i])) return false; } return true; } return false; } // Check for an exact match. return nameWord.equals_lower(typeWord); }
static bool isAutorelease(const FunctionDecl *FD, StringRef FName) { return FName.startswith_lower("autorelease") || FName.endswith_lower("autorelease"); }
static bool isRetain(const FunctionDecl *FD, StringRef FName) { return FName.startswith_lower("retain") || FName.endswith_lower("retain"); }
bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) { if (!Name.startswith_lower("j")) return true; auto CC = Name.drop_front().lower(); unsigned CondCode; if (CC == "ne" || CC == "nz") CondCode = MSP430CC::COND_NE; else if (CC == "eq" || CC == "z") CondCode = MSP430CC::COND_E; else if (CC == "lo" || CC == "nc") CondCode = MSP430CC::COND_LO; else if (CC == "hs" || CC == "c") CondCode = MSP430CC::COND_HS; else if (CC == "n") CondCode = MSP430CC::COND_N; else if (CC == "ge") CondCode = MSP430CC::COND_GE; else if (CC == "l") CondCode = MSP430CC::COND_L; else if (CC == "mp") CondCode = MSP430CC::COND_NONE; else return Error(NameLoc, "unknown instruction"); if (CondCode == (unsigned)MSP430CC::COND_NONE) Operands.push_back(MSP430Operand::CreateToken("jmp", NameLoc)); else { Operands.push_back(MSP430Operand::CreateToken("j", NameLoc)); const MCExpr *CCode = MCConstantExpr::create(CondCode, getContext()); Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc())); } // Skip optional '$' sign. if (getLexer().getKind() == AsmToken::Dollar) getLexer().Lex(); // Eat '$' const MCExpr *Val; SMLoc ExprLoc = getLexer().getLoc(); if (getParser().parseExpression(Val)) return Error(ExprLoc, "expected expression operand"); int64_t Res; if (Val->evaluateAsAbsolute(Res)) if (Res < -512 || Res > 511) return Error(ExprLoc, "invalid jump offset"); Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc, getLexer().getLoc())); if (getLexer().isNot(AsmToken::EndOfStatement)) { SMLoc Loc = getLexer().getLoc(); getParser().eatToEndOfStatement(); return Error(Loc, "unexpected token"); } getParser().Lex(); // Consume the EndOfStatement. return false; }