Template.h revision 212795
1212795Sdim//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/ 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim//===----------------------------------------------------------------------===/ 8212795Sdim// 9212795Sdim// This file provides types used in the semantic analysis of C++ templates. 10212795Sdim// 11212795Sdim//===----------------------------------------------------------------------===/ 12212795Sdim#ifndef LLVM_CLANG_SEMA_TEMPLATE_H 13212795Sdim#define LLVM_CLANG_SEMA_TEMPLATE_H 14212795Sdim 15212795Sdim#include "clang/AST/DeclTemplate.h" 16212795Sdim#include "llvm/ADT/SmallVector.h" 17212795Sdim#include <cassert> 18212795Sdim 19212795Sdimnamespace clang { 20212795Sdim /// \brief Data structure that captures multiple levels of template argument 21212795Sdim /// lists for use in template instantiation. 22212795Sdim /// 23212795Sdim /// Multiple levels of template arguments occur when instantiating the 24212795Sdim /// definitions of member templates. For example: 25212795Sdim /// 26212795Sdim /// \code 27212795Sdim /// template<typename T> 28212795Sdim /// struct X { 29212795Sdim /// template<T Value> 30212795Sdim /// struct Y { 31212795Sdim /// void f(); 32212795Sdim /// }; 33212795Sdim /// }; 34212795Sdim /// \endcode 35212795Sdim /// 36212795Sdim /// When instantiating X<int>::Y<17>::f, the multi-level template argument 37212795Sdim /// list will contain a template argument list (int) at depth 0 and a 38212795Sdim /// template argument list (17) at depth 1. 39212795Sdim class MultiLevelTemplateArgumentList { 40212795Sdim public: 41212795Sdim typedef std::pair<const TemplateArgument *, unsigned> ArgList; 42212795Sdim 43212795Sdim private: 44212795Sdim /// \brief The template argument lists, stored from the innermost template 45212795Sdim /// argument list (first) to the outermost template argument list (last). 46212795Sdim llvm::SmallVector<ArgList, 4> TemplateArgumentLists; 47212795Sdim 48212795Sdim public: 49212795Sdim /// \brief Construct an empty set of template argument lists. 50212795Sdim MultiLevelTemplateArgumentList() { } 51212795Sdim 52212795Sdim /// \brief Construct a single-level template argument list. 53212795Sdim explicit 54212795Sdim MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) { 55212795Sdim addOuterTemplateArguments(&TemplateArgs); 56212795Sdim } 57212795Sdim 58212795Sdim /// \brief Determine the number of levels in this template argument 59212795Sdim /// list. 60212795Sdim unsigned getNumLevels() const { return TemplateArgumentLists.size(); } 61212795Sdim 62212795Sdim /// \brief Retrieve the template argument at a given depth and index. 63212795Sdim const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { 64212795Sdim assert(Depth < TemplateArgumentLists.size()); 65212795Sdim assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].second); 66212795Sdim return TemplateArgumentLists[getNumLevels() - Depth - 1].first[Index]; 67212795Sdim } 68212795Sdim 69212795Sdim /// \brief Determine whether there is a non-NULL template argument at the 70212795Sdim /// given depth and index. 71212795Sdim /// 72212795Sdim /// There must exist a template argument list at the given depth. 73212795Sdim bool hasTemplateArgument(unsigned Depth, unsigned Index) const { 74212795Sdim assert(Depth < TemplateArgumentLists.size()); 75212795Sdim 76212795Sdim if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].second) 77212795Sdim return false; 78212795Sdim 79212795Sdim return !(*this)(Depth, Index).isNull(); 80212795Sdim } 81212795Sdim 82212795Sdim /// \brief Add a new outermost level to the multi-level template argument 83212795Sdim /// list. 84212795Sdim void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) { 85212795Sdim TemplateArgumentLists.push_back( 86212795Sdim ArgList(TemplateArgs->getFlatArgumentList(), 87212795Sdim TemplateArgs->flat_size())); 88212795Sdim } 89212795Sdim 90212795Sdim /// \brief Add a new outmost level to the multi-level template argument 91212795Sdim /// list. 92212795Sdim void addOuterTemplateArguments(const TemplateArgument *Args, 93212795Sdim unsigned NumArgs) { 94212795Sdim TemplateArgumentLists.push_back(ArgList(Args, NumArgs)); 95212795Sdim } 96212795Sdim 97212795Sdim /// \brief Retrieve the innermost template argument list. 98212795Sdim const ArgList &getInnermost() const { 99212795Sdim return TemplateArgumentLists.front(); 100212795Sdim } 101212795Sdim }; 102212795Sdim 103212795Sdim /// \brief The context in which partial ordering of function templates occurs. 104212795Sdim enum TPOC { 105212795Sdim /// \brief Partial ordering of function templates for a function call. 106212795Sdim TPOC_Call, 107212795Sdim /// \brief Partial ordering of function templates for a call to a 108212795Sdim /// conversion function. 109212795Sdim TPOC_Conversion, 110212795Sdim /// \brief Partial ordering of function templates in other contexts, e.g., 111212795Sdim /// taking the address of a function template or matching a function 112212795Sdim /// template specialization to a function template. 113212795Sdim TPOC_Other 114212795Sdim }; 115212795Sdim 116212795Sdim // This is lame but unavoidable in a world without forward 117212795Sdim // declarations of enums. The alternatives are to either pollute 118212795Sdim // Sema.h (by including this file) or sacrifice type safety (by 119212795Sdim // making Sema.h declare things as enums). 120212795Sdim class TemplatePartialOrderingContext { 121212795Sdim TPOC Value; 122212795Sdim public: 123212795Sdim TemplatePartialOrderingContext(TPOC Value) : Value(Value) {} 124212795Sdim operator TPOC() const { return Value; } 125212795Sdim }; 126212795Sdim 127212795Sdim /// \brief Captures a template argument whose value has been deduced 128212795Sdim /// via c++ template argument deduction. 129212795Sdim class DeducedTemplateArgument : public TemplateArgument { 130212795Sdim /// \brief For a non-type template argument, whether the value was 131212795Sdim /// deduced from an array bound. 132212795Sdim bool DeducedFromArrayBound; 133212795Sdim 134212795Sdim public: 135212795Sdim DeducedTemplateArgument() 136212795Sdim : TemplateArgument(), DeducedFromArrayBound(false) { } 137212795Sdim 138212795Sdim DeducedTemplateArgument(const TemplateArgument &Arg, 139212795Sdim bool DeducedFromArrayBound = false) 140212795Sdim : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { } 141212795Sdim 142212795Sdim /// \brief Construct an integral non-type template argument that 143212795Sdim /// has been deduced, possible from an array bound. 144212795Sdim DeducedTemplateArgument(const llvm::APSInt &Value, 145212795Sdim QualType ValueType, 146212795Sdim bool DeducedFromArrayBound) 147212795Sdim : TemplateArgument(Value, ValueType), 148212795Sdim DeducedFromArrayBound(DeducedFromArrayBound) { } 149212795Sdim 150212795Sdim /// \brief For a non-type template argument, determine whether the 151212795Sdim /// template argument was deduced from an array bound. 152212795Sdim bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; } 153212795Sdim 154212795Sdim /// \brief Specify whether the given non-type template argument 155212795Sdim /// was deduced from an array bound. 156212795Sdim void setDeducedFromArrayBound(bool Deduced) { 157212795Sdim DeducedFromArrayBound = Deduced; 158212795Sdim } 159212795Sdim }; 160212795Sdim 161212795Sdim /// \brief A stack-allocated class that identifies which local 162212795Sdim /// variable declaration instantiations are present in this scope. 163212795Sdim /// 164212795Sdim /// A new instance of this class type will be created whenever we 165212795Sdim /// instantiate a new function declaration, which will have its own 166212795Sdim /// set of parameter declarations. 167212795Sdim class LocalInstantiationScope { 168212795Sdim /// \brief Reference to the semantic analysis that is performing 169212795Sdim /// this template instantiation. 170212795Sdim Sema &SemaRef; 171212795Sdim 172212795Sdim /// \brief A mapping from local declarations that occur 173212795Sdim /// within a template to their instantiations. 174212795Sdim /// 175212795Sdim /// This mapping is used during instantiation to keep track of, 176212795Sdim /// e.g., function parameter and variable declarations. For example, 177212795Sdim /// given: 178212795Sdim /// 179212795Sdim /// \code 180212795Sdim /// template<typename T> T add(T x, T y) { return x + y; } 181212795Sdim /// \endcode 182212795Sdim /// 183212795Sdim /// when we instantiate add<int>, we will introduce a mapping from 184212795Sdim /// the ParmVarDecl for 'x' that occurs in the template to the 185212795Sdim /// instantiated ParmVarDecl for 'x'. 186212795Sdim llvm::DenseMap<const Decl *, Decl *> LocalDecls; 187212795Sdim 188212795Sdim /// \brief The outer scope, which contains local variable 189212795Sdim /// definitions from some other instantiation (that may not be 190212795Sdim /// relevant to this particular scope). 191212795Sdim LocalInstantiationScope *Outer; 192212795Sdim 193212795Sdim /// \brief Whether we have already exited this scope. 194212795Sdim bool Exited; 195212795Sdim 196212795Sdim /// \brief Whether to combine this scope with the outer scope, such that 197212795Sdim /// lookup will search our outer scope. 198212795Sdim bool CombineWithOuterScope; 199212795Sdim 200212795Sdim // This class is non-copyable 201212795Sdim LocalInstantiationScope(const LocalInstantiationScope &); 202212795Sdim LocalInstantiationScope &operator=(const LocalInstantiationScope &); 203212795Sdim 204212795Sdim public: 205212795Sdim LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) 206212795Sdim : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), 207212795Sdim Exited(false), CombineWithOuterScope(CombineWithOuterScope) 208212795Sdim { 209212795Sdim SemaRef.CurrentInstantiationScope = this; 210212795Sdim } 211212795Sdim 212212795Sdim ~LocalInstantiationScope() { 213212795Sdim Exit(); 214212795Sdim } 215212795Sdim 216212795Sdim /// \brief Exit this local instantiation scope early. 217212795Sdim void Exit() { 218212795Sdim if (Exited) 219212795Sdim return; 220212795Sdim 221212795Sdim SemaRef.CurrentInstantiationScope = Outer; 222212795Sdim Exited = true; 223212795Sdim } 224212795Sdim 225212795Sdim Decl *getInstantiationOf(const Decl *D); 226212795Sdim 227212795Sdim VarDecl *getInstantiationOf(const VarDecl *Var) { 228212795Sdim return cast<VarDecl>(getInstantiationOf(cast<Decl>(Var))); 229212795Sdim } 230212795Sdim 231212795Sdim ParmVarDecl *getInstantiationOf(const ParmVarDecl *Var) { 232212795Sdim return cast<ParmVarDecl>(getInstantiationOf(cast<Decl>(Var))); 233212795Sdim } 234212795Sdim 235212795Sdim NonTypeTemplateParmDecl *getInstantiationOf( 236212795Sdim const NonTypeTemplateParmDecl *Var) { 237212795Sdim return cast<NonTypeTemplateParmDecl>(getInstantiationOf(cast<Decl>(Var))); 238212795Sdim } 239212795Sdim 240212795Sdim void InstantiatedLocal(const Decl *D, Decl *Inst); 241212795Sdim }; 242212795Sdim} 243212795Sdim 244212795Sdim#endif // LLVM_CLANG_SEMA_TEMPLATE_H 245