Improved MemberPointerType source locations.

llvm-svn: 127085
This commit is contained in:
Abramo Bagnara 2011-03-05 14:42:21 +00:00
parent 369ea3fdb4
commit 5093578471
5 changed files with 95 additions and 13 deletions

View File

@ -943,10 +943,14 @@ public:
}
};
struct MemberPointerLocInfo : public PointerLikeLocInfo {
TypeSourceInfo *ClassTInfo;
};
/// \brief Wrapper for source info for member pointers.
class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
MemberPointerType> {
MemberPointerType,
MemberPointerLocInfo> {
public:
SourceLocation getStarLoc() const {
return getSigilLoc();
@ -954,6 +958,28 @@ public:
void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
const Type *getClass() const {
return getTypePtr()->getClass();
}
TypeSourceInfo *getClassTInfo() const {
return getLocalData()->ClassTInfo;
}
void setClassTInfo(TypeSourceInfo* TI) {
getLocalData()->ClassTInfo = TI;
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
setClassTInfo(0);
}
SourceRange getLocalSourceRange() const {
if (TypeSourceInfo *TI = getClassTInfo())
return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
else
return SourceRange(getStarLoc());
}
};
/// Wraps an ObjCPointerType with source location information.

View File

@ -2345,10 +2345,12 @@ namespace {
};
class DeclaratorLocFiller : public TypeLocVisitor<DeclaratorLocFiller> {
ASTContext &Context;
const DeclaratorChunk &Chunk;
public:
DeclaratorLocFiller(const DeclaratorChunk &Chunk) : Chunk(Chunk) {}
DeclaratorLocFiller(ASTContext &Context, const DeclaratorChunk &Chunk)
: Context(Context), Chunk(Chunk) {}
void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
llvm_unreachable("qualified type locs not expected here!");
@ -2368,8 +2370,48 @@ namespace {
}
void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
assert(Chunk.Kind == DeclaratorChunk::MemberPointer);
const CXXScopeSpec& SS = Chunk.Mem.Scope();
NestedNameSpecifierLoc NNSLoc = SS.getWithLocInContext(Context);
const Type* ClsTy = TL.getClass();
QualType ClsQT = QualType(ClsTy, 0);
TypeSourceInfo *ClsTInfo = Context.CreateTypeSourceInfo(ClsQT, 0);
// Now copy source location info into the type loc component.
TypeLoc ClsTL = ClsTInfo->getTypeLoc();
switch (NNSLoc.getNestedNameSpecifier()->getKind()) {
case NestedNameSpecifier::Identifier:
assert(isa<DependentNameType>(ClsTy) && "Unexpected TypeLoc");
{
DependentNameTypeLoc DNTLoc = *cast<DependentNameTypeLoc>(&ClsTL);
DNTLoc.setKeywordLoc(SourceLocation());
DNTLoc.setQualifierLoc(NNSLoc.getPrefix());
DNTLoc.setNameLoc(NNSLoc.getLocalBeginLoc());
}
break;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
if (isa<ElaboratedType>(ClsTy)) {
ElaboratedTypeLoc ETLoc = *cast<ElaboratedTypeLoc>(&ClsTL);
ETLoc.setKeywordLoc(SourceLocation());
ETLoc.setQualifierLoc(NNSLoc.getPrefix());
TypeLoc NamedTL = ETLoc.getNamedTypeLoc();
NamedTL.initializeFullCopy(NNSLoc.getTypeLoc());
} else {
ClsTL.initializeFullCopy(NNSLoc.getTypeLoc());
}
break;
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
llvm_unreachable("Nested-name-specifier must name a type");
break;
}
// Finally fill in MemberPointerLocInfo fields.
TL.setStarLoc(Chunk.Loc);
// FIXME: nested name specifier
TL.setClassTInfo(ClsTInfo);
}
void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
assert(Chunk.Kind == DeclaratorChunk::Reference);
@ -2440,7 +2482,7 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
}
DeclaratorLocFiller(D.getTypeObject(i)).Visit(CurrTL);
DeclaratorLocFiller(Context, D.getTypeObject(i)).Visit(CurrTL);
CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
}

View File

@ -3308,23 +3308,34 @@ template<typename Derived>
QualType
TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
MemberPointerTypeLoc TL) {
const MemberPointerType *T = TL.getTypePtr();
QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
if (PointeeType.isNull())
return QualType();
// TODO: preserve source information for this.
QualType ClassType
= getDerived().TransformType(QualType(T->getClass(), 0));
if (ClassType.isNull())
TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
TypeSourceInfo* NewClsTInfo = 0;
if (OldClsTInfo) {
NewClsTInfo = getDerived().TransformType(OldClsTInfo);
if (!NewClsTInfo)
return QualType();
}
const MemberPointerType *T = TL.getTypePtr();
QualType OldClsType = QualType(T->getClass(), 0);
QualType NewClsType;
if (NewClsTInfo)
NewClsType = NewClsTInfo->getType();
else {
NewClsType = getDerived().TransformType(OldClsType);
if (NewClsType.isNull())
return QualType();
}
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() ||
PointeeType != T->getPointeeType() ||
ClassType != QualType(T->getClass(), 0)) {
Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType,
NewClsType != OldClsType) {
Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
TL.getStarLoc());
if (Result.isNull())
return QualType();
@ -3332,6 +3343,7 @@ TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
NewTL.setSigilLoc(TL.getSigilLoc());
NewTL.setClassTInfo(NewClsTInfo);
return Result;
}

View File

@ -3401,6 +3401,7 @@ void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
}
void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
TL.setStarLoc(ReadSourceLocation(Record, Idx));
TL.setClassTInfo(Reader.GetTypeSourceInfo(F, Record, Idx));
}
void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
TL.setLBracketLoc(ReadSourceLocation(Record, Idx));

View File

@ -418,6 +418,7 @@ void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
}
void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
Writer.AddSourceLocation(TL.getStarLoc(), Record);
Writer.AddTypeSourceInfo(TL.getClassTInfo(), Record);
}
void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) {
Writer.AddSourceLocation(TL.getLBracketLoc(), Record);