brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.5 KiB · edfb72e Raw
221 lines · cpp
1//===- unittest/Tooling/CommentHandlerTest.cpp -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "TestVisitor.h"10#include "clang/Lex/Preprocessor.h"11 12namespace clang {13 14struct Comment {15  Comment(const std::string &Message, unsigned Line, unsigned Col)16    : Message(Message), Line(Line), Col(Col) { }17 18  std::string Message;19  unsigned Line, Col;20};21 22class CommentVerifier;23typedef std::vector<Comment> CommentList;24 25class CommentHandlerVisitor : public TestVisitor, public CommentHandler {26public:27  CommentHandlerVisitor() : PP(nullptr), Verified(false) {}28 29  ~CommentHandlerVisitor() override {30    EXPECT_TRUE(Verified) << "CommentVerifier not accessed";31  }32 33  bool HandleComment(Preprocessor &PP, SourceRange Loc) override {34    assert(&PP == this->PP && "Preprocessor changed!");35 36    SourceLocation Start = Loc.getBegin();37    SourceManager &SM = PP.getSourceManager();38    std::string C(SM.getCharacterData(Start),39                  SM.getCharacterData(Loc.getEnd()));40 41    bool Invalid;42    unsigned CLine = SM.getSpellingLineNumber(Start, &Invalid);43    EXPECT_TRUE(!Invalid) << "Invalid line number on comment " << C;44 45    unsigned CCol = SM.getSpellingColumnNumber(Start, &Invalid);46    EXPECT_TRUE(!Invalid) << "Invalid column number on comment " << C;47 48    Comments.push_back(Comment(C, CLine, CCol));49    return false;50  }51 52  CommentVerifier GetVerifier();53 54protected:55  std::unique_ptr<ASTFrontendAction> CreateTestAction() override {56    return std::make_unique<CommentHandlerAction>(this);57  }58 59private:60  Preprocessor *PP;61  CommentList Comments;62  bool Verified;63 64  class CommentHandlerAction : public TestAction {65  public:66    CommentHandlerAction(CommentHandlerVisitor *Visitor)67        : TestAction(Visitor) { }68 69    bool BeginSourceFileAction(CompilerInstance &CI) override {70      CommentHandlerVisitor *V =71          static_cast<CommentHandlerVisitor*>(this->Visitor);72      V->PP = &CI.getPreprocessor();73      V->PP->addCommentHandler(V);74      return true;75    }76 77    void EndSourceFileAction() override {78      CommentHandlerVisitor *V =79          static_cast<CommentHandlerVisitor*>(this->Visitor);80      V->PP->removeCommentHandler(V);81    }82  };83};84 85class CommentVerifier {86  CommentList::const_iterator Current;87  CommentList::const_iterator End;88  Preprocessor *PP;89 90public:91  CommentVerifier(const CommentList &Comments, Preprocessor *PP)92      : Current(Comments.begin()), End(Comments.end()), PP(PP)93    { }94 95  CommentVerifier(CommentVerifier &&C) : Current(C.Current), End(C.End), PP(C.PP) {96    C.Current = C.End;97  }98 99  ~CommentVerifier() {100    if (Current != End) {101      EXPECT_TRUE(Current == End) << "Unexpected comment \""102        << Current->Message << "\" at line " << Current->Line << ", column "103        << Current->Col;104    }105  }106 107  void Match(const char *Message, unsigned Line, unsigned Col) {108    EXPECT_TRUE(Current != End) << "Comment " << Message << " not found";109    if (Current == End) return;110 111    const Comment &C = *Current;112    EXPECT_TRUE(C.Message == Message && C.Line == Line && C.Col == Col)113      <<   "Expected comment \"" << Message114      << "\" at line " << Line   << ", column " << Col115      << "\nActual comment   \"" << C.Message116      << "\" at line " << C.Line << ", column " << C.Col;117 118    ++Current;119  }120};121 122CommentVerifier CommentHandlerVisitor::GetVerifier() {123  Verified = true;124  return CommentVerifier(Comments, PP);125}126 127 128TEST(CommentHandlerTest, BasicTest1) {129  CommentHandlerVisitor Visitor;130  EXPECT_TRUE(Visitor.runOver("class X {}; int main() { return 0; }"));131  CommentVerifier Verifier = Visitor.GetVerifier();132}133 134TEST(CommentHandlerTest, BasicTest2) {135  CommentHandlerVisitor Visitor;136  EXPECT_TRUE(Visitor.runOver(137        "class X {}; int main() { /* comment */ return 0; }"));138  CommentVerifier Verifier = Visitor.GetVerifier();139  Verifier.Match("/* comment */", 1, 26);140}141 142TEST(CommentHandlerTest, BasicTest3) {143  CommentHandlerVisitor Visitor;144  EXPECT_TRUE(Visitor.runOver(145        "class X {}; // comment 1\n"146        "int main() {\n"147        "  // comment 2\n"148        "  return 0;\n"149        "}"));150  CommentVerifier Verifier = Visitor.GetVerifier();151  Verifier.Match("// comment 1", 1, 13);152  Verifier.Match("// comment 2", 3, 3);153}154 155TEST(CommentHandlerTest, IfBlock1) {156  CommentHandlerVisitor Visitor;157  EXPECT_TRUE(Visitor.runOver(158        "#if 0\n"159        "// ignored comment\n"160        "#endif\n"161        "// visible comment\n"));162  CommentVerifier Verifier = Visitor.GetVerifier();163  Verifier.Match("// visible comment", 4, 1);164}165 166TEST(CommentHandlerTest, IfBlock2) {167  CommentHandlerVisitor Visitor;168  EXPECT_TRUE(Visitor.runOver(169        "#define TEST        // visible_1\n"170        "#ifndef TEST        // visible_2\n"171        "                    // ignored_3\n"172        "# ifdef UNDEFINED   // ignored_4\n"173        "# endif             // ignored_5\n"174        "#elif defined(TEST) // visible_6\n"175        "# if 1              // visible_7\n"176        "                    // visible_8\n"177        "# else              // visible_9\n"178        "                    // ignored_10\n"179        "#  ifndef TEST      // ignored_11\n"180        "#  endif            // ignored_12\n"181        "# endif             // visible_13\n"182        "#endif              // visible_14\n"));183 184  CommentVerifier Verifier = Visitor.GetVerifier();185  Verifier.Match("// visible_1", 1, 21);186  Verifier.Match("// visible_2", 2, 21);187  Verifier.Match("// visible_6", 6, 21);188  Verifier.Match("// visible_7", 7, 21);189  Verifier.Match("// visible_8", 8, 21);190  Verifier.Match("// visible_9", 9, 21);191  Verifier.Match("// visible_13", 13, 21);192  Verifier.Match("// visible_14", 14, 21);193}194 195TEST(CommentHandlerTest, IfBlock3) {196  const char *Source =197        "/* commented out ...\n"198        "#if 0\n"199        "// enclosed\n"200        "#endif */";201 202  CommentHandlerVisitor Visitor;203  EXPECT_TRUE(Visitor.runOver(Source));204  CommentVerifier Verifier = Visitor.GetVerifier();205  Verifier.Match(Source, 1, 1);206}207 208TEST(CommentHandlerTest, PPDirectives) {209  CommentHandlerVisitor Visitor;210  EXPECT_TRUE(Visitor.runOver(211        "#warning Y   // ignored_1\n" // #warning takes whole line as message212        "#undef MACRO // visible_2\n"213        "#line 1      // visible_3\n"));214 215  CommentVerifier Verifier = Visitor.GetVerifier();216  Verifier.Match("// visible_2", 2, 14);217  Verifier.Match("// visible_3", 3, 14);218}219 220} // end namespace clang221