TemplateBase.cpp revision a93c934af4fbf97cbe8e649d82e68ccacfe57c95
1//===--- TemplateBase.cpp - Common template AST class implementation ------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements common classes used throughout C++ template
11// representations.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/ADT/FoldingSet.h"
16#include "clang/AST/TemplateBase.h"
17#include "clang/AST/DeclBase.h"
18#include "clang/AST/DeclTemplate.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/TypeLoc.h"
21
22using namespace clang;
23
24//===----------------------------------------------------------------------===//
25// TemplateArgument Implementation
26//===----------------------------------------------------------------------===//
27
28/// \brief Construct a template argument pack.
29void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
30                                       bool CopyArgs) {
31  assert(isNull() && "Must call setArgumentPack on a null argument");
32
33  Kind = Pack;
34  Args.NumArgs = NumArgs;
35  Args.CopyArgs = CopyArgs;
36  if (!Args.CopyArgs) {
37    Args.Args = args;
38    return;
39  }
40
41  // FIXME: Allocate in ASTContext
42  Args.Args = new TemplateArgument[NumArgs];
43  for (unsigned I = 0; I != Args.NumArgs; ++I)
44    Args.Args[I] = args[I];
45}
46
47void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
48                               ASTContext &Context) const {
49  ID.AddInteger(Kind);
50  switch (Kind) {
51  case Null:
52    break;
53
54  case Type:
55    getAsType().Profile(ID);
56    break;
57
58  case Declaration:
59    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
60    break;
61
62  case Template:
63    if (TemplateTemplateParmDecl *TTP
64          = dyn_cast_or_null<TemplateTemplateParmDecl>(
65                                       getAsTemplate().getAsTemplateDecl())) {
66      ID.AddBoolean(true);
67      ID.AddInteger(TTP->getDepth());
68      ID.AddInteger(TTP->getPosition());
69    } else {
70      ID.AddBoolean(false);
71      ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
72                      .getAsVoidPointer());
73    }
74    break;
75
76  case Integral:
77    getAsIntegral()->Profile(ID);
78    getIntegralType().Profile(ID);
79    break;
80
81  case Expression:
82    getAsExpr()->Profile(ID, Context, true);
83    break;
84
85  case Pack:
86    ID.AddInteger(Args.NumArgs);
87    for (unsigned I = 0; I != Args.NumArgs; ++I)
88      Args.Args[I].Profile(ID, Context);
89  }
90}
91
92//===----------------------------------------------------------------------===//
93// TemplateArgumentLoc Implementation
94//===----------------------------------------------------------------------===//
95
96SourceRange TemplateArgumentLoc::getSourceRange() const {
97  switch (Argument.getKind()) {
98  case TemplateArgument::Expression:
99    return getSourceExpression()->getSourceRange();
100
101  case TemplateArgument::Declaration:
102    return getSourceDeclExpression()->getSourceRange();
103
104  case TemplateArgument::Type:
105    return getTypeSourceInfo()->getTypeLoc().getFullSourceRange();
106
107  case TemplateArgument::Template:
108    if (getTemplateQualifierRange().isValid())
109      return SourceRange(getTemplateQualifierRange().getBegin(),
110                         getTemplateNameLoc());
111    return SourceRange(getTemplateNameLoc());
112
113  case TemplateArgument::Integral:
114  case TemplateArgument::Pack:
115  case TemplateArgument::Null:
116    return SourceRange();
117  }
118
119  // Silence bonus gcc warning.
120  return SourceRange();
121}
122