本文整理汇总了C++中StringRef::back方法的典型用法代码示例。如果您正苦于以下问题:C++ StringRef::back方法的具体用法?C++ StringRef::back怎么用?C++ StringRef::back使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类StringRef
的用法示例。
在下文中一共展示了StringRef::back方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: getPartOfSpeech
PartOfSpeech swift::getPartOfSpeech(StringRef word) {
// FIXME: This implementation is woefully inefficient.
#define PREPOSITION(Word) \
if (word.equals_lower(#Word)) \
return PartOfSpeech::Preposition;
#define VERB(Word) \
if (word.equals_lower(#Word)) \
return PartOfSpeech::Verb;
#include "PartsOfSpeech.def"
// Identify gerunds, which always end in "ing".
if (word.endswith("ing") && word.size() > 4) {
StringRef possibleVerb = word.substr(0, word.size()-3);
// If what remains is a verb, we have a gerund.
if (getPartOfSpeech(possibleVerb) == PartOfSpeech::Verb)
return PartOfSpeech::Gerund;
// Try adding an "e" and look for that as a verb.
if (possibleVerb.back() != 'e') {
SmallString<16> possibleVerbWithE;
possibleVerbWithE += possibleVerb;
possibleVerbWithE += 'e';
if (getPartOfSpeech(possibleVerbWithE) == PartOfSpeech::Verb)
return PartOfSpeech::Gerund;
}
// If there is a repeated letter at the back, drop that second
// instance of that letter and try again.
unsigned count = possibleVerb.size();
if (possibleVerb[count-1] == possibleVerb[count-2] &&
getPartOfSpeech(possibleVerb.substr(0, count-1)) == PartOfSpeech::Verb)
return PartOfSpeech::Gerund;
}
// "auto" tends to be used as a verb prefix.
if (startsWithIgnoreFirstCase(word, "auto") && word.size() > 4) {
if (getPartOfSpeech(word.substr(4)) == PartOfSpeech::Verb)
return PartOfSpeech::Verb;
}
// "re" can prefix a verb.
if (startsWithIgnoreFirstCase(word, "re") && word.size() > 2) {
if (getPartOfSpeech(word.substr(2)) == PartOfSpeech::Verb)
return PartOfSpeech::Verb;
}
// "de" can prefix a verb.
if (startsWithIgnoreFirstCase(word, "de") && word.size() > 2) {
if (getPartOfSpeech(word.substr(2)) == PartOfSpeech::Verb)
return PartOfSpeech::Verb;
}
return PartOfSpeech::Unknown;
}
示例2: getCommonPluralPrefix
/// Returns the common word-prefix of two strings, allowing the second string
/// to be a common English plural form of the first.
///
/// For example, given "NSProperty" and "NSProperties", the full "NSProperty"
/// is returned. Given "NSMagicArmor" and "NSMagicArmory", only
/// "NSMagic" is returned.
///
/// The "-s", "-es", and "-ies" patterns cover every plural NS_OPTIONS name
/// in Cocoa and Cocoa Touch.
///
/// \see getCommonWordPrefix
StringRef importer::getCommonPluralPrefix(StringRef singular,
StringRef plural) {
assert(!plural.empty());
if (singular.empty())
return singular;
bool ignored;
StringRef commonPrefix = getCommonWordPrefix(singular, plural, ignored);
if (commonPrefix.size() == singular.size() || plural.back() != 's')
return commonPrefix;
StringRef leftover = singular.substr(commonPrefix.size());
StringRef firstLeftoverWord = camel_case::getFirstWord(leftover);
StringRef commonPrefixPlusWord =
singular.substr(0, commonPrefix.size() + firstLeftoverWord.size());
// Is the plural string just "[singular]s"?
plural = plural.drop_back();
if (plural.endswith(firstLeftoverWord))
return commonPrefixPlusWord;
if (plural.empty() || plural.back() != 'e')
return commonPrefix;
// Is the plural string "[singular]es"?
plural = plural.drop_back();
if (plural.endswith(firstLeftoverWord))
return commonPrefixPlusWord;
if (plural.empty() || !(plural.back() == 'i' && singular.back() == 'y'))
return commonPrefix;
// Is the plural string "[prefix]ies" and the singular "[prefix]y"?
plural = plural.drop_back();
firstLeftoverWord = firstLeftoverWord.drop_back();
if (plural.endswith(firstLeftoverWord))
return commonPrefixPlusWord;
return commonPrefix;
}
示例3: EmitInlineAsm
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, unsigned LocCookie) const {
assert(!Str.empty() && "Can't emit empty inline asm block");
// Remember if the buffer is nul terminated or not so we can avoid a copy.
bool isNullTerminated = Str.back() == 0;
if (isNullTerminated)
Str = Str.substr(0, Str.size()-1);
// If the output streamer is actually a .s file, just emit the blob textually.
// This is useful in case the asm parser doesn't handle something but the
// system assembler does.
if (OutStreamer.hasRawTextSupport()) {
OutStreamer.EmitRawText(Str);
return;
}
SourceMgr SrcMgr;
// If the current LLVMContext has an inline asm handler, set it in SourceMgr.
LLVMContext &LLVMCtx = MMI->getModule()->getContext();
bool HasDiagHandler = false;
if (void *DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler()) {
SrcMgr.setDiagHandler((SourceMgr::DiagHandlerTy)(intptr_t)DiagHandler,
LLVMCtx.getInlineAsmDiagnosticContext(), LocCookie);
HasDiagHandler = true;
}
MemoryBuffer *Buffer;
if (isNullTerminated)
Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
else
Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");
// Tell SrcMgr about this buffer, it takes ownership of the buffer.
SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
OwningPtr<MCAsmParser> Parser(createMCAsmParser(TM.getTarget(), SrcMgr,
OutContext, OutStreamer,
*MAI));
OwningPtr<TargetAsmParser> TAP(TM.getTarget().createAsmParser(*Parser, TM));
if (!TAP)
report_fatal_error("Inline asm not supported by this streamer because"
" we don't have an asm parser for this target\n");
Parser->setTargetParser(*TAP.get());
// Don't implicitly switch to the text section before the asm.
int Res = Parser->Run(/*NoInitialTextSection*/ true,
/*NoFinalize*/ true);
if (Res && !HasDiagHandler)
report_fatal_error("Error parsing inline asm\n");
}
示例4: ArgOS
void
TemplateSpecializationType::PrintTemplateArgumentList(
raw_ostream &OS,
const TemplateArgument *Args,
unsigned NumArgs,
const PrintingPolicy &Policy,
bool SkipBrackets) {
if (!SkipBrackets)
OS << '<';
bool needSpace = false;
for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
if (Arg > 0)
OS << ", ";
// Print the argument into a string.
SmallString<128> Buf;
llvm::raw_svector_ostream ArgOS(Buf);
if (Args[Arg].getKind() == TemplateArgument::Pack) {
PrintTemplateArgumentList(ArgOS,
Args[Arg].pack_begin(),
Args[Arg].pack_size(),
Policy, true);
} else {
Args[Arg].print(Policy, ArgOS);
}
StringRef ArgString = ArgOS.str();
// If this is the first argument and its string representation
// begins with the global scope specifier ('::foo'), add a space
// to avoid printing the diagraph '<:'.
if (!Arg && !ArgString.empty() && ArgString[0] == ':')
OS << ' ';
OS << ArgString;
needSpace = (!ArgString.empty() && ArgString.back() == '>');
}
// If the last character of our string is '>', add another space to
// keep the two '>''s separate tokens. We don't *have* to do this in
// C++0x, but it's still good hygiene.
if (needSpace)
OS << ' ';
if (!SkipBrackets)
OS << '>';
}
示例5: if
// Replace .. embedded in path for purposes of having
// a canonical path.
static std::string replaceDotDot(StringRef Path) {
SmallString<128> Buffer;
llvm::sys::path::const_iterator B = llvm::sys::path::begin(Path),
E = llvm::sys::path::end(Path);
while (B != E) {
if (B->compare(".") == 0) {
}
else if (B->compare("..") == 0)
llvm::sys::path::remove_filename(Buffer);
else
llvm::sys::path::append(Buffer, *B);
++B;
}
if (Path.endswith("/") || Path.endswith("\\"))
Buffer.append(1, Path.back());
return Buffer.c_str();
}
示例6: parseDeclName
/// 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;
}
示例7: while
size_t CaseInsensitiveHashTable<T>::get_indices(StringRef name, IndexVec* result) const {
result->clear();
bool is_case_sensitive = false;
if (name.size() > 0 && name.front() == '"' && name.back() == '"') {
is_case_sensitive = true;
name = name.substr(1, name.size() - 2);
}
size_t h = fnv1a_hash_lower(name) & index_mask_;
size_t start = h;
while (index_[h] != NULL && !iequals(name, index_[h]->name)) {
h = (h + 1) & index_mask_;
if (h == start) {
return 0;
}
}
const T* entry = index_[h];
if (entry == NULL) {
return 0;
}
if (!is_case_sensitive) {
while (entry != NULL) {
result->push_back(entry->index);
entry = entry->next;
}
} else {
while (entry != NULL) {
if (name.equals(entry->name)) {
result->push_back(entry->index);
}
entry = entry->next;
}
}
return result->size();
}
示例8: skipTypeSuffix
/// Skip a type suffix that can be dropped.
static Optional<StringRef> skipTypeSuffix(StringRef typeName) {
if (typeName.empty()) return None;
auto lastWord = camel_case::getLastWord(typeName);
// "Type" suffix.
if (lastWord == "Type" && typeName.size() > 4) {
return typeName.drop_back(4);
}
// "Ref" suffix.
if (lastWord == "Ref" && typeName.size() > 3) {
return typeName.drop_back(3);
}
// "Mask" suffix.
if (lastWord == "Mask" && typeName.size() > 4) {
return typeName.drop_back(4);
}
// \d+D for dimensionality.
if (typeName.back() == 'D' && typeName.size() > 1) {
unsigned firstDigit = typeName.size() - 1;
while (firstDigit > 0) {
if (!isdigit(typeName[firstDigit-1])) break;
--firstDigit;
}
if (firstDigit < typeName.size()-1) {
return typeName.substr(0, firstDigit);
}
}
// _t.
if (typeName.size() > 2 && typeName.endswith("_t")) {
return typeName.drop_back(2);
}
return None;
}
示例9: parseDuration
static Expected<std::chrono::seconds> parseDuration(StringRef Duration) {
if (Duration.empty())
return make_error<StringError>("Duration must not be empty",
inconvertibleErrorCode());
StringRef NumStr = Duration.slice(0, Duration.size()-1);
uint64_t Num;
if (NumStr.getAsInteger(0, Num))
return make_error<StringError>("'" + NumStr + "' not an integer",
inconvertibleErrorCode());
switch (Duration.back()) {
case 's':
return std::chrono::seconds(Num);
case 'm':
return std::chrono::minutes(Num);
case 'h':
return std::chrono::hours(Num);
default:
return make_error<StringError>("'" + Duration +
"' must end with one of 's', 'm' or 'h'",
inconvertibleErrorCode());
}
}
示例10: parseDeclName
ParsedDeclName swift::parseDeclName(StringRef name) {
if (name.empty()) return ParsedDeclName();
// Local function to handle the parsing of the base name + context.
//
// Returns true if an error occurred, without recording the base name.
ParsedDeclName result;
auto parseBaseName = [&](StringRef text) -> bool {
// Split the text into context name and base name.
StringRef contextName, baseName;
std::tie(contextName, baseName) = text.rsplit('.');
if (baseName.empty()) {
baseName = contextName;
contextName = StringRef();
} else if (contextName.empty()) {
return true;
}
auto isValidIdentifier = [](StringRef text) -> bool {
return Lexer::isIdentifier(text) && text != "_";
};
// Make sure we have an identifier for the base name.
if (!isValidIdentifier(baseName))
return true;
// If we have a context, make sure it is an identifier, or a series of
// dot-separated identifiers.
// FIXME: What about generic parameters?
if (!contextName.empty()) {
StringRef first;
StringRef rest = contextName;
do {
std::tie(first, rest) = rest.split('.');
if (!isValidIdentifier(first))
return true;
} while (!rest.empty());
}
// Record the results.
result.ContextName = contextName;
result.BaseName = baseName;
return false;
};
// If this is not a function name, just parse the base name and
// we're done.
if (name.back() != ')') {
if (Lexer::isOperator(name))
result.BaseName = name;
else if (parseBaseName(name))
return ParsedDeclName();
return result;
}
// We have a function name.
result.IsFunctionName = true;
// Split the base name from the parameters.
StringRef baseName, parameters;
std::tie(baseName, parameters) = name.split('(');
if (parameters.empty()) return ParsedDeclName();
// If the base name is prefixed by "getter:" or "setter:", it's an
// accessor.
if (baseName.startswith("getter:")) {
result.IsGetter = true;
result.IsFunctionName = false;
baseName = baseName.substr(7);
} else if (baseName.startswith("setter:")) {
result.IsSetter = true;
result.IsFunctionName = false;
baseName = baseName.substr(7);
}
// Parse the base name.
if (parseBaseName(baseName)) return ParsedDeclName();
parameters = parameters.drop_back(); // ')'
if (parameters.empty()) return result;
if (parameters.back() != ':')
return ParsedDeclName();
bool isMember = !result.ContextName.empty();
do {
StringRef NextParam;
std::tie(NextParam, parameters) = parameters.split(':');
if (!Lexer::isIdentifier(NextParam))
return ParsedDeclName();
if (NextParam == "_") {
result.ArgumentLabels.push_back("");
} else if (isMember && NextParam == "self") {
// For a member, "self" indicates the self parameter. There can
// only be one such parameter.
if (result.SelfIndex) return ParsedDeclName();
result.SelfIndex = result.ArgumentLabels.size();
} else {
result.ArgumentLabels.push_back(NextParam);
//.........这里部分代码省略.........
示例11: MacroBodyEndsInBackslash
static bool MacroBodyEndsInBackslash(StringRef MacroBody) {
while (!MacroBody.empty() && isWhitespace(MacroBody.back()))
MacroBody = MacroBody.drop_back();
return !MacroBody.empty() && MacroBody.back() == '\\';
}
示例12: ParsePattern
bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
PatternLoc = SMLoc::getFromPointer(PatternStr.data());
// Ignore trailing whitespace.
while (!PatternStr.empty() &&
(PatternStr.back() == ' ' || PatternStr.back() == '\t'))
PatternStr = PatternStr.substr(0, PatternStr.size()-1);
// Check that there is something on the line.
if (PatternStr.empty()) {
SM.PrintMessage(PatternLoc, "found empty check string with prefix '" +
CheckPrefix+":'", "error");
return true;
}
// Check to see if this is a fixed string, or if it has regex pieces.
if (PatternStr.size() < 2 ||
(PatternStr.find("{{") == StringRef::npos &&
PatternStr.find("[[") == StringRef::npos)) {
FixedStr = PatternStr;
return false;
}
// Paren value #0 is for the fully matched string. Any new parenthesized
// values add from their.
unsigned CurParen = 1;
// Otherwise, there is at least one regex piece. Build up the regex pattern
// by escaping scary characters in fixed strings, building up one big regex.
while (!PatternStr.empty()) {
// RegEx matches.
if (PatternStr.size() >= 2 &&
PatternStr[0] == '{' && PatternStr[1] == '{') {
// Otherwise, this is the start of a regex match. Scan for the }}.
size_t End = PatternStr.find("}}");
if (End == StringRef::npos) {
SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
"found start of regex string with no end '}}'", "error");
return true;
}
if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
return true;
PatternStr = PatternStr.substr(End+2);
continue;
}
// Named RegEx matches. These are of two forms: [[foo:.*]] which matches .*
// (or some other regex) and assigns it to the FileCheck variable 'foo'. The
// second form is [[foo]] which is a reference to foo. The variable name
// itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
// it. This is to catch some common errors.
if (PatternStr.size() >= 2 &&
PatternStr[0] == '[' && PatternStr[1] == '[') {
// Verify that it is terminated properly.
size_t End = PatternStr.find("]]");
if (End == StringRef::npos) {
SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
"invalid named regex reference, no ]] found", "error");
return true;
}
StringRef MatchStr = PatternStr.substr(2, End-2);
PatternStr = PatternStr.substr(End+2);
// Get the regex name (e.g. "foo").
size_t NameEnd = MatchStr.find(':');
StringRef Name = MatchStr.substr(0, NameEnd);
if (Name.empty()) {
SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
"invalid name in named regex: empty name", "error");
return true;
}
// Verify that the name is well formed.
for (unsigned i = 0, e = Name.size(); i != e; ++i)
if (Name[i] != '_' &&
(Name[i] < 'a' || Name[i] > 'z') &&
(Name[i] < 'A' || Name[i] > 'Z') &&
(Name[i] < '0' || Name[i] > '9')) {
SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
"invalid name in named regex", "error");
return true;
}
// Name can't start with a digit.
if (isdigit(Name[0])) {
SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
"invalid name in named regex", "error");
return true;
}
// Handle [[foo]].
if (NameEnd == StringRef::npos) {
VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
continue;
}
//.........这里部分代码省略.........
示例13: EmitInlineAsm
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode) const {
#ifndef ANDROID_TARGET_BUILD
assert(!Str.empty() && "Can't emit empty inline asm block");
// Remember if the buffer is nul terminated or not so we can avoid a copy.
bool isNullTerminated = Str.back() == 0;
if (isNullTerminated)
Str = Str.substr(0, Str.size()-1);
// If the output streamer is actually a .s file, just emit the blob textually.
// This is useful in case the asm parser doesn't handle something but the
// system assembler does.
if (OutStreamer.hasRawTextSupport()) {
OutStreamer.EmitRawText(Str);
return;
}
SourceMgr SrcMgr;
SrcMgrDiagInfo DiagInfo;
// If the current LLVMContext has an inline asm handler, set it in SourceMgr.
LLVMContext &LLVMCtx = MMI->getModule()->getContext();
bool HasDiagHandler = false;
if (LLVMCtx.getInlineAsmDiagnosticHandler() != 0) {
// If the source manager has an issue, we arrange for SrcMgrDiagHandler
// to be invoked, getting DiagInfo passed into it.
DiagInfo.LocInfo = LocMDNode;
DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
SrcMgr.setDiagHandler(SrcMgrDiagHandler, &DiagInfo);
HasDiagHandler = true;
}
MemoryBuffer *Buffer;
if (isNullTerminated)
Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
else
Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");
// Tell SrcMgr about this buffer, it takes ownership of the buffer.
SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr,
OutContext, OutStreamer,
*MAI));
// FIXME: It would be nice if we can avoid createing a new instance of
// MCSubtargetInfo here given TargetSubtargetInfo is available. However,
// we have to watch out for asm directives which can change subtarget
// state. e.g. .code 16, .code 32.
OwningPtr<MCSubtargetInfo>
STI(TM.getTarget().createMCSubtargetInfo(TM.getTargetTriple(),
TM.getTargetCPU(),
TM.getTargetFeatureString()));
OwningPtr<MCTargetAsmParser>
TAP(TM.getTarget().createMCAsmParser(*STI, *Parser));
if (!TAP)
report_fatal_error("Inline asm not supported by this streamer because"
" we don't have an asm parser for this target\n");
Parser->setTargetParser(*TAP.get());
// Don't implicitly switch to the text section before the asm.
int Res = Parser->Run(/*NoInitialTextSection*/ true,
/*NoFinalize*/ true);
if (Res && !HasDiagHandler)
report_fatal_error("Error parsing inline asm\n");
#endif // ANDROID_TARGET_BUILD
}
示例14: printCodeViewSection
void COFFDumper::printCodeViewSection(const SectionRef &Section) {
StringRef Data;
error(Section.getContents(Data));
SmallVector<StringRef, 10> FunctionNames;
StringMap<StringRef> FunctionLineTables;
ListScope D(W, "CodeViewDebugInfo");
{
// FIXME: Add more offset correctness checks.
DataExtractor DE(Data, true, 4);
uint32_t Offset = 0,
Magic = DE.getU32(&Offset);
W.printHex("Magic", Magic);
if (Magic != COFF::DEBUG_SECTION_MAGIC) {
error(object_error::parse_failed);
return;
}
bool Finished = false;
while (DE.isValidOffset(Offset) && !Finished) {
// The section consists of a number of subsection in the following format:
// |Type|PayloadSize|Payload...|
uint32_t SubSectionType = DE.getU32(&Offset),
PayloadSize = DE.getU32(&Offset);
ListScope S(W, "Subsection");
W.printHex("Type", SubSectionType);
W.printHex("PayloadSize", PayloadSize);
if (PayloadSize > Data.size() - Offset) {
error(object_error::parse_failed);
return;
}
StringRef Contents = Data.substr(Offset, PayloadSize);
if (opts::CodeViewSubsectionBytes) {
// Print the raw contents to simplify debugging if anything goes wrong
// afterwards.
W.printBinaryBlock("Contents", Contents);
}
switch (SubSectionType) {
case COFF::DEBUG_SYMBOL_SUBSECTION:
printCodeViewSymbolsSubsection(Contents, Section, Offset);
break;
case COFF::DEBUG_LINE_TABLE_SUBSECTION: {
// Holds a PC to file:line table. Some data to parse this subsection is
// stored in the other subsections, so just check sanity and store the
// pointers for deferred processing.
if (PayloadSize < 12) {
// There should be at least three words to store two function
// relocations and size of the code.
error(object_error::parse_failed);
return;
}
StringRef LinkageName;
error(resolveSymbolName(Obj->getCOFFSection(Section), Offset,
LinkageName));
W.printString("LinkageName", LinkageName);
if (FunctionLineTables.count(LinkageName) != 0) {
// Saw debug info for this function already?
error(object_error::parse_failed);
return;
}
FunctionLineTables[LinkageName] = Contents;
FunctionNames.push_back(LinkageName);
break;
}
case COFF::DEBUG_STRING_TABLE_SUBSECTION:
if (PayloadSize == 0 || CVStringTable.data() != nullptr ||
Contents.back() != '\0') {
// Empty or duplicate or non-null-terminated subsection.
error(object_error::parse_failed);
return;
}
CVStringTable = Contents;
break;
case COFF::DEBUG_INDEX_SUBSECTION:
// Holds the translation table from file indices
// to offsets in the string table.
if (PayloadSize == 0 ||
CVFileIndexToStringOffsetTable.data() != nullptr) {
// Empty or duplicate subsection.
error(object_error::parse_failed);
return;
}
CVFileIndexToStringOffsetTable = Contents;
break;
}
Offset += PayloadSize;
// Align the reading pointer by 4.
Offset += (-Offset) % 4;
}
}
// Dump the line tables now that we've read all the subsections and know all
//.........这里部分代码省略.........
示例15: ParsePattern
bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM,
unsigned LineNumber) {
this->LineNumber = LineNumber;
PatternLoc = SMLoc::getFromPointer(PatternStr.data());
// Ignore trailing whitespace.
while (!PatternStr.empty() &&
(PatternStr.back() == ' ' || PatternStr.back() == '\t'))
PatternStr = PatternStr.substr(0, PatternStr.size()-1);
// Check that there is something on the line.
if (PatternStr.empty()) {
SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
"found empty check string with prefix '" +
CheckPrefix+":'");
return true;
}
// Check to see if this is a fixed string, or if it has regex pieces.
if (PatternStr.size() < 2 ||
(PatternStr.find("{{") == StringRef::npos &&
PatternStr.find("[[") == StringRef::npos)) {
FixedStr = PatternStr;
return false;
}
// Paren value #0 is for the fully matched string. Any new parenthesized
// values add from there.
unsigned CurParen = 1;
// Otherwise, there is at least one regex piece. Build up the regex pattern
// by escaping scary characters in fixed strings, building up one big regex.
while (!PatternStr.empty()) {
// RegEx matches.
if (PatternStr.startswith("{{")) {
// This is the start of a regex match. Scan for the }}.
size_t End = PatternStr.find("}}");
if (End == StringRef::npos) {
SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
SourceMgr::DK_Error,
"found start of regex string with no end '}}'");
return true;
}
// Enclose {{}} patterns in parens just like [[]] even though we're not
// capturing the result for any purpose. This is required in case the
// expression contains an alternation like: CHECK: abc{{x|z}}def. We
// want this to turn into: "abc(x|z)def" not "abcx|zdef".
RegExStr += '(';
++CurParen;
if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
return true;
RegExStr += ')';
PatternStr = PatternStr.substr(End+2);
continue;
}
// Named RegEx matches. These are of two forms: [[foo:.*]] which matches .*
// (or some other regex) and assigns it to the FileCheck variable 'foo'. The
// second form is [[foo]] which is a reference to foo. The variable name
// itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
// it. This is to catch some common errors.
if (PatternStr.startswith("[[")) {
// Find the closing bracket pair ending the match. End is going to be an
// offset relative to the beginning of the match string.
size_t End = FindRegexVarEnd(PatternStr.substr(2));
if (End == StringRef::npos) {
SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
SourceMgr::DK_Error,
"invalid named regex reference, no ]] found");
return true;
}
StringRef MatchStr = PatternStr.substr(2, End);
PatternStr = PatternStr.substr(End+4);
// Get the regex name (e.g. "foo").
size_t NameEnd = MatchStr.find(':');
StringRef Name = MatchStr.substr(0, NameEnd);
if (Name.empty()) {
SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
"invalid name in named regex: empty name");
return true;
}
// Verify that the name/expression is well formed. FileCheck currently
// supports @LINE, @LINE+number, @LINE-number expressions. The check here
// is relaxed, more strict check is performed in \c EvaluateExpression.
bool IsExpression = false;
for (unsigned i = 0, e = Name.size(); i != e; ++i) {
if (i == 0 && Name[i] == '@') {
if (NameEnd != StringRef::npos) {
SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
SourceMgr::DK_Error,
"invalid name in named regex definition");
return true;
//.........这里部分代码省略.........