本文整理汇总了C++中StringRef::size方法的典型用法代码示例。如果您正苦于以下问题:C++ StringRef::size方法的具体用法?C++ StringRef::size怎么用?C++ StringRef::size使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类StringRef
的用法示例。
在下文中一共展示了StringRef::size方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: replaceKeepingName
// MinGW specific.
void Symbol::replaceKeepingName(Symbol *Other, size_t Size) {
StringRef OrigName = getName();
memcpy(this, Other, Size);
NameData = OrigName.data();
NameSize = OrigName.size();
}
示例2: Check
static CXCodeCompleteResults *
clang_codeCompleteAt_Impl(CXTranslationUnit TU, const char *complete_filename,
unsigned complete_line, unsigned complete_column,
ArrayRef<CXUnsavedFile> unsaved_files,
unsigned options) {
bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
#ifdef UDP_CODE_COMPLETION_LOGGER
#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime();
#endif
#endif
bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != nullptr;
if (cxtu::isNotUsableTU(TU)) {
LOG_BAD_TU(TU);
return nullptr;
}
ASTUnit *AST = cxtu::getASTUnit(TU);
if (!AST)
return nullptr;
CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
setThreadBackgroundPriority();
ASTUnit::ConcurrencyCheck Check(*AST);
// Perform the remapping of source files.
SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
for (auto &UF : unsaved_files) {
std::unique_ptr<llvm::MemoryBuffer> MB =
llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
RemappedFiles.push_back(std::make_pair(UF.Filename, MB.release()));
}
if (EnableLogging) {
// FIXME: Add logging.
}
// Parse the resulting source file to find code-completion results.
AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults(
&AST->getFileManager());
Results->Results = nullptr;
Results->NumResults = 0;
// Create a code-completion consumer to capture the results.
CodeCompleteOptions Opts;
Opts.IncludeBriefComments = IncludeBriefComments;
CaptureCompletionResults Capture(Opts, *Results, &TU);
// Perform completion.
AST->CodeComplete(complete_filename, complete_line, complete_column,
RemappedFiles, (options & CXCodeComplete_IncludeMacros),
(options & CXCodeComplete_IncludeCodePatterns),
IncludeBriefComments, Capture,
CXXIdx->getPCHContainerOperations(), *Results->Diag,
Results->LangOpts, *Results->SourceMgr, *Results->FileMgr,
Results->Diagnostics, Results->TemporaryBuffers);
Results->DiagnosticsWrappers.resize(Results->Diagnostics.size());
// Keep a reference to the allocator used for cached global completions, so
// that we can be sure that the memory used by our code completion strings
// doesn't get freed due to subsequent reparses (while the code completion
// results are still active).
Results->CachedCompletionAllocator = AST->getCachedCompletionAllocator();
#ifdef UDP_CODE_COMPLETION_LOGGER
#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
const llvm::TimeRecord &EndTime = llvm::TimeRecord::getCurrentTime();
SmallString<256> LogResult;
llvm::raw_svector_ostream os(LogResult);
// Figure out the language and whether or not it uses PCH.
const char *lang = 0;
bool usesPCH = false;
for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
I != E; ++I) {
if (*I == 0)
continue;
if (strcmp(*I, "-x") == 0) {
if (I + 1 != E) {
lang = *(++I);
continue;
}
}
else if (strcmp(*I, "-include") == 0) {
if (I+1 != E) {
const char *arg = *(++I);
SmallString<512> pchName;
{
llvm::raw_svector_ostream os(pchName);
os << arg << ".pth";
//.........这里部分代码省略.........
示例3: create_PRUNTIME_FUNCTION
static void create_PRUNTIME_FUNCTION(uint8_t *Code, size_t Size, StringRef fnname,
uint8_t *Section, size_t Allocated, uint8_t *UnwindData)
{
DWORD mod_size = 0;
#if defined(_CPU_X86_64_)
#if !defined(USE_MCJIT)
uint8_t *catchjmp = Section+Allocated;
UnwindData = (uint8_t*)(((uintptr_t)catchjmp+12+3)&~(uintptr_t)3);
if (!catchjmp[0]) {
catchjmp[0] = 0x48;
catchjmp[1] = 0xb8; // mov RAX, QWORD PTR [...]
*(uint64_t*)(&catchjmp[2]) = (uint64_t)&_seh_exception_handler;
catchjmp[10] = 0xff;
catchjmp[11] = 0xe0; // jmp RAX
UnwindData[0] = 0x09; // version info, UNW_FLAG_EHANDLER
UnwindData[1] = 4; // size of prolog (bytes)
UnwindData[2] = 2; // count of unwind codes (slots)
UnwindData[3] = 0x05; // frame register (rbp) = rsp
UnwindData[4] = 4; // second instruction
UnwindData[5] = 0x03; // mov RBP, RSP
UnwindData[6] = 1; // first instruction
UnwindData[7] = 0x50; // push RBP
*(DWORD*)&UnwindData[8] = (DWORD)(catchjmp - Section); // relative location of catchjmp
mod_size = (DWORD)Allocated+48;
}
PRUNTIME_FUNCTION tbl = (PRUNTIME_FUNCTION)(UnwindData+12);
#else
PRUNTIME_FUNCTION tbl = (PRUNTIME_FUNCTION)malloc(sizeof(RUNTIME_FUNCTION));
#endif
tbl->BeginAddress = (DWORD)(Code - Section);
tbl->EndAddress = (DWORD)(Code - Section + Size);
tbl->UnwindData = (DWORD)(UnwindData - Section);
#else // defined(_CPU_X86_64_)
Section += (uintptr_t)Code;
mod_size = Size;
#endif
if (0) {
assert(!jl_in_stackwalk);
jl_in_stackwalk = 1;
if (mod_size && !SymLoadModuleEx(GetCurrentProcess(), NULL, NULL, NULL, (DWORD64)Section, mod_size, NULL, SLMFLAG_VIRTUAL)) {
#if defined(_CPU_X86_64_) && !defined(USE_MCJIT)
catchjmp[0] = 0;
#endif
static int warned = 0;
if (!warned) {
jl_printf(JL_STDERR, "WARNING: failed to insert module info for backtrace: %lu\n", GetLastError());
warned = 1;
}
}
else {
size_t len = fnname.size()+1;
if (len > MAX_SYM_NAME)
len = MAX_SYM_NAME;
char *name = (char*)alloca(len);
memcpy(name, fnname.data(), len-1);
name[len-1] = 0;
if (!SymAddSymbol(GetCurrentProcess(), (ULONG64)Section, name,
(DWORD64)Code, (DWORD)Size, 0)) {
jl_printf(JL_STDERR, "WARNING: failed to insert function name %s into debug info: %lu\n", name, GetLastError());
}
}
jl_in_stackwalk = 0;
}
#if defined(_CPU_X86_64_)
if (!RtlAddFunctionTable(tbl, 1, (DWORD64)Section)) {
static int warned = 0;
if (!warned) {
jl_printf(JL_STDERR, "WARNING: failed to insert function stack unwind info: %lu\n", GetLastError());
warned = 1;
}
}
#endif
}
示例4: output
void Output::output(StringRef s) {
Column += s.size();
Out << s;
}
示例5: ApplyOneQAOverride
/// ApplyQAOverride - Apply a list of edits to the input argument lists.
///
/// The input string is a space separate list of edits to perform,
/// they are applied in order to the input argument lists. Edits
/// should be one of the following forms:
///
/// '#': Silence information about the changes to the command line arguments.
///
/// '^': Add FOO as a new argument at the beginning of the command line.
///
/// '+': Add FOO as a new argument at the end of the command line.
///
/// 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command
/// line.
///
/// 'xOPTION': Removes all instances of the literal argument OPTION.
///
/// 'XOPTION': Removes all instances of the literal argument OPTION,
/// and the following argument.
///
/// 'Ox': Removes all flags matching 'O' or 'O[sz0-9]' and adds 'Ox'
/// at the end of the command line.
///
/// \param OS - The stream to write edit information to.
/// \param Args - The vector of command line arguments.
/// \param Edit - The override command to perform.
/// \param SavedStrings - Set to use for storing string representations.
static void ApplyOneQAOverride(raw_ostream &OS,
SmallVectorImpl<const char*> &Args,
StringRef Edit,
std::set<std::string> &SavedStrings) {
// This does not need to be efficient.
if (Edit[0] == '^') {
const char *Str =
SaveStringInSet(SavedStrings, Edit.substr(1));
OS << "### Adding argument " << Str << " at beginning\n";
Args.insert(Args.begin() + 1, Str);
} else if (Edit[0] == '+') {
const char *Str =
SaveStringInSet(SavedStrings, Edit.substr(1));
OS << "### Adding argument " << Str << " at end\n";
Args.push_back(Str);
} else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") &&
Edit.slice(2, Edit.size()-1).find('/') != StringRef::npos) {
StringRef MatchPattern = Edit.substr(2).split('/').first;
StringRef ReplPattern = Edit.substr(2).split('/').second;
ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1);
for (unsigned i = 1, e = Args.size(); i != e; ++i) {
std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]);
if (Repl != Args[i]) {
OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n";
Args[i] = SaveStringInSet(SavedStrings, Repl);
}
}
} else if (Edit[0] == 'x' || Edit[0] == 'X') {
std::string Option = Edit.substr(1, std::string::npos);
for (unsigned i = 1; i < Args.size();) {
if (Option == Args[i]) {
OS << "### Deleting argument " << Args[i] << '\n';
Args.erase(Args.begin() + i);
if (Edit[0] == 'X') {
if (i < Args.size()) {
OS << "### Deleting argument " << Args[i] << '\n';
Args.erase(Args.begin() + i);
} else
OS << "### Invalid X edit, end of command line!\n";
}
} else
++i;
}
} else if (Edit[0] == 'O') {
for (unsigned i = 1; i < Args.size();) {
const char *A = Args[i];
if (A[0] == '-' && A[1] == 'O' &&
(A[2] == '\0' ||
(A[3] == '\0' && (A[2] == 's' || A[2] == 'z' ||
('0' <= A[2] && A[2] <= '9'))))) {
OS << "### Deleting argument " << Args[i] << '\n';
Args.erase(Args.begin() + i);
} else
++i;
}
OS << "### Adding argument " << Edit << " at end\n";
Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit.str()));
} else {
OS << "### Unrecognized edit: " << Edit << "\n";
}
}
示例6: EmitInlineAsm
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
const MCTargetOptions &MCOptions,
const MDNode *LocMDNode,
InlineAsm::AsmDialect Dialect) 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 does not have mature MC support or the integrated
// assembler has been disabled, just emit the blob textually.
// Otherwise parse the asm and emit it via MC support.
// This is useful in case the asm parser doesn't handle something but the
// system assembler does.
const MCAsmInfo *MCAI = TM.getMCAsmInfo();
assert(MCAI && "No MCAsmInfo");
if (!MCAI->useIntegratedAssembler() &&
!OutStreamer->isIntegratedAssemblerRequired()) {
emitInlineAsmStart();
OutStreamer->EmitRawText(Str);
emitInlineAsmEnd(STI, nullptr);
return;
}
if (!DiagInfo) {
DiagInfo = make_unique<SrcMgrDiagInfo>();
MCContext &Context = MMI->getContext();
Context.setInlineSourceManager(&DiagInfo->SrcMgr);
LLVMContext &LLVMCtx = MMI->getModule()->getContext();
if (LLVMCtx.getInlineAsmDiagnosticHandler()) {
DiagInfo->DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
DiagInfo->DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
DiagInfo->SrcMgr.setDiagHandler(srcMgrDiagHandler, DiagInfo.get());
}
}
SourceMgr &SrcMgr = DiagInfo->SrcMgr;
SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths);
std::unique_ptr<MemoryBuffer> Buffer;
// The inline asm source manager will outlive Str, so make a copy of the
// string for SourceMgr to own.
Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");
// Tell SrcMgr about this buffer, it takes ownership of the buffer.
unsigned BufNum = SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
// Store LocMDNode in DiagInfo, using BufNum as an identifier.
if (LocMDNode) {
DiagInfo->LocInfos.resize(BufNum);
DiagInfo->LocInfos[BufNum-1] = LocMDNode;
}
std::unique_ptr<MCAsmParser> Parser(
createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI, BufNum));
// We create a new MCInstrInfo here since we might be at the module level
// and not have a MachineFunction to initialize the TargetInstrInfo from and
// we only need MCInstrInfo for asm parsing. We create one unconditionally
// because it's not subtarget dependent.
std::unique_ptr<MCInstrInfo> MII(TM.getTarget().createMCInstrInfo());
std::unique_ptr<MCTargetAsmParser> TAP(TM.getTarget().createMCAsmParser(
STI, *Parser, *MII, MCOptions));
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->setAssemblerDialect(Dialect);
Parser->setTargetParser(*TAP.get());
if (Dialect == InlineAsm::AD_Intel)
// We need this flag to be able to parse numbers like "0bH"
Parser->setParsingInlineAsm(true);
if (MF) {
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
TAP->SetFrameRegister(TRI->getFrameRegister(*MF));
}
emitInlineAsmStart();
// Don't implicitly switch to the text section before the asm.
int Res = Parser->Run(/*NoInitialTextSection*/ true,
/*NoFinalize*/ true);
emitInlineAsmEnd(STI, &TAP->getSTI());
if (Res && !DiagInfo->DiagHandler)
report_fatal_error("Error parsing inline asm\n");
}
示例7: decompileFunction
Function* Decompiler::decompileFunction(unsigned Address) {
// Check that Address is inside the current section.
// TODO: Find a better way to do this check. What we really care about is
// avoiding reads to library calls and areas of memory we can't "see".
const object::SectionRef Sect = Dis->getCurrentSection();
uint64_t SectStart, SectEnd;
Sect.getAddress(SectStart);
Sect.getSize(SectEnd);
SectEnd += SectStart;
if (Address < SectStart || Address > SectEnd) {
errs() << "Address out of bounds for section (is this a library call?): "
<< format("%1" PRIx64, Address) << "\n";
return NULL;
}
MachineFunction *MF = Dis->disassemble(Address);
// Get Function Name
// TODO: Determine Function Type
FunctionType *FType = FunctionType::get(Type::getPrimitiveType(*Context,
Type::VoidTyID), false);
Function *F =
cast<Function>(Mod->getOrInsertFunction(MF->getName(), FType));
if (!F->empty()) {
return F;
}
// Create a basic block to hold entry point (alloca) information
BasicBlock *entry = getOrCreateBasicBlock("entry", F);
// For each basic block
MachineFunction::iterator BI = MF->begin(), BE = MF->end();
while (BI != BE) {
// Add branch from "entry"
if (BI == MF->begin()) {
entry->getInstList().push_back(
BranchInst::Create(getOrCreateBasicBlock(BI->getName(), F)));
} else {
getOrCreateBasicBlock(BI->getName(), F);
}
++BI;
}
BI = MF->begin();
while (BI != BE) {
if (decompileBasicBlock(BI, F) == NULL) {
printError("Unable to decompile basic block!");
}
++BI;
}
// During Decompilation, did any "in-between" basic blocks get created?
// Nothing ever splits the entry block, so we skip it.
for (Function::iterator I = ++F->begin(), E = F->end(); I != E; ++I) {
if (!(I->empty())) {
continue;
}
// Right now, the only way to get the right offset is to parse its name
// it sucks, but it works.
StringRef Name = I->getName();
if (Name == "end" || Name == "entry") continue; // these can be empty
size_t Off = F->getName().size() + 1;
size_t Size = Name.size() - Off;
StringRef BBAddrStr = Name.substr(Off, Size);
unsigned long long BBAddr;
getAsUnsignedInteger(BBAddrStr, 10, BBAddr);
BBAddr += Address;
DEBUG(errs() << "Split Target: " << Name << "\t Address: "
<< BBAddr << "\n");
// split Block at AddrStr
Function::iterator SB; // Split basic block
BasicBlock::iterator SI, SE; // Split instruction
// Note the ++, nothing ever splits the entry block.
for (SB = ++F->begin(); SB != E; ++SB) {
DEBUG(outs() << "SB: " << SB->getName()
<< "\tRange: " << Dis->getDebugOffset(SB->begin()->getDebugLoc())
<< " " << Dis->getDebugOffset(SB->getTerminator()->getDebugLoc())
<< "\n");
if (SB->empty() || BBAddr < getBasicBlockAddress(SB)
|| BBAddr > Dis->getDebugOffset(SB->getTerminator()->getDebugLoc())) {
continue;
}
// Reorder instructions based on Debug Location
sortBasicBlock(SB);
DEBUG(errs() << "Found Split Block: " << SB->getName() << "\n");
// Find iterator to split on.
for (SI = SB->begin(), SE = SB->end(); SI != SE; ++SI) {
// outs() << "SI: " << SI->getDebugLoc().getLine() << "\n";
if (Dis->getDebugOffset(SI->getDebugLoc()) == BBAddr) break;
if (Dis->getDebugOffset(SI->getDebugLoc()) > BBAddr) {
errs() << "Could not find address inside basic block!\n"
<< "SI: " << Dis->getDebugOffset(SI->getDebugLoc()) << "\n"
<< "BBAddr: " << BBAddr << "\n";
break;
}
}
break;
}
//.........这里部分代码省略.........
示例8: ReadCheckFile
/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings. The strings are added to the CheckStrings vector.
static bool ReadCheckFile(SourceMgr &SM,
std::vector<CheckString> &CheckStrings) {
// Open the check file, and tell SourceMgr about it.
OwningPtr<MemoryBuffer> File;
if (error_code ec =
MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), File)) {
errs() << "Could not open check file '" << CheckFilename << "': "
<< ec.message() << '\n';
return true;
}
MemoryBuffer *F = File.take();
// If we want to canonicalize whitespace, strip excess whitespace from the
// buffer containing the CHECK lines.
if (!NoCanonicalizeWhiteSpace)
F = CanonicalizeInputFile(F);
SM.AddNewSourceBuffer(F, SMLoc());
// Find all instances of CheckPrefix followed by : in the file.
StringRef Buffer = F->getBuffer();
std::vector<std::pair<SMLoc, Pattern> > NotMatches;
while (1) {
// See if Prefix occurs in the memory buffer.
Buffer = Buffer.substr(Buffer.find(CheckPrefix));
// If we didn't find a match, we're done.
if (Buffer.empty())
break;
const char *CheckPrefixStart = Buffer.data();
// When we find a check prefix, keep track of whether we find CHECK: or
// CHECK-NEXT:
bool IsCheckNext = false, IsCheckNot = false;
// Verify that the : is present after the prefix.
if (Buffer[CheckPrefix.size()] == ':') {
Buffer = Buffer.substr(CheckPrefix.size()+1);
} else if (Buffer.size() > CheckPrefix.size()+6 &&
memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
Buffer = Buffer.substr(CheckPrefix.size()+7);
IsCheckNext = true;
} else if (Buffer.size() > CheckPrefix.size()+5 &&
memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
Buffer = Buffer.substr(CheckPrefix.size()+6);
IsCheckNot = true;
} else {
Buffer = Buffer.substr(1);
continue;
}
// Okay, we found the prefix, yay. Remember the rest of the line, but
// ignore leading and trailing whitespace.
Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
// Scan ahead to the end of line.
size_t EOL = Buffer.find_first_of("\n\r");
// Remember the location of the start of the pattern, for diagnostics.
SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
// Parse the pattern.
Pattern P;
if (P.ParsePattern(Buffer.substr(0, EOL), SM))
return true;
Buffer = Buffer.substr(EOL);
// Verify that CHECK-NEXT lines have at least one CHECK line before them.
if (IsCheckNext && CheckStrings.empty()) {
SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
"found '"+CheckPrefix+"-NEXT:' without previous '"+
CheckPrefix+ ": line", "error");
return true;
}
// Handle CHECK-NOT.
if (IsCheckNot) {
NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
P));
continue;
}
// Okay, add the string we captured to the output vector and move on.
CheckStrings.push_back(CheckString(P,
PatternLoc,
IsCheckNext));
std::swap(NotMatches, CheckStrings.back().NotStrings);
}
// Add an EOF pattern for any trailing CHECK-NOTs.
if (!NotMatches.empty()) {
CheckStrings.push_back(CheckString(Pattern(true),
//.........这里部分代码省略.........
示例9: Parse
SourceCompleteResult
ide::isSourceInputComplete(std::unique_ptr<llvm::MemoryBuffer> MemBuf) {
SourceManager SM;
auto BufferID = SM.addNewSourceBuffer(std::move(MemBuf));
ParserUnit Parse(SM, BufferID);
Parser &P = Parse.getParser();
bool Done;
do {
P.parseTopLevel();
Done = P.Tok.is(tok::eof);
} while (!Done);
SourceCompleteResult SCR;
SCR.IsComplete = !P.isInputIncomplete();
// Use the same code that was in the REPL code to track the indent level
// for now. In the future we should get this from the Parser if possible.
CharSourceRange entireRange = SM.getRangeForBuffer(BufferID);
StringRef Buffer = SM.extractText(entireRange);
const char *SourceStart = Buffer.data();
const char *SourceEnd = Buffer.data() + Buffer.size();
const char *LineStart = SourceStart;
const char *LineSourceStart = nullptr;
uint32_t LineIndent = 0;
struct IndentInfo {
StringRef Prefix;
uint32_t Indent;
IndentInfo(const char *s, size_t n, uint32_t i) :
Prefix(s, n),
Indent(i) {}
};
SmallVector<IndentInfo, 4> IndentInfos;
for (const char *p = SourceStart; p<SourceEnd; ++p) {
switch (*p) {
case '\r':
case '\n':
LineIndent = 0;
LineSourceStart = nullptr;
LineStart = p + 1;
break;
case '"':
p = skipStringInCode (p, SourceEnd);
break;
case '{':
case '(':
case '[':
++LineIndent;
if (LineSourceStart == nullptr)
IndentInfos.push_back(IndentInfo(LineStart,
p - LineStart,
LineIndent));
else
IndentInfos.push_back(IndentInfo(LineStart,
LineSourceStart - LineStart,
LineIndent));
break;
case '}':
case ')':
case ']':
if (LineIndent > 0)
--LineIndent;
if (!IndentInfos.empty())
IndentInfos.pop_back();
break;
default:
if (LineSourceStart == nullptr && !isspace(*p))
LineSourceStart = p;
break;
}
if (*p == '\0')
break;
}
if (!IndentInfos.empty()) {
SCR.IndentPrefix = IndentInfos.back().Prefix.str();
// Trim off anything that follows a non-space character
const size_t pos = SCR.IndentPrefix.find_first_not_of(" \t");
if (pos != std::string::npos)
SCR.IndentPrefix.erase(pos);
SCR.IndentLevel = IndentInfos.back().Indent;
}
return SCR;
}
示例10: Match
/// 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 the EOF pattern, match it immediately.
if (MatchEOF) {
MatchLen = 0;
return Buffer.size();
}
// 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();
}
示例11: PrintFailureInfo
void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
const StringMap<StringRef> &VariableTable) const{
// If this was a regular expression using variables, print the current
// variable values.
if (!VariableUses.empty()) {
for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
StringRef Var = VariableUses[i].first;
StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
SmallString<256> Msg;
raw_svector_ostream OS(Msg);
// Check for undefined variable references.
if (it == VariableTable.end()) {
OS << "uses undefined variable \"";
OS.write_escaped(Var) << "\"";;
} else {
OS << "with variable \"";
OS.write_escaped(Var) << "\" equal to \"";
OS.write_escaped(it->second) << "\"";
}
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), OS.str(), "note",
/*ShowLine=*/false);
}
}
// Attempt to find the closest/best fuzzy match. Usually an error happens
// because some string in the output didn't exactly match. In these cases, we
// would like to show the user a best guess at what "should have" matched, to
// save them having to actually check the input manually.
size_t NumLinesForward = 0;
size_t Best = StringRef::npos;
double BestQuality = 0;
// Use an arbitrary 4k limit on how far we will search.
for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
if (Buffer[i] == '\n')
++NumLinesForward;
// Patterns have leading whitespace stripped, so skip whitespace when
// looking for something which looks like a pattern.
if (Buffer[i] == ' ' || Buffer[i] == '\t')
continue;
// Compute the "quality" of this match as an arbitrary combination of the
// match distance and the number of lines skipped to get to this match.
unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
double Quality = Distance + (NumLinesForward / 100.);
if (Quality < BestQuality || Best == StringRef::npos) {
Best = i;
BestQuality = Quality;
}
}
// Print the "possible intended match here" line if we found something
// reasonable and not equal to what we showed in the "scanning from here"
// line.
if (Best && Best != StringRef::npos && BestQuality < 50) {
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
"possible intended match here", "note");
// FIXME: If we wanted to be really friendly we would show why the match
// failed, as it can be hard to spot simple one character differences.
}
}
示例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: startsWithWord
/// Interpreting the given string using the normal CamelCase
/// conventions, determine whether the given string starts with the
/// given "word", which is assumed to end in a lowercase letter.
static bool startsWithWord(StringRef name, StringRef word) {
if (name.size() < word.size()) return false;
return ((name.size() == word.size() || !isLowercase(name[word.size()])) &&
name.startswith(word));
}
示例14: decodePunycode
bool Punycode::decodePunycode(StringRef InputPunycode,
std::vector<uint32_t> &OutCodePoints) {
OutCodePoints.clear();
OutCodePoints.reserve(InputPunycode.size());
// -- Build the decoded string as UTF32 first because we need random access.
uint32_t n = initial_n;
int i = 0;
int bias = initial_bias;
/// let output = an empty string indexed from 0
// consume all code points before the last delimiter (if there is one)
// and copy them to output,
size_t lastDelimiter = InputPunycode.find_last_of(delimiter);
if (lastDelimiter != StringRef::npos) {
for (char c : InputPunycode.slice(0, lastDelimiter)) {
// fail on any non-basic code point
if (static_cast<unsigned char>(c) > 0x7f)
return true;
OutCodePoints.push_back(c);
}
// if more than zero code points were consumed then consume one more
// (which will be the last delimiter)
InputPunycode =
InputPunycode.slice(lastDelimiter + 1, InputPunycode.size());
}
while (!InputPunycode.empty()) {
int oldi = i;
int w = 1;
for (int k = base; ; k += base) {
// consume a code point, or fail if there was none to consume
if (InputPunycode.empty())
return true;
char codePoint = InputPunycode.front();
InputPunycode = InputPunycode.slice(1, InputPunycode.size());
// let digit = the code point's digit-value, fail if it has none
int digit = digit_index(codePoint);
if (digit < 0)
return true;
i = i + digit * w;
int t = k <= bias ? tmin
: k >= bias + tmax ? tmax
: k - bias;
if (digit < t)
break;
w = w * (base - t);
}
bias = adapt(i - oldi, OutCodePoints.size() + 1, oldi == 0);
n = n + i / (OutCodePoints.size() + 1);
i = i % (OutCodePoints.size() + 1);
// if n is a basic code point then fail
if (n < 0x80)
return true;
// insert n into output at position i
OutCodePoints.insert(OutCodePoints.begin() + i, n);
i++;
}
return true;
}
示例15: check
void IntegerTypesCheck::check(const MatchFinder::MatchResult &Result) {
auto TL = *Result.Nodes.getNodeAs<TypeLoc>("tl");
SourceLocation Loc = TL.getBeginLoc();
if (Loc.isInvalid() || Loc.isMacroID())
return;
// Look through qualification.
if (auto QualLoc = TL.getAs<QualifiedTypeLoc>())
TL = QualLoc.getUnqualifiedLoc();
auto BuiltinLoc = TL.getAs<BuiltinTypeLoc>();
if (!BuiltinLoc)
return;
Token Tok = getTokenAtLoc(Loc, Result, *IdentTable);
// Ensure the location actually points to one of the builting integral type
// names we're interested in. Otherwise, we might be getting this match from
// implicit code (e.g. an implicit assignment operator of a class containing
// an array of non-POD types).
if (!Tok.isOneOf(tok::kw_short, tok::kw_long, tok::kw_unsigned,
tok::kw_signed))
return;
bool IsSigned;
unsigned Width;
const TargetInfo &TargetInfo = Result.Context->getTargetInfo();
// Look for uses of short, long, long long and their unsigned versions.
switch (BuiltinLoc.getTypePtr()->getKind()) {
case BuiltinType::Short:
Width = TargetInfo.getShortWidth();
IsSigned = true;
break;
case BuiltinType::Long:
Width = TargetInfo.getLongWidth();
IsSigned = true;
break;
case BuiltinType::LongLong:
Width = TargetInfo.getLongLongWidth();
IsSigned = true;
break;
case BuiltinType::UShort:
Width = TargetInfo.getShortWidth();
IsSigned = false;
break;
case BuiltinType::ULong:
Width = TargetInfo.getLongWidth();
IsSigned = false;
break;
case BuiltinType::ULongLong:
Width = TargetInfo.getLongLongWidth();
IsSigned = false;
break;
default:
return;
}
// We allow "unsigned short port" as that's reasonably common and required by
// the sockets API.
const StringRef Port = "unsigned short port";
const char *Data = Result.SourceManager->getCharacterData(Loc);
if (!std::strncmp(Data, Port.data(), Port.size()) &&
!isIdentifierBody(Data[Port.size()]))
return;
std::string Replacement =
((IsSigned ? SignedTypePrefix : UnsignedTypePrefix) + Twine(Width) +
TypeSuffix)
.str();
// We don't add a fix-it as changing the type can easily break code,
// e.g. when a function requires a 'long' argument on all platforms.
// QualTypes are printed with implicit quotes.
diag(Loc, "consider replacing %0 with '%1'") << BuiltinLoc.getType()
<< Replacement;
}