Teach TemplateSpecializationTypeLoc::initializeArgLocs() to actually

generate meaningful [*] template argument location information.

[*] Well, as meaningful as possible, given that this entire code path
is a hack for when we've lost type-source information.

llvm-svn: 124211
This commit is contained in:
Douglas Gregor 2011-01-25 19:13:18 +00:00
parent 05842dabb8
commit 2d525f08c2
6 changed files with 78 additions and 43 deletions

View File

@ -20,6 +20,7 @@
#include "clang/Basic/Specifiers.h"
namespace clang {
class ASTContext;
class ParmVarDecl;
class TypeSourceInfo;
class UnqualTypeLoc;
@ -126,8 +127,8 @@ public:
///
/// This method exists to provide a simple transition for code that
/// relies on location-less types.
void initialize(SourceLocation Loc) const {
initializeImpl(*this, Loc);
void initialize(ASTContext &Context, SourceLocation Loc) const {
initializeImpl(Context, *this, Loc);
}
/// \brief Initializes this by copying its information from another
@ -158,7 +159,7 @@ public:
static bool classof(const TypeLoc *TL) { return true; }
private:
static void initializeImpl(TypeLoc TL, SourceLocation Loc);
static void initializeImpl(ASTContext &Context, TypeLoc TL, SourceLocation Loc);
static TypeLoc getNextTypeLocImpl(TypeLoc TL);
static TypeLoc IgnoreParensImpl(TypeLoc TL);
static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
@ -207,7 +208,7 @@ public:
/// Initializes the local data of this type source info block to
/// provide no information.
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
// do nothing
}
@ -407,7 +408,7 @@ public:
SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setNameLoc(Loc);
}
@ -508,7 +509,7 @@ public:
getWrittenBuiltinSpecs().ModeAttr = written;
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setBuiltinLoc(Loc);
if (needsExtraLocalData()) {
WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
@ -707,7 +708,7 @@ public:
return range;
}
void initializeLocal(SourceLocation loc) {
void initializeLocal(ASTContext &Context, SourceLocation loc) {
setAttrNameLoc(loc);
if (hasAttrExprOperand()) {
setAttrOperandParensRange(SourceRange(loc));
@ -793,7 +794,7 @@ public:
return SourceRange(getLAngleLoc(), getRAngleLoc());
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setHasBaseTypeAsWritten(true);
setLAngleLoc(Loc);
setRAngleLoc(Loc);
@ -837,7 +838,7 @@ public:
return SourceRange(getNameLoc());
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setNameLoc(Loc);
}
};
@ -868,7 +869,7 @@ public:
return SourceRange(getLParenLoc(), getRParenLoc());
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setLParenLoc(Loc);
setRParenLoc(Loc);
}
@ -907,7 +908,7 @@ public:
return SourceRange(getSigilLoc(), getSigilLoc());
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
}
@ -1058,7 +1059,7 @@ public:
return SourceRange(getLParenLoc(), getRParenLoc());
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setLParenLoc(Loc);
setRParenLoc(Loc);
setTrailingReturn(false);
@ -1132,7 +1133,7 @@ public:
return SourceRange(getLBracketLoc(), getRBracketLoc());
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setLBracketLoc(Loc);
setRBracketLoc(Loc);
setSizeExpr(NULL);
@ -1234,24 +1235,18 @@ public:
return SourceRange(getTemplateNameLoc(), getRAngleLoc());
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setLAngleLoc(Loc);
setRAngleLoc(Loc);
setTemplateNameLoc(Loc);
initializeArgLocs(getNumArgs(), getTypePtr()->getArgs(),
initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
getArgInfos(), Loc);
}
static void initializeArgLocs(unsigned NumArgs,
static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
const TemplateArgument *Args,
TemplateArgumentLocInfo *ArgInfos,
SourceLocation Loc) {
for (unsigned i = 0, e = NumArgs; i != e; ++i) {
// FIXME: We can generate better location info here for type arguments,
// template template arguments, and template template pack expansions (?).
ArgInfos[i] = TemplateArgumentLocInfo();
}
}
SourceLocation Loc);
unsigned getExtraLocalDataSize() const {
return getNumArgs() * sizeof(TemplateArgumentLocInfo);
@ -1346,7 +1341,7 @@ public:
return SourceRange(getTypeofLoc(), getRParenLoc());
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setTypeofLoc(Loc);
setLParenLoc(Loc);
setRParenLoc(Loc);
@ -1420,7 +1415,7 @@ public:
return getQualifierRange();
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
}
@ -1485,7 +1480,7 @@ public:
memcpy(Data, Loc.Data, size);
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
setNameLoc(Loc);
@ -1569,13 +1564,13 @@ public:
memcpy(Data, Loc.Data, size);
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
setNameLoc(Loc);
setLAngleLoc(Loc);
setRAngleLoc(Loc);
TemplateSpecializationTypeLoc::initializeArgLocs(getNumArgs(),
TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
getTypePtr()->getArgs(),
getArgInfos(), Loc);
}
@ -1611,7 +1606,7 @@ public:
return SourceRange(getEllipsisLoc(), getEllipsisLoc());
}
void initializeLocal(SourceLocation Loc) {
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setEllipsisLoc(Loc);
}

View File

@ -1127,7 +1127,7 @@ TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T,
TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T,
SourceLocation L) const {
TypeSourceInfo *DI = CreateTypeSourceInfo(T);
DI->getTypeLoc().initialize(L);
DI->getTypeLoc().initialize(const_cast<ASTContext &>(*this), L);
return DI;
}

View File

@ -77,14 +77,15 @@ TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
/// \brief Initializes a type location, and all of its children
/// recursively, as if the entire tree had been written in the
/// given location.
void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) {
void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,
SourceLocation Loc) {
while (true) {
switch (TL.getTypeLocClass()) {
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
case CLASS: { \
CLASS##TypeLoc TLCasted = cast<CLASS##TypeLoc>(TL); \
TLCasted.initializeLocal(Loc); \
TLCasted.initializeLocal(Context, Loc); \
TL = TLCasted.getNextTypeLoc(); \
if (!TL) return; \
continue; \
@ -229,3 +230,38 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
TL = PTL->getInnerLoc();
return TL;
}
void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context,
unsigned NumArgs,
const TemplateArgument *Args,
TemplateArgumentLocInfo *ArgInfos,
SourceLocation Loc) {
for (unsigned i = 0, e = NumArgs; i != e; ++i) {
switch (Args[i].getKind()) {
case TemplateArgument::Null:
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
case TemplateArgument::Pack:
case TemplateArgument::Expression:
// FIXME: Can we do better for declarations and integral values?
ArgInfos[i] = TemplateArgumentLocInfo();
break;
case TemplateArgument::Type:
ArgInfos[i] = TemplateArgumentLocInfo(
Context.getTrivialTypeSourceInfo(Args[i].getAsType(),
Loc));
break;
case TemplateArgument::Template:
ArgInfos[i] = TemplateArgumentLocInfo(SourceRange(Loc), Loc,
SourceLocation());
break;
case TemplateArgument::TemplateExpansion:
ArgInfos[i] = TemplateArgumentLocInfo(SourceRange(Loc), Loc, Loc);
break;
}
}
}

View File

@ -5901,7 +5901,8 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
if (InnerTSI)
Builder.pushFullCopy(InnerTSI->getTypeLoc());
else
Builder.push<TemplateSpecializationTypeLoc>(T).initialize(TemplateLoc);
Builder.push<TemplateSpecializationTypeLoc>(T).initialize(Context,
TemplateLoc);
/* Note: NNS already embedded in template specialization type T. */
T = Context.getElaboratedType(ETK_Typename, /*NNS=*/0, T);
@ -5937,7 +5938,8 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
for (unsigned I = 0, E = TST->getNumArgs(); I != E; ++I)
TL.setArgLocInfo(I, TSTL.getArgLocInfo(I));
} else {
TL.initializeLocal(SourceLocation());
// FIXME: Poor source-location information here.
TL.initializeLocal(Context, TemplateLoc);
}
TL.setKeywordLoc(TypenameLoc);
TL.setQualifierRange(SS.getRange());

View File

@ -1972,10 +1972,12 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
namespace {
class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
ASTContext &Context;
const DeclSpec &DS;
public:
TypeSpecLocFiller(const DeclSpec &DS) : DS(DS) {}
TypeSpecLocFiller(ASTContext &Context, const DeclSpec &DS)
: Context(Context), DS(DS) {}
void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
Visit(TL.getUnqualifiedLoc());
@ -1990,7 +1992,7 @@ namespace {
// Handle the base type, which might not have been written explicitly.
if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
TL.setHasBaseTypeAsWritten(false);
TL.getBaseLoc().initialize(SourceLocation());
TL.getBaseLoc().initialize(Context, SourceLocation());
} else {
TL.setHasBaseTypeAsWritten(true);
Visit(TL.getBaseLoc());
@ -2021,7 +2023,7 @@ namespace {
// If we got no declarator info from previous Sema routines,
// just fill with the typespec loc.
if (!TInfo) {
TL.initialize(DS.getTypeSpecTypeLoc());
TL.initialize(Context, DS.getTypeSpecTypeLoc());
return;
}
@ -2114,7 +2116,7 @@ namespace {
return;
}
}
TL.initializeLocal(SourceLocation());
TL.initializeLocal(Context, SourceLocation());
TL.setKeywordLoc(Keyword != ETK_None
? DS.getTypeSpecTypeLoc()
: SourceLocation());
@ -2126,7 +2128,7 @@ namespace {
void VisitTypeLoc(TypeLoc TL) {
// FIXME: add other typespec types and change this to an assert.
TL.initialize(DS.getTypeSpecTypeLoc());
TL.initialize(Context, DS.getTypeSpecTypeLoc());
}
};
@ -2231,7 +2233,7 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize());
} else {
TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
TypeSpecLocFiller(Context, D.getDeclSpec()).Visit(CurrTL);
}
return TInfo;

View File

@ -2980,8 +2980,8 @@ QualType TreeTransform<Derived>::TransformType(QualType T) {
// Temporary workaround. All of these transformations should
// eventually turn into transformations on TypeLocs.
TypeSourceInfo *DI = getSema().Context.CreateTypeSourceInfo(T);
DI->getTypeLoc().initialize(getDerived().getBaseLocation());
TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
getDerived().getBaseLocation());
TypeSourceInfo *NewDI = getDerived().TransformType(DI);
@ -3073,7 +3073,7 @@ TreeTransform<Derived>::TransformTypeInObjectScope(QualType T,
return T;
TypeSourceInfo *TSI =
SemaRef.Context.getTrivialTypeSourceInfo(T, getBaseLocation());
SemaRef.Context.getTrivialTypeSourceInfo(T, getDerived().getBaseLocation());
TSI = getDerived().TransformTypeInObjectScope(TSI, ObjectType,
UnqualLookup, Prefix);