TemplateBase.cpp revision 199990
1198893Srdivacky//===--- TemplateBase.cpp - Common template AST class implementation ------===//
2198893Srdivacky//
3198893Srdivacky//                     The LLVM Compiler Infrastructure
4198893Srdivacky//
5198893Srdivacky// This file is distributed under the University of Illinois Open Source
6198893Srdivacky// License. See LICENSE.TXT for details.
7198893Srdivacky//
8198893Srdivacky//===----------------------------------------------------------------------===//
9198893Srdivacky//
10198893Srdivacky// This file implements common classes used throughout C++ template
11198893Srdivacky// representations.
12198893Srdivacky//
13198893Srdivacky//===----------------------------------------------------------------------===//
14198893Srdivacky
15198893Srdivacky#include "llvm/ADT/FoldingSet.h"
16198893Srdivacky#include "clang/AST/TemplateBase.h"
17198893Srdivacky#include "clang/AST/DeclBase.h"
18199990Srdivacky#include "clang/AST/DeclTemplate.h"
19198893Srdivacky#include "clang/AST/Expr.h"
20198893Srdivacky#include "clang/AST/TypeLoc.h"
21198893Srdivacky
22198893Srdivackyusing namespace clang;
23198893Srdivacky
24198893Srdivacky//===----------------------------------------------------------------------===//
25198893Srdivacky// TemplateArgument Implementation
26198893Srdivacky//===----------------------------------------------------------------------===//
27198893Srdivacky
28198893Srdivacky/// \brief Construct a template argument pack.
29198893Srdivackyvoid TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
30198893Srdivacky                                       bool CopyArgs) {
31198893Srdivacky  assert(isNull() && "Must call setArgumentPack on a null argument");
32198893Srdivacky
33198893Srdivacky  Kind = Pack;
34198893Srdivacky  Args.NumArgs = NumArgs;
35198893Srdivacky  Args.CopyArgs = CopyArgs;
36198893Srdivacky  if (!Args.CopyArgs) {
37198893Srdivacky    Args.Args = args;
38198893Srdivacky    return;
39198893Srdivacky  }
40198893Srdivacky
41198893Srdivacky  // FIXME: Allocate in ASTContext
42198893Srdivacky  Args.Args = new TemplateArgument[NumArgs];
43198893Srdivacky  for (unsigned I = 0; I != Args.NumArgs; ++I)
44198893Srdivacky    Args.Args[I] = args[I];
45198893Srdivacky}
46198893Srdivacky
47198893Srdivackyvoid TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
48198893Srdivacky                               ASTContext &Context) const {
49198893Srdivacky  ID.AddInteger(Kind);
50198893Srdivacky  switch (Kind) {
51198893Srdivacky  case Null:
52198893Srdivacky    break;
53198893Srdivacky
54198893Srdivacky  case Type:
55198893Srdivacky    getAsType().Profile(ID);
56198893Srdivacky    break;
57198893Srdivacky
58198893Srdivacky  case Declaration:
59198893Srdivacky    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
60198893Srdivacky    break;
61198893Srdivacky
62199482Srdivacky  case Template:
63199990Srdivacky    if (TemplateTemplateParmDecl *TTP
64199990Srdivacky          = dyn_cast_or_null<TemplateTemplateParmDecl>(
65199990Srdivacky                                       getAsTemplate().getAsTemplateDecl())) {
66199990Srdivacky      ID.AddBoolean(true);
67199990Srdivacky      ID.AddInteger(TTP->getDepth());
68199990Srdivacky      ID.AddInteger(TTP->getPosition());
69199990Srdivacky    } else {
70199990Srdivacky      ID.AddBoolean(false);
71199990Srdivacky      ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
72199990Srdivacky                      .getAsVoidPointer());
73199990Srdivacky    }
74199482Srdivacky    break;
75199482Srdivacky
76198893Srdivacky  case Integral:
77198893Srdivacky    getAsIntegral()->Profile(ID);
78198893Srdivacky    getIntegralType().Profile(ID);
79198893Srdivacky    break;
80198893Srdivacky
81198893Srdivacky  case Expression:
82198893Srdivacky    getAsExpr()->Profile(ID, Context, true);
83198893Srdivacky    break;
84198893Srdivacky
85198893Srdivacky  case Pack:
86198893Srdivacky    ID.AddInteger(Args.NumArgs);
87198893Srdivacky    for (unsigned I = 0; I != Args.NumArgs; ++I)
88198893Srdivacky      Args.Args[I].Profile(ID, Context);
89198893Srdivacky  }
90198893Srdivacky}
91198893Srdivacky
92198893Srdivacky//===----------------------------------------------------------------------===//
93198893Srdivacky// TemplateArgumentLoc Implementation
94198893Srdivacky//===----------------------------------------------------------------------===//
95198893Srdivacky
96198893SrdivackySourceRange TemplateArgumentLoc::getSourceRange() const {
97198893Srdivacky  switch (Argument.getKind()) {
98198893Srdivacky  case TemplateArgument::Expression:
99198893Srdivacky    return getSourceExpression()->getSourceRange();
100199482Srdivacky
101198893Srdivacky  case TemplateArgument::Declaration:
102198893Srdivacky    return getSourceDeclExpression()->getSourceRange();
103199482Srdivacky
104198893Srdivacky  case TemplateArgument::Type:
105198893Srdivacky    return getSourceDeclaratorInfo()->getTypeLoc().getFullSourceRange();
106199482Srdivacky
107199482Srdivacky  case TemplateArgument::Template:
108199482Srdivacky    if (getTemplateQualifierRange().isValid())
109199482Srdivacky      return SourceRange(getTemplateQualifierRange().getBegin(),
110199482Srdivacky                         getTemplateNameLoc());
111199482Srdivacky    return SourceRange(getTemplateNameLoc());
112199482Srdivacky
113198893Srdivacky  case TemplateArgument::Integral:
114198893Srdivacky  case TemplateArgument::Pack:
115198893Srdivacky  case TemplateArgument::Null:
116198893Srdivacky    return SourceRange();
117198893Srdivacky  }
118198893Srdivacky
119198893Srdivacky  // Silence bonus gcc warning.
120198893Srdivacky  return SourceRange();
121198893Srdivacky}
122