CommentParser.cpp revision 477a9f58c1b197f315befd03b42a8a0b3a2f0ff9
1b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj//===- unittests/AST/CommentParser.cpp ------ Comment parser tests --------===//
2e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn//
3e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn//                     The LLVM Compiler Infrastructure
4e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn//
57fd15d674f18757167305947732057099e175914njn// This file is distributed under the University of Illinois Open Source
67fd15d674f18757167305947732057099e175914njn// License. See LICENSE.TXT for details.
77fd15d674f18757167305947732057099e175914njn//
87fd15d674f18757167305947732057099e175914njn//===----------------------------------------------------------------------===//
9e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
10e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "clang/Basic/SourceManager.h"
11e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "clang/Basic/FileManager.h"
12b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn#include "clang/Basic/Diagnostic.h"
13b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn#include "clang/AST/Comment.h"
14de4a1d01951937632098a6cda45859afa587a06fsewardj#include "clang/AST/CommentLexer.h"
159f207460d70d38c46c9e81996a3dcdf90961c6dbnjn#include "clang/AST/CommentParser.h"
16e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "clang/AST/CommentSema.h"
17e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/ADT/STLExtras.h"
18e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "llvm/Support/Allocator.h"
19e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include <vector>
20e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
21e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include "gtest/gtest.h"
22e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
23e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnusing namespace llvm;
24e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnusing namespace clang;
25e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
26e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnnamespace clang {
27e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnnamespace comments {
28de4a1d01951937632098a6cda45859afa587a06fsewardj
29e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnnamespace {
30e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
31de4a1d01951937632098a6cda45859afa587a06fsewardjconst bool DEBUG = true;
32e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
33e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnclass CommentParserTest : public ::testing::Test {
34e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnprotected:
35de4a1d01951937632098a6cda45859afa587a06fsewardj  CommentParserTest()
36e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn    : FileMgr(FileMgrOpts),
37e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      DiagID(new DiagnosticIDs()),
38e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      Diags(DiagID, new IgnoringDiagConsumer()),
39e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      SourceMgr(Diags, FileMgr) {
40e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn  }
41e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
42e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn  FileSystemOptions FileMgrOpts;
43e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn  FileManager FileMgr;
44e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn  IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
45e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn  DiagnosticsEngine Diags;
46e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn  SourceManager SourceMgr;
47de4a1d01951937632098a6cda45859afa587a06fsewardj  llvm::BumpPtrAllocator Allocator;
48e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
49e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn  FullComment *parseString(const char *Source);
50e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn};
51e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
52e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnFullComment *CommentParserTest::parseString(const char *Source) {
53e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn  MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source);
54e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn  FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
55e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn  SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
56de4a1d01951937632098a6cda45859afa587a06fsewardj
57de4a1d01951937632098a6cda45859afa587a06fsewardj  comments::Lexer L(Allocator, Begin, CommentOptions(),
58de4a1d01951937632098a6cda45859afa587a06fsewardj                    Source, Source + strlen(Source));
5930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
6030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  comments::Sema S(Allocator, SourceMgr, Diags);
6130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  comments::Parser P(L, S, Allocator, SourceMgr, Diags);
6230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  comments::FullComment *FC = P.parseFullComment();
6330d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
6430d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  if (DEBUG) {
6530d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    llvm::errs() << "=== Source:\n" << Source << "\n=== AST:\n";
6630d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    FC->dump(SourceMgr);
670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
6830d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
6930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  Token Tok;
7030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  L.lex(Tok);
7130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  if (Tok.is(tok::eof))
7230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    return FC;
73de4a1d01951937632098a6cda45859afa587a06fsewardj  else
74de4a1d01951937632098a6cda45859afa587a06fsewardj    return NULL;
75de4a1d01951937632098a6cda45859afa587a06fsewardj}
7639de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
7739de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge::testing::AssertionResult HasChildCount(const Comment *C, size_t Count) {
783dd0a912e48a4884ee51ab3afe41856c165185canjn  if (!C)
793dd0a912e48a4884ee51ab3afe41856c165185canjn    return ::testing::AssertionFailure() << "Comment is NULL";
803dd0a912e48a4884ee51ab3afe41856c165185canjn
813dd0a912e48a4884ee51ab3afe41856c165185canjn  if (Count != C->child_count())
82f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "Count = " << Count
840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << ", child_count = " << C->child_count();
850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  return ::testing::AssertionSuccess();
87f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj}
88f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
89f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardjtemplate <typename T>
90f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj::testing::AssertionResult GetChildAt(const Comment *C,
91f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                      size_t Idx,
92f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                      T *&Child) {
93f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (!C)
94f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure() << "Comment is NULL";
95f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
96f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  if (Idx >= C->child_count())
97f76d27a697a7b0bf3b84490baf60623fc96a23afnjn    return ::testing::AssertionFailure()
98f76d27a697a7b0bf3b84490baf60623fc96a23afnjn        << "Idx out of range.  Idx = " << Idx
99f76d27a697a7b0bf3b84490baf60623fc96a23afnjn        << ", child_count = " << C->child_count();
100f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
101f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  Comment::child_iterator I = C->child_begin() + Idx;
102f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  Comment *CommentChild = *I;
103f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  if (!CommentChild)
104f76d27a697a7b0bf3b84490baf60623fc96a23afnjn    return ::testing::AssertionFailure() << "Child is NULL";
105f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
106f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  Child = dyn_cast<T>(CommentChild);
107f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (!Child)
108f76d27a697a7b0bf3b84490baf60623fc96a23afnjn    return ::testing::AssertionFailure()
109f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "Child is not of requested type, but a "
110f76d27a697a7b0bf3b84490baf60623fc96a23afnjn        << CommentChild->getCommentKindName();
111f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
112f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  return ::testing::AssertionSuccess();
113f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj}
1140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj::testing::AssertionResult HasTextAt(const Comment *C,
1160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                     size_t Idx,
1170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                     StringRef Text) {
118b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj  TextComment *TC;
119b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj  ::testing::AssertionResult AR = GetChildAt(C, Idx, TC);
1200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (!AR)
12130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    return AR;
1220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  StringRef ActualText = TC->getText();
12430d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  if (ActualText != Text)
125de4a1d01951937632098a6cda45859afa587a06fsewardj    return ::testing::AssertionFailure()
1260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "TextComment has text \"" << ActualText.str() << "\", "
12726aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn           "expected \"" << Text.str() << "\"";
12826aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
1290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (TC->hasTrailingNewline())
1300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
1310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "TextComment has a trailing newline";
1320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1339af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  return ::testing::AssertionSuccess();
1340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
1350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
13626aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn::testing::AssertionResult HasTextWithNewlineAt(const Comment *C,
13726aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn                                                size_t Idx,
1380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                                StringRef Text) {
1390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  TextComment *TC;
1400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ::testing::AssertionResult AR = GetChildAt(C, Idx, TC);
1410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (!AR)
1420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return AR;
143de4a1d01951937632098a6cda45859afa587a06fsewardj
1440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  StringRef ActualText = TC->getText();
1450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (ActualText != Text)
1460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
1470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "TextComment has text \"" << ActualText.str() << "\", "
1480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "expected \"" << Text.str() << "\"";
1490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (!TC->hasTrailingNewline())
1510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
1529af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        << "TextComment has no trailing newline";
153e90c6836fd430124799e52896c99ea27b1c88541nethercote
1545426544c9c3fc835ead99fae9e2054625110ef3enethercote  return ::testing::AssertionSuccess();
1555426544c9c3fc835ead99fae9e2054625110ef3enethercote}
1565426544c9c3fc835ead99fae9e2054625110ef3enethercote
1575426544c9c3fc835ead99fae9e2054625110ef3enethercote::testing::AssertionResult HasBlockCommandAt(const Comment *C,
1589af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                                             size_t Idx,
1595426544c9c3fc835ead99fae9e2054625110ef3enethercote                                             BlockCommandComment *&BCC,
1600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                             StringRef Name,
161d68ac3e974d25f88492774f6baa491999afde9f9sewardj                                             ParagraphComment *&Paragraph) {
162d68ac3e974d25f88492774f6baa491999afde9f9sewardj  ::testing::AssertionResult AR = GetChildAt(C, Idx, BCC);
163d68ac3e974d25f88492774f6baa491999afde9f9sewardj  if (!AR)
164d68ac3e974d25f88492774f6baa491999afde9f9sewardj    return AR;
165d68ac3e974d25f88492774f6baa491999afde9f9sewardj
166d68ac3e974d25f88492774f6baa491999afde9f9sewardj  StringRef ActualName = BCC->getCommandName();
167d68ac3e974d25f88492774f6baa491999afde9f9sewardj  if (ActualName != Name)
168d68ac3e974d25f88492774f6baa491999afde9f9sewardj    return ::testing::AssertionFailure()
169d68ac3e974d25f88492774f6baa491999afde9f9sewardj        << "BlockCommandComment has name \"" << ActualName.str() << "\", "
170d68ac3e974d25f88492774f6baa491999afde9f9sewardj           "expected \"" << Name.str() << "\"";
171d68ac3e974d25f88492774f6baa491999afde9f9sewardj
172d68ac3e974d25f88492774f6baa491999afde9f9sewardj  Paragraph = BCC->getParagraph();
173e90c6836fd430124799e52896c99ea27b1c88541nethercote
174de4a1d01951937632098a6cda45859afa587a06fsewardj  return ::testing::AssertionSuccess();
175f76d27a697a7b0bf3b84490baf60623fc96a23afnjn}
1760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
177f76d27a697a7b0bf3b84490baf60623fc96a23afnjn::testing::AssertionResult HasParamCommandAt(
178c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj                              const Comment *C,
179c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj                              size_t Idx,
180c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj                              ParamCommandComment *&PCC,
181c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj                              StringRef CommandName,
182c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj                              ParamCommandComment::PassDirection Direction,
183c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj                              bool IsDirectionExplicit,
184c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj                              StringRef ParamName,
1850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                              ParagraphComment *&Paragraph) {
1860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ::testing::AssertionResult AR = GetChildAt(C, Idx, PCC);
1871a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  if (!AR)
1880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return AR;
1890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  StringRef ActualCommandName = PCC->getCommandName();
1919af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  if (ActualCommandName != CommandName)
1929af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    return ::testing::AssertionFailure()
1930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "ParamCommandComment has name \"" << ActualCommandName.str() << "\", "
1940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "expected \"" << CommandName.str() << "\"";
1950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (PCC->getDirection() != Direction)
1970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
1980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "ParamCommandComment has direction " << PCC->getDirection() << ", "
1999af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj           "expected " << Direction;
2000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (PCC->isDirectionExplicit() != IsDirectionExplicit)
2020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
2030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "ParamCommandComment has "
2040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << (PCC->isDirectionExplicit() ? "explicit" : "implicit")
2050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << " direction, "
2060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "expected " << (IsDirectionExplicit ? "explicit" : "implicit");
2070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
208c616819253fcf211745060b2be26076174b1df19njn  if (!PCC->hasParamName())
2090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
210c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj        << "ParamCommandComment has no parameter name";
211c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
212c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  StringRef ActualParamName = PCC->getParamName();
2130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (ActualParamName != ParamName)
2140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
2150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "ParamCommandComment has parameter name \"" << ActualParamName.str()
2160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "\", "
2170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "expected \"" << ParamName.str() << "\"";
2180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  Paragraph = PCC->getParagraph();
220c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
221ca0518df66f8c3375a860f1a55a51f18e2a16c44njn  return ::testing::AssertionSuccess();
2220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
2230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj::testing::AssertionResult HasInlineCommandAt(const Comment *C,
2250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                              size_t Idx,
2260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                              InlineCommandComment *&ICC,
227f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                                              StringRef Name) {
2280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ::testing::AssertionResult AR = GetChildAt(C, Idx, ICC);
229f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  if (!AR)
2300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return AR;
231f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
232c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  StringRef ActualName = ICC->getCommandName();
233c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  if (ActualName != Name)
234c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    return ::testing::AssertionFailure()
235c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj        << "InlineCommandComment has name \"" << ActualName.str() << "\", "
236c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj           "expected \"" << Name.str() << "\"";
237c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
238c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  return ::testing::AssertionSuccess();
2390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
2400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2411a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardjstruct NoArgs {};
2420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj::testing::AssertionResult HasInlineCommandAt(const Comment *C,
2440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                              size_t Idx,
2459af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                                              InlineCommandComment *&ICC,
2469af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                                              StringRef Name,
2470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                              NoArgs) {
2480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ::testing::AssertionResult AR = HasInlineCommandAt(C, Idx, ICC, Name);
2490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (!AR)
2500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return AR;
2510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (ICC->getNumArgs() != 0)
2539af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    return ::testing::AssertionFailure()
2540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), "
2550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "expected 0";
2560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  return ::testing::AssertionSuccess();
2580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
2590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj::testing::AssertionResult HasInlineCommandAt(const Comment *C,
2610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                              size_t Idx,
26285665ca6fa29dd64754dabe50eb98f25896e752acerion                                              InlineCommandComment *&ICC,
2630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                              StringRef Name,
264c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj                                              StringRef Arg) {
265c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  ::testing::AssertionResult AR = HasInlineCommandAt(C, Idx, ICC, Name);
266c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  if (!AR)
2670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return AR;
2680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (ICC->getNumArgs() != 1)
2700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
2710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), "
2720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "expected 1";
2730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
274c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  StringRef ActualArg = ICC->getArgText(0);
2752c48c7b0a453d32375a4df17e153011b797ef28csewardj  if (ActualArg != Arg)
2760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
2770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "InlineCommandComment has argument \"" << ActualArg.str() << "\", "
2780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "expected \"" << Arg.str() << "\"";
2790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  return ::testing::AssertionSuccess();
281f76d27a697a7b0bf3b84490baf60623fc96a23afnjn}
2820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
283f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
2840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                             size_t Idx,
285f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                             HTMLStartTagComment *&HST,
286d68ac3e974d25f88492774f6baa491999afde9f9sewardj                                             StringRef TagName) {
287d68ac3e974d25f88492774f6baa491999afde9f9sewardj  ::testing::AssertionResult AR = GetChildAt(C, Idx, HST);
288d68ac3e974d25f88492774f6baa491999afde9f9sewardj  if (!AR)
289c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    return AR;
290d68ac3e974d25f88492774f6baa491999afde9f9sewardj
291d68ac3e974d25f88492774f6baa491999afde9f9sewardj  StringRef ActualTagName = HST->getTagName();
292d68ac3e974d25f88492774f6baa491999afde9f9sewardj  if (ActualTagName != TagName)
2930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
2940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "HTMLStartTagComment has name \"" << ActualTagName.str() << "\", "
2951a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj           "expected \"" << TagName.str() << "\"";
2960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  return ::testing::AssertionSuccess();
2980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
2999af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj
3000ec07f32bbbb209d749b9974408e6f025ad40b31sewardjstruct SelfClosing {};
3019af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj
3021c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
3031c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                                             size_t Idx,
3040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                             HTMLStartTagComment *&HST,
3050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                             StringRef TagName,
3060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                             SelfClosing) {
3070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
3080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (!AR)
3099af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    return AR;
3100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3111c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj  if (!HST->isSelfClosing())
3121c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    return ::testing::AssertionFailure()
3131c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj        << "HTMLStartTagComment is not self-closing";
3140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3151c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj  return ::testing::AssertionSuccess();
3161c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj}
3171c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj
3181c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj
3191c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardjstruct NoAttrs {};
3200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
3220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                             size_t Idx,
323d68ac3e974d25f88492774f6baa491999afde9f9sewardj                                             HTMLStartTagComment *&HST,
324d68ac3e974d25f88492774f6baa491999afde9f9sewardj                                             StringRef TagName,
3251c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                                             NoAttrs) {
3260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
3270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  if (!AR)
3281c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    return AR;
3291c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj
3301c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj  if (HST->isSelfClosing())
3310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
3321c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj        << "HTMLStartTagComment is self-closing";
3330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
334d68ac3e974d25f88492774f6baa491999afde9f9sewardj  if (HST->getNumAttrs() != 0)
3350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    return ::testing::AssertionFailure()
3360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), "
3370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "expected 0";
3380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  return ::testing::AssertionSuccess();
3400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
341f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
343f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                             size_t Idx,
3440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                             HTMLStartTagComment *&HST,
345f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                             StringRef TagName,
346d68ac3e974d25f88492774f6baa491999afde9f9sewardj                                             StringRef AttrName,
347d68ac3e974d25f88492774f6baa491999afde9f9sewardj                                             StringRef AttrValue) {
348d68ac3e974d25f88492774f6baa491999afde9f9sewardj  ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
349d68ac3e974d25f88492774f6baa491999afde9f9sewardj  if (!AR)
350d68ac3e974d25f88492774f6baa491999afde9f9sewardj    return AR;
351d68ac3e974d25f88492774f6baa491999afde9f9sewardj
352d68ac3e974d25f88492774f6baa491999afde9f9sewardj  if (HST->isSelfClosing())
353d68ac3e974d25f88492774f6baa491999afde9f9sewardj    return ::testing::AssertionFailure()
3541a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj        << "HTMLStartTagComment is self-closing";
3551a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
3561a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  if (HST->getNumAttrs() != 1)
3571a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    return ::testing::AssertionFailure()
3580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), "
3590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "expected 1";
3609af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj
3610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  StringRef ActualName = HST->getAttr(0).Name;
3629af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  if (ActualName != AttrName)
3631a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    return ::testing::AssertionFailure()
3641a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj        << "HTMLStartTagComment has attr \"" << ActualName.str() << "\", "
3651a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj           "expected \"" << AttrName.str() << "\"";
3661a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
3671a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  StringRef ActualValue = HST->getAttr(0).Value;
3681a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  if (ActualValue != AttrValue)
3691a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    return ::testing::AssertionFailure()
3709af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        << "HTMLStartTagComment has attr value \"" << ActualValue.str() << "\", "
3710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj           "expected \"" << AttrValue.str() << "\"";
3721a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
3731a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  return ::testing::AssertionSuccess();
3741a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj}
3751a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
3760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj::testing::AssertionResult HasHTMLEndTagAt(const Comment *C,
3771a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                                           size_t Idx,
3781a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                                           HTMLEndTagComment *&HET,
3791a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                                           StringRef TagName) {
3801a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  ::testing::AssertionResult AR = GetChildAt(C, Idx, HET);
381d68ac3e974d25f88492774f6baa491999afde9f9sewardj  if (!AR)
382d68ac3e974d25f88492774f6baa491999afde9f9sewardj    return AR;
383d68ac3e974d25f88492774f6baa491999afde9f9sewardj
3841a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  StringRef ActualTagName = HET->getTagName();
3851a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  if (ActualTagName != TagName)
3861a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    return ::testing::AssertionFailure()
3871a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj        << "HTMLEndTagComment has name \"" << ActualTagName.str() << "\", "
3881a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj           "expected \"" << TagName.str() << "\"";
3891a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
3901a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  return ::testing::AssertionSuccess();
391d68ac3e974d25f88492774f6baa491999afde9f9sewardj}
392d68ac3e974d25f88492774f6baa491999afde9f9sewardj
393d68ac3e974d25f88492774f6baa491999afde9f9sewardj::testing::AssertionResult HasParagraphCommentAt(const Comment *C,
394d68ac3e974d25f88492774f6baa491999afde9f9sewardj                                                 size_t Idx,
395d68ac3e974d25f88492774f6baa491999afde9f9sewardj                                                 StringRef Text) {
396d68ac3e974d25f88492774f6baa491999afde9f9sewardj  ParagraphComment *PC;
397d68ac3e974d25f88492774f6baa491999afde9f9sewardj
398d68ac3e974d25f88492774f6baa491999afde9f9sewardj  {
399d68ac3e974d25f88492774f6baa491999afde9f9sewardj    ::testing::AssertionResult AR = GetChildAt(C, Idx, PC);
4000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    if (!AR)
4011a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj      return AR;
4021a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  }
4031a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
4041a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  {
4051a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    ::testing::AssertionResult AR = HasChildCount(PC, 1);
4061a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    if (!AR)
407f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      return AR;
408f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
409f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
410f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  {
411f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    ::testing::AssertionResult AR = HasTextAt(PC, 0, Text);
412f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    if (!AR)
413f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      return AR;
414f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
415f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
416f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  return ::testing::AssertionSuccess();
417f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj}
418f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
419f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
420f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              size_t Idx,
421f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              VerbatimBlockComment *&VBC,
422f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef Name,
423f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef CloseName) {
424f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  ::testing::AssertionResult AR = GetChildAt(C, Idx, VBC);
425f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (!AR)
426f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return AR;
427f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
428f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  StringRef ActualName = VBC->getCommandName();
429f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (ActualName != Name)
430f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
431f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "VerbatimBlockComment has name \"" << ActualName.str() << "\", "
432f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj           "expected \"" << Name.str() << "\"";
433f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
434f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  StringRef ActualCloseName = VBC->getCloseName();
435f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (ActualCloseName != CloseName)
436f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
437f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "VerbatimBlockComment has closing command name \""
438f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << ActualCloseName.str() << "\", "
439f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj           "expected \"" << CloseName.str() << "\"";
440f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
441f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  return ::testing::AssertionSuccess();
442f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj}
443f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
444f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardjstruct NoLines {};
445f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardjstruct Lines {};
446f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
447f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
448f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              size_t Idx,
449f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              VerbatimBlockComment *&VBC,
450f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef Name,
451f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef CloseName,
452f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              NoLines) {
453f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name,
454f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                                     CloseName);
455f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (!AR)
456f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return AR;
457f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
458f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (VBC->getNumLines() != 0)
459f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
460f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
461f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj           "expected 0";
462f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
463f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  return ::testing::AssertionSuccess();
464f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj}
465f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
466f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
467f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              size_t Idx,
468f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              VerbatimBlockComment *&VBC,
469f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef Name,
470f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef CloseName,
471f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              Lines,
472f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef Line0) {
473f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name,
474f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                                     CloseName);
475f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (!AR)
476f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return AR;
477f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
478f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (VBC->getNumLines() != 1)
479f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
480f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
481f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj           "expected 1";
482f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
483f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  StringRef ActualLine0 = VBC->getText(0);
484f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (ActualLine0 != Line0)
485f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
486f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "VerbatimBlockComment has lines[0] \"" << ActualLine0.str() << "\", "
487f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj           "expected \"" << Line0.str() << "\"";
488f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
489f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  return ::testing::AssertionSuccess();
490f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj}
491f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
492f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
493f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              size_t Idx,
494f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              VerbatimBlockComment *&VBC,
495f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef Name,
496f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef CloseName,
497f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              Lines,
498f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef Line0,
499f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                              StringRef Line1) {
500f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name,
501f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                                     CloseName);
502f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (!AR)
503f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return AR;
504f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
505f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (VBC->getNumLines() != 2)
506f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
507f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
508f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj           "expected 2";
509f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
510f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  StringRef ActualLine0 = VBC->getText(0);
511f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (ActualLine0 != Line0)
512f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
513f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "VerbatimBlockComment has lines[0] \"" << ActualLine0.str() << "\", "
514f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj           "expected \"" << Line0.str() << "\"";
515f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
516f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  StringRef ActualLine1 = VBC->getText(1);
517f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (ActualLine1 != Line1)
518f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
519f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "VerbatimBlockComment has lines[1] \"" << ActualLine1.str() << "\", "
520f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj           "expected \"" << Line1.str() << "\"";
521f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
522f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  return ::testing::AssertionSuccess();
523f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj}
524f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
525f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj::testing::AssertionResult HasVerbatimLineAt(const Comment *C,
526f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                             size_t Idx,
527f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                             VerbatimLineComment *&VLC,
528f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                             StringRef Name,
529f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                             StringRef Text) {
530f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  ::testing::AssertionResult AR = GetChildAt(C, Idx, VLC);
531f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (!AR)
532f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return AR;
533f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
534f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  StringRef ActualName = VLC->getCommandName();
535f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (ActualName != Name)
536f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
537f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "VerbatimLineComment has name \"" << ActualName.str() << "\", "
538f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj           "expected \"" << Name.str() << "\"";
539f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
540f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  StringRef ActualText = VLC->getText();
541f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  if (ActualText != Text)
542f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    return ::testing::AssertionFailure()
543f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        << "VerbatimLineComment has text \"" << ActualText.str() << "\", "
544f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj           "expected \"" << Text.str() << "\"";
545f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
546f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  return ::testing::AssertionSuccess();
547f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj}
548f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
549f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
550f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardjTEST_F(CommentParserTest, Basic1) {
551f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  const char *Source = "//";
55285665ca6fa29dd64754dabe50eb98f25896e752acerion
553f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  FullComment *FC = parseString(Source);
55426aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn  ASSERT_TRUE(HasChildCount(FC, 0));
55537091fb739760631f436043c47de612cf9fd2dd1sewardj}
5562e93c50dc50235189661b70e3f27a4098d5cccccsewardj
55769d9c4625034b60c08e04cc246fcf8093d23fde5nethercoteTEST_F(CommentParserTest, Basic2) {
55830d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  const char *Source = "// Meow";
559f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
5600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
5610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasChildCount(FC, 1));
5620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Meow"));
5640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
5650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5660ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, Basic3) {
5670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Source =
5680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Aaa\n"
5690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Bbb";
5700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
5720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasChildCount(FC, 1));
5730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  {
5750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ParagraphComment *PC;
5760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(GetChildAt(FC, 0, PC));
5770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(PC, 2));
5790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa"));
5800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 1, " Bbb"));
5810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
5820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
5830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
5845f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njnTEST_F(CommentParserTest, Paragraph1) {
5855f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn  const char *Sources[] = {
5865f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn    "// Aaa\n"
5875f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn    "//\n"
5880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Bbb",
5895f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn
5900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Aaa\n"
5910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "//\n"
5925f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn    "//\n"
5930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Bbb",
594d68ac3e974d25f88492774f6baa491999afde9f9sewardj  };
595d68ac3e974d25f88492774f6baa491999afde9f9sewardj
596d68ac3e974d25f88492774f6baa491999afde9f9sewardj
597d68ac3e974d25f88492774f6baa491999afde9f9sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
598d68ac3e974d25f88492774f6baa491999afde9f9sewardj    FullComment *FC = parseString(Sources[i]);
5990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(FC, 2));
6000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Aaa"));
6020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 1, " Bbb"));
6030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
6040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
6050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6060ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, Paragraph2) {
6070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Source =
6080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\brief Aaa\n"
6090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "//\n"
6100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Bbb";
6110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
6130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasChildCount(FC, 3));
6140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6155ce4b150ce5d32c9af07a24717081ea34568388asewardj  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
6165ce4b150ce5d32c9af07a24717081ea34568388asewardj  {
6175ce4b150ce5d32c9af07a24717081ea34568388asewardj    BlockCommandComment *BCC;
6185ce4b150ce5d32c9af07a24717081ea34568388asewardj    ParagraphComment *PC;
6192b5f0a90334a2271791c110548a842fadb5ffc65njn    ASSERT_TRUE(HasBlockCommandAt(FC, 1, BCC, "brief", PC));
6202b5f0a90334a2271791c110548a842fadb5ffc65njn
6212b5f0a90334a2271791c110548a842fadb5ffc65njn    ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Aaa"));
6222b5f0a90334a2271791c110548a842fadb5ffc65njn  }
6232b5f0a90334a2271791c110548a842fadb5ffc65njn  ASSERT_TRUE(HasParagraphCommentAt(FC, 2, " Bbb"));
6242b5f0a90334a2271791c110548a842fadb5ffc65njn}
6252b5f0a90334a2271791c110548a842fadb5ffc65njn
6262b5f0a90334a2271791c110548a842fadb5ffc65njnTEST_F(CommentParserTest, Paragraph3) {
6272b5f0a90334a2271791c110548a842fadb5ffc65njn  const char *Source = "// \\brief \\author";
6282b5f0a90334a2271791c110548a842fadb5ffc65njn
6292b5f0a90334a2271791c110548a842fadb5ffc65njn  FullComment *FC = parseString(Source);
6302b5f0a90334a2271791c110548a842fadb5ffc65njn  ASSERT_TRUE(HasChildCount(FC, 3));
6312b5f0a90334a2271791c110548a842fadb5ffc65njn
6322b5f0a90334a2271791c110548a842fadb5ffc65njn  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
6332b5f0a90334a2271791c110548a842fadb5ffc65njn  {
6342b5f0a90334a2271791c110548a842fadb5ffc65njn    BlockCommandComment *BCC;
635f76d27a697a7b0bf3b84490baf60623fc96a23afnjn    ParagraphComment *PC;
6360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasBlockCommandAt(FC, 1, BCC, "brief", PC));
637f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
6380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " "));
6390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
6400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  {
6410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    BlockCommandComment *BCC;
6420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ParagraphComment *PC;
6430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasBlockCommandAt(FC, 2, BCC, "author", PC));
6440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(GetChildAt(BCC, 0, PC));
64666226cc1e5e852de3584c76984dace8679730b42sewardj      ASSERT_TRUE(HasChildCount(PC, 0));
6470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
64866226cc1e5e852de3584c76984dace8679730b42sewardj}
6490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6500ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, Paragraph4) {
65166226cc1e5e852de3584c76984dace8679730b42sewardj  const char *Source =
6520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\brief Aaa\n"
6530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Bbb \\author\n"
6540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Ccc";
6550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
6570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasChildCount(FC, 3));
6580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
6600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  {
6610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    BlockCommandComment *BCC;
66266226cc1e5e852de3584c76984dace8679730b42sewardj    ParagraphComment *PC;
6630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasBlockCommandAt(FC, 1, BCC, "brief", PC));
66466226cc1e5e852de3584c76984dace8679730b42sewardj
6650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(GetChildAt(BCC, 0, PC));
6660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasChildCount(PC, 2));
66766226cc1e5e852de3584c76984dace8679730b42sewardj      ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa"));
6680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 1, " Bbb "));
6690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
6700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  {
6710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    BlockCommandComment *BCC;
6720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ParagraphComment *PC;
6730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasBlockCommandAt(FC, 2, BCC, "author", PC));
6740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Ccc"));
6760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
6770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
6780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6790ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, ParamCommand1) {
6800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Sources[] = {
68166226cc1e5e852de3584c76984dace8679730b42sewardj    "// \\param aaa Bbb\n",
6820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param\n"
68366226cc1e5e852de3584c76984dace8679730b42sewardj    "//     aaa Bbb\n",
6840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param \n"
6850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "//     aaa Bbb\n",
68666226cc1e5e852de3584c76984dace8679730b42sewardj    "// \\param aaa\n"
6870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Bbb\n"
6880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  };
6890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
6910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    FullComment *FC = parseString(Sources[i]);
6920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(FC, 2));
6930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
6950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    {
6969e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      ParamCommandComment *PCC;
6979e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      ParagraphComment *PC;
6989e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
6999e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj                                    ParamCommandComment::In,
7009e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj                                    /* IsDirectionExplicit = */ false,
7019e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj                                    "aaa", PC));
7029e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      ASSERT_TRUE(HasChildCount(PCC, 1));
7039e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
7049e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    }
7059e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  }
7069e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj}
7079e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj
7089e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardjTEST_F(CommentParserTest, ParamCommand2) {
7099e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  const char *Sources[] = {
7109e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    "// \\param [in] aaa Bbb\n",
7119e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    "// \\param\n"
7129e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    "//     [in] aaa Bbb\n",
7139e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    "// \\param [in]\n"
7149e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    "//     aaa Bbb\n",
7159e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    "// \\param [in] aaa\n"
7169e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj    "// Bbb\n",
7179e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj  };
7189e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj
7190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
7200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    FullComment *FC = parseString(Sources[i]);
7210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(FC, 2));
7220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
7240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    {
72566226cc1e5e852de3584c76984dace8679730b42sewardj      ParamCommandComment *PCC;
7260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ParagraphComment *PC;
72766226cc1e5e852de3584c76984dace8679730b42sewardj      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
7280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                    ParamCommandComment::In,
7290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                    /* IsDirectionExplicit = */ true,
73066226cc1e5e852de3584c76984dace8679730b42sewardj                                    "aaa", PC));
7310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasChildCount(PCC, 1));
7320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
7330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    }
7340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
7350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
7360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7370ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, ParamCommand3) {
7380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Sources[] = {
7390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param [out] aaa Bbb\n",
7400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param\n"
7410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "//     [out] aaa Bbb\n",
7420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param [out]\n"
7430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "//     aaa Bbb\n",
7440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param [out] aaa\n"
7450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Bbb\n",
7460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  };
7470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
7490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    FullComment *FC = parseString(Sources[i]);
75066226cc1e5e852de3584c76984dace8679730b42sewardj    ASSERT_TRUE(HasChildCount(FC, 2));
7510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
75266226cc1e5e852de3584c76984dace8679730b42sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
7530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    {
7540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ParamCommandComment *PCC;
75566226cc1e5e852de3584c76984dace8679730b42sewardj      ParagraphComment *PC;
7560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
7570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                    ParamCommandComment::Out,
7580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                    /* IsDirectionExplicit = */ true,
7590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                    "aaa", PC));
7600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasChildCount(PCC, 1));
7610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
7620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    }
7630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
7640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
7650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7660ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, ParamCommand4) {
7670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Sources[] = {
7680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param [in,out] aaa Bbb\n",
7690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param [in, out] aaa Bbb\n",
7700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param [in,\n"
7710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "//     out] aaa Bbb\n",
7720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param [in,out]\n"
7730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "//     aaa Bbb\n",
7740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param [in,out] aaa\n"
7750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Bbb\n"
7760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  };
77766226cc1e5e852de3584c76984dace8679730b42sewardj
7780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
77966226cc1e5e852de3584c76984dace8679730b42sewardj    FullComment *FC = parseString(Sources[i]);
7800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(FC, 2));
7810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
78266226cc1e5e852de3584c76984dace8679730b42sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
7830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    {
7840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ParamCommandComment *PCC;
7850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ParagraphComment *PC;
7860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
7870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                    ParamCommandComment::InOut,
7880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                    /* IsDirectionExplicit = */ true,
7890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                    "aaa", PC));
7900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasChildCount(PCC, 1));
7910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
7920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    }
7930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
7940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
7950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7960ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, ParamCommand5) {
7970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Source =
7980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// \\param aaa \\% Bbb \\$ ccc\n";
7990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
8010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasChildCount(FC, 2));
8020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
8040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  {
8050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ParamCommandComment *PCC;
80666226cc1e5e852de3584c76984dace8679730b42sewardj    ParagraphComment *PC;
80766226cc1e5e852de3584c76984dace8679730b42sewardj    ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
8080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                  ParamCommandComment::In,
80966226cc1e5e852de3584c76984dace8679730b42sewardj                                  /* IsDirectionExplicit = */ false,
8100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                  "aaa", PC));
8110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(PCC, 1));
81266226cc1e5e852de3584c76984dace8679730b42sewardj
8130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(PC, 5));
8140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 0, " "));
8150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 1, "%"));
8160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 2, " Bbb "));
8170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 3, "$"));
8180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 4, " ccc"));
8190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
8200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
8210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8220ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, InlineCommand1) {
8230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Source = "// \\c";
8240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
8260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasChildCount(FC, 1));
8270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  {
8290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ParagraphComment *PC;
8300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    InlineCommandComment *ICC;
8310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(GetChildAt(FC, 0, PC));
8320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(PC, 2));
8340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 0, " "));
8350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", NoArgs()));
8360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
8370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
83866226cc1e5e852de3584c76984dace8679730b42sewardj
83966226cc1e5e852de3584c76984dace8679730b42sewardjTEST_F(CommentParserTest, InlineCommand2) {
8400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Source = "// \\c ";
84166226cc1e5e852de3584c76984dace8679730b42sewardj
8420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
8430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasChildCount(FC, 1));
84466226cc1e5e852de3584c76984dace8679730b42sewardj
8450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  {
8460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ParagraphComment *PC;
8470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    InlineCommandComment *ICC;
8480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(GetChildAt(FC, 0, PC));
8490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(PC, 3));
8510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 0, " "));
8520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", NoArgs()));
8530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 2, " "));
8540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
8550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
8560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8570ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, InlineCommand3) {
8580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Source = "// \\c aaa\n";
8590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
8610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasChildCount(FC, 1));
8620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  {
8640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ParagraphComment *PC;
8650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    InlineCommandComment *ICC;
8660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(GetChildAt(FC, 0, PC));
8670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
8680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(PC, 2));
8690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 0, " "));
8700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", "aaa"));
8710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
87245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj}
87345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
87445fa5b0cef1884f5025e64401a1443d3e129ed5esewardjTEST_F(CommentParserTest, InlineCommand4) {
87545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  const char *Source = "// \\c aaa bbb";
87645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
87745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  FullComment *FC = parseString(Source);
87845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  ASSERT_TRUE(HasChildCount(FC, 1));
87945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
88045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  {
88145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    ParagraphComment *PC;
88245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    InlineCommandComment *ICC;
88345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    ASSERT_TRUE(GetChildAt(FC, 0, PC));
88445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
88545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    ASSERT_TRUE(HasChildCount(PC, 3));
88645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      ASSERT_TRUE(HasTextAt(PC, 0, " "));
88745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", "aaa"));
88845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      ASSERT_TRUE(HasTextAt(PC, 2, " bbb"));
88945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  }
89045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj}
89145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
89245fa5b0cef1884f5025e64401a1443d3e129ed5esewardjTEST_F(CommentParserTest, InlineCommand5) {
89345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  const char *Source = "// \\unknown aaa\n";
89445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
89545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  FullComment *FC = parseString(Source);
89645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  ASSERT_TRUE(HasChildCount(FC, 1));
89745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
89845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  {
89945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    ParagraphComment *PC;
90045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    InlineCommandComment *ICC;
90145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    ASSERT_TRUE(GetChildAt(FC, 0, PC));
90245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
90345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    ASSERT_TRUE(HasChildCount(PC, 3));
90445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      ASSERT_TRUE(HasTextAt(PC, 0, " "));
90545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "unknown", NoArgs()));
90645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      ASSERT_TRUE(HasTextAt(PC, 2, " aaa"));
90745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  }
90845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj}
90945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
91045fa5b0cef1884f5025e64401a1443d3e129ed5esewardjTEST_F(CommentParserTest, HTML1) {
91145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  const char *Sources[] = {
91245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    "// <a",
91345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    "// <a>",
91445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    "// <a >"
91545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  };
91645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
91745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
91845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    FullComment *FC = parseString(Sources[i]);
91945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    ASSERT_TRUE(HasChildCount(FC, 1));
92045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
92145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    {
92245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      ParagraphComment *PC;
92345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      HTMLStartTagComment *HST;
92445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      ASSERT_TRUE(GetChildAt(FC, 0, PC));
92545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
92645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      ASSERT_TRUE(HasChildCount(PC, 2));
92745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        ASSERT_TRUE(HasTextAt(PC, 0, " "));
92845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj        ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", NoAttrs()));
92945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    }
93045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  }
93145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj}
93245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
93345fa5b0cef1884f5025e64401a1443d3e129ed5esewardjTEST_F(CommentParserTest, HTML2) {
93445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  const char *Sources[] = {
93545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    "// <br/>",
93645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    "// <br />"
93745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  };
93845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
93945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
94045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    FullComment *FC = parseString(Sources[i]);
94145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    ASSERT_TRUE(HasChildCount(FC, 1));
94245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
94345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj    {
94445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      ParagraphComment *PC;
94545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      HTMLStartTagComment *HST;
9465ce4b150ce5d32c9af07a24717081ea34568388asewardj      ASSERT_TRUE(GetChildAt(FC, 0, PC));
9475ce4b150ce5d32c9af07a24717081ea34568388asewardj
9485ce4b150ce5d32c9af07a24717081ea34568388asewardj      ASSERT_TRUE(HasChildCount(PC, 2));
9495ce4b150ce5d32c9af07a24717081ea34568388asewardj        ASSERT_TRUE(HasTextAt(PC, 0, " "));
9505ce4b150ce5d32c9af07a24717081ea34568388asewardj        ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "br", SelfClosing()));
9515ce4b150ce5d32c9af07a24717081ea34568388asewardj    }
9525ce4b150ce5d32c9af07a24717081ea34568388asewardj  }
9535ce4b150ce5d32c9af07a24717081ea34568388asewardj}
9545ce4b150ce5d32c9af07a24717081ea34568388asewardj
9555ce4b150ce5d32c9af07a24717081ea34568388asewardjTEST_F(CommentParserTest, HTML3) {
9565ce4b150ce5d32c9af07a24717081ea34568388asewardj  const char *Sources[] = {
9575ce4b150ce5d32c9af07a24717081ea34568388asewardj    "// <a href",
9585ce4b150ce5d32c9af07a24717081ea34568388asewardj    "// <a href ",
9595ce4b150ce5d32c9af07a24717081ea34568388asewardj    "// <a href>",
9605ce4b150ce5d32c9af07a24717081ea34568388asewardj    "// <a href >",
9615ce4b150ce5d32c9af07a24717081ea34568388asewardj  };
9625ce4b150ce5d32c9af07a24717081ea34568388asewardj
9635ce4b150ce5d32c9af07a24717081ea34568388asewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
9645ce4b150ce5d32c9af07a24717081ea34568388asewardj    FullComment *FC = parseString(Sources[i]);
9655ce4b150ce5d32c9af07a24717081ea34568388asewardj    ASSERT_TRUE(HasChildCount(FC, 1));
9665ce4b150ce5d32c9af07a24717081ea34568388asewardj
9675ce4b150ce5d32c9af07a24717081ea34568388asewardj    {
9685ce4b150ce5d32c9af07a24717081ea34568388asewardj      ParagraphComment *PC;
9695ce4b150ce5d32c9af07a24717081ea34568388asewardj      HTMLStartTagComment *HST;
9705ce4b150ce5d32c9af07a24717081ea34568388asewardj      ASSERT_TRUE(GetChildAt(FC, 0, PC));
9715ce4b150ce5d32c9af07a24717081ea34568388asewardj
9725ce4b150ce5d32c9af07a24717081ea34568388asewardj      ASSERT_TRUE(HasChildCount(PC, 2));
9735ce4b150ce5d32c9af07a24717081ea34568388asewardj        ASSERT_TRUE(HasTextAt(PC, 0, " "));
9745ce4b150ce5d32c9af07a24717081ea34568388asewardj        ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", ""));
9755ce4b150ce5d32c9af07a24717081ea34568388asewardj    }
9765ce4b150ce5d32c9af07a24717081ea34568388asewardj  }
9775ce4b150ce5d32c9af07a24717081ea34568388asewardj}
9785ce4b150ce5d32c9af07a24717081ea34568388asewardj
9795ce4b150ce5d32c9af07a24717081ea34568388asewardjTEST_F(CommentParserTest, HTML4) {
9805ce4b150ce5d32c9af07a24717081ea34568388asewardj  const char *Sources[] = {
9815ce4b150ce5d32c9af07a24717081ea34568388asewardj    "// <a href=\"bbb\"",
9825ce4b150ce5d32c9af07a24717081ea34568388asewardj    "// <a href=\"bbb\">",
9835ce4b150ce5d32c9af07a24717081ea34568388asewardj  };
9845ce4b150ce5d32c9af07a24717081ea34568388asewardj
9855ce4b150ce5d32c9af07a24717081ea34568388asewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
9865ce4b150ce5d32c9af07a24717081ea34568388asewardj    FullComment *FC = parseString(Sources[i]);
98766226cc1e5e852de3584c76984dace8679730b42sewardj    ASSERT_TRUE(HasChildCount(FC, 1));
98866226cc1e5e852de3584c76984dace8679730b42sewardj
98966226cc1e5e852de3584c76984dace8679730b42sewardj    {
9900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ParagraphComment *PC;
99166226cc1e5e852de3584c76984dace8679730b42sewardj      HTMLStartTagComment *HST;
9920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(GetChildAt(FC, 0, PC));
9930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
99466226cc1e5e852de3584c76984dace8679730b42sewardj      ASSERT_TRUE(HasChildCount(PC, 2));
9950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        ASSERT_TRUE(HasTextAt(PC, 0, " "));
9960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "bbb"));
9970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    }
9980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
9990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
10000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10010ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, HTML5) {
10020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Sources[] = {
10030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// </a",
10040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// </a>",
10050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// </a >"
10060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  };
10070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
10090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    FullComment *FC = parseString(Sources[i]);
10100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(FC, 1));
10110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    {
10130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ParagraphComment *PC;
10140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      HTMLEndTagComment *HET;
10150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(GetChildAt(FC, 0, PC));
10160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasChildCount(PC, 2));
10180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        ASSERT_TRUE(HasTextAt(PC, 0, " "));
10190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        ASSERT_TRUE(HasHTMLEndTagAt(PC, 1, HET, "a"));
10200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    }
10210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
10220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
10230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10240ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, HTML6) {
10250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Source =
10260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// <pre>\n"
10270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Aaa\n"
10280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Bbb\n"
10290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// </pre>\n";
1030f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
10310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
1032f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  ASSERT_TRUE(HasChildCount(FC, 1));
10330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1034f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  {
10350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ParagraphComment *PC;
10360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    HTMLStartTagComment *HST;
10370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    HTMLEndTagComment *HET;
10380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(GetChildAt(FC, 0, PC));
10390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(PC, 6));
10410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextAt(PC, 0, " "));
10420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "pre", NoAttrs()));
10430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextWithNewlineAt(PC, 2, " Aaa"));
10440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasTextWithNewlineAt(PC, 3, " Bbb"));
1045a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj      ASSERT_TRUE(HasTextAt(PC, 4, " "));
1046a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj      ASSERT_TRUE(HasHTMLEndTagAt(PC, 5, HET, "pre"));
1047a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj  }
1048a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj}
1049a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1050a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardjTEST_F(CommentParserTest, VerbatimBlock1) {
1051a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj  const char *Source = "// \\verbatim\\endverbatim\n";
1052a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1053a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj  FullComment *FC = parseString(Source);
1054a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj  ASSERT_TRUE(HasChildCount(FC, 2));
1055a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1056a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1057a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj  {
1058a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    VerbatimBlockComment *VCC;
1059a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VCC, "verbatim", "endverbatim",
1060a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj                                   NoLines()));
1061a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj  }
1062a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj}
1063a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1064a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardjTEST_F(CommentParserTest, VerbatimBlock2) {
1065a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj  const char *Source = "// \\verbatim Aaa \\endverbatim\n";
1066c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
10670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
1068c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  ASSERT_TRUE(HasChildCount(FC, 2));
10690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1071c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  {
10720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VerbatimBlockComment *VBC;
1073a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
10740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                   Lines(), " Aaa "));
10750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
1076a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj}
10770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10780ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, VerbatimBlock3) {
10790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Source = "// \\verbatim Aaa\n";
10800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
10810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
10820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasChildCount(FC, 2));
10830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1084c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
10850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  {
1086c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    VerbatimBlockComment *VBC;
10870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "",
10880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                   Lines(), " Aaa"));
1089c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  }
10900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
10910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1092a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardjTEST_F(CommentParserTest, VerbatimBlock4) {
10930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Source =
10940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "//\\verbatim\n"
10950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "//\\endverbatim\n";
1096a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
10970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  FullComment *FC = parseString(Source);
10980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  ASSERT_TRUE(HasChildCount(FC, 1));
10990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
11000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  {
11010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VerbatimBlockComment *VBC;
11020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", "endverbatim",
11030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                   NoLines()));
1104c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  }
11050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj}
1106c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
11070ec07f32bbbb209d749b9974408e6f025ad40b31sewardjTEST_F(CommentParserTest, VerbatimBlock5) {
11080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  const char *Sources[] = {
1109c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    "//\\verbatim\n"
11100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "// Aaa\n"
11110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    "//\\endverbatim\n",
11120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1113a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    "/*\\verbatim\n"
11140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    " * Aaa\n"
11150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    " *\\endverbatim*/"
11160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  };
11170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1118a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
11190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    FullComment *FC = parseString(Sources[i]);
11200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    ASSERT_TRUE(HasChildCount(FC, 1));
11210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
11220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    {
11230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      VerbatimBlockComment *VBC;
11240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", "endverbatim",
11250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                     Lines(), " Aaa"));
1126a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    }
1127a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  }
1128a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj}
1129a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1130a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardjTEST_F(CommentParserTest, VerbatimBlock6) {
1131a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  const char *Sources[] = {
1132a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// \\verbatim\n"
1133a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// Aaa\n"
1134a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// \\endverbatim\n",
1135a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1136a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    "/* \\verbatim\n"
1137a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    " * Aaa\n"
1138a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    " * \\endverbatim*/"
1139a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  };
1140a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1141a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1142a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    FullComment *FC = parseString(Sources[i]);
1143a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    ASSERT_TRUE(HasChildCount(FC, 2));
1144a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1145a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1146a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    {
1147a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      VerbatimBlockComment *VBC;
1148a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
1149a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                     Lines(), " Aaa"));
1150a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    }
1151a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  }
1152a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj}
1153a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1154a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardjTEST_F(CommentParserTest, VerbatimBlock7) {
1155a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  const char *Sources[] = {
1156a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// \\verbatim\n"
1157a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// Aaa\n"
1158a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// Bbb\n"
1159a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// \\endverbatim\n",
1160a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1161a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    "/* \\verbatim\n"
1162a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    " * Aaa\n"
1163a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    " * Bbb\n"
1164a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    " * \\endverbatim*/"
1165a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  };
1166a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1167a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1168a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    FullComment *FC = parseString(Sources[i]);
1169a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    ASSERT_TRUE(HasChildCount(FC, 2));
1170a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1171a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1172a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    {
1173a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      VerbatimBlockComment *VBC;
1174a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
1175a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                     Lines(), " Aaa", " Bbb"));
1176a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    }
1177a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  }
1178a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj}
1179a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1180a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardjTEST_F(CommentParserTest, VerbatimBlock8) {
1181a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  const char *Sources[] = {
1182a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// \\verbatim\n"
1183a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// Aaa\n"
1184a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "//\n"
1185a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// Bbb\n"
1186a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// \\endverbatim\n",
1187a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1188a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    "/* \\verbatim\n"
1189a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    " * Aaa\n"
1190a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    " *\n"
1191a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    " * Bbb\n"
1192a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    " * \\endverbatim*/"
1193a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  };
1194a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1195a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    FullComment *FC = parseString(Sources[i]);
1196a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    ASSERT_TRUE(HasChildCount(FC, 2));
1197a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1198a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1199a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    {
1200a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      VerbatimBlockComment *VBC;
1201a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim"));
1202a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      ASSERT_EQ(3U, VBC->getNumLines());
1203a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      ASSERT_EQ(" Aaa", VBC->getText(0));
1204a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      ASSERT_EQ("",     VBC->getText(1));
1205a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      ASSERT_EQ(" Bbb", VBC->getText(2));
1206a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    }
1207a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  }
1208a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj}
1209a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1210a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardjTEST_F(CommentParserTest, VerbatimLine1) {
1211a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  const char *Sources[] = {
1212a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// \\fn",
1213a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "// \\fn\n"
1214a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  };
1215a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1216a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1217a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj    FullComment *FC = parseString(Sources[i]);
1218a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    ASSERT_TRUE(HasChildCount(FC, 2));
1219a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1220a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1221a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    {
1222a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      VerbatimLineComment *VLC;
1223a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      ASSERT_TRUE(HasVerbatimLineAt(FC, 1, VLC, "fn", ""));
1224a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    }
1225a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj  }
1226a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj}
1227a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1228a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardjTEST_F(CommentParserTest, VerbatimLine2) {
1229a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  const char *Sources[] = {
1230a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "/// \\fn void *foo(const char *zzz = \"\\$\");\n//",
1231a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    "/** \\fn void *foo(const char *zzz = \"\\$\");*/"
1232a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  };
1233a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1234a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1235a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    FullComment *FC = parseString(Sources[i]);
1236a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    ASSERT_TRUE(HasChildCount(FC, 2));
1237a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1238a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
1239a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    {
1240a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      VerbatimLineComment *VLC;
1241a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      ASSERT_TRUE(HasVerbatimLineAt(FC, 1, VLC, "fn",
1242a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                  " void *foo(const char *zzz = \"\\$\");"));
1243a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj    }
1244a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj  }
1245a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj}
1246a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1247a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj} // unnamed namespace
1248a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1249a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj} // end namespace comments
1250a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj} // end namespace clang
1251a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1252a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj