1239313Sdim//===--- CommentVisitor.h - Visitor for Comment subclasses ------*- C++ -*-===//
2239313Sdim//
3239313Sdim//                     The LLVM Compiler Infrastructure
4239313Sdim//
5239313Sdim// This file is distributed under the University of Illinois Open Source
6239313Sdim// License. See LICENSE.TXT for details.
7239313Sdim//
8239313Sdim//===----------------------------------------------------------------------===//
9239313Sdim
10249423Sdim#ifndef LLVM_CLANG_AST_COMMENTVISITOR_H
11249423Sdim#define LLVM_CLANG_AST_COMMENTVISITOR_H
12249423Sdim
13239313Sdim#include "clang/AST/Comment.h"
14239313Sdim#include "llvm/Support/ErrorHandling.h"
15239313Sdim
16239313Sdimnamespace clang {
17239313Sdimnamespace comments {
18239313Sdim
19239313Sdimtemplate <typename T> struct make_ptr       { typedef       T *type; };
20239313Sdimtemplate <typename T> struct make_const_ptr { typedef const T *type; };
21239313Sdim
22239313Sdimtemplate<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
23239313Sdimclass CommentVisitorBase {
24239313Sdimpublic:
25239313Sdim#define PTR(CLASS) typename Ptr<CLASS>::type
26239313Sdim#define DISPATCH(NAME, CLASS) \
27239313Sdim return static_cast<ImplClass*>(this)->visit ## NAME(static_cast<PTR(CLASS)>(C))
28239313Sdim
29239313Sdim  RetTy visit(PTR(Comment) C) {
30239313Sdim    if (!C)
31239313Sdim      return RetTy();
32239313Sdim
33239313Sdim    switch (C->getCommentKind()) {
34239313Sdim    default: llvm_unreachable("Unknown comment kind!");
35239313Sdim#define ABSTRACT_COMMENT(COMMENT)
36239313Sdim#define COMMENT(CLASS, PARENT) \
37239313Sdim    case Comment::CLASS##Kind: DISPATCH(CLASS, CLASS);
38239313Sdim#include "clang/AST/CommentNodes.inc"
39239313Sdim#undef ABSTRACT_COMMENT
40239313Sdim#undef COMMENT
41239313Sdim    }
42239313Sdim  }
43239313Sdim
44239313Sdim  // If the derived class does not implement a certain Visit* method, fall back
45239313Sdim  // on Visit* method for the superclass.
46239313Sdim#define ABSTRACT_COMMENT(COMMENT) COMMENT
47239313Sdim#define COMMENT(CLASS, PARENT) \
48239313Sdim  RetTy visit ## CLASS(PTR(CLASS) C) { DISPATCH(PARENT, PARENT); }
49239313Sdim#include "clang/AST/CommentNodes.inc"
50239313Sdim#undef ABSTRACT_COMMENT
51239313Sdim#undef COMMENT
52239313Sdim
53239313Sdim  RetTy visitComment(PTR(Comment) C) { return RetTy(); }
54239313Sdim
55239313Sdim#undef PTR
56239313Sdim#undef DISPATCH
57239313Sdim};
58239313Sdim
59239313Sdimtemplate<typename ImplClass, typename RetTy=void>
60239313Sdimclass CommentVisitor :
61239313Sdim    public CommentVisitorBase<make_ptr, ImplClass, RetTy> {};
62239313Sdim
63239313Sdimtemplate<typename ImplClass, typename RetTy=void>
64239313Sdimclass ConstCommentVisitor :
65239313Sdim    public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
66239313Sdim
67239313Sdim} // end namespace comments
68239313Sdim} // end namespace clang
69239313Sdim
70249423Sdim#endif
71