/// CheckLists - Compare expected to seen diagnostic lists and return the /// the difference between them. static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr, const char *Label, DirectiveList &Left, const_diag_iterator d2_begin, const_diag_iterator d2_end, bool IgnoreUnexpected) { std::vector<Directive *> LeftOnly; DiagList Right(d2_begin, d2_end); for (auto &Owner : Left) { Directive &D = *Owner; unsigned LineNo1 = SourceMgr.getPresumedLineNumber(D.DiagnosticLoc); for (unsigned i = 0; i < D.Max; ++i) { DiagList::iterator II, IE; for (II = Right.begin(), IE = Right.end(); II != IE; ++II) { if (!D.MatchAnyLine) { unsigned LineNo2 = SourceMgr.getPresumedLineNumber(II->first); if (LineNo1 != LineNo2) continue; } if (!D.DiagnosticLoc.isInvalid() && !IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first)) continue; const std::string &RightText = II->second; if (D.match(RightText)) break; } if (II == IE) { // Not found. if (i >= D.Min) break; LeftOnly.push_back(&D); } else { // Found. The same cannot be found twice. Right.erase(II); } } } // Now all that's left in Right are those that were not matched. unsigned num = PrintExpected(Diags, SourceMgr, LeftOnly, Label); if (!IgnoreUnexpected) num += PrintUnexpected(Diags, &SourceMgr, Right.begin(), Right.end(), Label); return num; }
void Initialize(ASTContext &context) { //llvm::errs() << "initializing consumer\n"; Context = &context; SM = &Context->getSourceManager(); // Get the ID and start/end of the main file. MainFileID = SM->getMainFileID(); }
TEST(FileSpecificDiagnosticConsumer, SubConsumersFinishInOrder) { SourceManager sourceMgr; (void)sourceMgr.addMemBufferCopy("abcde", "A"); (void)sourceMgr.addMemBufferCopy("vwxyz", "B"); auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>( nullptr, None); auto consumerUnaffiliated = llvm::make_unique<ExpectationDiagnosticConsumer>( consumerA.get(), None); SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers; consumers.emplace_back("A", std::move(consumerA)); consumers.emplace_back("", std::move(consumerUnaffiliated)); FileSpecificDiagnosticConsumer topConsumer(consumers); topConsumer.finishProcessing(); }
// visit a function declaration bool VisitFunctionDecl(FunctionDecl *D) { if(!D) return true; //llvm::errs() << "begin to visit function declation: " << D->getNameAsString() << "\n"; SourceLocation Loc = D->getLocation(); Loc = SM->getSpellingLoc(Loc); //llvm::errs() << "end to visit function declation: " << D->getNameAsString() << "\n"; if (!SM->isInSystemHeader(Loc) && !SM->isInExternCSystemHeader(Loc)) { //llvm::errs() << ">>>>> visit function declaration: " << D->getNameAsString() << "\n"; if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { Method *m = HandleFunctionDecl(MD); if (m) methods.insert(std::make_pair(m->getMethodAsString(), m)); } } //else llvm::errs() << "uninteresting function declation: " << D->getNameAsString() << "\n"; return true; }
void Replacement::setFromSourceRange(const SourceManager &Sources, const CharSourceRange &Range, StringRef ReplacementText, const LangOptions &LangOpts) { setFromSourceLocation(Sources, Sources.getSpellingLoc(Range.getBegin()), getRangeSize(Sources, Range, LangOpts), ReplacementText); }
/// \brief Helper to recursivly walk up the import stack and print each layer /// on the way back down. void DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc, StringRef ModuleName, const SourceManager &SM) { if (ModuleName.empty()) { return; } PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); // Emit the other import frames first. std::pair<SourceLocation, StringRef> NextImportLoc = SM.getModuleImportLoc(Loc); emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM); // Emit the inclusion text/note. emitImportLocation(Loc, PLoc, ModuleName, SM); }
static void ReportEvent(raw_ostream &o, const PathDiagnosticPiece& P, const FIDMap& FM, const SourceManager &SM, const LangOptions &LangOpts, unsigned indent, unsigned depth, bool isKeyEvent = false) { Indent(o, indent) << "<dict>\n"; ++indent; Indent(o, indent) << "<key>kind</key><string>event</string>\n"; if (isKeyEvent) { Indent(o, indent) << "<key>key_event</key><true/>\n"; } // Output the location. FullSourceLoc L = P.getLocation().asLocation(); Indent(o, indent) << "<key>location</key>\n"; EmitLocation(o, SM, L, FM, indent); // Output the ranges (if any). ArrayRef<SourceRange> Ranges = P.getRanges(); if (!Ranges.empty()) { Indent(o, indent) << "<key>ranges</key>\n"; Indent(o, indent) << "<array>\n"; ++indent; for (auto &R : Ranges) EmitRange(o, SM, Lexer::getAsCharRange(SM.getExpansionRange(R), SM, LangOpts), FM, indent + 1); --indent; Indent(o, indent) << "</array>\n"; } // Output the call depth. Indent(o, indent) << "<key>depth</key>"; EmitInteger(o, depth) << '\n'; // Output the text. assert(!P.getString().empty()); Indent(o, indent) << "<key>extended_message</key>\n"; Indent(o, indent); EmitString(o, P.getString()) << '\n'; // Output the short text. // FIXME: Really use a short string. Indent(o, indent) << "<key>message</key>\n"; Indent(o, indent); EmitString(o, P.getString()) << '\n'; // Finish up. --indent; Indent(o, indent); o << "</dict>\n"; }
void SerializedDiagnosticConsumer:: emitDiagnosticMessage(SourceManager &SM, SourceLoc Loc, DiagnosticKind Kind, StringRef Text, const DiagnosticInfo &Info) { // Emit the diagnostic to bitcode. llvm::BitstreamWriter &Stream = State->Stream; RecordData &Record = State->Record; AbbreviationMap &Abbrevs = State->Abbrevs; StringRef filename = ""; if (Loc.isValid()) filename = SM.getDisplayNameForLoc(Loc); // Emit the RECORD_DIAG record. Record.clear(); Record.push_back(RECORD_DIAG); Record.push_back(getDiagnosticLevel(Kind)); addLocToRecord(Loc, SM, filename, Record); // FIXME: Swift diagnostics currently have no category. Record.push_back(0); // FIXME: Swift diagnostics currently have no flags. Record.push_back(0); // Emit the message. Record.push_back(Text.size()); Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_DIAG), Record, Text); // If the location is invalid, do not emit source ranges or fixits. if (Loc.isInvalid()) return; // Emit source ranges. auto RangeAbbrev = State->Abbrevs.get(RECORD_SOURCE_RANGE); for (const auto &R : Info.Ranges) { if (R.isInvalid()) continue; State->Record.clear(); State->Record.push_back(RECORD_SOURCE_RANGE); addRangeToRecord(R, SM, filename, State->Record); State->Stream.EmitRecordWithAbbrev(RangeAbbrev, State->Record); } // Emit FixIts. auto FixItAbbrev = State->Abbrevs.get(RECORD_FIXIT); for (const auto &F : Info.FixIts) { if (F.getRange().isValid()) { State->Record.clear(); State->Record.push_back(RECORD_FIXIT); addRangeToRecord(F.getRange(), SM, filename, State->Record); State->Record.push_back(F.getText().size()); Stream.EmitRecordWithBlob(FixItAbbrev, Record, F.getText()); } } }
static void addParameters(ArrayRef<Identifier> &ArgNames, const Pattern *Pat, TextEntity &Ent, SourceManager &SM, unsigned BufferID) { if (auto ParenPat = dyn_cast<ParenPattern>(Pat)) { addParameters(ArgNames, ParenPat->getSubPattern(), Ent, SM, BufferID); return; } if (auto Tuple = dyn_cast<TuplePattern>(Pat)) { for (const auto &Elt : Tuple->getElements()) addParameters(ArgNames, Elt.getPattern(), Ent, SM, BufferID); return; } StringRef Arg; if (!ArgNames.empty()) { Identifier Id = ArgNames.front(); Arg = Id.empty() ? "_" : Id.str(); ArgNames = ArgNames.slice(1); } if (auto Typed = dyn_cast<TypedPattern>(Pat)) { VarDecl *VD = nullptr; if (auto Named = dyn_cast<NamedPattern>(Typed->getSubPattern())) { VD = Named->getDecl(); } SourceRange TypeRange = Typed->getTypeLoc().getSourceRange(); if (auto InOutTyR = dyn_cast_or_null<InOutTypeRepr>(Typed->getTypeLoc().getTypeRepr())) { TypeRange = InOutTyR->getBase()->getSourceRange(); } if (TypeRange.isInvalid()) return; unsigned StartOffs = SM.getLocOffsetInBuffer(TypeRange.Start, BufferID); unsigned EndOffs = SM.getLocOffsetInBuffer(Lexer::getLocForEndOfToken(SM, TypeRange.End), BufferID); TextRange TR{ StartOffs, EndOffs-StartOffs }; TextEntity Param(VD, Arg, TR, StartOffs); Ent.SubEntities.push_back(std::move(Param)); } }
// Checks if 'typedef' keyword can be removed - we do it only if // it is the only declaration in a declaration chain. static bool CheckRemoval(SourceManager &SM, SourceLocation StartLoc, ASTContext &Context) { assert(StartLoc.isFileID() && "StartLoc must not be in a macro"); std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(StartLoc); StringRef File = SM.getBufferData(LocInfo.first); const char *TokenBegin = File.data() + LocInfo.second; Lexer DeclLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(), File.begin(), TokenBegin, File.end()); Token Tok; int ParenLevel = 0; bool FoundTypedef = false; while (!DeclLexer.LexFromRawLexer(Tok) && !Tok.is(tok::semi)) { switch (Tok.getKind()) { case tok::l_brace: case tok::r_brace: // This might be the `typedef struct {...} T;` case. return false; case tok::l_paren: ParenLevel++; break; case tok::r_paren: ParenLevel--; break; case tok::comma: if (ParenLevel == 0) { // If there is comma and we are not between open parenthesis then it is // two or more declarations in this chain. return false; } break; case tok::raw_identifier: if (Tok.getRawIdentifier() == "typedef") { FoundTypedef = true; } break; default: break; } } // Sanity check against weird macro cases. return FoundTypedef; }
static void Scan(IvarUsageMap &M, const DeclContext *C, const FileID FID, SourceManager &SM) { for (const auto *I : C->decls()) if (const auto *FD = dyn_cast<FunctionDecl>(I)) { SourceLocation L = FD->getLocStart(); if (SM.getFileID(L) == FID) Scan(M, FD->getBody()); } }
std::pair<unsigned, unsigned> getLineAndColumn(unsigned ByteOffset) const { auto &Buf = memBuffer(); if (ByteOffset > Buf.getBufferSize()) return std::make_pair(0, 0); SMLoc Loc = SMLoc::getFromPointer(Buf.getBufferStart() + ByteOffset); return SM.getLLVMSourceMgr().getLineAndColumn(Loc, BufferID); }
void Replacement::setFromSourceLocation(const SourceManager &Sources, SourceLocation Start, unsigned Length, StringRef ReplacementText) { const std::pair<FileID, unsigned> DecomposedLocation = Sources.getDecomposedLoc(Start); const FileEntry *Entry = Sources.getFileEntryForID(DecomposedLocation.first); if (Entry) { // Make FilePath absolute so replacements can be applied correctly when // relative paths for files are used. llvm::SmallString<256> FilePath(Entry->getName()); std::error_code EC = llvm::sys::fs::make_absolute(FilePath); this->FilePath = EC ? FilePath.c_str() : Entry->getName(); } else { this->FilePath = InvalidLocation; } this->ReplacementRange = Range(DecomposedLocation.second, Length); this->ReplacementText = ReplacementText; }
void SourceLoc::print(raw_ostream &OS, const SourceManager &SM, unsigned &LastBufferID) const { if (isInvalid()) { OS << "<invalid loc>"; return; } unsigned BufferID = SM.findBufferContainingLoc(*this); if (BufferID != LastBufferID) { OS << SM.getIdentifierForBuffer(BufferID); LastBufferID = BufferID; } else { OS << "line"; } auto LineAndCol = SM.getLineAndColumn(*this, BufferID); OS << ':' << LineAndCol.first << ':' << LineAndCol.second; }
static SourceLocation getTopMostMacro(SourceLocation Loc, SourceManager &SM) { assert(Loc.isMacroID()); SourceLocation Last; while (Loc.isMacroID()) { Last = Loc; Loc = SM.getImmediateMacroCallerLoc(Loc); } return Last; }
TEST(FileSpecificDiagnosticConsumer, ErrorsInUnaffiliatedFilesGoToEveryConsumer) { SourceManager sourceMgr; // 01234 unsigned bufferA = sourceMgr.addMemBufferCopy("abcde", "A"); unsigned bufferB = sourceMgr.addMemBufferCopy("vwxyz", "B"); SourceLoc frontOfA = sourceMgr.getLocForOffset(bufferA, 0); SourceLoc middleOfA = sourceMgr.getLocForOffset(bufferA, 2); SourceLoc backOfA = sourceMgr.getLocForOffset(bufferA, 4); SourceLoc frontOfB = sourceMgr.getLocForOffset(bufferB, 0); SourceLoc middleOfB = sourceMgr.getLocForOffset(bufferB, 2); SourceLoc backOfB = sourceMgr.getLocForOffset(bufferB, 4); ExpectedDiagnostic expectedA[] = { {frontOfA, "front"}, {frontOfB, "front"}, {middleOfA, "middle"}, {middleOfB, "middle"}, {backOfA, "back"}, {backOfB, "back"} }; ExpectedDiagnostic expectedUnaffiliated[] = { {frontOfB, "front"}, {middleOfB, "middle"}, {backOfB, "back"} }; auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>( nullptr, expectedA); auto consumerUnaffiliated = llvm::make_unique<ExpectationDiagnosticConsumer>( consumerA.get(), expectedUnaffiliated); SmallVector<FileSpecificDiagnosticConsumer::Subconsumer, 2> consumers; consumers.emplace_back("A", std::move(consumerA)); consumers.emplace_back("", std::move(consumerUnaffiliated)); auto topConsumer = FileSpecificDiagnosticConsumer::consolidateSubconsumers(consumers); topConsumer->handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error, "front", {}, DiagnosticInfo(), SourceLoc()); topConsumer->handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Error, "front", {}, DiagnosticInfo(), SourceLoc()); topConsumer->handleDiagnostic(sourceMgr, middleOfA, DiagnosticKind::Error, "middle", {}, DiagnosticInfo(), SourceLoc()); topConsumer->handleDiagnostic(sourceMgr, middleOfB, DiagnosticKind::Error, "middle", {}, DiagnosticInfo(), SourceLoc()); topConsumer->handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Error, "back", {}, DiagnosticInfo(), SourceLoc()); topConsumer->handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Error, "back", {}, DiagnosticInfo(), SourceLoc()); topConsumer->finishProcessing(); }
bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, DiagnosticsEngine &Diags, FileManager &FileMgr, SourceManager &SourceMgr, const FrontendOptions &Opts) { SrcMgr::CharacteristicKind Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; if (Input.isBuffer()) { SourceMgr.createMainFileIDForMemBuffer(Input.getBuffer(), Kind); assert(!SourceMgr.getMainFileID().isInvalid() && "Couldn't establish MainFileID!"); return true; } StringRef InputFile = Input.getFile(); // Figure out where to get and map in the main file. if (InputFile != "-") { const FileEntry *File = FileMgr.getFile(InputFile); if (!File) { Diags.Report(diag::err_fe_error_reading) << InputFile; return false; } // The natural SourceManager infrastructure can't currently handle named // pipes, but we would at least like to accept them for the main // file. Detect them here, read them with the more generic MemoryBuffer // function, and simply override their contents as we do for STDIN. if (File->isNamedPipe()) { OwningPtr<llvm::MemoryBuffer> MB; if (llvm::error_code ec = llvm::MemoryBuffer::getFile(InputFile, MB)) { Diags.Report(diag::err_cannot_open_file) << InputFile << ec.message(); return false; } // Create a new virtual file that will have the correct size. File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0); SourceMgr.overrideFileContents(File, MB.take()); } SourceMgr.createMainFileID(File, Kind); } else { OwningPtr<llvm::MemoryBuffer> SB; if (llvm::MemoryBuffer::getSTDIN(SB)) { // FIXME: Give ec.message() in this diag. Diags.Report(diag::err_fe_error_reading_stdin); return false; } const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), SB->getBufferSize(), 0); SourceMgr.createMainFileID(File, Kind); SourceMgr.overrideFileContents(File, SB.take()); } assert(!SourceMgr.getMainFileID().isInvalid() && "Couldn't establish MainFileID!"); return true; }
bool DoubleFetchChecker::diffTaintInBranch(ProgramStateRef state, SVal val, const Stmt* LoadS, SourceManager &mgr) const{ //assert(ifTainted(state, arg)); TaintList tl; std::list<TAINT>::iterator i, j; GlobalBranchesTy GB = state->get<GlobalBranches>(); GlobalBranchesTy::iterator I, E; I = GB.begin(); E = GB.end(); /*Get the GlobalBranch list, * which should be pointed by iterator I. */ if(I != E){ /*get the taints of val, stored in tl*/ bool ret = this->getSingleTaintListByTime(tl, state, val); if(ret) tl.showTaints("--->(diffTaintInBranch)-val: "); /* check if Expr (in the form of loc) within a controlled branch, * return the taintlist of that branch, stored in btl. * otherwise return null * LoadS is Expr*/ unsigned int location = mgr.getExpansionLineNumber(LoadS->getLocStart()); if( GlobalFuncTable.getNameByLoc(location) == "get_user"){ std::cout<<"--->(it is source func, return)\n"; return false; } std::cout<<"--->(diffTaintInBranch) location: "<<location<<std::endl; TaintList * btl = (*I).getBranchTLbyExprLoc(location); if ( btl != NULL){ if(btl->isEmpty()) std::cout<<"--->(get empty)\n"; btl->showTaints("--->(diffTaintInBranch)-branch: "); for (i = tl.getList().begin(); i != tl.getList().end(); i++) { for (j = btl->getList().begin(); j!= btl->getList().end(); j++){ if (((*i).taint != (*j).taint) && ((*i).origin == (*j).origin)){ printf("DDDDDDDDFFFFFF!!!!!!!!!!!!!!!!!!!!!!!!\n"); return true; } } } } else std::cout<<"--->(diffTaintInBranch) : get controlled branch taintlist failed.\n"; } else std::cout<<"--->(diffTaintInBranch) : get GlobalBranchesTy failed, probably no branch yet.\n"; return false; }
static void Scan(IvarUsageMap &M, const DeclContext *C, const FileID FID, SourceManager &SM) { for (DeclContext::decl_iterator I=C->decls_begin(), E=C->decls_end(); I!=E; ++I) if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) { SourceLocation L = FD->getLocStart(); if (SM.getFileID(L) == FID) Scan(M, FD->getBody()); } }
/// Check that the macro argument location of Loc starts with ArgumentLoc. /// The starting location of the macro expansions is used to differeniate /// different macro expansions. static bool checkLocForMacroArgExpansion(SourceLocation Loc, const SourceManager &SM, SourceLocation ArgumentLoc) { SourceLocation MacroLoc; if (SM.isMacroArgExpansion(Loc, &MacroLoc)) { if (ArgumentLoc == MacroLoc) return true; } return false; }
void updateCode(std::unique_ptr<llvm::MemoryBuffer> Buffer) { BufferID = SM.addNewSourceBuffer(std::move(Buffer)); Parser.reset(new ParserUnit(SM, BufferID, CompInv.getLangOptions(), CompInv.getModuleName())); Parser->getDiagnosticEngine().addConsumer(DiagConsumer); auto &P = Parser->getParser(); for (bool Done = false; !Done; Done = P.Tok.is(tok::eof)) { P.parseTopLevel(); } }
void ClangInternalState::printIncludedFiles(llvm::raw_ostream& Out, SourceManager& SM) { for (clang::SourceManager::fileinfo_iterator I = SM.fileinfo_begin(), E = SM.fileinfo_end(); I != E; ++I) { const clang::SrcMgr::ContentCache &C = *I->second; const clang::FileEntry *FE = C.OrigEntry; // Our error recovery purges the cache of the FileEntry, but keeps // the FileEntry's pointer so that if it was used by smb (like the // SourceManager) it wouldn't be dangling. In that case we shouldn't // print the FileName, because semantically it is not there. if (!FE->getSize() && !FE->getModificationTime()) continue; std::string fileName(FE->getName()); if (!(fileName.compare(0, 5, "/usr/") == 0 && fileName.find("/bits/") != std::string::npos)) { Out << fileName << '\n'; } } }
/// \brief Guess the end-of-line sequence used in the given FileID. If the /// sequence can't be guessed return an Unix-style newline. static StringRef guessEOL(SourceManager &SM, FileID ID) { StringRef Content = SM.getBufferData(ID); StringRef Buffer = Content.substr(Content.find_first_of("\r\n")); return llvm::StringSwitch<StringRef>(Buffer) .StartsWith("\r\n", "\r\n") .StartsWith("\n\r", "\n\r") .StartsWith("\r", "\r") .Default("\n"); }
std::string ide::extractPlainTextFromComment(const StringRef Text) { LangOptions LangOpts; SourceManager SourceMgr; auto Tokens = swift::tokenize(LangOpts, SourceMgr, SourceMgr.addMemBufferCopy(Text)); std::vector<SingleRawComment> Comments; Comments.reserve(Tokens.size()); for (auto &Tok : Tokens) { if (Tok.is(tok::comment)) { Comments.push_back(SingleRawComment(Tok.getText(), 0)); } } if (Comments.empty()) return {}; RawComment Comment(Comments); swift::markup::MarkupContext MC; return MC.getLineList(Comment).str(); }
void SourceLoc::printLineAndColumn(raw_ostream &OS, const SourceManager &SM) const { if (isInvalid()) { OS << "<invalid loc>"; return; } auto LineAndCol = SM.getLineAndColumn(*this); OS << "line:" << LineAndCol.first << ':' << LineAndCol.second; }
/*---------------------------------------------------------------------*//** デフォルトのソースリストに設定する **//*---------------------------------------------------------------------*/ void StoryManager::setupDefaultSourceList(bool isReserveOnly) { MyParty* party = ((MyParty*)Game::getGame()->getMyParty()); SourceManager* srcmng = party->getSourceManager(); // ソース予約処理 party->reserveDefaultSourceList(); // 基本固定ソースの追加 if(!isReserveOnly) { srcmng->addFixedSource(FixedSourceIdDef::FSRCID_EP01_AIER); // トランス srcmng->addFixedSource(FixedSourceIdDef::FSRCID_EP01_NERUROS); // 水飛沫 srcmng->addFixedSource(FixedSourceIdDef::FSRCID_EP01_NERUHAMAD); // 水のベール } // 空きソースを並び替える // srcmng->sortForEmptySource(); }
int runFD(const FunctionDecl *md, SourceManager &sm) { if (!md->hasBody()) return 0; if (!md->isThisDeclarationADefinition()) return 0; DeclarationNameInfo info = md->getNameInfo(); FullSourceLoc b(md->getLocStart(), sm), _e(md->getLocEnd(), sm); FullSourceLoc e(clang::Lexer::getLocForEndOfToken(_e, 0, sm, *this->lopt), sm); SourceRange nameRange = SourceRange(info.getLoc()); FullSourceLoc d(nameRange.getBegin(), sm), _f(nameRange.getEnd(), sm); FullSourceLoc f(clang::Lexer::getLocForEndOfToken(_f, 0, sm, *this->lopt), sm); string start(sm.getCharacterData(b), sm.getCharacterData(d)-sm.getCharacterData(b)); string name(sm.getCharacterData(d), sm.getCharacterData(f)-sm.getCharacterData(d)); string end(sm.getCharacterData(f), sm.getCharacterData(e)-sm.getCharacterData(f)); if (this->methods.find(name) != this->methods.end()) { message("Redefinition of method " + name); return 1; } METHOD* m = new METHOD(); m->pre = start; m->name = name; m->post = end; getAbsoluteLocation(FullSourceLoc(md->getLocStart(), sm), FullSourceLoc(md->getLocEnd(), sm), &m->location.begin, &m->location.end, *this->lopt); m->sm = &sm; m->range = CharSourceRange:: getTokenRange(SourceRange(info.getLoc())); this->methods[name] = m; // For debugging purposes // cout << start << "|" << name << "|" << end << endl; return 0; }
/// \brief Find the end of the end of the directive, either the beginning of a /// newline or the end of file. // // \return The offset into the file where the directive ends along with a // boolean value indicating whether the directive ends because the end of file // was reached or not. static std::pair<unsigned, bool> findDirectiveEnd(SourceLocation HashLoc, SourceManager &SM, const LangOptions &LangOpts) { FileID FID = SM.getFileID(HashLoc); unsigned Offset = SM.getFileOffset(HashLoc); StringRef Content = SM.getBufferData(FID); Lexer Lex(SM.getLocForStartOfFile(FID), LangOpts, Content.begin(), Content.begin() + Offset, Content.end()); Lex.SetCommentRetentionState(true); Token Tok; // This loop look for the newline after our directive but avoids the ones part // of a multi-line comments: // // #include <foo> /* long \n comment */\n // ~~ no ~~ yes for (;;) { // find the beginning of the end-of-line sequence StringRef::size_type EOLOffset = Content.find_first_of("\r\n", Offset); // ends because EOF was reached if (EOLOffset == StringRef::npos) return std::make_pair(Content.size(), true); // find the token that contains our end-of-line unsigned TokEnd = 0; do { Lex.LexFromRawLexer(Tok); TokEnd = SM.getFileOffset(Tok.getLocation()) + Tok.getLength(); // happens when the whitespaces are eaten after a multiline comment if (Tok.is(tok::eof)) return std::make_pair(EOLOffset, false); } while (TokEnd < EOLOffset); // the end-of-line is not part of a multi-line comment, return its location if (Tok.isNot(tok::comment)) return std::make_pair(EOLOffset, false); // for the next search to start after the end of this token Offset = TokEnd; } }
/// \brief Emit the module import stack associated with the current location. void DiagnosticRenderer::emitImportStack(SourceLocation Loc, const SourceManager &SM) { if (Loc.isInvalid()) { //emitModuleBuildStack(SM); return; } std::pair<SourceLocation, StringRef> NextImportLoc = SM.getModuleImportLoc(Loc); emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM); }
/// \brief Emit the module build stack, for cases where a module is (re-)built /// on demand. void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) { ModuleBuildStack Stack = SM.getModuleBuildStack(); for (unsigned I = 0, N = Stack.size(); I != N; ++I) { const SourceManager &CurSM = Stack[I].second.getManager(); SourceLocation CurLoc = Stack[I].second; emitBuildingModuleLocation(CurLoc, CurSM.getPresumedLoc(CurLoc), Stack[I].first, CurSM); } }