clang API Documentation

TemplateBase.cpp
Go to the documentation of this file.
00001 //===--- TemplateBase.cpp - Common template AST class implementation ------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements common classes used throughout C++ template
00011 // representations.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "clang/AST/TemplateBase.h"
00016 #include "clang/AST/ASTContext.h"
00017 #include "clang/AST/DeclBase.h"
00018 #include "clang/AST/DeclTemplate.h"
00019 #include "clang/AST/Expr.h"
00020 #include "clang/AST/ExprCXX.h"
00021 #include "clang/AST/Type.h"
00022 #include "clang/AST/TypeLoc.h"
00023 #include "clang/Basic/Diagnostic.h"
00024 #include "llvm/ADT/FoldingSet.h"
00025 #include "llvm/ADT/SmallString.h"
00026 #include <algorithm>
00027 #include <cctype>
00028 
00029 using namespace clang;
00030 
00031 /// \brief Print a template integral argument value.
00032 ///
00033 /// \param TemplArg the TemplateArgument instance to print.
00034 ///
00035 /// \param Out the raw_ostream instance to use for printing.
00036 static void printIntegral(const TemplateArgument &TemplArg,
00037                           raw_ostream &Out) {
00038   const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
00039   const llvm::APSInt *Val = TemplArg.getAsIntegral();
00040 
00041   if (T->isBooleanType()) {
00042     Out << (Val->getBoolValue() ? "true" : "false");
00043   } else if (T->isCharType()) {
00044     const char Ch = Val->getZExtValue();
00045     Out << ((Ch == '\'') ? "'\\" : "'");
00046     Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
00047     Out << "'";
00048   } else {
00049     Out << Val->toString(10);
00050   }
00051 }
00052 
00053 //===----------------------------------------------------------------------===//
00054 // TemplateArgument Implementation
00055 //===----------------------------------------------------------------------===//
00056 
00057 TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context,
00058                                                   const TemplateArgument *Args,
00059                                                   unsigned NumArgs) {
00060   if (NumArgs == 0)
00061     return TemplateArgument(0, 0);
00062   
00063   TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs];
00064   std::copy(Args, Args + NumArgs, Storage);
00065   return TemplateArgument(Storage, NumArgs);
00066 }
00067 
00068 bool TemplateArgument::isDependent() const {
00069   switch (getKind()) {
00070   case Null:
00071     llvm_unreachable("Should not have a NULL template argument");
00072 
00073   case Type:
00074     return getAsType()->isDependentType();
00075 
00076   case Template:
00077     return getAsTemplate().isDependent();
00078 
00079   case TemplateExpansion:
00080     return true;
00081 
00082   case Declaration:
00083     if (Decl *D = getAsDecl()) {
00084       if (DeclContext *DC = dyn_cast<DeclContext>(D))
00085         return DC->isDependentContext();
00086       return D->getDeclContext()->isDependentContext();
00087     }
00088       
00089     return false;
00090 
00091   case Integral:
00092     // Never dependent
00093     return false;
00094 
00095   case Expression:
00096     return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
00097 
00098   case Pack:
00099     for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
00100       if (P->isDependent())
00101         return true;
00102     }
00103 
00104     return false;
00105   }
00106 
00107   llvm_unreachable("Invalid TemplateArgument Kind!");
00108 }
00109 
00110 bool TemplateArgument::isInstantiationDependent() const {
00111   switch (getKind()) {
00112   case Null:
00113     llvm_unreachable("Should not have a NULL template argument");
00114     
00115   case Type:
00116     return getAsType()->isInstantiationDependentType();
00117     
00118   case Template:
00119     return getAsTemplate().isInstantiationDependent();
00120     
00121   case TemplateExpansion:
00122     return true;
00123     
00124   case Declaration:
00125     if (Decl *D = getAsDecl()) {
00126       if (DeclContext *DC = dyn_cast<DeclContext>(D))
00127         return DC->isDependentContext();
00128       return D->getDeclContext()->isDependentContext();
00129     }
00130     return false;
00131       
00132   case Integral:
00133     // Never dependent
00134     return false;
00135     
00136   case Expression:
00137     return getAsExpr()->isInstantiationDependent();
00138     
00139   case Pack:
00140     for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
00141       if (P->isInstantiationDependent())
00142         return true;
00143     }
00144     
00145     return false;
00146   }
00147 
00148   llvm_unreachable("Invalid TemplateArgument Kind!");
00149 }
00150 
00151 bool TemplateArgument::isPackExpansion() const {
00152   switch (getKind()) {
00153   case Null:
00154   case Declaration:
00155   case Integral:
00156   case Pack:    
00157   case Template:
00158     return false;
00159       
00160   case TemplateExpansion:
00161     return true;
00162       
00163   case Type:
00164     return isa<PackExpansionType>(getAsType());
00165           
00166   case Expression:
00167     return isa<PackExpansionExpr>(getAsExpr());
00168   }
00169 
00170   llvm_unreachable("Invalid TemplateArgument Kind!");
00171 }
00172 
00173 bool TemplateArgument::containsUnexpandedParameterPack() const {
00174   switch (getKind()) {
00175   case Null:
00176   case Declaration:
00177   case Integral:
00178   case TemplateExpansion:
00179     break;
00180 
00181   case Type:
00182     if (getAsType()->containsUnexpandedParameterPack())
00183       return true;
00184     break;
00185 
00186   case Template:
00187     if (getAsTemplate().containsUnexpandedParameterPack())
00188       return true;
00189     break;
00190         
00191   case Expression:
00192     if (getAsExpr()->containsUnexpandedParameterPack())
00193       return true;
00194     break;
00195 
00196   case Pack:
00197     for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
00198       if (P->containsUnexpandedParameterPack())
00199         return true;
00200 
00201     break;
00202   }
00203 
00204   return false;
00205 }
00206 
00207 llvm::Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
00208   assert(Kind == TemplateExpansion);
00209   if (TemplateArg.NumExpansions)
00210     return TemplateArg.NumExpansions - 1;
00211   
00212   return llvm::Optional<unsigned>();
00213 }
00214 
00215 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
00216                                const ASTContext &Context) const {
00217   ID.AddInteger(Kind);
00218   switch (Kind) {
00219   case Null:
00220     break;
00221 
00222   case Type:
00223     getAsType().Profile(ID);
00224     break;
00225 
00226   case Declaration:
00227     ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
00228     break;
00229 
00230   case Template:
00231   case TemplateExpansion: {
00232     TemplateName Template = getAsTemplateOrTemplatePattern();
00233     if (TemplateTemplateParmDecl *TTP
00234           = dyn_cast_or_null<TemplateTemplateParmDecl>(
00235                                                 Template.getAsTemplateDecl())) {
00236       ID.AddBoolean(true);
00237       ID.AddInteger(TTP->getDepth());
00238       ID.AddInteger(TTP->getPosition());
00239       ID.AddBoolean(TTP->isParameterPack());
00240     } else {
00241       ID.AddBoolean(false);
00242       ID.AddPointer(Context.getCanonicalTemplateName(Template)
00243                                                           .getAsVoidPointer());
00244     }
00245     break;
00246   }
00247       
00248   case Integral:
00249     getAsIntegral()->Profile(ID);
00250     getIntegralType().Profile(ID);
00251     break;
00252 
00253   case Expression:
00254     getAsExpr()->Profile(ID, Context, true);
00255     break;
00256 
00257   case Pack:
00258     ID.AddInteger(Args.NumArgs);
00259     for (unsigned I = 0; I != Args.NumArgs; ++I)
00260       Args.Args[I].Profile(ID, Context);
00261   }
00262 }
00263 
00264 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
00265   if (getKind() != Other.getKind()) return false;
00266 
00267   switch (getKind()) {
00268   case Null:
00269   case Type:
00270   case Declaration:
00271   case Expression:      
00272   case Template:
00273   case TemplateExpansion:
00274     return TypeOrValue == Other.TypeOrValue;
00275 
00276   case Integral:
00277     return getIntegralType() == Other.getIntegralType() &&
00278            *getAsIntegral() == *Other.getAsIntegral();
00279 
00280   case Pack:
00281     if (Args.NumArgs != Other.Args.NumArgs) return false;
00282     for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
00283       if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
00284         return false;
00285     return true;
00286   }
00287 
00288   llvm_unreachable("Invalid TemplateArgument Kind!");
00289 }
00290 
00291 TemplateArgument TemplateArgument::getPackExpansionPattern() const {
00292   assert(isPackExpansion());
00293   
00294   switch (getKind()) {
00295   case Type:
00296     return getAsType()->getAs<PackExpansionType>()->getPattern();
00297     
00298   case Expression:
00299     return cast<PackExpansionExpr>(getAsExpr())->getPattern();
00300     
00301   case TemplateExpansion:
00302     return TemplateArgument(getAsTemplateOrTemplatePattern());
00303     
00304   case Declaration:
00305   case Integral:
00306   case Pack:
00307   case Null:
00308   case Template:
00309     return TemplateArgument();
00310   }
00311 
00312   llvm_unreachable("Invalid TemplateArgument Kind!");
00313 }
00314 
00315 void TemplateArgument::print(const PrintingPolicy &Policy, 
00316                              raw_ostream &Out) const {
00317   switch (getKind()) {
00318   case Null:
00319     Out << "<no value>";
00320     break;
00321     
00322   case Type: {
00323     PrintingPolicy SubPolicy(Policy);
00324     SubPolicy.SuppressStrongLifetime = true;
00325     std::string TypeStr;
00326     getAsType().getAsStringInternal(TypeStr, SubPolicy);
00327     Out << TypeStr;
00328     break;
00329   }
00330     
00331   case Declaration: {
00332     if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
00333       if (ND->getDeclName()) {
00334         Out << *ND;
00335       } else {
00336         Out << "<anonymous>";
00337       }
00338     } else {
00339       Out << "nullptr";
00340     }
00341     break;
00342   }
00343     
00344   case Template:
00345     getAsTemplate().print(Out, Policy);
00346     break;
00347 
00348   case TemplateExpansion:
00349     getAsTemplateOrTemplatePattern().print(Out, Policy);
00350     Out << "...";
00351     break;
00352       
00353   case Integral: {
00354     printIntegral(*this, Out);
00355     break;
00356   }
00357     
00358   case Expression:
00359     getAsExpr()->printPretty(Out, 0, Policy);
00360     break;
00361     
00362   case Pack:
00363     Out << "<";
00364     bool First = true;
00365     for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
00366          P != PEnd; ++P) {
00367       if (First)
00368         First = false;
00369       else
00370         Out << ", ";
00371       
00372       P->print(Policy, Out);
00373     }
00374     Out << ">";
00375     break;        
00376   }
00377 }
00378 
00379 //===----------------------------------------------------------------------===//
00380 // TemplateArgumentLoc Implementation
00381 //===----------------------------------------------------------------------===//
00382 
00383 TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
00384   memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
00385 }
00386 
00387 SourceRange TemplateArgumentLoc::getSourceRange() const {
00388   switch (Argument.getKind()) {
00389   case TemplateArgument::Expression:
00390     return getSourceExpression()->getSourceRange();
00391 
00392   case TemplateArgument::Declaration:
00393     return getSourceDeclExpression()->getSourceRange();
00394 
00395   case TemplateArgument::Type:
00396     if (TypeSourceInfo *TSI = getTypeSourceInfo())
00397       return TSI->getTypeLoc().getSourceRange();
00398     else
00399       return SourceRange();
00400 
00401   case TemplateArgument::Template:
00402     if (getTemplateQualifierLoc())
00403       return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 
00404                          getTemplateNameLoc());
00405     return SourceRange(getTemplateNameLoc());
00406 
00407   case TemplateArgument::TemplateExpansion:
00408     if (getTemplateQualifierLoc())
00409       return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 
00410                          getTemplateEllipsisLoc());
00411     return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
00412 
00413   case TemplateArgument::Integral:
00414   case TemplateArgument::Pack:
00415   case TemplateArgument::Null:
00416     return SourceRange();
00417   }
00418 
00419   llvm_unreachable("Invalid TemplateArgument Kind!");
00420 }
00421 
00422 TemplateArgumentLoc 
00423 TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
00424                                        llvm::Optional<unsigned> &NumExpansions,
00425                                              ASTContext &Context) const {
00426   assert(Argument.isPackExpansion());
00427   
00428   switch (Argument.getKind()) {
00429   case TemplateArgument::Type: {
00430     // FIXME: We shouldn't ever have to worry about missing
00431     // type-source info!
00432     TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo();
00433     if (!ExpansionTSInfo)
00434       ExpansionTSInfo = Context.getTrivialTypeSourceInfo(
00435                                                      getArgument().getAsType(),
00436                                                          Ellipsis);
00437     PackExpansionTypeLoc Expansion
00438       = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc());
00439     Ellipsis = Expansion.getEllipsisLoc();
00440     
00441     TypeLoc Pattern = Expansion.getPatternLoc();
00442     NumExpansions = Expansion.getTypePtr()->getNumExpansions();
00443     
00444     // FIXME: This is horrible. We know where the source location data is for
00445     // the pattern, and we have the pattern's type, but we are forced to copy
00446     // them into an ASTContext because TypeSourceInfo bundles them together
00447     // and TemplateArgumentLoc traffics in TypeSourceInfo pointers.
00448     TypeSourceInfo *PatternTSInfo
00449       = Context.CreateTypeSourceInfo(Pattern.getType(),
00450                                      Pattern.getFullDataSize());
00451     memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(), 
00452            Pattern.getOpaqueData(), Pattern.getFullDataSize());
00453     return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
00454                                PatternTSInfo);
00455   }
00456       
00457   case TemplateArgument::Expression: {
00458     PackExpansionExpr *Expansion
00459       = cast<PackExpansionExpr>(Argument.getAsExpr());
00460     Expr *Pattern = Expansion->getPattern();
00461     Ellipsis = Expansion->getEllipsisLoc();
00462     NumExpansions = Expansion->getNumExpansions();
00463     return TemplateArgumentLoc(Pattern, Pattern);
00464   }
00465 
00466   case TemplateArgument::TemplateExpansion:
00467     Ellipsis = getTemplateEllipsisLoc();
00468     NumExpansions = Argument.getNumTemplateExpansions();
00469     return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
00470                                getTemplateQualifierLoc(),
00471                                getTemplateNameLoc());
00472     
00473   case TemplateArgument::Declaration:
00474   case TemplateArgument::Template:
00475   case TemplateArgument::Integral:
00476   case TemplateArgument::Pack:
00477   case TemplateArgument::Null:
00478     return TemplateArgumentLoc();
00479   }
00480 
00481   llvm_unreachable("Invalid TemplateArgument Kind!");
00482 }
00483 
00484 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
00485                                            const TemplateArgument &Arg) {
00486   switch (Arg.getKind()) {
00487   case TemplateArgument::Null:
00488     // This is bad, but not as bad as crashing because of argument
00489     // count mismatches.
00490     return DB << "(null template argument)";
00491       
00492   case TemplateArgument::Type:
00493     return DB << Arg.getAsType();
00494       
00495   case TemplateArgument::Declaration:
00496     if (Decl *D = Arg.getAsDecl())
00497       return DB << D;
00498     return DB << "nullptr";
00499       
00500   case TemplateArgument::Integral:
00501     return DB << Arg.getAsIntegral()->toString(10);
00502       
00503   case TemplateArgument::Template:
00504     return DB << Arg.getAsTemplate();
00505 
00506   case TemplateArgument::TemplateExpansion:
00507     return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
00508 
00509   case TemplateArgument::Expression: {
00510     // This shouldn't actually ever happen, so it's okay that we're
00511     // regurgitating an expression here.
00512     // FIXME: We're guessing at LangOptions!
00513     SmallString<32> Str;
00514     llvm::raw_svector_ostream OS(Str);
00515     LangOptions LangOpts;
00516     LangOpts.CPlusPlus = true;
00517     PrintingPolicy Policy(LangOpts);
00518     Arg.getAsExpr()->printPretty(OS, 0, Policy);
00519     return DB << OS.str();
00520   }
00521       
00522   case TemplateArgument::Pack: {
00523     // FIXME: We're guessing at LangOptions!
00524     SmallString<32> Str;
00525     llvm::raw_svector_ostream OS(Str);
00526     LangOptions LangOpts;
00527     LangOpts.CPlusPlus = true;
00528     PrintingPolicy Policy(LangOpts);
00529     Arg.print(Policy, OS);
00530     return DB << OS.str();
00531   }
00532   }
00533 
00534   llvm_unreachable("Invalid TemplateArgument Kind!");
00535 }
00536 
00537 const ASTTemplateArgumentListInfo *
00538 ASTTemplateArgumentListInfo::Create(ASTContext &C,
00539                                     const TemplateArgumentListInfo &List) {
00540   std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
00541                      ASTTemplateArgumentListInfo::sizeFor(List.size());
00542   void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
00543   ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
00544   TAI->initializeFrom(List);
00545   return TAI;
00546 }
00547 
00548 void ASTTemplateArgumentListInfo::initializeFrom(
00549                                       const TemplateArgumentListInfo &Info) {
00550   LAngleLoc = Info.getLAngleLoc();
00551   RAngleLoc = Info.getRAngleLoc();
00552   NumTemplateArgs = Info.size();
00553 
00554   TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
00555   for (unsigned i = 0; i != NumTemplateArgs; ++i)
00556     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
00557 }
00558 
00559 void ASTTemplateArgumentListInfo::initializeFrom(
00560                                           const TemplateArgumentListInfo &Info,
00561                                                   bool &Dependent, 
00562                                                   bool &InstantiationDependent,
00563                                        bool &ContainsUnexpandedParameterPack) {
00564   LAngleLoc = Info.getLAngleLoc();
00565   RAngleLoc = Info.getRAngleLoc();
00566   NumTemplateArgs = Info.size();
00567 
00568   TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
00569   for (unsigned i = 0; i != NumTemplateArgs; ++i) {
00570     Dependent = Dependent || Info[i].getArgument().isDependent();
00571     InstantiationDependent = InstantiationDependent || 
00572                              Info[i].getArgument().isInstantiationDependent();
00573     ContainsUnexpandedParameterPack 
00574       = ContainsUnexpandedParameterPack || 
00575         Info[i].getArgument().containsUnexpandedParameterPack();
00576 
00577     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
00578   }
00579 }
00580 
00581 void ASTTemplateArgumentListInfo::copyInto(
00582                                       TemplateArgumentListInfo &Info) const {
00583   Info.setLAngleLoc(LAngleLoc);
00584   Info.setRAngleLoc(RAngleLoc);
00585   for (unsigned I = 0; I != NumTemplateArgs; ++I)
00586     Info.addArgument(getTemplateArgs()[I]);
00587 }
00588 
00589 std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) {
00590   return sizeof(ASTTemplateArgumentListInfo) +
00591          sizeof(TemplateArgumentLoc) * NumTemplateArgs;
00592 }
00593 
00594 void
00595 ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc,
00596                                          const TemplateArgumentListInfo &Info) {
00597   Base::initializeFrom(Info);
00598   setTemplateKeywordLoc(TemplateKWLoc);
00599 }
00600 
00601 void
00602 ASTTemplateKWAndArgsInfo
00603 ::initializeFrom(SourceLocation TemplateKWLoc,
00604                  const TemplateArgumentListInfo &Info,
00605                  bool &Dependent,
00606                  bool &InstantiationDependent,
00607                  bool &ContainsUnexpandedParameterPack) {
00608   Base::initializeFrom(Info, Dependent, InstantiationDependent,
00609                        ContainsUnexpandedParameterPack);
00610   setTemplateKeywordLoc(TemplateKWLoc);
00611 }
00612 
00613 void
00614 ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
00615   // No explicit template arguments, but template keyword loc is valid.
00616   assert(TemplateKWLoc.isValid());
00617   LAngleLoc = SourceLocation();
00618   RAngleLoc = SourceLocation();
00619   NumTemplateArgs = 0;
00620   setTemplateKeywordLoc(TemplateKWLoc);
00621 }
00622 
00623 std::size_t
00624 ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) {
00625   // Add space for the template keyword location.
00626   return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation);
00627 }
00628