1//===--- CommentVisitor.h - Visitor for Comment subclasses ------*- C++ -*-===//
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
13namespace clang {
14namespace comments {
15
16template <typename T> struct make_ptr       { typedef       T *type; };
17template <typename T> struct make_const_ptr { typedef const T *type; };
18
19template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
20class CommentVisitorBase {
21public:
22#define PTR(CLASS) typename Ptr<CLASS>::type
23#define DISPATCH(NAME, CLASS) \
24 return static_cast<ImplClass*>(this)->visit ## NAME(static_cast<PTR(CLASS)>(C))
25
26  RetTy visit(PTR(Comment) C) {
27    if (!C)
28      return RetTy();
29
30    switch (C->getCommentKind()) {
31    default: llvm_unreachable("Unknown comment kind!");
32#define ABSTRACT_COMMENT(COMMENT)
33#define COMMENT(CLASS, PARENT) \
34    case Comment::CLASS##Kind: DISPATCH(CLASS, CLASS);
35#include "clang/AST/CommentNodes.inc"
36#undef ABSTRACT_COMMENT
37#undef COMMENT
38    }
39  }
40
41  // If the derived class does not implement a certain Visit* method, fall back
42  // on Visit* method for the superclass.
43#define ABSTRACT_COMMENT(COMMENT) COMMENT
44#define COMMENT(CLASS, PARENT) \
45  RetTy visit ## CLASS(PTR(CLASS) C) { DISPATCH(PARENT, PARENT); }
46#include "clang/AST/CommentNodes.inc"
47#undef ABSTRACT_COMMENT
48#undef COMMENT
49
50  RetTy visitComment(PTR(Comment) C) { return RetTy(); }
51
52#undef PTR
53#undef DISPATCH
54};
55
56template<typename ImplClass, typename RetTy=void>
57class CommentVisitor :
58    public CommentVisitorBase<make_ptr, ImplClass, RetTy> {};
59
60template<typename ImplClass, typename RetTy=void>
61class ConstCommentVisitor :
62    public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
63
64} // end namespace comments
65} // end namespace clang
66
67