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
This commit is contained in:
John McCall 2009-10-29 18:45:58 +00:00
parent 94f8f87890
commit 0d07eb32de
5 changed files with 89 additions and 52 deletions

View File

@ -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<DeclaratorInfo*>(Union);
return Declarator;
}
Expr *getAsExpr() const {
assert(Kind == K_Expression);
return reinterpret_cast<Expr*>(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();
}
};

View File

@ -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 {

View File

@ -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();
}

View File

@ -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;

View File

@ -1919,7 +1919,7 @@ void TreeTransform<Derived>::InventTemplateArgumentLoc(
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
case TemplateArgument::Pack:
Output = TemplateArgumentLoc(Arg);
Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
break;
}
}
@ -1956,7 +1956,20 @@ bool TreeTransform<Derived>::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<Expr>();
SourceExpr->Retain();
}
}
Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
return false;
}
@ -1973,6 +1986,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
if (E.isInvalid()) return true;
Expr *ETaken = E.takeAs<Expr>();
ETaken->Retain();
Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
return false;
}
@ -1987,18 +2001,18 @@ bool TreeTransform<Derived>::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<Derived>::TransformTemplateSpecializationType(
TemplateSpecializationTypeLoc TL
= TLB.push<TemplateSpecializationTypeLoc>(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;