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