Comment.cpp revision 858e69fe1305bdffb76a200c0f498685f11e65ae
1//===--- Comment.cpp - Comment AST node implementation --------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "clang/AST/Comment.h" 11#include "llvm/Support/ErrorHandling.h" 12#include "llvm/Support/raw_ostream.h" 13 14namespace clang { 15namespace comments { 16 17const char *Comment::getCommentKindName() const { 18 switch (getCommentKind()) { 19 case NoCommentKind: return "NoCommentKind"; 20#define ABSTRACT_COMMENT(COMMENT) 21#define COMMENT(CLASS, PARENT) \ 22 case CLASS##Kind: \ 23 return #CLASS; 24#include "clang/AST/CommentNodes.inc" 25#undef COMMENT 26#undef ABSTRACT_COMMENT 27 } 28 llvm_unreachable("Unknown comment kind!"); 29} 30 31void Comment::dump() const { 32 // It is important that Comment::dump() is defined in a different TU than 33 // Comment::dump(raw_ostream, SourceManager). If both functions were defined 34 // in CommentDumper.cpp, that object file would be removed by linker because 35 // none of its functions are referenced by other object files, despite the 36 // LLVM_ATTRIBUTE_USED. 37 dump(llvm::errs(), NULL); 38} 39 40void Comment::dump(SourceManager &SM) const { 41 dump(llvm::errs(), &SM); 42} 43 44namespace { 45struct good {}; 46struct bad {}; 47 48template <typename T> 49good implements_child_begin_end(Comment::child_iterator (T::*)() const) { 50 return good(); 51} 52 53static inline bad implements_child_begin_end( 54 Comment::child_iterator (Comment::*)() const) { 55 return bad(); 56} 57 58#define ASSERT_IMPLEMENTS_child_begin(function) \ 59 (void) sizeof(good(implements_child_begin_end(function))) 60 61static inline void CheckCommentASTNodes() { 62#define ABSTRACT_COMMENT(COMMENT) 63#define COMMENT(CLASS, PARENT) \ 64 ASSERT_IMPLEMENTS_child_begin(&CLASS::child_begin); \ 65 ASSERT_IMPLEMENTS_child_begin(&CLASS::child_end); 66#include "clang/AST/CommentNodes.inc" 67#undef COMMENT 68#undef ABSTRACT_COMMENT 69} 70 71#undef ASSERT_IMPLEMENTS_child_begin 72 73} // end unnamed namespace 74 75Comment::child_iterator Comment::child_begin() const { 76 switch (getCommentKind()) { 77 case NoCommentKind: llvm_unreachable("comment without a kind"); 78#define ABSTRACT_COMMENT(COMMENT) 79#define COMMENT(CLASS, PARENT) \ 80 case CLASS##Kind: \ 81 return static_cast<const CLASS *>(this)->child_begin(); 82#include "clang/AST/CommentNodes.inc" 83#undef COMMENT 84#undef ABSTRACT_COMMENT 85 } 86 llvm_unreachable("Unknown comment kind!"); 87} 88 89Comment::child_iterator Comment::child_end() const { 90 switch (getCommentKind()) { 91 case NoCommentKind: llvm_unreachable("comment without a kind"); 92#define ABSTRACT_COMMENT(COMMENT) 93#define COMMENT(CLASS, PARENT) \ 94 case CLASS##Kind: \ 95 return static_cast<const CLASS *>(this)->child_end(); 96#include "clang/AST/CommentNodes.inc" 97#undef COMMENT 98#undef ABSTRACT_COMMENT 99 } 100 llvm_unreachable("Unknown comment kind!"); 101} 102 103bool TextComment::isWhitespaceNoCache() const { 104 for (StringRef::const_iterator I = Text.begin(), E = Text.end(); 105 I != E; ++I) { 106 const char C = *I; 107 if (C != ' ' && C != '\n' && C != '\r' && 108 C != '\t' && C != '\f' && C != '\v') 109 return false; 110 } 111 return true; 112} 113 114bool ParagraphComment::isWhitespaceNoCache() const { 115 for (child_iterator I = child_begin(), E = child_end(); I != E; ++I) { 116 if (const TextComment *TC = dyn_cast<TextComment>(*I)) { 117 if (!TC->isWhitespace()) 118 return false; 119 } else 120 return false; 121 } 122 return true; 123} 124 125const char *ParamCommandComment::getDirectionAsString(PassDirection D) { 126 switch (D) { 127 case ParamCommandComment::In: 128 return "[in]"; 129 case ParamCommandComment::Out: 130 return "[out]"; 131 case ParamCommandComment::InOut: 132 return "[in,out]"; 133 } 134 llvm_unreachable("unknown PassDirection"); 135} 136 137} // end namespace comments 138} // end namespace clang 139