Home | History | Annotate | Download | only in AST
      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 "clang/AST/TemplateBase.h"
     16 #include "clang/AST/ASTContext.h"
     17 #include "clang/AST/DeclBase.h"
     18 #include "clang/AST/DeclTemplate.h"
     19 #include "clang/AST/Expr.h"
     20 #include "clang/AST/ExprCXX.h"
     21 #include "clang/AST/Type.h"
     22 #include "clang/AST/TypeLoc.h"
     23 #include "clang/Basic/Diagnostic.h"
     24 #include "llvm/ADT/FoldingSet.h"
     25 #include "llvm/ADT/SmallString.h"
     26 #include <algorithm>
     27 #include <cctype>
     28 
     29 using namespace clang;
     30 
     31 /// \brief Print a template integral argument value.
     32 ///
     33 /// \param TemplArg the TemplateArgument instance to print.
     34 ///
     35 /// \param Out the raw_ostream instance to use for printing.
     36 static void printIntegral(const TemplateArgument &TemplArg,
     37                           raw_ostream &Out) {
     38   const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
     39   const llvm::APSInt *Val = TemplArg.getAsIntegral();
     40 
     41   if (T->isBooleanType()) {
     42     Out << (Val->getBoolValue() ? "true" : "false");
     43   } else if (T->isCharType()) {
     44     const char Ch = Val->getZExtValue();
     45     Out << ((Ch == '\'') ? "'\\" : "'");
     46     Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
     47     Out << "'";
     48   } else {
     49     Out << Val->toString(10);
     50   }
     51 }
     52 
     53 //===----------------------------------------------------------------------===//
     54 // TemplateArgument Implementation
     55 //===----------------------------------------------------------------------===//
     56 
     57 TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context,
     58                                                   const TemplateArgument *Args,
     59                                                   unsigned NumArgs) {
     60   if (NumArgs == 0)
     61     return TemplateArgument(0, 0);
     62 
     63   TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs];
     64   std::copy(Args, Args + NumArgs, Storage);
     65   return TemplateArgument(Storage, NumArgs);
     66 }
     67 
     68 bool TemplateArgument::isDependent() const {
     69   switch (getKind()) {
     70   case Null:
     71     llvm_unreachable("Should not have a NULL template argument");
     72 
     73   case Type:
     74     return getAsType()->isDependentType();
     75 
     76   case Template:
     77     return getAsTemplate().isDependent();
     78 
     79   case TemplateExpansion:
     80     return true;
     81 
     82   case Declaration:
     83     if (Decl *D = getAsDecl()) {
     84       if (DeclContext *DC = dyn_cast<DeclContext>(D))
     85         return DC->isDependentContext();
     86       return D->getDeclContext()->isDependentContext();
     87     }
     88 
     89     return false;
     90 
     91   case Integral:
     92     // Never dependent
     93     return false;
     94 
     95   case Expression:
     96     return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
     97 
     98   case Pack:
     99     for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
    100       if (P->isDependent())
    101         return true;
    102     }
    103 
    104     return false;
    105   }
    106 
    107   llvm_unreachable("Invalid TemplateArgument Kind!");
    108 }
    109 
    110 bool TemplateArgument::isInstantiationDependent() const {
    111   switch (getKind()) {
    112   case Null:
    113     llvm_unreachable("Should not have a NULL template argument");
    114 
    115   case Type:
    116     return getAsType()->isInstantiationDependentType();
    117 
    118   case Template:
    119     return getAsTemplate().isInstantiationDependent();
    120 
    121   case TemplateExpansion:
    122     return true;
    123 
    124   case Declaration:
    125     if (Decl *D = getAsDecl()) {
    126       if (DeclContext *DC = dyn_cast<DeclContext>(D))
    127         return DC->isDependentContext();
    128       return D->getDeclContext()->isDependentContext();
    129     }
    130     return false;
    131 
    132   case Integral:
    133     // Never dependent
    134     return false;
    135 
    136   case Expression:
    137     return getAsExpr()->isInstantiationDependent();
    138 
    139   case Pack:
    140     for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
    141       if (P->isInstantiationDependent())
    142         return true;
    143     }
    144 
    145     return false;
    146   }
    147 
    148   llvm_unreachable("Invalid TemplateArgument Kind!");
    149 }
    150 
    151 bool TemplateArgument::isPackExpansion() const {
    152   switch (getKind()) {
    153   case Null:
    154   case Declaration:
    155   case Integral:
    156   case Pack:
    157   case Template:
    158     return false;
    159 
    160   case TemplateExpansion:
    161     return true;
    162 
    163   case Type:
    164     return isa<PackExpansionType>(getAsType());
    165 
    166   case Expression:
    167     return isa<PackExpansionExpr>(getAsExpr());
    168   }
    169 
    170   llvm_unreachable("Invalid TemplateArgument Kind!");
    171 }
    172 
    173 bool TemplateArgument::containsUnexpandedParameterPack() const {
    174   switch (getKind()) {
    175   case Null:
    176   case Declaration:
    177   case Integral:
    178   case TemplateExpansion:
    179     break;
    180 
    181   case Type:
    182     if (getAsType()->containsUnexpandedParameterPack())
    183       return true;
    184     break;
    185 
    186   case Template:
    187     if (getAsTemplate().containsUnexpandedParameterPack())
    188       return true;
    189     break;
    190 
    191   case Expression:
    192     if (getAsExpr()->containsUnexpandedParameterPack())
    193       return true;
    194     break;
    195 
    196   case Pack:
    197     for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
    198       if (P->containsUnexpandedParameterPack())
    199         return true;
    200 
    201     break;
    202   }
    203 
    204   return false;
    205 }
    206 
    207 llvm::Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
    208   assert(Kind == TemplateExpansion);
    209   if (TemplateArg.NumExpansions)
    210     return TemplateArg.NumExpansions - 1;
    211 
    212   return llvm::Optional<unsigned>();
    213 }
    214 
    215 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
    216                                const ASTContext &Context) const {
    217   ID.AddInteger(Kind);
    218   switch (Kind) {
    219   case Null:
    220     break;
    221 
    222   case Type:
    223     getAsType().Profile(ID);
    224     break;
    225 
    226   case Declaration:
    227     ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
    228     break;
    229 
    230   case Template:
    231   case TemplateExpansion: {
    232     TemplateName Template = getAsTemplateOrTemplatePattern();
    233     if (TemplateTemplateParmDecl *TTP
    234           = dyn_cast_or_null<TemplateTemplateParmDecl>(
    235                                                 Template.getAsTemplateDecl())) {
    236       ID.AddBoolean(true);
    237       ID.AddInteger(TTP->getDepth());
    238       ID.AddInteger(TTP->getPosition());
    239       ID.AddBoolean(TTP->isParameterPack());
    240     } else {
    241       ID.AddBoolean(false);
    242       ID.AddPointer(Context.getCanonicalTemplateName(Template)
    243                                                           .getAsVoidPointer());
    244     }
    245     break;
    246   }
    247 
    248   case Integral:
    249     getAsIntegral()->Profile(ID);
    250     getIntegralType().Profile(ID);
    251     break;
    252 
    253   case Expression:
    254     getAsExpr()->Profile(ID, Context, true);
    255     break;
    256 
    257   case Pack:
    258     ID.AddInteger(Args.NumArgs);
    259     for (unsigned I = 0; I != Args.NumArgs; ++I)
    260       Args.Args[I].Profile(ID, Context);
    261   }
    262 }
    263 
    264 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
    265   if (getKind() != Other.getKind()) return false;
    266 
    267   switch (getKind()) {
    268   case Null:
    269   case Type:
    270   case Declaration:
    271   case Expression:
    272   case Template:
    273   case TemplateExpansion:
    274     return TypeOrValue == Other.TypeOrValue;
    275 
    276   case Integral:
    277     return getIntegralType() == Other.getIntegralType() &&
    278            *getAsIntegral() == *Other.getAsIntegral();
    279 
    280   case Pack:
    281     if (Args.NumArgs != Other.Args.NumArgs) return false;
    282     for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
    283       if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
    284         return false;
    285     return true;
    286   }
    287 
    288   llvm_unreachable("Invalid TemplateArgument Kind!");
    289 }
    290 
    291 TemplateArgument TemplateArgument::getPackExpansionPattern() const {
    292   assert(isPackExpansion());
    293 
    294   switch (getKind()) {
    295   case Type:
    296     return getAsType()->getAs<PackExpansionType>()->getPattern();
    297 
    298   case Expression:
    299     return cast<PackExpansionExpr>(getAsExpr())->getPattern();
    300 
    301   case TemplateExpansion:
    302     return TemplateArgument(getAsTemplateOrTemplatePattern());
    303 
    304   case Declaration:
    305   case Integral:
    306   case Pack:
    307   case Null:
    308   case Template:
    309     return TemplateArgument();
    310   }
    311 
    312   llvm_unreachable("Invalid TemplateArgument Kind!");
    313 }
    314 
    315 void TemplateArgument::print(const PrintingPolicy &Policy,
    316                              raw_ostream &Out) const {
    317   switch (getKind()) {
    318   case Null:
    319     Out << "<no value>";
    320     break;
    321 
    322   case Type: {
    323     PrintingPolicy SubPolicy(Policy);
    324     SubPolicy.SuppressStrongLifetime = true;
    325     std::string TypeStr;
    326     getAsType().getAsStringInternal(TypeStr, SubPolicy);
    327     Out << TypeStr;
    328     break;
    329   }
    330 
    331   case Declaration: {
    332     if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
    333       if (ND->getDeclName()) {
    334         Out << *ND;
    335       } else {
    336         Out << "<anonymous>";
    337       }
    338     } else {
    339       Out << "nullptr";
    340     }
    341     break;
    342   }
    343 
    344   case Template:
    345     getAsTemplate().print(Out, Policy);
    346     break;
    347 
    348   case TemplateExpansion:
    349     getAsTemplateOrTemplatePattern().print(Out, Policy);
    350     Out << "...";
    351     break;
    352 
    353   case Integral: {
    354     printIntegral(*this, Out);
    355     break;
    356   }
    357 
    358   case Expression:
    359     getAsExpr()->printPretty(Out, 0, Policy);
    360     break;
    361 
    362   case Pack:
    363     Out << "<";
    364     bool First = true;
    365     for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
    366          P != PEnd; ++P) {
    367       if (First)
    368         First = false;
    369       else
    370         Out << ", ";
    371 
    372       P->print(Policy, Out);
    373     }
    374     Out << ">";
    375     break;
    376   }
    377 }
    378 
    379 //===----------------------------------------------------------------------===//
    380 // TemplateArgumentLoc Implementation
    381 //===----------------------------------------------------------------------===//
    382 
    383 TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
    384   memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
    385 }
    386 
    387 SourceRange TemplateArgumentLoc::getSourceRange() const {
    388   switch (Argument.getKind()) {
    389   case TemplateArgument::Expression:
    390     return getSourceExpression()->getSourceRange();
    391 
    392   case TemplateArgument::Declaration:
    393     return getSourceDeclExpression()->getSourceRange();
    394 
    395   case TemplateArgument::Type:
    396     if (TypeSourceInfo *TSI = getTypeSourceInfo())
    397       return TSI->getTypeLoc().getSourceRange();
    398     else
    399       return SourceRange();
    400 
    401   case TemplateArgument::Template:
    402     if (getTemplateQualifierLoc())
    403       return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
    404                          getTemplateNameLoc());
    405     return SourceRange(getTemplateNameLoc());
    406 
    407   case TemplateArgument::TemplateExpansion:
    408     if (getTemplateQualifierLoc())
    409       return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
    410                          getTemplateEllipsisLoc());
    411     return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
    412 
    413   case TemplateArgument::Integral:
    414   case TemplateArgument::Pack:
    415   case TemplateArgument::Null:
    416     return SourceRange();
    417   }
    418 
    419   llvm_unreachable("Invalid TemplateArgument Kind!");
    420 }
    421 
    422 TemplateArgumentLoc
    423 TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
    424                                        llvm::Optional<unsigned> &NumExpansions,
    425                                              ASTContext &Context) const {
    426   assert(Argument.isPackExpansion());
    427 
    428   switch (Argument.getKind()) {
    429   case TemplateArgument::Type: {
    430     // FIXME: We shouldn't ever have to worry about missing
    431     // type-source info!
    432     TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo();
    433     if (!ExpansionTSInfo)
    434       ExpansionTSInfo = Context.getTrivialTypeSourceInfo(
    435                                                      getArgument().getAsType(),
    436                                                          Ellipsis);
    437     PackExpansionTypeLoc Expansion
    438       = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc());
    439     Ellipsis = Expansion.getEllipsisLoc();
    440 
    441     TypeLoc Pattern = Expansion.getPatternLoc();
    442     NumExpansions = Expansion.getTypePtr()->getNumExpansions();
    443 
    444     // FIXME: This is horrible. We know where the source location data is for
    445     // the pattern, and we have the pattern's type, but we are forced to copy
    446     // them into an ASTContext because TypeSourceInfo bundles them together
    447     // and TemplateArgumentLoc traffics in TypeSourceInfo pointers.
    448     TypeSourceInfo *PatternTSInfo
    449       = Context.CreateTypeSourceInfo(Pattern.getType(),
    450                                      Pattern.getFullDataSize());
    451     memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(),
    452            Pattern.getOpaqueData(), Pattern.getFullDataSize());
    453     return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
    454                                PatternTSInfo);
    455   }
    456 
    457   case TemplateArgument::Expression: {
    458     PackExpansionExpr *Expansion
    459       = cast<PackExpansionExpr>(Argument.getAsExpr());
    460     Expr *Pattern = Expansion->getPattern();
    461     Ellipsis = Expansion->getEllipsisLoc();
    462     NumExpansions = Expansion->getNumExpansions();
    463     return TemplateArgumentLoc(Pattern, Pattern);
    464   }
    465 
    466   case TemplateArgument::TemplateExpansion:
    467     Ellipsis = getTemplateEllipsisLoc();
    468     NumExpansions = Argument.getNumTemplateExpansions();
    469     return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
    470                                getTemplateQualifierLoc(),
    471                                getTemplateNameLoc());
    472 
    473   case TemplateArgument::Declaration:
    474   case TemplateArgument::Template:
    475   case TemplateArgument::Integral:
    476   case TemplateArgument::Pack:
    477   case TemplateArgument::Null:
    478     return TemplateArgumentLoc();
    479   }
    480 
    481   llvm_unreachable("Invalid TemplateArgument Kind!");
    482 }
    483 
    484 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
    485                                            const TemplateArgument &Arg) {
    486   switch (Arg.getKind()) {
    487   case TemplateArgument::Null:
    488     // This is bad, but not as bad as crashing because of argument
    489     // count mismatches.
    490     return DB << "(null template argument)";
    491 
    492   case TemplateArgument::Type:
    493     return DB << Arg.getAsType();
    494 
    495   case TemplateArgument::Declaration:
    496     if (Decl *D = Arg.getAsDecl())
    497       return DB << D;
    498     return DB << "nullptr";
    499 
    500   case TemplateArgument::Integral:
    501     return DB << Arg.getAsIntegral()->toString(10);
    502 
    503   case TemplateArgument::Template:
    504     return DB << Arg.getAsTemplate();
    505 
    506   case TemplateArgument::TemplateExpansion:
    507     return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
    508 
    509   case TemplateArgument::Expression: {
    510     // This shouldn't actually ever happen, so it's okay that we're
    511     // regurgitating an expression here.
    512     // FIXME: We're guessing at LangOptions!
    513     SmallString<32> Str;
    514     llvm::raw_svector_ostream OS(Str);
    515     LangOptions LangOpts;
    516     LangOpts.CPlusPlus = true;
    517     PrintingPolicy Policy(LangOpts);
    518     Arg.getAsExpr()->printPretty(OS, 0, Policy);
    519     return DB << OS.str();
    520   }
    521 
    522   case TemplateArgument::Pack: {
    523     // FIXME: We're guessing at LangOptions!
    524     SmallString<32> Str;
    525     llvm::raw_svector_ostream OS(Str);
    526     LangOptions LangOpts;
    527     LangOpts.CPlusPlus = true;
    528     PrintingPolicy Policy(LangOpts);
    529     Arg.print(Policy, OS);
    530     return DB << OS.str();
    531   }
    532   }
    533 
    534   llvm_unreachable("Invalid TemplateArgument Kind!");
    535 }
    536 
    537 const ASTTemplateArgumentListInfo *
    538 ASTTemplateArgumentListInfo::Create(ASTContext &C,
    539                                     const TemplateArgumentListInfo &List) {
    540   std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
    541                      ASTTemplateArgumentListInfo::sizeFor(List.size());
    542   void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
    543   ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
    544   TAI->initializeFrom(List);
    545   return TAI;
    546 }
    547 
    548 void ASTTemplateArgumentListInfo::initializeFrom(
    549                                       const TemplateArgumentListInfo &Info) {
    550   LAngleLoc = Info.getLAngleLoc();
    551   RAngleLoc = Info.getRAngleLoc();
    552   NumTemplateArgs = Info.size();
    553 
    554   TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
    555   for (unsigned i = 0; i != NumTemplateArgs; ++i)
    556     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
    557 }
    558 
    559 void ASTTemplateArgumentListInfo::initializeFrom(
    560                                           const TemplateArgumentListInfo &Info,
    561                                                   bool &Dependent,
    562                                                   bool &InstantiationDependent,
    563                                        bool &ContainsUnexpandedParameterPack) {
    564   LAngleLoc = Info.getLAngleLoc();
    565   RAngleLoc = Info.getRAngleLoc();
    566   NumTemplateArgs = Info.size();
    567 
    568   TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
    569   for (unsigned i = 0; i != NumTemplateArgs; ++i) {
    570     Dependent = Dependent || Info[i].getArgument().isDependent();
    571     InstantiationDependent = InstantiationDependent ||
    572                              Info[i].getArgument().isInstantiationDependent();
    573     ContainsUnexpandedParameterPack
    574       = ContainsUnexpandedParameterPack ||
    575         Info[i].getArgument().containsUnexpandedParameterPack();
    576 
    577     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
    578   }
    579 }
    580 
    581 void ASTTemplateArgumentListInfo::copyInto(
    582                                       TemplateArgumentListInfo &Info) const {
    583   Info.setLAngleLoc(LAngleLoc);
    584   Info.setRAngleLoc(RAngleLoc);
    585   for (unsigned I = 0; I != NumTemplateArgs; ++I)
    586     Info.addArgument(getTemplateArgs()[I]);
    587 }
    588 
    589 std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) {
    590   return sizeof(ASTTemplateArgumentListInfo) +
    591          sizeof(TemplateArgumentLoc) * NumTemplateArgs;
    592 }
    593 
    594 void
    595 ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc,
    596                                          const TemplateArgumentListInfo &Info) {
    597   Base::initializeFrom(Info);
    598   setTemplateKeywordLoc(TemplateKWLoc);
    599 }
    600 
    601 void
    602 ASTTemplateKWAndArgsInfo
    603 ::initializeFrom(SourceLocation TemplateKWLoc,
    604                  const TemplateArgumentListInfo &Info,
    605                  bool &Dependent,
    606                  bool &InstantiationDependent,
    607                  bool &ContainsUnexpandedParameterPack) {
    608   Base::initializeFrom(Info, Dependent, InstantiationDependent,
    609                        ContainsUnexpandedParameterPack);
    610   setTemplateKeywordLoc(TemplateKWLoc);
    611 }
    612 
    613 void
    614 ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
    615   // No explicit template arguments, but template keyword loc is valid.
    616   assert(TemplateKWLoc.isValid());
    617   LAngleLoc = SourceLocation();
    618   RAngleLoc = SourceLocation();
    619   NumTemplateArgs = 0;
    620   setTemplateKeywordLoc(TemplateKWLoc);
    621 }
    622 
    623 std::size_t
    624 ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) {
    625   // Add space for the template keyword location.
    626   return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation);
    627 }
    628 
    629