//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/ // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. //===----------------------------------------------------------------------===/ // // This file provides types used in the semantic analysis of C++ templates. // //===----------------------------------------------------------------------===/ #ifndef LLVM_CLANG_SEMA_TEMPLATE_H #define LLVM_CLANG_SEMA_TEMPLATE_H #include "clang/AST/DeclTemplate.h" #include "llvm/ADT/SmallVector.h" #include namespace clang { /// \brief Data structure that captures multiple levels of template argument /// lists for use in template instantiation. /// /// Multiple levels of template arguments occur when instantiating the /// definitions of member templates. For example: /// /// \code /// template /// struct X { /// template /// struct Y { /// void f(); /// }; /// }; /// \endcode /// /// When instantiating X::Y<17>::f, the multi-level template argument /// list will contain a template argument list (int) at depth 0 and a /// template argument list (17) at depth 1. struct MultiLevelTemplateArgumentList { /// \brief The template argument lists, stored from the innermost template /// argument list (first) to the outermost template argument list (last). llvm::SmallVector TemplateArgumentLists; public: /// \brief Construct an empty set of template argument lists. MultiLevelTemplateArgumentList() { } /// \brief Construct a single-level template argument list. explicit MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) { TemplateArgumentLists.push_back(&TemplateArgs); } /// \brief Determine the number of levels in this template argument /// list. unsigned getNumLevels() const { return TemplateArgumentLists.size(); } /// \brief Retrieve the template argument at a given depth and index. const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { assert(Depth < TemplateArgumentLists.size()); assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1]->size()); return TemplateArgumentLists[getNumLevels() - Depth - 1]->get(Index); } /// \brief Determine whether there is a non-NULL template argument at the /// given depth and index. /// /// There must exist a template argument list at the given depth. bool hasTemplateArgument(unsigned Depth, unsigned Index) const { assert(Depth < TemplateArgumentLists.size()); if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1]->size()) return false; return !(*this)(Depth, Index).isNull(); } /// \brief Add a new outermost level to the multi-level template argument /// list. void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) { TemplateArgumentLists.push_back(TemplateArgs); } /// \brief Retrieve the innermost template argument list. const TemplateArgumentList &getInnermost() const { return *TemplateArgumentLists.front(); } }; /// \brief The context in which partial ordering of function templates occurs. enum TemplatePartialOrderingContext { /// \brief Partial ordering of function templates for a function call. TPOC_Call, /// \brief Partial ordering of function templates for a call to a /// conversion function. TPOC_Conversion, /// \brief Partial ordering of function templates in other contexts, e.g., /// taking the address of a function template or matching a function /// template specialization to a function template. TPOC_Other }; } #endif // LLVM_CLANG_SEMA_TEMPLATE_H