clang API Documentation
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