TemplateBase.cpp revision 7bb87fca7d22a8a194d04188746b90f46512975f
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/Expr.h"
19#include "clang/AST/TypeLoc.h"
20
21using namespace clang;
22
23//===----------------------------------------------------------------------===//
24// TemplateArgument Implementation
25//===----------------------------------------------------------------------===//
26
27/// \brief Construct a template argument pack.
28void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
29                                       bool CopyArgs) {
30  assert(isNull() && "Must call setArgumentPack on a null argument");
31
32  Kind = Pack;
33  Args.NumArgs = NumArgs;
34  Args.CopyArgs = CopyArgs;
35  if (!Args.CopyArgs) {
36    Args.Args = args;
37    return;
38  }
39
40  // FIXME: Allocate in ASTContext
41  Args.Args = new TemplateArgument[NumArgs];
42  for (unsigned I = 0; I != Args.NumArgs; ++I)
43    Args.Args[I] = args[I];
44}
45
46void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
47                               ASTContext &Context) const {
48  ID.AddInteger(Kind);
49  switch (Kind) {
50  case Null:
51    break;
52
53  case Type:
54    getAsType().Profile(ID);
55    break;
56
57  case Declaration:
58    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
59    break;
60
61  case Template:
62    ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
63                    .getAsVoidPointer());
64    break;
65
66  case Integral:
67    getAsIntegral()->Profile(ID);
68    getIntegralType().Profile(ID);
69    break;
70
71  case Expression:
72    getAsExpr()->Profile(ID, Context, true);
73    break;
74
75  case Pack:
76    ID.AddInteger(Args.NumArgs);
77    for (unsigned I = 0; I != Args.NumArgs; ++I)
78      Args.Args[I].Profile(ID, Context);
79  }
80}
81
82//===----------------------------------------------------------------------===//
83// TemplateArgumentLoc Implementation
84//===----------------------------------------------------------------------===//
85
86SourceRange TemplateArgumentLoc::getSourceRange() const {
87  switch (Argument.getKind()) {
88  case TemplateArgument::Expression:
89    return getSourceExpression()->getSourceRange();
90
91  case TemplateArgument::Declaration:
92    return getSourceDeclExpression()->getSourceRange();
93
94  case TemplateArgument::Type:
95    return getSourceDeclaratorInfo()->getTypeLoc().getFullSourceRange();
96
97  case TemplateArgument::Template:
98    if (getTemplateQualifierRange().isValid())
99      return SourceRange(getTemplateQualifierRange().getBegin(),
100                         getTemplateNameLoc());
101    return SourceRange(getTemplateNameLoc());
102
103  case TemplateArgument::Integral:
104  case TemplateArgument::Pack:
105  case TemplateArgument::Null:
106    return SourceRange();
107  }
108
109  // Silence bonus gcc warning.
110  return SourceRange();
111}
112