From 0d07eb32decf4480a0a90616c397f0dbe6cce537 Mon Sep 17 00:00:00 2001 From: John McCall Date: Thu, 29 Oct 2009 18:45:58 +0000 Subject: [PATCH] A few TemplateArgumentLoc clean-ups. Try to remember the Expr for a declaration. Provide an API for getting the SourceRange of a TAL and use it judiciously. llvm-svn: 85520 --- clang/include/clang/AST/TemplateBase.h | 49 ++++++++++++-------------- clang/include/clang/AST/TypeLoc.h | 26 ++++++++++++-- clang/lib/AST/TemplateBase.cpp | 14 ++++---- clang/lib/Sema/SemaTemplate.cpp | 14 ++++---- clang/lib/Sema/TreeTransform.h | 38 ++++++++++++++------ 5 files changed, 89 insertions(+), 52 deletions(-) diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index 912bbdfe0c1e..19fd56ff52b1 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -239,7 +239,10 @@ public: /// Location information for a TemplateArgument. struct TemplateArgumentLocInfo { private: - void *Union; + union { + Expr *Expression; + DeclaratorInfo *Declarator; + }; #ifndef NDEBUG enum Kind { @@ -251,39 +254,33 @@ private: public: TemplateArgumentLocInfo() - : Union() #ifndef NDEBUG - , Kind(K_None) + : Kind(K_None) #endif {} TemplateArgumentLocInfo(DeclaratorInfo *DInfo) - : Union(DInfo) + : Declarator(DInfo) #ifndef NDEBUG , Kind(K_DeclaratorInfo) #endif {} TemplateArgumentLocInfo(Expr *E) - : Union(E) + : Expression(E) #ifndef NDEBUG , Kind(K_Expression) #endif {} - /// \brief Returns whether this - bool empty() const { - return Union == NULL; - } - DeclaratorInfo *getAsDeclaratorInfo() const { assert(Kind == K_DeclaratorInfo); - return reinterpret_cast(Union); + return Declarator; } Expr *getAsExpr() const { assert(Kind == K_Expression); - return reinterpret_cast(Union); + return Expression; } #ifndef NDEBUG @@ -293,9 +290,9 @@ public: assert(Kind == K_DeclaratorInfo); break; case TemplateArgument::Expression: + case TemplateArgument::Declaration: assert(Kind == K_Expression); break; - case TemplateArgument::Declaration: case TemplateArgument::Integral: case TemplateArgument::Pack: assert(Kind == K_None); @@ -313,15 +310,14 @@ class TemplateArgumentLoc { TemplateArgument Argument; TemplateArgumentLocInfo LocInfo; - friend class TemplateSpecializationTypeLoc; +public: + TemplateArgumentLoc() {} + TemplateArgumentLoc(const TemplateArgument &Argument, TemplateArgumentLocInfo Opaque) : Argument(Argument), LocInfo(Opaque) { } -public: - TemplateArgumentLoc() {} - TemplateArgumentLoc(const TemplateArgument &Argument, DeclaratorInfo *DInfo) : Argument(Argument), LocInfo(DInfo) { assert(Argument.getKind() == TemplateArgument::Type); @@ -332,15 +328,13 @@ public: assert(Argument.getKind() == TemplateArgument::Expression); } - /// This is a temporary measure. - TemplateArgumentLoc(const TemplateArgument &Argument) - : Argument(Argument), LocInfo() { - assert(Argument.getKind() != TemplateArgument::Expression && - Argument.getKind() != TemplateArgument::Type); + /// \brief - Fetches the start location of the argument. + SourceLocation getLocation() const { + return getSourceRange().getBegin(); } - /// \brief - Fetches the start location of the argument, if possible. - SourceLocation getLocation() const; + /// \brief - Fetches the full source range of the argument. + SourceRange getSourceRange() const; const TemplateArgument &getArgument() const { return Argument; @@ -352,13 +346,16 @@ public: DeclaratorInfo *getSourceDeclaratorInfo() const { assert(Argument.getKind() == TemplateArgument::Type); - if (LocInfo.empty()) return 0; return LocInfo.getAsDeclaratorInfo(); } Expr *getSourceExpression() const { assert(Argument.getKind() == TemplateArgument::Expression); - if (LocInfo.empty()) return 0; + return LocInfo.getAsExpr(); + } + + Expr *getSourceDeclExpression() const { + assert(Argument.getKind() == TemplateArgument::Declaration); return LocInfo.getAsExpr(); } }; diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index b4e3fc4179cb..b544bc37e861 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -900,8 +900,30 @@ public: setRAngleLoc(Loc); setTemplateNameLoc(Loc); - for (unsigned i = 0, e = getNumArgs(); i != e; ++i) - getArgInfos()[i] = TemplateArgumentLocInfo(); + for (unsigned i = 0, e = getNumArgs(); i != e; ++i) { + TemplateArgumentLocInfo Info; +#ifndef NDEBUG + // If asserts are enabled, be sure to initialize the argument + // loc with the right kind of pointer. + switch (getTypePtr()->getArg(i).getKind()) { + case TemplateArgument::Expression: + case TemplateArgument::Declaration: + Info = TemplateArgumentLocInfo((Expr*) 0); + break; + + case TemplateArgument::Type: + Info = TemplateArgumentLocInfo((DeclaratorInfo*) 0); + break; + + case TemplateArgument::Integral: + case TemplateArgument::Pack: + case TemplateArgument::Null: + // K_None is fine. + break; + } +#endif + getArgInfos()[i] = Info; + } } unsigned getExtraLocalDataSize() const { diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index b136fe0d3823..94e1ca1e06e7 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -78,20 +78,20 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, // TemplateArgumentLoc Implementation //===----------------------------------------------------------------------===// -SourceLocation TemplateArgumentLoc::getLocation() const { +SourceRange TemplateArgumentLoc::getSourceRange() const { switch (Argument.getKind()) { case TemplateArgument::Expression: - return getSourceExpression()->getExprLoc(); - case TemplateArgument::Type: - return getSourceDeclaratorInfo()-> - getTypeLoc().getFullSourceRange().getBegin(); + return getSourceExpression()->getSourceRange(); case TemplateArgument::Declaration: + return getSourceDeclExpression()->getSourceRange(); + case TemplateArgument::Type: + return getSourceDeclaratorInfo()->getTypeLoc().getFullSourceRange(); case TemplateArgument::Integral: case TemplateArgument::Pack: case TemplateArgument::Null: - return SourceLocation(); + return SourceRange(); } // Silence bonus gcc warning. - return SourceLocation(); + return SourceRange(); } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index a2883fa9804f..fb5eef276058 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1425,7 +1425,8 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, // We have a template type parameter but the template argument // is not a type. - Diag(AL.getLocation(), diag::err_template_arg_must_be_type); + SourceRange SR = AL.getSourceRange(); + Diag(SR.getBegin(), diag::err_template_arg_must_be_type) << SR; Diag(Param->getLocation(), diag::note_template_param_here); return true; @@ -1558,8 +1559,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, break; // FIXME: Subst default argument - // FIXME: preserve source information - Arg = TemplateArgumentLoc(TemplateArgument(TempParm->getDefaultArgument())); + Arg = TemplateArgumentLoc(TemplateArgument(TempParm->getDefaultArgument()), + TempParm->getDefaultArgument()); } } else { // Retrieve the template argument produced by the user. @@ -1646,11 +1647,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // We warn specifically about this case, since it can be rather // confusing for users. QualType T = Arg.getArgument().getAsType(); + SourceRange SR = Arg.getSourceRange(); if (T->isFunctionType()) - Diag(Arg.getLocation(), diag::err_template_arg_nontype_ambig) - << T; + Diag(SR.getBegin(), diag::err_template_arg_nontype_ambig) + << SR << T; else - Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr); + Diag(SR.getBegin(), diag::err_template_arg_must_be_expr) << SR; Diag((*Param)->getLocation(), diag::note_template_param_here); Invalid = true; break; diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index cb7b69fc95d2..04bec726c016 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1919,7 +1919,7 @@ void TreeTransform::InventTemplateArgumentLoc( case TemplateArgument::Declaration: case TemplateArgument::Integral: case TemplateArgument::Pack: - Output = TemplateArgumentLoc(Arg); + Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo()); break; } } @@ -1956,7 +1956,20 @@ bool TreeTransform::TransformTemplateArgument( Decl *D = getDerived().TransformDecl(Arg.getAsDecl()); if (!D) return true; - Output = TemplateArgumentLoc(TemplateArgument(D)); + Expr *SourceExpr = Input.getSourceDeclExpression(); + if (SourceExpr) { + EnterExpressionEvaluationContext Unevaluated(getSema(), + Action::Unevaluated); + Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr); + if (E.isInvalid()) + SourceExpr = NULL; + else { + SourceExpr = E.takeAs(); + SourceExpr->Retain(); + } + } + + Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr); return false; } @@ -1973,6 +1986,7 @@ bool TreeTransform::TransformTemplateArgument( if (E.isInvalid()) return true; Expr *ETaken = E.takeAs(); + ETaken->Retain(); Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken); return false; } @@ -1987,18 +2001,18 @@ bool TreeTransform::TransformTemplateArgument( // FIXME: preserve source information here when we start // caring about parameter packs. - TemplateArgumentLoc Input; - TemplateArgumentLoc Output; - getDerived().InventTemplateArgumentLoc(*A, Input); - if (getDerived().TransformTemplateArgument(Input, Output)) + TemplateArgumentLoc InputArg; + TemplateArgumentLoc OutputArg; + getDerived().InventTemplateArgumentLoc(*A, InputArg); + if (getDerived().TransformTemplateArgument(InputArg, OutputArg)) return true; - TransformedArgs.push_back(Output.getArgument()); + TransformedArgs.push_back(OutputArg.getArgument()); } TemplateArgument Result; Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(), true); - Output = TemplateArgumentLoc(Result); + Output = TemplateArgumentLoc(Result, Input.getLocInfo()); return false; } } @@ -2764,9 +2778,11 @@ QualType TreeTransform::TransformTemplateSpecializationType( TemplateSpecializationTypeLoc TL = TLB.push(QualType(TST, 0)); - TL.setTemplateNameLoc(getDerived().getBaseLocation()); - TL.setLAngleLoc(SourceLocation()); - TL.setRAngleLoc(SourceLocation()); + SourceLocation BaseLoc = getDerived().getBaseLocation(); + + TL.setTemplateNameLoc(BaseLoc); + TL.setLAngleLoc(BaseLoc); + TL.setRAngleLoc(BaseLoc); for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) { const TemplateArgument &TA = TST->getArg(i); TemplateArgumentLoc TAL;