blob: ff16bc499a142a918108e597504aab788ff3a6d6 [file] [log] [blame]
//===--- TypeMemberVisitor.h - ASTVisitor specialization --------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the curiously-recursive TypeMemberVisitor class
// and a few specializations thereof.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_AST_TYPEMEMBERVISITOR_H
#define SWIFT_AST_TYPEMEMBERVISITOR_H
#include "swift/AST/ASTVisitor.h"
namespace swift {
/// TypeMemberVisitor - This is a convenience adapter of DeclVisitor
/// which filters out a few common declaration kinds that are never
/// members of nominal types.
template<typename ImplClass, typename RetTy = void>
class TypeMemberVisitor : public DeclVisitor<ImplClass, RetTy> {
protected:
ImplClass &asImpl() { return static_cast<ImplClass&>(*this); }
public:
#define BAD_MEMBER(KIND) \
RetTy visit##KIND##Decl(KIND##Decl *D) { \
llvm_unreachable(#KIND "Decls cannot be members of nominal types"); \
}
BAD_MEMBER(Extension)
BAD_MEMBER(Import)
BAD_MEMBER(Protocol)
BAD_MEMBER(TopLevelCode)
BAD_MEMBER(Operator)
BAD_MEMBER(PrecedenceGroup)
// The children of these are automatically inserted into the
// surrounding context.
RetTy visitIfConfigDecl(IfConfigDecl *D) {
return RetTy();
}
// These decls are disregarded.
RetTy visitPoundDiagnosticDecl(PoundDiagnosticDecl *D) {
return RetTy();
}
/// A convenience method to visit all the members.
void visitMembers(NominalTypeDecl *D) {
for (Decl *member : D->getMembers()) {
asImpl().visit(member);
}
}
};
template<typename ImplClass, typename RetTy = void>
class ClassMemberVisitor : public TypeMemberVisitor<ImplClass, RetTy> {
public:
BAD_MEMBER(EnumElement)
BAD_MEMBER(EnumCase)
void visitMembers(ClassDecl *D) {
TypeMemberVisitor<ImplClass, RetTy>::visitMembers(D);
}
};
#undef BAD_MEMBER
} // end namespace swift
#endif