xref: /aosp_15_r20/external/clang/lib/Frontend/Rewrite/HTMLPrint.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // Pretty-printing of source code to HTML.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li 
14*67e74705SXin Li #include "clang/Rewrite/Frontend/ASTConsumers.h"
15*67e74705SXin Li #include "clang/AST/ASTConsumer.h"
16*67e74705SXin Li #include "clang/AST/ASTContext.h"
17*67e74705SXin Li #include "clang/AST/Decl.h"
18*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
19*67e74705SXin Li #include "clang/Basic/FileManager.h"
20*67e74705SXin Li #include "clang/Basic/SourceManager.h"
21*67e74705SXin Li #include "clang/Lex/Preprocessor.h"
22*67e74705SXin Li #include "clang/Rewrite/Core/HTMLRewrite.h"
23*67e74705SXin Li #include "clang/Rewrite/Core/Rewriter.h"
24*67e74705SXin Li #include "llvm/Support/MemoryBuffer.h"
25*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
26*67e74705SXin Li using namespace clang;
27*67e74705SXin Li 
28*67e74705SXin Li //===----------------------------------------------------------------------===//
29*67e74705SXin Li // Functional HTML pretty-printing.
30*67e74705SXin Li //===----------------------------------------------------------------------===//
31*67e74705SXin Li 
32*67e74705SXin Li namespace {
33*67e74705SXin Li   class HTMLPrinter : public ASTConsumer {
34*67e74705SXin Li     Rewriter R;
35*67e74705SXin Li     raw_ostream *Out;
36*67e74705SXin Li     Preprocessor &PP;
37*67e74705SXin Li     bool SyntaxHighlight, HighlightMacros;
38*67e74705SXin Li 
39*67e74705SXin Li   public:
HTMLPrinter(raw_ostream * OS,Preprocessor & pp,bool _SyntaxHighlight,bool _HighlightMacros)40*67e74705SXin Li     HTMLPrinter(raw_ostream *OS, Preprocessor &pp,
41*67e74705SXin Li                 bool _SyntaxHighlight, bool _HighlightMacros)
42*67e74705SXin Li       : Out(OS), PP(pp), SyntaxHighlight(_SyntaxHighlight),
43*67e74705SXin Li         HighlightMacros(_HighlightMacros) {}
44*67e74705SXin Li 
45*67e74705SXin Li     void Initialize(ASTContext &context) override;
46*67e74705SXin Li     void HandleTranslationUnit(ASTContext &Ctx) override;
47*67e74705SXin Li   };
48*67e74705SXin Li }
49*67e74705SXin Li 
CreateHTMLPrinter(raw_ostream * OS,Preprocessor & PP,bool SyntaxHighlight,bool HighlightMacros)50*67e74705SXin Li std::unique_ptr<ASTConsumer> clang::CreateHTMLPrinter(raw_ostream *OS,
51*67e74705SXin Li                                                       Preprocessor &PP,
52*67e74705SXin Li                                                       bool SyntaxHighlight,
53*67e74705SXin Li                                                       bool HighlightMacros) {
54*67e74705SXin Li   return llvm::make_unique<HTMLPrinter>(OS, PP, SyntaxHighlight,
55*67e74705SXin Li                                         HighlightMacros);
56*67e74705SXin Li }
57*67e74705SXin Li 
Initialize(ASTContext & context)58*67e74705SXin Li void HTMLPrinter::Initialize(ASTContext &context) {
59*67e74705SXin Li   R.setSourceMgr(context.getSourceManager(), context.getLangOpts());
60*67e74705SXin Li }
61*67e74705SXin Li 
HandleTranslationUnit(ASTContext & Ctx)62*67e74705SXin Li void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
63*67e74705SXin Li   if (PP.getDiagnostics().hasErrorOccurred())
64*67e74705SXin Li     return;
65*67e74705SXin Li 
66*67e74705SXin Li   // Format the file.
67*67e74705SXin Li   FileID FID = R.getSourceMgr().getMainFileID();
68*67e74705SXin Li   const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID);
69*67e74705SXin Li   const char* Name;
70*67e74705SXin Li   // In some cases, in particular the case where the input is from stdin,
71*67e74705SXin Li   // there is no entry.  Fall back to the memory buffer for a name in those
72*67e74705SXin Li   // cases.
73*67e74705SXin Li   if (Entry)
74*67e74705SXin Li     Name = Entry->getName();
75*67e74705SXin Li   else
76*67e74705SXin Li     Name = R.getSourceMgr().getBuffer(FID)->getBufferIdentifier();
77*67e74705SXin Li 
78*67e74705SXin Li   html::AddLineNumbers(R, FID);
79*67e74705SXin Li   html::AddHeaderFooterInternalBuiltinCSS(R, FID, Name);
80*67e74705SXin Li 
81*67e74705SXin Li   // If we have a preprocessor, relex the file and syntax highlight.
82*67e74705SXin Li   // We might not have a preprocessor if we come from a deserialized AST file,
83*67e74705SXin Li   // for example.
84*67e74705SXin Li 
85*67e74705SXin Li   if (SyntaxHighlight) html::SyntaxHighlight(R, FID, PP);
86*67e74705SXin Li   if (HighlightMacros) html::HighlightMacros(R, FID, PP);
87*67e74705SXin Li   html::EscapeText(R, FID, false, true);
88*67e74705SXin Li 
89*67e74705SXin Li   // Emit the HTML.
90*67e74705SXin Li   const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
91*67e74705SXin Li   char *Buffer = (char*)malloc(RewriteBuf.size());
92*67e74705SXin Li   std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
93*67e74705SXin Li   Out->write(Buffer, RewriteBuf.size());
94*67e74705SXin Li   free(Buffer);
95*67e74705SXin Li }
96