diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 22 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 19 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 20 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 26 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 70 | ||||
-rw-r--r-- | lib/AST/TemplateBase.cpp | 28 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 159 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 28 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 23 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 43 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 195 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 63 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 24 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 260 |
21 files changed, 663 insertions, 365 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 7be55ebb11..d60a8204c7 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1765,6 +1765,19 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, QualType ASTContext::getTemplateSpecializationType(TemplateName Template, + const TemplateArgumentLoc *Args, + unsigned NumArgs, + QualType Canon) { + llvm::SmallVector<TemplateArgument, 4> ArgVec; + ArgVec.reserve(NumArgs); + for (unsigned i = 0; i != NumArgs; ++i) + ArgVec.push_back(Args[i].getArgument()); + + return getTemplateSpecializationType(Template, ArgVec.data(), NumArgs, Canon); +} + +QualType +ASTContext::getTemplateSpecializationType(TemplateName Template, const TemplateArgument *Args, unsigned NumArgs, QualType Canon) { @@ -2298,17 +2311,14 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) { return Arg; case TemplateArgument::Declaration: - return TemplateArgument(SourceLocation(), - Arg.getAsDecl()->getCanonicalDecl()); + return TemplateArgument(Arg.getAsDecl()->getCanonicalDecl()); case TemplateArgument::Integral: - return TemplateArgument(SourceLocation(), - *Arg.getAsIntegral(), + return TemplateArgument(*Arg.getAsIntegral(), getCanonicalType(Arg.getIntegralType())); case TemplateArgument::Type: - return TemplateArgument(SourceLocation(), - getCanonicalType(Arg.getAsType())); + return TemplateArgument(getCanonicalType(Arg.getAsType())); case TemplateArgument::Pack: { // FIXME: Allocate in ASTContext diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 49244e1dba..9ebc91afe1 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -15,6 +15,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/TypeLoc.h" #include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/STLExtras.h" using namespace clang; @@ -209,8 +210,7 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) { Param != ParamEnd; ++Param) { if (isa<TemplateTypeParmDecl>(*Param)) { QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param)); - TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(), - ParamType)); + TemplateArgs.push_back(TemplateArgument(ParamType)); } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*Param)) { Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(), @@ -220,7 +220,7 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) { TemplateArgs.push_back(TemplateArgument(E)); } else { TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); - TemplateArgs.push_back(TemplateArgument(TTP->getLocation(), TTP)); + TemplateArgs.push_back(TemplateArgument(TTP)); } } @@ -244,6 +244,10 @@ TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC, return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack); } +SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { + return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin(); +} + unsigned TemplateTypeParmDecl::getDepth() const { return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth(); } @@ -454,12 +458,19 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, + TemplateArgumentLoc *ArgInfos, unsigned N, ClassTemplatePartialSpecializationDecl *PrevDecl) { + TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N]; + for (unsigned I = 0; I != N; ++I) + ClonedArgs[I] = ArgInfos[I]; + ClassTemplatePartialSpecializationDecl *Result = new (Context)ClassTemplatePartialSpecializationDecl(Context, DC, L, Params, SpecializedTemplate, - Builder, PrevDecl); + Builder, + ClonedArgs, N, + PrevDecl); Result->setSpecializationKind(TSK_ExplicitSpecialization); Context.getTypeDeclType(Result, PrevDecl); return Result; diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index ad9c9cbe10..ad91cd393f 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -35,7 +35,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, NamedDecl *D, SourceLocation NameLoc, bool HasExplicitTemplateArgumentList, SourceLocation LAngleLoc, - const TemplateArgument *ExplicitTemplateArgs, + const TemplateArgumentLoc *ExplicitTemplateArgs, unsigned NumExplicitTemplateArgs, SourceLocation RAngleLoc, QualType T, bool TD, bool VD) @@ -58,9 +58,9 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, ETemplateArgs->RAngleLoc = RAngleLoc; ETemplateArgs->NumTemplateArgs = NumExplicitTemplateArgs; - TemplateArgument *TemplateArgs = ETemplateArgs->getTemplateArgs(); + TemplateArgumentLoc *TemplateArgs = ETemplateArgs->getTemplateArgs(); for (unsigned I = 0; I < NumExplicitTemplateArgs; ++I) - new (TemplateArgs + I) TemplateArgument(ExplicitTemplateArgs[I]); + new (TemplateArgs + I) TemplateArgumentLoc(ExplicitTemplateArgs[I]); } } @@ -82,7 +82,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, SourceLocation NameLoc, bool HasExplicitTemplateArgumentList, SourceLocation LAngleLoc, - const TemplateArgument *ExplicitTemplateArgs, + const TemplateArgumentLoc *ExplicitTemplateArgs, unsigned NumExplicitTemplateArgs, SourceLocation RAngleLoc, QualType T, bool TD, bool VD) { @@ -92,7 +92,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, if (HasExplicitTemplateArgumentList) Size += sizeof(ExplicitTemplateArgumentList) + - sizeof(TemplateArgument) * NumExplicitTemplateArgs; + sizeof(TemplateArgumentLoc) * NumExplicitTemplateArgs; void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>()); return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc, @@ -428,7 +428,7 @@ MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual, SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l, bool has_explicit, SourceLocation langle, - const TemplateArgument *targs, unsigned numtargs, + const TemplateArgumentLoc *targs, unsigned numtargs, SourceLocation rangle, QualType ty) : Expr(MemberExprClass, ty, base->isTypeDependent() || (qual && qual->isDependent()), @@ -450,9 +450,9 @@ MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual, ETemplateArgs->RAngleLoc = rangle; ETemplateArgs->NumTemplateArgs = numtargs; - TemplateArgument *TemplateArgs = ETemplateArgs->getTemplateArgs(); + TemplateArgumentLoc *TemplateArgs = ETemplateArgs->getTemplateArgs(); for (unsigned I = 0; I < numtargs; ++I) - new (TemplateArgs + I) TemplateArgument(targs[I]); + new (TemplateArgs + I) TemplateArgumentLoc(targs[I]); } } @@ -463,7 +463,7 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, SourceLocation l, bool has_explicit, SourceLocation langle, - const TemplateArgument *targs, + const TemplateArgumentLoc *targs, unsigned numtargs, SourceLocation rangle, QualType ty) { @@ -473,7 +473,7 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, if (has_explicit) Size += sizeof(ExplicitTemplateArgumentList) + - sizeof(TemplateArgument) * numtargs; + sizeof(TemplateArgumentLoc) * numtargs; void *Mem = C.Allocate(Size, llvm::alignof<MemberExpr>()); return new (Mem) MemberExpr(base, isarrow, qual, qualrange, memberdecl, l, diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index cba0e22095..7c6fc41ef1 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -151,7 +151,7 @@ TemplateIdRefExpr::TemplateIdRefExpr(QualType T, TemplateName Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, - const TemplateArgument *TemplateArgs, + const TemplateArgumentLoc *TemplateArgs, unsigned NumTemplateArgs, SourceLocation RAngleLoc) : Expr(TemplateIdRefExprClass, T, @@ -164,10 +164,10 @@ TemplateIdRefExpr::TemplateIdRefExpr(QualType T, Qualifier(Qualifier), QualifierRange(QualifierRange), Template(Template), TemplateNameLoc(TemplateNameLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), NumTemplateArgs(NumTemplateArgs) { - TemplateArgument *StoredTemplateArgs - = reinterpret_cast<TemplateArgument *> (this+1); + TemplateArgumentLoc *StoredTemplateArgs + = reinterpret_cast<TemplateArgumentLoc *> (this+1); for (unsigned I = 0; I != NumTemplateArgs; ++I) - new (StoredTemplateArgs + I) TemplateArgument(TemplateArgs[I]); + new (StoredTemplateArgs + I) TemplateArgumentLoc(TemplateArgs[I]); } TemplateIdRefExpr * @@ -176,19 +176,19 @@ TemplateIdRefExpr::Create(ASTContext &Context, QualType T, SourceRange QualifierRange, TemplateName Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, - const TemplateArgument *TemplateArgs, + const TemplateArgumentLoc *TemplateArgs, unsigned NumTemplateArgs, SourceLocation RAngleLoc) { void *Mem = Context.Allocate(sizeof(TemplateIdRefExpr) + - sizeof(TemplateArgument) * NumTemplateArgs); + sizeof(TemplateArgumentLoc) * NumTemplateArgs); return new (Mem) TemplateIdRefExpr(T, Qualifier, QualifierRange, Template, TemplateNameLoc, LAngleLoc, TemplateArgs, NumTemplateArgs, RAngleLoc); } void TemplateIdRefExpr::DoDestroy(ASTContext &Context) { - const TemplateArgument *TemplateArgs = getTemplateArgs(); + const TemplateArgumentLoc *TemplateArgs = getTemplateArgs(); for (unsigned I = 0; I != NumTemplateArgs; ++I) - if (Expr *E = TemplateArgs[I].getAsExpr()) + if (Expr *E = TemplateArgs[I].getArgument().getAsExpr()) E->Destroy(Context); this->~TemplateIdRefExpr(); Context.Deallocate(this); @@ -528,7 +528,7 @@ CXXUnresolvedMemberExpr::CXXUnresolvedMemberExpr(ASTContext &C, SourceLocation MemberLoc, bool HasExplicitTemplateArgs, SourceLocation LAngleLoc, - const TemplateArgument *TemplateArgs, + const TemplateArgumentLoc *TemplateArgs, unsigned NumTemplateArgs, SourceLocation RAngleLoc) : Expr(CXXUnresolvedMemberExprClass, C.DependentTy, true, true), @@ -545,9 +545,9 @@ CXXUnresolvedMemberExpr::CXXUnresolvedMemberExpr(ASTContext &C, ETemplateArgs->RAngleLoc = RAngleLoc; ETemplateArgs->NumTemplateArgs = NumTemplateArgs; - TemplateArgument *SavedTemplateArgs = ETemplateArgs->getTemplateArgs(); + TemplateArgumentLoc *SavedTemplateArgs = ETemplateArgs->getTemplateArgs(); for (unsigned I = 0; I < NumTemplateArgs; ++I) - new (SavedTemplateArgs + I) TemplateArgument(TemplateArgs[I]); + new (SavedTemplateArgs + I) TemplateArgumentLoc(TemplateArgs[I]); } } @@ -562,7 +562,7 @@ CXXUnresolvedMemberExpr::Create(ASTContext &C, SourceLocation MemberLoc, bool HasExplicitTemplateArgs, SourceLocation LAngleLoc, - const TemplateArgument *TemplateArgs, + const TemplateArgumentLoc *TemplateArgs, unsigned NumTemplateArgs, SourceLocation RAngleLoc) { if (!HasExplicitTemplateArgs) @@ -573,7 +573,7 @@ CXXUnresolvedMemberExpr::Create(ASTContext &C, void *Mem = C.Allocate(sizeof(CXXUnresolvedMemberExpr) + sizeof(ExplicitTemplateArgumentList) + - sizeof(TemplateArgument) * NumTemplateArgs, + sizeof(TemplateArgumentLoc) * NumTemplateArgs, llvm::alignof<CXXUnresolvedMemberExpr>()); return new (Mem) CXXUnresolvedMemberExpr(C, Base, IsArrow, OperatorLoc, Qualifier, QualifierRange, diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index a6327c9ea7..02e0c74bb6 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -60,7 +60,10 @@ namespace { /// \brief Visit template arguments that occur within an expression or /// statement. - void VisitTemplateArguments(const TemplateArgument *Args, unsigned NumArgs); + void VisitTemplateArguments(const TemplateArgumentLoc *Args, unsigned NumArgs); + + /// \brief Visit a single template argument. + void VisitTemplateArgument(const TemplateArgument &Arg); }; } @@ -674,39 +677,42 @@ void StmtProfiler::VisitTemplateName(TemplateName Name) { Name.Profile(ID); } -void StmtProfiler::VisitTemplateArguments(const TemplateArgument *Args, +void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args, unsigned NumArgs) { ID.AddInteger(NumArgs); - for (unsigned I = 0; I != NumArgs; ++I) { - const TemplateArgument &Arg = Args[I]; - - // Mostly repetitive with TemplateArgument::Profile! - ID.AddInteger(Arg.getKind()); - switch (Arg.getKind()) { - case TemplateArgument::Null: - break; - - case TemplateArgument::Type: - VisitType(Arg.getAsType()); - break; - - case TemplateArgument::Declaration: - VisitDecl(Arg.getAsDecl()); - break; - - case TemplateArgument::Integral: - Arg.getAsIntegral()->Profile(ID); - VisitType(Arg.getIntegralType()); - break; - - case TemplateArgument::Expression: - Visit(Arg.getAsExpr()); - break; - - case TemplateArgument::Pack: - VisitTemplateArguments(Arg.pack_begin(), Arg.pack_size()); - break; - } + for (unsigned I = 0; I != NumArgs; ++I) + VisitTemplateArgument(Args[I].getArgument()); +} + +void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) { + // Mostly repetitive with TemplateArgument::Profile! + ID.AddInteger(Arg.getKind()); + switch (Arg.getKind()) { + case TemplateArgument::Null: + break; + + case TemplateArgument::Type: + VisitType(Arg.getAsType()); + break; + + case TemplateArgument::Declaration: + VisitDecl(Arg.getAsDecl()); + break; + + case TemplateArgument::Integral: + Arg.getAsIntegral()->Profile(ID); + VisitType(Arg.getIntegralType()); + break; + + case TemplateArgument::Expression: + Visit(Arg.getAsExpr()); + break; + + case TemplateArgument::Pack: + const TemplateArgument *Pack = Arg.pack_begin(); + for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i) + VisitTemplateArgument(Pack[i]); + break; } } diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index 3b3ec2b530..b136fe0d38 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -16,6 +16,7 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/DeclBase.h" #include "clang/AST/Expr.h" +#include "clang/AST/TypeLoc.h" using namespace clang; @@ -23,11 +24,6 @@ using namespace clang; // TemplateArgument Implementation //===----------------------------------------------------------------------===// -TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) { - TypeOrValue = reinterpret_cast<uintptr_t>(E); - StartLoc = E->getSourceRange().getBegin(); -} - /// \brief Construct a template argument pack. void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs, bool CopyArgs) { @@ -77,3 +73,25 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, Args.Args[I].Profile(ID, Context); } } + +//===----------------------------------------------------------------------===// +// TemplateArgumentLoc Implementation +//===----------------------------------------------------------------------===// + +SourceLocation TemplateArgumentLoc::getLocation() const { + switch (Argument.getKind()) { + case TemplateArgument::Expression: + return getSourceExpression()->getExprLoc(); + case TemplateArgument::Type: + return getSourceDeclaratorInfo()-> + getTypeLoc().getFullSourceRange().getBegin(); + case TemplateArgument::Declaration: + case TemplateArgument::Integral: + case TemplateArgument::Pack: + case TemplateArgument::Null: + return SourceLocation(); + } + + // Silence bonus gcc warning. + return SourceLocation(); +} diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 5fb0178834..65ed767522 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -791,40 +791,48 @@ bool EnumType::classof(const TagType *TT) { return isa<EnumDecl>(TT->getDecl()); } -bool -TemplateSpecializationType:: -anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) { - for (unsigned Idx = 0; Idx < NumArgs; ++Idx) { - switch (Args[Idx].getKind()) { - case TemplateArgument::Null: - assert(false && "Should not have a NULL template argument"); - break; - - case TemplateArgument::Type: - if (Args[Idx].getAsType()->isDependentType()) - return true; - break; - - case TemplateArgument::Declaration: - case TemplateArgument::Integral: - // Never dependent - break; - - case TemplateArgument::Expression: - if (Args[Idx].getAsExpr()->isTypeDependent() || - Args[Idx].getAsExpr()->isValueDependent()) - return true; - break; - - case TemplateArgument::Pack: - assert(0 && "FIXME: Implement!"); - break; - } +static bool isDependent(const TemplateArgument &Arg) { + switch (Arg.getKind()) { + case TemplateArgument::Null: + assert(false && "Should not have a NULL template argument"); + return false; + + case TemplateArgument::Type: + return Arg.getAsType()->isDependentType(); + + case TemplateArgument::Declaration: + case TemplateArgument::Integral: + // Never dependent + return false; + + case TemplateArgument::Expression: + return (Arg.getAsExpr()->isTypeDependent() || + Arg.getAsExpr()->isValueDependent()); + + case TemplateArgument::Pack: + assert(0 && "FIXME: Implement!"); + return false; } return false; } +bool TemplateSpecializationType:: +anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) { + for (unsigned i = 0; i != N; ++i) + if (isDependent(Args[i].getArgument())) + return true; + return false; +} + +bool TemplateSpecializationType:: +anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) { + for (unsigned i = 0; i != N; ++i) + if (isDependent(Args[i])) + return true; + return false; +} + TemplateSpecializationType:: TemplateSpecializationType(ASTContext &Context, TemplateName T, const TemplateArgument *Args, @@ -1260,6 +1268,38 @@ void SubstTemplateTypeParmType::getAsStringInternal(std::string &InnerString, co getReplacementType().getAsStringInternal(InnerString, Policy); } +static void PrintTemplateArgument(std::string &Buffer, + const TemplateArgument &Arg, + const PrintingPolicy &Policy) { + switch (Arg.getKind()) { + case TemplateArgument::Null: + assert(false && "Null template argument"); + break; + + case TemplateArgument::Type: + Arg.getAsType().getAsStringInternal(Buffer, Policy); + break; + + case TemplateArgument::Declaration: + Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString(); + break; + + case TemplateArgument::Integral: + Buffer = Arg.getAsIntegral()->toString(10, true); + break; + + case TemplateArgument::Expression: { + llvm::raw_string_ostream s(Buffer); + Arg.getAsExpr()->printPretty(s, 0, Policy); + break; + } + + case TemplateArgument::Pack: + assert(0 && "FIXME: Implement!"); + break; + } +} + std::string TemplateSpecializationType::PrintTemplateArgumentList( const TemplateArgument *Args, @@ -1273,32 +1313,41 @@ TemplateSpecializationType::PrintTemplateArgumentList( // Print the argument into a string. std::string ArgString; - switch (Args[Arg].getKind()) { - case TemplateArgument::Null: - assert(false && "Null template argument"); - break; - - case TemplateArgument::Type: - Args[Arg].getAsType().getAsStringInternal(ArgString, Policy); - break; - - case TemplateArgument::Declaration: - ArgString = cast<NamedDecl>(Args[Arg].getAsDecl())->getNameAsString(); - break; - - case TemplateArgument::Integral: - ArgString = Args[Arg].getAsIntegral()->toString(10, true); - break; - - case TemplateArgument::Expression: { - llvm::raw_string_ostream s(ArgString); - Args[Arg].getAsExpr()->printPretty(s, 0, Policy); - break; - } - case TemplateArgument::Pack: - assert(0 && "FIXME: Implement!"); - break; - } + PrintTemplateArgument(ArgString, Args[Arg], Policy); + + // If this is the first argument and its string representation + // begins with the global scope specifier ('::foo'), add a space + // to avoid printing the diagraph '<:'. + if (!Arg && !ArgString.empty() && ArgString[0] == ':') + SpecString += ' '; + + SpecString += ArgString; + } + + // If the last character of our string is '>', add another space to + // keep the two '>''s separate tokens. We don't *have* to do this in + // C++0x, but it's still good hygiene. + if (SpecString[SpecString.size() - 1] == '>') + SpecString += ' '; + + SpecString += '>'; + + return SpecString; +} + +// Sadly, repeat all that with TemplateArgLoc. +std::string TemplateSpecializationType:: +PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs, + const PrintingPolicy &Policy) { + std::string SpecString; + SpecString += '<'; + for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { + if (Arg) + SpecString += ", "; + + // Print the argument into a string. + std::string ArgString; + PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy); // If this is the first argument and its string representation // begins with the global scope specifier ('::foo'), add a space diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 9c6059b1c7..26f426ba32 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -32,6 +32,7 @@ #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/ErrorHandling.h" #include <algorithm> #include <iterator> #include <cstdio> @@ -2104,7 +2105,13 @@ void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc( } void TypeLocReader::VisitTemplateSpecializationTypeLoc( TemplateSpecializationTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) + TL.setArgLocInfo(i, + Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(), + Record, Idx)); } void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) { TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); @@ -2197,6 +2204,25 @@ QualType PCHReader::GetType(pch::TypeID ID) { return TypesLoaded[Index].withFastQualifiers(FastQuals); } +TemplateArgumentLocInfo +PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, + const RecordData &Record, + unsigned &Index) { + switch (Kind) { + case TemplateArgument::Expression: + return ReadDeclExpr(); + case TemplateArgument::Type: + return GetDeclaratorInfo(Record, Index); + case TemplateArgument::Null: + case TemplateArgument::Integral: + case TemplateArgument::Declaration: + case TemplateArgument::Pack: + return TemplateArgumentLocInfo(); + } + llvm::llvm_unreachable("unexpected template argument loc"); + return TemplateArgumentLocInfo(); +} + Decl *PCHReader::GetDecl(pch::DeclID ID) { if (ID == 0) return 0; diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 4c733db1a0..de56166125 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -368,7 +368,11 @@ void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc( } void TypeLocWriter::VisitTemplateSpecializationTypeLoc( TemplateSpecializationTypeLoc TL) { - Writer.AddSourceLocation(TL.getNameLoc(), Record); + Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record); + Writer.AddSourceLocation(TL.getLAngleLoc(), Record); + Writer.AddSourceLocation(TL.getRAngleLoc(), Record); + for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) + Writer.AddTemplateArgumentLoc(TL.getArgLoc(i), Record); } void TypeLocWriter::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); @@ -2105,6 +2109,23 @@ void PCHWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) { Record.push_back(SID); } +void PCHWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, + RecordData &Record) { + switch (Arg.getArgument().getKind()) { + case TemplateArgument::Expression: + AddStmt(Arg.getLocInfo().getAsExpr()); + break; + case TemplateArgument::Type: + AddDeclaratorInfo(Arg.getLocInfo().getAsDeclaratorInfo(), Record); + break; + case TemplateArgument::Null: + case TemplateArgument::Integral: + case TemplateArgument::Declaration: + case TemplateArgument::Pack: + break; + } +} + void PCHWriter::AddDeclaratorInfo(DeclaratorInfo *DInfo, RecordData &Record) { if (DInfo == 0) { AddTypeRef(QualType(), Record); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 66ee81833e..11a3938544 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -73,6 +73,7 @@ namespace clang { class TypedefDecl; class TemplateDecl; class TemplateArgument; + class TemplateArgumentLoc; class TemplateArgumentList; class TemplateParameterList; class TemplateTemplateParmDecl; @@ -866,7 +867,7 @@ public: bool ForceRValue = false); void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, bool HasExplicitTemplateArgs, - const TemplateArgument *ExplicitTemplateArgs, + const TemplateArgumentLoc *ExplicitTemplateArgs, unsigned NumExplicitTemplateArgs, Expr *Object, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, @@ -874,7 +875,7 @@ public: bool ForceRValue = false); void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, bool HasExplicitTemplateArgs, - const TemplateArgument *ExplicitTemplateArgs, + const TemplateArgumentLoc *ExplicitTemplateArgs, unsigned NumExplicitTemplateArgs, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, @@ -912,7 +913,7 @@ public: void AddArgumentDependentLookupCandidates(DeclarationName Name, Expr **Args, unsigned NumArgs, bool HasExplicitTemplateArgs, - const TemplateArgument *ExplicitTemplateArgs, + const TemplateArgumentLoc *ExplicitTemplateArgs, unsigned NumExplicitTemplateArgs, OverloadCandidateSet& CandidateSet, bool PartialOverloading = false); @@ -934,7 +935,7 @@ public: DeclarationName &UnqualifiedName, bool &ArgumentDependentLookup, bool HasExplicitTemplateArgs, - const TemplateArgument *ExplicitTemplateArgs, + const TemplateArgumentLoc *ExplicitTemplateArgs, unsigned NumExplicitTemplateArgs, Expr **Args, unsigned NumArgs, OverloadCandidateSet &CandidateSet, @@ -943,7 +944,7 @@ public: FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, DeclarationName UnqualifiedName, bool HasExplicitTemplateArgs, - const TemplateArgument *ExplicitTemplateArgs, + const TemplateArgumentLoc *ExplicitTemplateArgs, unsigned NumExplicitTemplateArgs, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, @@ -1708,7 +1709,7 @@ public: DeclarationName MemberName, bool HasExplicitTemplateArgs, SourceLocation LAngleLoc, - const TemplateArgument *ExplicitTemplateArgs, + |