diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-03-19 07:53:42 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-03-19 07:53:42 +0000 |
commit | 13e479b2b74771738a5e5c5dc1c270416924b126 (patch) | |
tree | aaae19db0db5691858c6017e4ee56e77317fb53d /Driver/HTMLPrint.cpp | |
parent | 0fdf06e5eef80ce56ce6499ba662453919b95af1 (diff) |
Initial experimentation with adding boxed "annotations" to HTMLized source.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48540 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Driver/HTMLPrint.cpp')
-rw-r--r-- | Driver/HTMLPrint.cpp | 167 |
1 files changed, 161 insertions, 6 deletions
diff --git a/Driver/HTMLPrint.cpp b/Driver/HTMLPrint.cpp index a513bf975d..1108bc3bda 100644 --- a/Driver/HTMLPrint.cpp +++ b/Driver/HTMLPrint.cpp @@ -18,10 +18,17 @@ #include "clang/Basic/SourceManager.h" #include "llvm/Support/MemoryBuffer.h" #include "clang/AST/ASTContext.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Analysis/LocalCheckers.h" +#include "clang/AST/CFG.h" #include <sstream> using namespace clang; +//===----------------------------------------------------------------------===// +// Functional HTML pretty-printing. +//===----------------------------------------------------------------------===// + namespace { class HTMLPrinter : public ASTConsumer { Rewriter R; @@ -40,14 +47,58 @@ void HTMLPrinter::Initialize(ASTContext &context) { } HTMLPrinter::~HTMLPrinter() { + unsigned FileID = R.getSourceMgr().getMainFileID(); - - const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID); - const char* FileStart = Buf->getBufferStart(); - const char* FileEnd = Buf->getBufferEnd(); - SourceLocation StartLoc = SourceLocation::getFileLoc(FileID, 0); - SourceLocation EndLoc = SourceLocation::getFileLoc(FileID, FileEnd-FileStart); + html::EscapeText(R, FileID); + html::AddLineNumbers(R, FileID); + html::AddHeaderFooterInternalBuiltinCSS(R, FileID); + // Emit the HTML. + + if (const RewriteBuffer *RewriteBuf = R.getRewriteBufferFor(FileID)) { + std::string S(RewriteBuf->begin(), RewriteBuf->end()); + printf("%s\n", S.c_str()); + } +} + +//===----------------------------------------------------------------------===// +// Other HTML pretty-printing code used to test new features. +//===----------------------------------------------------------------------===// + +namespace { + class HTMLTest : public ASTConsumer { + Rewriter R; + ASTContext* Ctx; + public: + HTMLTest() : Ctx(NULL) {} + virtual ~HTMLTest(); + virtual void HandleTopLevelDecl(Decl* D); + + void Initialize(ASTContext &context); + void ProcessBody(Stmt* S); + }; +} + +ASTConsumer* clang::CreateHTMLTest() { return new HTMLTest(); } + +void HTMLTest::Initialize(ASTContext &context) { + Ctx = &context; + R.setSourceMgr(context.getSourceManager()); +} + +void HTMLTest::HandleTopLevelDecl(Decl* D) { + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) + if (Stmt* B = FD->getBody()) { + SourceLocation L = B->getLocStart(); + + if (L.isFileID() && L.getFileID() == R.getSourceMgr().getMainFileID()) + ProcessBody(B); + } +} + +HTMLTest::~HTMLTest() { + + unsigned FileID = R.getSourceMgr().getMainFileID(); html::EscapeText(R, FileID); html::AddLineNumbers(R, FileID); html::AddHeaderFooterInternalBuiltinCSS(R, FileID); @@ -59,3 +110,107 @@ HTMLPrinter::~HTMLPrinter() { printf("%s\n", S.c_str()); } } + +namespace { + class HTMLDiagnostic : public DiagnosticClient { + Rewriter& R; + public: + HTMLDiagnostic(Rewriter& r) : R(r) {} + virtual void HandleDiagnostic(Diagnostic &Diags, + Diagnostic::Level DiagLevel, + FullSourceLoc Pos, + diag::kind ID, + const std::string *Strs, + unsigned NumStrs, + const SourceRange *Ranges, + unsigned NumRanges); + }; +} + +void HTMLTest::ProcessBody(Stmt* S) { + CFG* cfg = CFG::buildCFG(S); + + if (!cfg) + return; + + HTMLDiagnostic HD(R); + Diagnostic D(HD); + + CheckDeadStores(*cfg, *Ctx, D); +} + +void HTMLDiagnostic::HandleDiagnostic(Diagnostic &Diags, + Diagnostic::Level DiagLevel, + FullSourceLoc Pos, + diag::kind ID, + const std::string *Strs, + unsigned NumStrs, + const SourceRange *Ranges, + unsigned NumRanges) { + + // For now, just draw a box above the line in question, and emit the + // warning. + + if (!Pos.isValid()) + return; + + FullSourceLoc LPos = Pos.getLogicalLoc(); + unsigned FileID = LPos.getLocation().getFileID(); + + if (FileID != LPos.getManager().getMainFileID()) + return; + + + // Compute the column number. Rewind from the current position to the start + // of the line. + + unsigned ColNo = LPos.getColumnNumber(); + const char *TokLogicalPtr = LPos.getCharacterData(); + const char *LineStart = TokLogicalPtr-ColNo; + + // Ripped from TextDiagnostics::FormatDiagnostic: + + std::string Msg = Diags.getDescription(ID); + + for (unsigned i = 0; i < Msg.size() - 1; ++i) { + if (Msg[i] == '%' && isdigit(Msg[i + 1])) { + unsigned StrNo = Msg[i + 1] - '0'; + Msg = std::string(Msg.begin(), Msg.begin() + i) + + (StrNo < NumStrs ? Strs[StrNo] : "<<<INTERNAL ERROR>>>") + + std::string(Msg.begin() + i + 2, Msg.end()); + } + } + + // Start making the div tag. + + std::ostringstream os; + + os << "\n<div class=\"codeline\"><div class=\"nums\"> </div>" + << "<div class=\"lines\">"; + + for (unsigned i = 0; i < ColNo+1; ++i) + os << ' '; + + os << "</div><span class=\"msg\">"; + + switch (DiagLevel) { + default: assert(0 && "Unknown diagnostic type!"); + case Diagnostic::Note: os << "note: "; break; + case Diagnostic::Warning: os << "warning: "; break; + case Diagnostic::Error: os << "error: "; break; + case Diagnostic::Fatal: os << "fatal error: "; break; + break; + } + + os << Msg; // FIXME: HTML escape "Msg" + os << "</span></div"; + + // Insert a div tag with the warning. + + const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FileID); + const char* FileStart = Buf->getBufferStart(); + + + R.InsertStrBefore(SourceLocation::getFileLoc(FileID, LineStart - FileStart), + os.str()); +} |