xref: /freebsd/contrib/llvm-project/clang/lib/Frontend/Rewrite/HTMLPrint.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Pretty-printing of source code to HTML.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/AST/ASTConsumer.h"
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
150b57cec5SDimitry Andric #include "clang/AST/Decl.h"
160b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h"
170b57cec5SDimitry Andric #include "clang/Basic/FileManager.h"
180b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
190b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
200b57cec5SDimitry Andric #include "clang/Rewrite/Core/HTMLRewrite.h"
210b57cec5SDimitry Andric #include "clang/Rewrite/Core/Rewriter.h"
220b57cec5SDimitry Andric #include "clang/Rewrite/Frontend/ASTConsumers.h"
230b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
240b57cec5SDimitry Andric using namespace clang;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
270b57cec5SDimitry Andric // Functional HTML pretty-printing.
280b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric namespace {
310b57cec5SDimitry Andric   class HTMLPrinter : public ASTConsumer {
320b57cec5SDimitry Andric     Rewriter R;
330b57cec5SDimitry Andric     std::unique_ptr<raw_ostream> Out;
340b57cec5SDimitry Andric     Preprocessor &PP;
350b57cec5SDimitry Andric     bool SyntaxHighlight, HighlightMacros;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric   public:
380b57cec5SDimitry Andric     HTMLPrinter(std::unique_ptr<raw_ostream> OS, Preprocessor &pp,
390b57cec5SDimitry Andric                 bool _SyntaxHighlight, bool _HighlightMacros)
400b57cec5SDimitry Andric       : Out(std::move(OS)), PP(pp), SyntaxHighlight(_SyntaxHighlight),
410b57cec5SDimitry Andric         HighlightMacros(_HighlightMacros) {}
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric     void Initialize(ASTContext &context) override;
440b57cec5SDimitry Andric     void HandleTranslationUnit(ASTContext &Ctx) override;
450b57cec5SDimitry Andric   };
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric std::unique_ptr<ASTConsumer>
490b57cec5SDimitry Andric clang::CreateHTMLPrinter(std::unique_ptr<raw_ostream> OS, Preprocessor &PP,
500b57cec5SDimitry Andric                          bool SyntaxHighlight, bool HighlightMacros) {
51a7dea167SDimitry Andric   return std::make_unique<HTMLPrinter>(std::move(OS), PP, SyntaxHighlight,
520b57cec5SDimitry Andric                                         HighlightMacros);
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric void HTMLPrinter::Initialize(ASTContext &context) {
560b57cec5SDimitry Andric   R.setSourceMgr(context.getSourceManager(), context.getLangOpts());
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
600b57cec5SDimitry Andric   if (PP.getDiagnostics().hasErrorOccurred())
610b57cec5SDimitry Andric     return;
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   // Format the file.
640b57cec5SDimitry Andric   FileID FID = R.getSourceMgr().getMainFileID();
65*5f757f3fSDimitry Andric   OptionalFileEntryRef Entry = R.getSourceMgr().getFileEntryRefForID(FID);
660b57cec5SDimitry Andric   StringRef Name;
670b57cec5SDimitry Andric   // In some cases, in particular the case where the input is from stdin,
680b57cec5SDimitry Andric   // there is no entry.  Fall back to the memory buffer for a name in those
690b57cec5SDimitry Andric   // cases.
700b57cec5SDimitry Andric   if (Entry)
710b57cec5SDimitry Andric     Name = Entry->getName();
720b57cec5SDimitry Andric   else
73e8d8bef9SDimitry Andric     Name = R.getSourceMgr().getBufferOrFake(FID).getBufferIdentifier();
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   html::AddLineNumbers(R, FID);
760b57cec5SDimitry Andric   html::AddHeaderFooterInternalBuiltinCSS(R, FID, Name);
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   // If we have a preprocessor, relex the file and syntax highlight.
790b57cec5SDimitry Andric   // We might not have a preprocessor if we come from a deserialized AST file,
800b57cec5SDimitry Andric   // for example.
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   if (SyntaxHighlight) html::SyntaxHighlight(R, FID, PP);
830b57cec5SDimitry Andric   if (HighlightMacros) html::HighlightMacros(R, FID, PP);
840b57cec5SDimitry Andric   html::EscapeText(R, FID, false, true);
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   // Emit the HTML.
870b57cec5SDimitry Andric   const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
880b57cec5SDimitry Andric   std::unique_ptr<char[]> Buffer(new char[RewriteBuf.size()]);
890b57cec5SDimitry Andric   std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer.get());
900b57cec5SDimitry Andric   Out->write(Buffer.get(), RewriteBuf.size());
910b57cec5SDimitry Andric }
92