A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/HTMLDiagnostics_8cpp_source.html below:

clang: lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp Source File

29#include "llvm/ADT/ArrayRef.h" 30#include "llvm/ADT/RewriteBuffer.h" 31#include "llvm/ADT/STLExtras.h" 32#include "llvm/ADT/Sequence.h" 33#include "llvm/ADT/SmallString.h" 34#include "llvm/ADT/StringRef.h" 35#include "llvm/ADT/iterator_range.h" 36#include "llvm/Support/Casting.h" 37#include "llvm/Support/Errc.h" 38#include "llvm/Support/ErrorHandling.h" 39#include "llvm/Support/FileSystem.h" 40#include "llvm/Support/MemoryBuffer.h" 41#include "llvm/Support/Path.h" 42#include "llvm/Support/raw_ostream.h" 50#include <system_error> 54using namespace clang

;

56using

llvm::RewriteBuffer;

68

std::string Directory;

69 bool

createdDir =

false

;

72 const bool

SupportsCrossFileDiagnostics;

73

llvm::StringSet<> EmittedHashes;

80 bool

supportsMultipleFiles)

81

: DiagOpts(

std

::move(DiagOpts)), Directory(OutputDir), PP(pp),

82

SupportsCrossFileDiagnostics(supportsMultipleFiles) {}

87

FilesMade *filesMade)

override

;

89

StringRef

getName

()

const override

{

return "HTMLDiagnostics"

; }

92 return

SupportsCrossFileDiagnostics;

103 const

std::vector<SourceRange> &PopUpRanges,

unsigned

num,

107 const char

*HighlightStart =

"<span class=\"mrange\">"

,

108 const char

*HighlightEnd =

"</span>"

);

115 const char

*declName);

131 const

ArrowMap &ArrowIndices);

134

StringRef showHelpJavascript();

137

StringRef generateKeyboardNavigationJavascript();

140

StringRef generateArrowDrawingJavascript();

148

llvm::raw_string_ostream &os);

152 return

isa<PathDiagnosticControlFlowPiece>(

P

) &&

P

.getString().empty();

156 unsigned

TotalPieces =

Path

.size();

157 unsigned

TotalArrowPieces = llvm::count_if(

159 return

TotalPieces - TotalArrowPieces;

162class

ArrowMap :

public

std::vector<unsigned> {

163 using Base

= std::vector<unsigned>;

166

ArrowMap(

unsigned

Size) :

Base

(

Size

, 0) {}

167 unsigned

getTotalNumberOfArrows()

const

{

return

at(0); }

170

llvm::raw_ostream &

operator<<

(llvm::raw_ostream &OS,

const

ArrowMap &Indices) {

172

llvm::interleave(Indices, OS,

","

);

178void

ento::createHTMLDiagnosticConsumer(

189

createTextMinimalPathDiagnosticConsumer(DiagOpts,

C

, OutputDir, PP, CTU,

193 if

(OutputDir.empty())

196 C

.push_back(

new

HTMLDiagnostics(std::move(DiagOpts), OutputDir, PP,

true

));

199void

ento::createHTMLSingleFileDiagnosticConsumer(

204

createTextMinimalPathDiagnosticConsumer(DiagOpts,

C

, OutputDir, PP, CTU,

208 if

(OutputDir.empty())

211 C

.push_back(

new

HTMLDiagnostics(std::move(DiagOpts), OutputDir, PP,

false

));

214void

ento::createPlistHTMLDiagnosticConsumer(

219

createHTMLDiagnosticConsumer(

220

DiagOpts,

C

, std::string(llvm::sys::path::parent_path(prefix)), PP, CTU,

222

createPlistMultiFileDiagnosticConsumer(DiagOpts,

C

, prefix, PP, CTU,

224

createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts),

C

, prefix, PP,

225

CTU, MacroExpansions);

228void

ento::createSarifHTMLDiagnosticConsumer(

233

createHTMLDiagnosticConsumer(

234

DiagOpts,

C

, std::string(llvm::sys::path::parent_path(sarif_file)), PP,

235

CTU, MacroExpansions);

236

createSarifDiagnosticConsumer(DiagOpts,

C

, sarif_file, PP, CTU,

238

createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts),

C

, sarif_file,

239

PP, CTU, MacroExpansions);

246void

HTMLDiagnostics::FlushDiagnosticsImpl(

247

std::vector<const PathDiagnostic *> &Diags,

248

FilesMade *filesMade) {

249 for

(

const auto Diag

: Diags)

250

ReportDiag(*

Diag

, filesMade);

266

FilesMade *filesMade) {

270 if

(std::error_code ec = llvm::sys::fs::create_directories(Directory)) {

271

llvm::errs() <<

"warning: could not create directory '" 272

<< Directory <<

"': "

<< ec.message() <<

'\n'

;

285

assert(!path.empty());

286 const SourceManager

&SMgr = path.front()->getLocation().getManager();

294 if

(

const Decl

*DeclWithIssue =

D

.getDeclWithIssue()) {

295 if

(

const auto

*ND = dyn_cast<NamedDecl>(DeclWithIssue))

296

declName = ND->getDeclName().getAsString();

298 if

(

const Stmt

*Body = DeclWithIssue->getBody()) {

305

offsetDecl = L.getExpansionLineNumber() - FunL.getExpansionLineNumber();

310 auto

[It, IsNew] = EmittedHashes.insert(IssueHash);

316

std::string report = GenerateHTML(

D

, R, SMgr, path, declName.c_str());

317 if

(report.empty()) {

318

llvm::errs() <<

"warning: no diagnostics generated for main file.\n"

;

326

llvm::raw_svector_ostream

FileName

(FileNameStr);

339

path.back()->getLocation().asLocation().getExpansionLoc().getFileID();

344

<< declName.c_str() <<

"-"

<< offsetDecl <<

"-"

;

347 FileName

<< StringRef(IssueHash).substr(0, 6).str() <<

".html"

;

350

llvm::sys::path::append(ResultPath, Directory,

FileName

.str());

351 if

(std::error_code EC = llvm::sys::fs::make_absolute(ResultPath)) {

352

llvm::errs() <<

"warning: could not make '"

<< ResultPath

353

<<

"' absolute: "

<< EC.message() <<

'\n'

;

357 if

(std::error_code EC = llvm::sys::fs::openFileForReadWrite(

358

ResultPath, FD, llvm::sys::fs::CD_CreateNew,

359

llvm::sys::fs::OF_Text)) {

365 if

(EC != llvm::errc::file_exists) {

366

llvm::errs() <<

"warning: could not create file in '"

<< Directory

367

<<

"': "

<< EC.message() <<

'\n'

;

372

llvm::raw_fd_ostream os(FD,

true

);

375

filesMade->addDiagnostic(

D

,

getName

(),

376

llvm::sys::path::filename(ResultPath));

385

std::vector<FileID> FileIDs;

386 for

(

auto

I : path) {

387 FileID

FID = I->getLocation().asLocation().getExpansionLoc().getFileID();

388 if

(llvm::is_contained(FileIDs, FID))

391

FileIDs.push_back(FID);

392

RewriteFile(R, path, FID);

395 if

(SupportsCrossFileDiagnostics && FileIDs.size() > 1) {

397 for

(

auto

I = FileIDs.begin(),

E

= FileIDs.end(); I !=

E

; I++) {

399

llvm::raw_string_ostream os(

s

);

401 if

(I != FileIDs.begin())

402

os <<

"<hr class=divider>\n"

;

404

os <<

"<div id=File"

<< I->getHashValue() <<

">\n"

;

407 if

(I != FileIDs.begin())

408

os <<

"<div class=FileNav><a href=\"#File"

<< (I - 1)->getHashValue()

409

<<

"\">&#x2190;</a></div>"

;

416

os <<

"<div class=FileNav><a href=\"#File"

<< (I + 1)->getHashValue()

417

<<

"\">&#x2192;</a></div>"

;

425 for

(

auto

I : llvm::drop_begin(FileIDs)) {

427

llvm::raw_string_ostream os(

s

);

430 for

(

auto

BI : *Buf)

443

path.back()->getLocation().asLocation().getExpansionLoc().getFileID();

445

FinalizeHTML(

D

, R, SMgr, path, FileIDs[0], *Entry, declName);

448

llvm::raw_string_ostream os(file);

449 for

(

auto

BI : *Buf)

455void

HTMLDiagnostics::dumpCoverageData(

458

llvm::raw_string_ostream &os) {

462

os <<

"var relevant_lines = {"

;

463 for

(

auto

I = ExecutedLines.begin(),

464 E

= ExecutedLines.end(); I !=

E

; ++I) {

465 if

(I != ExecutedLines.begin())

468

os <<

"\""

<< I->first.getHashValue() <<

"\": {"

;

469 for

(

unsigned

LineNo : I->second) {

470 if

(LineNo != *(I->second.begin()))

473

os <<

"\""

<< LineNo <<

"\": 1"

;

481

std::string HTMLDiagnostics::showRelevantLinesJavascript(

484

llvm::raw_string_ostream os(

s

);

485

os <<

"<script type='text/javascript'>\n"

;

486

dumpCoverageData(

D

, path, os);

489var filterCounterexample = function (hide) { 490 var tables = document.getElementsByClassName("code"); 491 for (var t=0; t<tables.length; t++) { 492 var table = tables[t]; 493 var file_id = table.getAttribute("data-fileid"); 494 var lines_in_fid = relevant_lines[file_id]; 498 var lines = table.getElementsByClassName("codeline"); 499 for (var i=0; i<lines.length; i++) { 501 var lineNo = el.getAttribute("data-linenumber"); 502 if (!lines_in_fid[lineNo]) { 504 el.setAttribute("hidden", ""); 506 el.removeAttribute("hidden"); 513window.addEventListener("keydown", function (event) { 514 if (event.defaultPrevented) { 518 if (event.shiftKey && event.keyCode == 83) { 519 var checked = document.getElementsByName("showCounterexample")[0].checked; 520 filterCounterexample(!checked); 521 document.getElementsByName("showCounterexample")[0].click(); 525 event.preventDefault(); 528document.addEventListener("DOMContentLoaded", function() { 529 document.querySelector('input[name="showCounterexample"]').onchange= 531 filterCounterexample(this.checked); 537 <input type="checkbox" name="showCounterexample" id="showCounterexample" /> 538 <label for="showCounterexample"> 539 Show only relevant lines 541 <input type="checkbox" name="showArrows" 542 id="showArrows" style="margin-left: 10px" /> 543 <label for="showArrows"> 544 Show control flow arrows 562 if

(llvm::sys::path::is_relative(Entry.

getName

())) {

563

llvm::sys::fs::current_path(DirName);

567 int

LineNumber = path.back()->getLocation().asLocation().getExpansionLineNumber();

568 int

ColumnNumber = path.back()->getLocation().asLocation().getExpansionColumnNumber();

573

generateKeyboardNavigationJavascript());

576

generateArrowDrawingJavascript());

580

showRelevantLinesJavascript(

D

, path));

585

llvm::raw_string_ostream os(

s

);

587

os <<

"<!-- REPORTHEADER -->\n" 588

<<

"<h3>Bug Summary</h3>\n<table class=\"simpletable\">\n" 589 "<tr><td class=\"rowname\">File:</td><td>" 592

<<

"</td></tr>\n<tr><td class=\"rowname\">Warning:</td><td>" 593 "<a href=\"#EndPath\">line " 598

<<

D

.getVerboseDescription() <<

"</td></tr>\n"

;

601 unsigned

NumExtraPieces = 0;

602 for

(

const auto

&Piece : path) {

603 if

(

const auto

*

P

= dyn_cast<PathDiagnosticNotePiece>(Piece.get())) {

605 P

->getLocation().asLocation().getExpansionLineNumber();

607 P

->getLocation().asLocation().getExpansionColumnNumber();

609

os <<

"<tr><td class=\"rowname\">Note:</td><td>" 610

<<

"<a href=\"#Note"

<< NumExtraPieces <<

"\">line " 611

<< LineNumber <<

", column "

<< ColumnNumber <<

"</a><br />" 612

<<

P

->getString() <<

"</td></tr>"

;

618 for

(

const

std::string &Metadata :

619

llvm::make_range(

D

.meta_begin(),

D

.meta_end())) {

620

os <<

"<tr><td></td><td>"

<<

html::EscapeText

(Metadata) <<

"</td></tr>\n"

;

625<!-- REPORTSUMMARYEXTRA --> 626<h3>Annotated Source Code</h3> 627<p>Press <a href="#" onclick="toggleHelp(); return false;">'?'</a> 628 to see keyboard shortcuts</p> 629<input type="checkbox" class="spoilerhider" id="showinvocation" /> 630<label for="showinvocation" >Show analyzer invocation</label> 631<div class="spoiler">clang -cc1 )<<<"; 635<div id='tooltiphint' hidden="true"> 636 <p>Keyboard shortcuts: </p> 638 <li>Use 'j/k' keys for keyboard navigation</li> 639 <li>Use 'Shift+S' to show/hide relevant lines</li> 640 <li>Use '?' to toggle this window</li> 642 <a href="#" onclick="toggleHelp(); return false;">Close</a> 652

llvm::raw_string_ostream os(

s

);

654

StringRef BugDesc =

D

.getVerboseDescription();

655 if

(!BugDesc.empty())

656

os <<

"\n<!-- BUGDESC "

<< BugDesc <<

" -->\n"

;

658

StringRef

BugType

=

D

.getBugType();

660

os <<

"\n<!-- BUGTYPE "

<<

BugType

<<

" -->\n"

;

668

StringRef BugCategory =

D

.getCategory();

669 if

(!BugCategory.empty())

670

os <<

"\n<!-- BUGCATEGORY "

<< BugCategory <<

" -->\n"

;

672

os <<

"\n<!-- BUGFILE "

<< DirName << Entry.

getName

() <<

" -->\n"

;

674

os <<

"\n<!-- FILENAME "

<< llvm::sys::path::filename(Entry.

getName

()) <<

" -->\n"

;

676

os <<

"\n<!-- FUNCTIONNAME "

<< declName <<

" -->\n"

;

678

os <<

"\n<!-- ISSUEHASHCONTENTOFLINEINCONTEXT "

<<

getIssueHash

(

D

, PP)

681

os <<

"\n<!-- BUGLINE " 685

os <<

"\n<!-- BUGCOLUMN " 689

os <<

"\n<!-- BUGPATHLENGTH "

<< getPathSizeWithoutArrows(path) <<

" -->\n"

;

692

os <<

"\n<!-- BUGMETAEND -->\n"

;

701

StringRef HTMLDiagnostics::showHelpJavascript() {

703<script type='text/javascript'> 705var toggleHelp = function() { 706 var hint = document.querySelector("#tooltiphint"); 707 var attributeName = "hidden"; 708 if (hint.hasAttribute(attributeName)) { 709 hint.removeAttribute(attributeName); 711 hint.setAttribute("hidden", "true"); 714window.addEventListener("keydown", function (event) { 715 if (event.defaultPrevented) { 718 if (event.key == "?") { 723 event.preventDefault(); 730 return

!(

Range

.getBegin().isMacroID() ||

Range

.getEnd().isMacroID());

735 const

std::vector<SourceRange> &PopUpRanges) {

736 for

(

const auto

&

Range

: PopUpRanges) {

741 "<table class='variable_popup'><tbody>"

,

748

std::vector<SourceRange> &PopUpRanges,

749 unsigned int

LastReportedPieceIndex,

750 unsigned int

PopUpPieceIndex) {

752

llvm::raw_svector_ostream Out(Buf);

759

Out <<

"<tr><td valign='top'><div class='PathIndex PathIndexPopUp'>" 760

<< LastReportedPieceIndex;

763

Out <<

'.'

<< PopUpPieceIndex;

765

Out <<

"</div></td><td>"

<< Piece.

getString

() <<

"</td></tr>"

;

768 if

(!llvm::is_contained(PopUpRanges,

Range

)) {

770

PopUpRanges.push_back(

Range

);

772

Out <<

"</tbody></table></span>"

;

774 "<span class='variable'>"

, Buf.c_str(),

788 unsigned

TotalPieces = getPathSizeWithoutArrows(path);

789 unsigned

TotalNotePieces =

791 return

isa<PathDiagnosticNotePiece>(*p);

793 unsigned

PopUpPieceCount =

795 return

isa<PathDiagnosticPopUpPiece>(*p);

798 unsigned

TotalRegularPieces = TotalPieces - TotalNotePieces - PopUpPieceCount;

799 unsigned

NumRegularPieces = TotalRegularPieces;

800 unsigned

NumNotePieces = TotalNotePieces;

801 unsigned

NumberOfArrows = 0;

803

std::map<int, int> IndexMap;

804

ArrowMap ArrowIndices(TotalRegularPieces + 1);

807

std::vector<SourceRange> PopUpRanges;

809 const auto

&Piece = *I.get();

811 if

(isa<PathDiagnosticPopUpPiece>(Piece)) {

812

++IndexMap[NumRegularPieces];

813

}

else if

(isa<PathDiagnosticNotePiece>(Piece)) {

817

HandlePiece(R, FID, Piece, PopUpRanges, NumNotePieces, TotalNotePieces);

820

}

else if

(isArrowPiece(Piece)) {

821

NumberOfArrows = ProcessControlFlowPiece(

822

R, FID, cast<PathDiagnosticControlFlowPiece>(Piece), NumberOfArrows);

823

ArrowIndices[NumRegularPieces] = NumberOfArrows;

826

HandlePiece(R, FID, Piece, PopUpRanges, NumRegularPieces,

829

ArrowIndices[NumRegularPieces] = ArrowIndices[NumRegularPieces + 1];

832

ArrowIndices[0] = NumberOfArrows;

842

assert(ArrowIndices.back() == 0 &&

843 "No arrows should be after the last event"

);

845

assert(llvm::is_sorted(ArrowIndices, std::greater<unsigned>()) &&

846 "Incorrect arrow indices map"

);

850

NumRegularPieces = TotalRegularPieces;

852 const auto

&Piece = *I.get();

854 if

(

const auto

*PopUpP = dyn_cast<PathDiagnosticPopUpPiece>(&Piece)) {

855 int

PopUpPieceIndex = IndexMap[NumRegularPieces];

865 if

(PopUpPieceIndex > 0)

866

--IndexMap[NumRegularPieces];

868

}

else if

(!isa<PathDiagnosticNotePiece>(Piece) && !isArrowPiece(Piece)) {

880

addArrowSVGs(R, FID, ArrowIndices);

891 const

std::vector<SourceRange> &PopUpRanges,

892 unsigned

num,

unsigned max

) {

901

assert(&Pos.

getManager

() == &

SM

&&

"SourceManagers are different!"

);

902

std::pair<FileID, unsigned> LPosInfo =

SM

.getDecomposedExpansionLoc(Pos);

904 if

(LPosInfo.first != BugFileID)

907

llvm::MemoryBufferRef Buf =

SM

.getBufferOrFake(LPosInfo.first);

908 const char

*FileStart = Buf.getBufferStart();

912 unsigned

ColNo =

SM

.getColumnNumber(LPosInfo.first, LPosInfo.second);

914 const char

*LineStart = TokInstantiationPtr-ColNo;

917 const char

*LineEnd = TokInstantiationPtr;

918 const char

*FileEnd = Buf.getBufferEnd();

919 while

(*LineEnd !=

'\n'

&& LineEnd != FileEnd)

924 for

(

const char

*

c

= LineStart;

c

!= TokInstantiationPtr; ++

c

)

925

PosNo += *

c

==

'\t'

? 8 : 1;

929 const char

*

Kind

=

nullptr

;

930 bool

IsNote =

false

;

931 bool

SuppressIndex = (

max

== 1);

932 switch

(

P

.getKind()) {

940

SuppressIndex =

true

;

944

llvm_unreachable(

"Calls and extra notes should already be handled"

);

948

llvm::raw_string_ostream os(sbuf);

950

os <<

"\n<tr><td class=\"num\"></td><td class=\"line\"><div id=\""

;

954 else if

(num ==

max

)

959

os <<

"\" class=\"msg"

;

961

os <<

" msg"

<<

Kind

;

962

os <<

"\" style=\"margin-left:"

<< PosNo <<

"ex"

;

965 if

(!isa<PathDiagnosticMacroPiece>(

P

)) {

967 const auto

&Msg =

P

.getString();

968 unsigned

max_token = 0;

970 unsigned

len = Msg.size();

980 if

(cnt > max_token) max_token = cnt;

989 const unsigned

max_line = 120;

991 if

(max_token >= max_line)

994 unsigned

characters = max_line;

995 unsigned

lines = len / max_line;

998 for

(; characters > max_token; --characters)

999 if

(len / characters > lines) {

1005

em = characters / 2;

1008 if

(em < max_line/2)

1009

os <<

"; max-width:"

<< em <<

"em"

;

1012

os <<

"; max-width:100em"

;

1016 if

(!SuppressIndex) {

1017

os <<

"<table class=\"msgT\"><tr><td valign=\"top\">"

;

1018

os <<

"<div class=\"PathIndex"

;

1019 if

(Kind) os <<

" PathIndex"

<<

Kind

;

1020

os <<

"\">"

<< num <<

"</div>"

;

1023

os <<

"</td><td><div class=\"PathNav\"><a href=\"#Path" 1025

<<

"\" title=\"Previous event (" 1027

<<

")\">&#x2190;</a></div>"

;

1033 if

(

const auto

*MP = dyn_cast<PathDiagnosticMacroPiece>(&

P

)) {

1034

os <<

"Within the expansion of the macro '"

;

1042 const char

* MacroName = LocInfo.second + BufferInfo.data();

1044

BufferInfo.begin(), MacroName, BufferInfo.end());

1048 for

(

unsigned

i = 0, n = TheTok.

getLength

(); i < n; ++i)

1054 if

(!SuppressIndex) {

1057

os <<

"<td><div class=\"PathNav\"><a href=\"#"

;

1061

os <<

"Path"

<< (num + 1);

1062

os <<

"\" title=\"Next event (" 1064

<<

")\">&#x2192;</a></div></td>"

;

1067

os <<

"</tr></table>"

;

1071

ProcessMacroPiece(os, *MP, 0);

1076 if

(!SuppressIndex) {

1079

os <<

"<td><div class=\"PathNav\"><a href=\"#"

;

1083

os <<

"Path"

<< (num + 1);

1084

os <<

"\" title=\"Next event (" 1086

<<

")\">&#x2192;</a></div></td>"

;

1089

os <<

"</tr></table>"

;

1093

os <<

"</div></td></tr>"

;

1096 unsigned

DisplayPos = LineEnd - FileStart;

1098 SM

.getLocForStartOfFile(LPosInfo.first).getLocWithOffset(DisplayPos);

1104 for

(

const auto

&

Range

: Ranges) {

1106 if

(llvm::is_contained(PopUpRanges,

Range

))

1109

HighlightRange(R, LPosInfo.first,

Range

);

1114 unsigned

x = n % (

'z'

-

'a'

);

1120

os << char(

'a'

+ x);

1123unsigned

HTMLDiagnostics::ProcessMacroPiece(raw_ostream &os,

1126 for

(

const auto

&subPiece :

P

.subPieces) {

1127 if

(

const auto

*MP = dyn_cast<PathDiagnosticMacroPiece>(subPiece.get())) {

1128

num = ProcessMacroPiece(os, *MP, num);

1132 if

(

const auto

*EP = dyn_cast<PathDiagnosticEventPiece>(subPiece.get())) {

1133

os <<

"<div class=\"msg msgEvent\" style=\"width:94%; " 1134 "margin-left:5px\">" 1135 "<table class=\"msgT\"><tr>" 1136 "<td valign=\"top\"><div class=\"PathIndex PathIndexEvent\">"

;

1138

os <<

"</div></td><td valign=\"top\">" 1140

<<

"</td></tr></table></div>\n"

;

1147void

HTMLDiagnostics::addArrowSVGs(

Rewriter

&R,

FileID

BugFileID,

1148 const

ArrowMap &ArrowIndices) {

1150

llvm::raw_string_ostream OS(S);

1153<style type="text/css"> 1160 pointer-events: none; 1164 stroke-opacity: 0.2; 1166 marker-end: url(#arrowhead); 1170 stroke-opacity: 0.6; 1172 marker-end: url(#arrowheadSelected); 1182<svg xmlns="http://www.w3.org/2000/svg"> 1184 <marker id="arrowheadSelected" class="arrowhead" opacity="0.6" 1185 viewBox="0 0 10 10" refX="3" refY="5" 1186 markerWidth="4" markerHeight="4"> 1187 <path d="M 0 0 L 10 5 L 0 10 z" /> 1189 <marker id="arrowhead" class="arrowhead" opacity="0.2" 1190 viewBox="0 0 10 10" refX="3" refY="5" 1191 markerWidth="4" markerHeight="4"> 1192 <path d="M 0 0 L 10 5 L 0 10 z" /> 1195 <g id="arrows" fill="none" stroke="blue" visibility="hidden"> 1198 for

(

unsigned

Index : llvm::seq(0u, ArrowIndices.getTotalNumberOfArrows())) {

1199

OS <<

" <path class=\"arrow\" id=\"arrow"

<< Index <<

"\"/>\n"

;

1205<script type='text/javascript'> 1206const arrowIndices = )<<<"; 1208 OS << ArrowIndices << "\n</script>\n"

;

1217

llvm::raw_string_ostream OS(Result);

1218

OS <<

"<span id=\""

<< ClassName << Index <<

"\">"

;

1230unsigned

HTMLDiagnostics::ProcessControlFlowPiece(

1237 HighlightRange

(R, BugFileID, LPair.getStart().asRange().getBegin(),

1239 HighlightRange

(R, BugFileID, LPair.getEnd().asRange().getBegin(),

1246void

HTMLDiagnostics::HighlightRange(

Rewriter

& R,

FileID

BugFileID,

1248 const char

*HighlightStart,

1249 const char

*HighlightEnd) {

1254 unsigned

StartLineNo =

SM

.getExpansionLineNumber(InstantiationStart);

1257 unsigned

EndLineNo =

SM

.getExpansionLineNumber(InstantiationEnd);

1259 if

(EndLineNo < StartLineNo)

1262 if

(

SM

.getFileID(InstantiationStart) != BugFileID ||

1263 SM

.getFileID(InstantiationEnd) != BugFileID)

1267 unsigned

EndColNo =

SM

.getExpansionColumnNumber(InstantiationEnd);

1268 unsigned

OldEndColNo = EndColNo;

1284

StringRef HTMLDiagnostics::generateKeyboardNavigationJavascript() {

1286<script type='text/javascript'> 1287var digitMatcher = new RegExp("[0-9]+"); 1289var querySelectorAllArray = function(selector) { 1290 return Array.prototype.slice.call( 1291 document.querySelectorAll(selector)); 1294document.addEventListener("DOMContentLoaded", function() { 1295 querySelectorAllArray(".PathNav > a").forEach( 1296 function(currentValue, currentIndex) { 1297 var hrefValue = currentValue.getAttribute("href"); 1298 currentValue.onclick = function() { 1299 scrollTo(document.querySelector(hrefValue)); 1305var findNum = function() { 1306 var s = document.querySelector(".msg.selected"); 1307 if (!s || s.id == "EndPath") { 1310 var out = parseInt(digitMatcher.exec(s.id)[0]); 1314var classListAdd = function(el, theClass) { 1315 if(!el.className.baseVal) 1316 el.className += " " + theClass; 1318 el.className.baseVal += " " + theClass; 1321var classListRemove = function(el, theClass) { 1322 var className = (!el.className.baseVal) ? 1323 el.className : el.className.baseVal; 1324 className = className.replace(" " + theClass, ""); 1325 if(!el.className.baseVal) 1326 el.className = className; 1328 el.className.baseVal = className; 1331var scrollTo = function(el) { 1332 querySelectorAllArray(".selected").forEach(function(s) { 1333 classListRemove(s, "selected"); 1335 classListAdd(el, "selected"); 1336 window.scrollBy(0, el.getBoundingClientRect().top - 1337 (window.innerHeight / 2)); 1338 highlightArrowsForSelectedEvent(); 1341var move = function(num, up, numItems) { 1342 if (num == 1 && up || num == numItems - 1 && !up) { 1344 } else if (num == 0 && up) { 1345 return numItems - 1; 1346 } else if (num == 0 && !up) { 1347 return 1 % numItems; 1349 return up ? num - 1 : num + 1; 1352var numToId = function(num) { 1354 return document.getElementById("EndPath") 1356 return document.getElementById("Path" + num); 1359var navigateTo = function(up) { 1360 var numItems = document.querySelectorAll( 1361 ".line > .msgEvent, .line > .msgControl").length; 1362 var currentSelected = findNum(); 1363 var newSelected = move(currentSelected, up, numItems); 1364 var newEl = numToId(newSelected, numItems); 1366 // Scroll element into center. 1370window.addEventListener("keydown", function (event) { 1371 if (event.defaultPrevented) { 1375 if (event.keyCode == 74) { 1376 navigateTo(/*up=*/false); 1378 } else if (event.keyCode == 75) { 1379 navigateTo(/*up=*/true); 1383 event.preventDefault(); 1389StringRef HTMLDiagnostics::generateArrowDrawingJavascript() { 1391<script type='text/javascript'> 1392// Return range of numbers from a range [lower, upper). 1393function range(lower, upper) { 1395 for (var i = lower; i <= upper; ++i) { 1401var getRelatedArrowIndices = function(pathId) { 1402 // HTML numeration of events is a bit different than it is in the path. 1403 // Everything is rotated one step to the right, so the last element 1404 // (error diagnostic) has index 0. 1406 // arrowIndices has at least 2 elements 1407 pathId = arrowIndices.length - 1; 1410 return range(arrowIndices[pathId], arrowIndices[pathId - 1]); 1413var highlightArrowsForSelectedEvent = function() { 1414 const selectedNum = findNum(); 1415 const arrowIndicesToHighlight = getRelatedArrowIndices(selectedNum); 1416 arrowIndicesToHighlight.forEach((index) => { 1417 var arrow = document.querySelector("#arrow" + index); 1419 classListAdd(arrow, "selected") 1424var getAbsoluteBoundingRect = function(element) { 1425 const relative = element.getBoundingClientRect(); 1427 left: relative.left + window.pageXOffset, 1428 right: relative.right + window.pageXOffset, 1429 top: relative.top + window.pageYOffset, 1430 bottom: relative.bottom + window.pageYOffset, 1431 height: relative.height, 1432 width: relative.width 1436var drawArrow = function(index) { 1437 // This function is based on the great answer from SO: 1438 // https://stackoverflow.com/a/39575674/11582326 1439 var start = document.querySelector("#start" + index); 1440 var end = document.querySelector("#end" + index); 1441 var arrow = document.querySelector("#arrow" + index); 1443 var startRect = getAbsoluteBoundingRect(start); 1444 var endRect = getAbsoluteBoundingRect(end); 1446 // It is an arrow from a token to itself, no need to visualize it. 1447 if (startRect.top == endRect.top && 1448 startRect.left == endRect.left) 1451 // Each arrow is a very simple Bézier curve, with two nodes and 1452 // two handles. So, we need to calculate four points in the window: 1454 var posStart = { x: 0, y: 0 }; 1456 var posEnd = { x: 0, y: 0 }; 1457 // * handle for the start node 1458 var startHandle = { x: 0, y: 0 }; 1459 // * handle for the end node 1460 var endHandle = { x: 0, y: 0 }; 1461 // One can visualize it as follows: 1477 // NOTE: (0, 0) is the top left corner of the window. 1479 // We have 3 similar, but still different scenarios to cover: 1481 // 1. Two tokens on different lines. 1486 // In this situation, we draw arrow on the left curving to the left. 1487 // 2. Two tokens on the same line, and the destination is on the right. 1492 // In this situation, we draw arrow above curving upwards. 1493 // 3. Two tokens on the same line, and the destination is on the left. 1497 // In this situation, we draw arrow below curving downwards. 1498 const onDifferentLines = startRect.top <= endRect.top - 5 || 1499 startRect.top >= endRect.top + 5; 1500 const leftToRight = startRect.left < endRect.left; 1502 // NOTE: various magic constants are chosen empirically for 1503 // better positioning and look 1504 if (onDifferentLines) { 1506 const topToBottom = startRect.top < endRect.top; 1507 posStart.x = startRect.left - 1; 1508 // We don't want to start it at the top left corner of the token, 1509 // it doesn't feel like this is where the arrow comes from. 1510 // For this reason, we start it in the middle of the left side 1512 posStart.y = startRect.top + startRect.height / 2; 1514 // End node has arrow head and we give it a bit more space. 1515 posEnd.x = endRect.left - 4; 1516 posEnd.y = endRect.top; 1518 // Utility object with x and y offsets for handles. 1520 // We want bottom-to-top arrow to curve a bit more, so it doesn't 1521 // overlap much with top-to-bottom curves (much more frequent). 1522 x: topToBottom ? 15 : 25, 1523 y: Math.min((posEnd.y - posStart.y) / 3, 10) 1526 // When destination is on the different line, we can make a 1527 // curvier arrow because we have space for it. 1528 // So, instead of using 1530 // startHandle.x = posStart.x - curvature.x 1531 // endHandle.x = posEnd.x - curvature.x 1533 // We use the leftmost of these two values for both handles. 1534 startHandle.x = Math.min(posStart.x, posEnd.x) - curvature.x; 1535 endHandle.x = startHandle.x; 1537 // Curving downwards from the start node... 1538 startHandle.y = posStart.y + curvature.y; 1539 // ... and upwards from the end node. 1540 endHandle.y = posEnd.y - curvature.y; 1542 } else if (leftToRight) { 1544 // Starting from the top right corner... 1545 posStart.x = startRect.right - 1; 1546 posStart.y = startRect.top; 1548 // ...and ending at the top left corner of the end token. 1549 posEnd.x = endRect.left + 1; 1550 posEnd.y = endRect.top - 1; 1552 // Utility object with x and y offsets for handles. 1554 x: Math.min((posEnd.x - posStart.x) / 3, 15), 1558 // Curving to the right... 1559 startHandle.x = posStart.x + curvature.x; 1560 // ... and upwards from the start node. 1561 startHandle.y = posStart.y - curvature.y; 1563 // And to the left... 1564 endHandle.x = posEnd.x - curvature.x; 1565 // ... and upwards from the end node. 1566 endHandle.y = posEnd.y - curvature.y; 1570 // Starting from the bottom right corner... 1571 posStart.x = startRect.right; 1572 posStart.y = startRect.bottom; 1574 // ...and ending also at the bottom right corner, but of the end token. 1575 posEnd.x = endRect.right - 1; 1576 posEnd.y = endRect.bottom + 1; 1578 // Utility object with x and y offsets for handles. 1580 x: Math.min((posStart.x - posEnd.x) / 3, 15), 1584 // Curving to the left... 1585 startHandle.x = posStart.x - curvature.x; 1586 // ... and downwards from the start node. 1587 startHandle.y = posStart.y + curvature.y; 1589 // And to the right... 1590 endHandle.x = posEnd.x + curvature.x; 1591 // ... and downwards from the end node. 1592 endHandle.y = posEnd.y + curvature.y; 1595 // Put it all together into a path. 1596 // More information on the format: 1597 // https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths 1598 var pathStr = "M" + posStart.x + "," + posStart.y + " " + 1599 "C" + startHandle.x + "," + startHandle.y + " " + 1600 endHandle.x + "," + endHandle.y + " " + 1601 posEnd.x + "," + posEnd.y; 1603 arrow.setAttribute("d", pathStr); 1606var drawArrows = function() { 1607 const numOfArrows = document.querySelectorAll("path[id^=arrow]").length; 1608 for (var i = 0; i < numOfArrows; ++i) { 1613var toggleArrows = function(event) { 1614 const arrows = document.querySelector("#arrows"); 1615 if (event.target.checked) { 1616 arrows.setAttribute("visibility", "visible"); 1618 arrows.setAttribute("visibility", "hidden"); 1622window.addEventListener("resize", drawArrows); 1623document.addEventListener("DOMContentLoaded", function() { 1624 // Whenever we show invocation, locations change, i.e. we 1625 // need to redraw arrows. 1627 .querySelector('input[id="showinvocation"]') 1628 .addEventListener("click", drawArrows); 1629 // Hiding irrelevant lines also should cause arrow rerender. 1631 .querySelector('input[name="showCounterexample"]') 1632 .addEventListener("change", drawArrows); 1634 .querySelector('input[name="showArrows"]') 1635 .addEventListener("change", toggleArrows); 1637 // Default highlighting for the last event. 1638 highlightArrowsForSelectedEvent();

Defines the clang::FileManager interface and associated types.

static bool shouldDisplayPopUpRange(const SourceRange &Range)

static void EmitAlphaCounter(raw_ostream &os, unsigned n)

static std::string getSpanBeginForControl(const char *ClassName, unsigned Index)

static llvm::SmallString< 32 > getIssueHash(const PathDiagnostic &D, const Preprocessor &PP)

static void HandlePopUpPieceStartTag(Rewriter &R, const std::vector< SourceRange > &PopUpRanges)

static std::string getSpanBeginForControlEnd(unsigned Index)

static void HandlePopUpPieceEndTag(Rewriter &R, const PathDiagnosticPopUpPiece &Piece, std::vector< SourceRange > &PopUpRanges, unsigned int LastReportedPieceIndex, unsigned int PopUpPieceIndex)

static std::string getSpanBeginForControlStart(unsigned Index)

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

Defines the clang::Preprocessor interface.

static std::string getName(const CallEvent &Call)

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

__DEVICE__ int max(int __a, int __b)

__device__ __2f16 float __ockl_bool s

__device__ __2f16 float c

Decl - This represents one declaration (or definition), e.g.

SourceLocation getLocation() const

A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...

StringRef getName() const

The name of this FileEntry.

An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...

A SourceLocation and its associated SourceManager.

FullSourceLoc getExpansionLoc() const

const char * getCharacterData(bool *Invalid=nullptr) const

StringRef getBufferData(bool *Invalid=nullptr) const

Return a StringRef to the source buffer data for the specified FileID.

std::pair< FileID, unsigned > getDecomposedLoc() const

Decompose the specified location into a raw FileID + Offset pair.

const SourceManager & getManager() const

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.

bool LexFromRawLexer(Token &Result)

LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...

static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)

MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...

MacroExpansionContext tracks the macro expansions processed by the Preprocessor.

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

SourceManager & getSourceManager() const

const LangOptions & getLangOpts() const

Rewriter - This is the main interface to the rewrite buffers.

bool InsertTextBefore(SourceLocation Loc, StringRef Str)

InsertText - Insert the specified string at the specified location in the original buffer.

SourceManager & getSourceMgr() const

const LangOptions & getLangOpts() const

const llvm::RewriteBuffer * getRewriteBufferFor(FileID FID) const

getRewriteBufferFor - Return the rewrite buffer for the specified FileID.

bool InsertTextAfter(SourceLocation Loc, StringRef Str)

InsertTextAfter - Insert the specified string at the specified location in the original buffer.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

SourceLocation getLocWithOffset(IntTy Offset) const

Return a source location with the specified offset from this SourceLocation.

This class handles loading and caching of source files into memory.

OptionalFileEntryRef getFileEntryRefForID(FileID FID) const

Returns the FileEntryRef for the provided FileID.

SourceLocation getLocForEndOfFile(FileID FID) const

Return the source location corresponding to the last byte of the specified file.

SourceLocation getLocForStartOfFile(FileID FID) const

Return the source location corresponding to the first byte of the specified file.

SourceLocation getExpansionLoc(SourceLocation Loc) const

Given a SourceLocation object Loc, return the expansion location referenced by the ID.

A trivial tuple used to represent a source range.

Stmt - This represents one statement.

Token - This structure provides full information about a lexed token.

unsigned getLength() const

This class is used for tools that requires cross translation unit capability.

@ Everything

Used for HTML, shows both "arrows" and control notes.

virtual void FlushDiagnosticsImpl(std::vector< const PathDiagnostic * > &Diags, FilesMade *filesMade)=0

virtual bool supportsCrossFileDiagnostics() const

Return true if the PathDiagnosticConsumer supports individual PathDiagnostics that span multiple file...

virtual StringRef getName() const =0

virtual PathGenerationScheme getGenerationScheme() const

void FlushDiagnostics(FilesMade *FilesMade)

PathDiagnosticRange asRange() const

FullSourceLoc asLocation() const

StringRef getString() const

PathDiagnosticLocation getLocation() const override

PathDiagnostic - PathDiagnostic objects represent a single path-sensitive diagnostic.

A Range represents the closed range [from, to].

std::map< FileID, std::set< unsigned > > FilesToLineNumsMap

File IDs mapped to sets of line numbers.

std::vector< PathDiagnosticConsumer * > PathDiagnosticConsumers

std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef

void AddHeaderFooterInternalBuiltinCSS(Rewriter &R, FileID FID, StringRef title)

void HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E, const char *StartTag, const char *EndTag, bool IsTokenRange=true)

HighlightRange - Highlight a range in the source code with the specified start/end tags.

RelexRewriteCacheRef instantiateRelexRewriteCache()

If you need to rewrite the same file multiple times, you can instantiate a RelexRewriteCache and refe...

void AddLineNumbers(Rewriter &R, FileID FID)

void SyntaxHighlight(Rewriter &R, FileID FID, const Preprocessor &PP, RelexRewriteCacheRef Cache=nullptr)

SyntaxHighlight - Relex the specified FileID and annotate the HTML with information about keywords,...

void HighlightMacros(Rewriter &R, FileID FID, const Preprocessor &PP, RelexRewriteCacheRef Cache=nullptr)

HighlightMacros - This uses the macro table state from the end of the file, to reexpand macros and in...

void EscapeText(Rewriter &R, FileID FID, bool EscapeSpaces=false, bool ReplaceTabs=false)

EscapeText - HTMLize a specified file so that special characters are are translated so that they are ...

std::shared_ptr< RelexRewriteCache > RelexRewriteCacheRef

The JSON file list parser is used to communicate input to InstallAPI.

const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)

Insertion operator for diagnostics.

These options tweak the behavior of path diangostic consumers.

bool ShouldWriteVerboseReportFilename

If the consumer intends to produce multiple output files, should it use a pseudo-random file name or ...

std::string ToolInvocation

Run-line of the tool that produced the diagnostic.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4