blob: 336c5ef4a8308d1fe19d250520bef6e14b863c9a [file] [log] [blame]
//===--- TypeVisitor.h - Type Visitor ---------------------------*- 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 TypeVisitor class.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_AST_TYPEVISITOR_H
#define SWIFT_AST_TYPEVISITOR_H
#include "swift/AST/Types.h"
#include "llvm/Support/ErrorHandling.h"
namespace swift {
/// TypeVisitor - This is a simple visitor class for Swift types.
template<typename ImplClass, typename RetTy = void, typename... Args>
class TypeVisitor {
public:
RetTy visit(Type T, Args... args) {
switch (T->getKind()) {
#define TYPE(CLASS, PARENT) \
case TypeKind::CLASS: \
return static_cast<ImplClass*>(this) \
->visit##CLASS##Type(static_cast<CLASS##Type*>(T.getPointer()), \
::std::forward<Args>(args)...);
#include "swift/AST/TypeNodes.def"
}
llvm_unreachable("Not reachable, all cases handled");
}
// Provide default implementations of abstract "visit" implementations that
// just chain to their base class. This allows visitors to just implement
// the base behavior and handle all subclasses if they desire. Since this is
// a template, it will only instantiate cases that are used and thus we still
// require full coverage of the AST nodes by the visitor.
#define ABSTRACT_TYPE(CLASS, PARENT) \
RetTy visit##CLASS##Type(CLASS##Type *T, Args... args) { \
return static_cast<ImplClass*>(this) \
->visit##PARENT(T, std::forward<Args>(args)...); \
}
#define TYPE(CLASS, PARENT) ABSTRACT_TYPE(CLASS, PARENT)
#include "swift/AST/TypeNodes.def"
};
} // end namespace swift
#endif