]> granicus.if.org Git - clang/blob - lib/AST/TemplateBase.cpp
Fix speculative parsing of dependent template names in
[clang] / lib / AST / TemplateBase.cpp
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
21 using namespace clang;
22
23 //===----------------------------------------------------------------------===//
24 // TemplateArgument Implementation
25 //===----------------------------------------------------------------------===//
26
27 /// \brief Construct a template argument pack.
28 void 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
46 void 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
86 SourceRange 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 }