19 #include "llvm/ADT/SmallString.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/MemoryBuffer.h" 22 #include "llvm/Support/raw_ostream.h" 24 using namespace clang;
32 const char *StartTag,
const char *EndTag,
35 B =
SM.getExpansionLoc(B);
36 E =
SM.getExpansionLoc(E);
38 assert(
SM.getFileID(E) == FID &&
"B/E not in the same file!");
40 unsigned BOffset =
SM.getFileOffset(B);
41 unsigned EOffset =
SM.getFileOffset(E);
48 const char *BufferStart =
SM.getBufferData(FID, &Invalid).data();
53 BufferStart, StartTag, EndTag);
59 const char *BufferStart,
60 const char *StartTag,
const char *EndTag) {
67 bool HadOpenTag =
true;
69 unsigned LastNonWhiteSpace = B;
70 for (
unsigned i = B; i != E; ++i) {
71 switch (BufferStart[i]) {
101 LastNonWhiteSpace = i;
108 bool EscapeSpaces,
bool ReplaceTabs) {
111 const char*
C = Buf.getBufferStart();
112 const char* FileEnd = Buf.getBufferEnd();
114 assert (
C <= FileEnd);
119 for (
unsigned FilePos = 0;
C != FileEnd ; ++
C, ++FilePos) {
121 default: ++ColNo;
break;
140 unsigned NumSpaces = 8-(ColNo&7);
143 StringRef(
" " 144 " ", 6*NumSpaces));
146 RB.
ReplaceText(FilePos, 1, StringRef(
" ", NumSpaces));
170 unsigned len =
s.size();
172 llvm::raw_string_ostream os(Str);
174 for (
unsigned i = 0 ; i < len; ++i) {
182 if (EscapeSpaces) os <<
" ";
189 for (
unsigned i = 0; i < 4; ++i)
192 for (
unsigned i = 0; i < 4; ++i)
200 case '<': os <<
"<";
break;
201 case '>': os <<
">";
break;
202 case '&': os <<
"&";
break;
210 unsigned B,
unsigned E) {
212 llvm::raw_svector_ostream OS(Str);
214 OS <<
"<tr class=\"codeline\" data-linenumber=\"" << LineNo <<
"\">" 215 <<
"<td class=\"num\" id=\"LN" << LineNo <<
"\">" << LineNo
216 <<
"</td><td class=\"line\">";
230 const char* FileBeg = Buf.getBufferStart();
231 const char* FileEnd = Buf.getBufferEnd();
232 const char*
C = FileBeg;
235 assert (
C <= FileEnd);
238 unsigned FilePos = 0;
240 while (
C != FileEnd) {
243 unsigned LineStartPos = FilePos;
244 unsigned LineEndPos = FileEnd - FileBeg;
246 assert (FilePos <= LineEndPos);
247 assert (
C < FileEnd);
251 while (
C != FileEnd) {
256 LineEndPos = FilePos++;
268 llvm::raw_string_ostream os(
s);
269 os <<
"<table class=\"code\" data-fileid=\"" << FID.
getHashValue() <<
"\">\n";
278 const char* FileStart = Buf.getBufferStart();
279 const char* FileEnd = Buf.getBufferEnd();
285 llvm::raw_string_ostream os(
s);
286 os <<
"<!doctype html>\n" 293 <style type="text/css"> 294 body { color:#000000; background-color:#ffffff } 295 body { font-family:Helvetica, sans-serif; font-size:10pt } 296 h1 { font-size:14pt } 297 .FileName { margin-top: 5px; margin-bottom: 5px; display: inline; } 298 .FileNav { margin-left: 5px; margin-right: 5px; display: inline; } 299 .FileNav a { text-decoration:none; font-size: larger; } 300 .divider { margin-top: 30px; margin-bottom: 30px; height: 15px; } 301 .divider { background-color: gray; } 302 .code { border-collapse:collapse; width:100%; } 303 .code { font-family: "Monospace", monospace; font-size:10pt } 304 .code { line-height: 1.2em } 305 .comment { color: green; font-style: oblique } 306 .keyword { color: blue } 307 .string_literal { color: red } 308 .directive { color: darkmagenta } 310 /* Macros and variables could have pop-up notes hidden by default. 311 - Macro pop-up: expansion of the macro 312 - Variable pop-up: value (table) of the variable */ 313 .macro_popup, .variable_popup { display: none; } 315 /* Pop-up appears on mouse-hover event. */ 316 .macro:hover .macro_popup, .variable:hover .variable_popup { 319 -webkit-border-radius:5px; 320 -webkit-box-shadow:1px 1px 7px #000; 322 box-shadow:1px 1px 7px #000; 330 border: 2px solid red; 331 background-color:#FFF0F0; 336 border: 2px solid blue; 337 background-color:#F0F0FF; 339 font-family: Helvetica, sans-serif; 343 /* Pop-up notes needs a relative position as a base where they pops up. */ 345 background-color: PaleGoldenRod; 348 .macro { color: DarkMagenta; } 356 border: 1px solid #b0b0b0; 358 box-shadow: 1px 1px 7px black; 359 background-color: #c0c0c0; 363 .num { width:2.5em; padding-right:2ex; background-color:#eeeeee } 364 .num { text-align:right; font-size:8pt } 365 .num { color:#444444 } 366 .line { padding-left: 1ex; border-left: 3px solid #ccc } 367 .line { white-space: pre } 368 .msg { -webkit-box-shadow:1px 1px 7px #000 } 369 .msg { box-shadow:1px 1px 7px #000 } 370 .msg { -webkit-border-radius:5px } 371 .msg { border-radius:5px } 372 .msg { font-family:Helvetica, sans-serif; font-size:8pt } 374 .msg { padding:0.25em 1ex 0.25em 1ex } 375 .msg { margin-top:10px; margin-bottom:10px } 376 .msg { font-weight:bold } 377 .msg { max-width:60em; word-wrap: break-word; white-space: pre-wrap } 378 .msgT { padding:0x; spacing:0x } 379 .msgEvent { background-color:#fff8b4; color:#000000 } 380 .msgControl { background-color:#bbbbbb; color:#000000 } 381 .msgNote { background-color:#ddeeff; color:#000000 } 382 .mrange { background-color:#dfddf3 } 383 .mrange { border-bottom:1px solid #6F9DBE } 384 .PathIndex { font-weight: bold; padding:0px 5px; margin-right:5px; } 385 .PathIndex { -webkit-border-radius:8px } 386 .PathIndex { border-radius:8px } 387 .PathIndexEvent { background-color:#bfba87 } 388 .PathIndexControl { background-color:#8c8c8c } 389 .PathIndexPopUp { background-color: #879abc; } 390 .PathNav a { text-decoration:none; font-size: larger } 391 .CodeInsertionHint { font-weight: bold; background-color: #10dd10 } 392 .CodeRemovalHint { background-color:#de1010 } 393 .CodeRemovalHint { border-bottom:1px solid #6F9DBE } 394 .selected{ background-color:orange !important; } 400 border-collapse: collapse; border-spacing: 0px; 411 input.spoilerhider + label { 413 text-decoration: underline; 419 input.spoilerhider ~ .spoiler { 425 input.spoilerhider:checked + label + .spoiler{ 448 llvm::MemoryBufferRef FromFile =
SM.getBufferOrFake(FID);
450 const char *BufferStart = L.
getBuffer().data();
454 L.SetCommentRetentionState(
true);
459 L.LexFromRawLexer(
Tok);
464 unsigned TokOffs =
SM.getFileOffset(
Tok.getLocation());
465 unsigned TokLen =
Tok.getLength();
466 switch (
Tok.getKind()) {
468 case tok::identifier:
469 llvm_unreachable(
"tok::identifier in raw lexing mode!");
470 case tok::raw_identifier: {
478 "<span class='keyword'>",
"</span>");
483 "<span class='comment'>",
"</span>");
485 case tok::utf8_string_literal:
491 case tok::wide_string_literal:
492 case tok::utf16_string_literal:
493 case tok::utf32_string_literal:
498 case tok::string_literal:
501 "<span class='string_literal'>",
"</span>");
505 if (!
Tok.isAtStartOfLine())
510 unsigned TokEnd = TokOffs+TokLen;
511 L.LexFromRawLexer(
Tok);
513 TokEnd =
SM.getFileOffset(
Tok.getLocation())+
Tok.getLength();
514 L.LexFromRawLexer(
Tok);
519 "<span class='directive'>",
"</span>");
526 L.LexFromRawLexer(
Tok);
537 std::vector<Token> TokenStream;
539 llvm::MemoryBufferRef FromFile =
SM.getBufferOrFake(FID);
546 L.LexFromRawLexer(
Tok);
551 if (
Tok.
is(tok::hash) &&
Tok.isAtStartOfLine())
556 if (
Tok.
is(tok::hashhash))
557 Tok.setKind(tok::unknown);
562 if (
Tok.
is(tok::raw_identifier))
565 TokenStream.push_back(
Tok);
581 TmpPP.setDiagnostics(TmpDiags);
584 TmpPP.SetCommentRetentionState(
false,
false);
588 bool PragmasPreviouslyEnabled = TmpPP.getPragmasEnabled();
589 TmpPP.setPragmasEnabled(
false);
593 TmpPP.EnterTokenStream(TokenStream,
false,
false);
602 if (!
Tok.getLocation().isMacroID()) {
618 assert(
SM.getFileID(LLoc.
getEnd()) == FID &&
619 "Start and end of expansion must be in the same ultimate file!");
622 unsigned LineLen = Expansion.size();
640 LineLen -= Expansion.size();
644 if (
Tok.hasLeadingSpace() ||
650 LineLen += Expansion.size();
652 PrevPrevTok = PrevTok;
659 Expansion =
"<span class='macro_popup'>" + Expansion +
"</span></span>";
666 TmpPP.setDiagnostics(*OldDiags);
667 TmpPP.setPragmasEnabled(PragmasPreviouslyEnabled);
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
Defines the SourceManager interface.
TokenConcatenation class, which answers the question of "Is it safe to emit two tokens without a whit...
RewriteBuffer & getEditBuffer(FileID FID)
getEditBuffer - This is like getRewriteBufferFor, but always returns a buffer, and allows you to writ...
RewriteBuffer - As code is rewritten, SourceBuffer's from the original input with modifications get a...
SourceLocation getBegin() const
static void AddLineNumber(RewriteBuffer &RB, unsigned LineNo, unsigned B, unsigned E)
void HighlightMacros(Rewriter &R, FileID FID, const Preprocessor &PP)
HighlightMacros - This uses the macro table state from the end of the file, to reexpand macros and in...
void AddLineNumbers(Rewriter &R, FileID FID)
unsigned getHashValue() const
Token - This structure provides full information about a lexed token.
const LangOptions & getLangOpts() const
SourceManager & getSourceMgr() const
Concrete class used by the front-end to report problems and issues.
StringRef getBuffer() const
Gets source code buffer.
void SyntaxHighlight(Rewriter &R, FileID FID, const Preprocessor &PP)
SyntaxHighlight - Relex the specified FileID and annotate the HTML with information about keywords,...
__device__ __2f16 float bool s
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
Represents a character-granular source range.
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 ...
Defines the clang::Preprocessor interface.
void InsertTextAfter(unsigned OrigOffset, StringRef Str)
InsertTextAfter - Insert some text at the specified point, where the offset in the buffer is specifie...
SourceManager & getSourceManager() const
llvm::MemoryBufferRef getBufferOrFake(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
void ReplaceText(unsigned OrigOffset, unsigned OrigLength, StringRef NewStr)
ReplaceText - This method replaces a range of characters in the input buffer with a new string.
Encodes a location in the source.
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 ...
bool InsertTextAfter(SourceLocation Loc, StringRef Str)
InsertTextAfter - Insert the specified string at the specified location in the original buffer.
bool InsertTextBefore(SourceLocation Loc, StringRef Str)
InsertText - Insert the specified string at the specified location in the original buffer.
bool isTokenRange() const
Return true if the end of this range specifies the start of the last token.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
void InsertTextBefore(unsigned OrigOffset, StringRef Str)
InsertTextBefore - Insert some text before the specified point, where the offset in the buffer is spe...
Dataflow Directional Tag Classes.
A diagnostic client that ignores all diagnostics.
DiagnosticOptions & getDiagnosticOptions() const
Retrieve the diagnostic options.
void AddHeaderFooterInternalBuiltinCSS(Rewriter &R, FileID FID, StringRef title)
const LangOptions & getLangOpts() const
SourceLocation getEnd() const
bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok, const Token &Tok) const
AvoidConcat - If printing PrevTok immediately followed by Tok would cause the two individual tokens t...
Rewriter - This is the main interface to the rewrite buffers.
const IntrusiveRefCntPtr< DiagnosticIDs > & getDiagnosticIDs() const
DiagnosticsEngine & getDiagnostics() const
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.
This class handles loading and caching of source files into memory.
__device__ __2f16 float c
Engages in a tight little dance with the lexer to efficiently preprocess tokens.