From 5093578471ff811af5c512093b422daeee30444f Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Sat, 5 Mar 2011 14:42:21 +0000 Subject: [PATCH] Improved MemberPointerType source locations. llvm-svn: 127085 --- clang/include/clang/AST/TypeLoc.h | 28 +++++++++++++++- clang/lib/Sema/SemaType.cpp | 48 +++++++++++++++++++++++++-- clang/lib/Sema/TreeTransform.h | 30 ++++++++++++----- clang/lib/Serialization/ASTReader.cpp | 1 + clang/lib/Serialization/ASTWriter.cpp | 1 + 5 files changed, 95 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index fe184bb6c849..8a0b650947d0 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -943,10 +943,14 @@ public: } }; +struct MemberPointerLocInfo : public PointerLikeLocInfo { + TypeSourceInfo *ClassTInfo; +}; /// \brief Wrapper for source info for member pointers. class MemberPointerTypeLoc : public PointerLikeTypeLoc { + 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. diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index a9e63922471b..dcd61a8d1ae2 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2345,10 +2345,12 @@ namespace { }; class DeclaratorLocFiller : public TypeLocVisitor { + 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(ClsTy) && "Unexpected TypeLoc"); + { + DependentNameTypeLoc DNTLoc = *cast(&ClsTL); + DNTLoc.setKeywordLoc(SourceLocation()); + DNTLoc.setQualifierLoc(NNSLoc.getPrefix()); + DNTLoc.setNameLoc(NNSLoc.getLocalBeginLoc()); + } + break; + + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + if (isa(ClsTy)) { + ElaboratedTypeLoc ETLoc = *cast(&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(); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 9eb7d6350520..1a5a98a23e65 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -3308,23 +3308,34 @@ template QualType TreeTransform::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()) - return QualType(); + 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::TransformMemberPointerType(TypeLocBuilder &TLB, MemberPointerTypeLoc NewTL = TLB.push(Result); NewTL.setSigilLoc(TL.getSigilLoc()); + NewTL.setClassTInfo(NewClsTInfo); return Result; } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 98dd4c2fd662..83b1239b7f31 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -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)); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 78a01e29b7e0..708fafe168d9 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -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);