diff options
author | Abramo Bagnara <abramo.bagnara@gmail.com> | 2010-05-19 21:37:53 +0000 |
---|---|---|
committer | Abramo Bagnara <abramo.bagnara@gmail.com> | 2010-05-19 21:37:53 +0000 |
commit | d754848f10c86d33079756b6a2d27d03a7f49395 (patch) | |
tree | bd13db4aa3e65b67c071a761853a254e7d2e4c33 | |
parent | f633ebd961d6f87f0d974f8ff1ef99fe5e67373f (diff) | |
download | bcm5719-llvm-d754848f10c86d33079756b6a2d27d03a7f49395.tar.gz bcm5719-llvm-d754848f10c86d33079756b6a2d27d03a7f49395.zip |
Added basic source locations to Elaborated and DependentName types.
llvm-svn: 104169
-rw-r--r-- | clang/include/clang/AST/TypeLoc.h | 122 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHReader.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHWriter.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 66 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 54 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 102 |
11 files changed, 297 insertions, 74 deletions
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index ae478c8c8dd..ec9423664e2 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -269,6 +269,16 @@ public: return TypeClass::classof(Ty); } + static bool classof(const TypeLoc *TL) { + return Derived::classofType(TL->getTypePtr()); + } + static bool classof(const UnqualTypeLoc *TL) { + return Derived::classofType(TL->getTypePtr()); + } + static bool classof(const Derived *TL) { + return true; + } + TypeLoc getNextTypeLoc() const { return getNextTypeLoc(asDerived()->getInnerType()); } @@ -1188,18 +1198,110 @@ class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DecltypeType> { }; -// FIXME: locations for the nested name specifier; at the very least, -// a SourceRange. -class ElaboratedTypeLoc : - public InheritingConcreteTypeLoc<TypeSpecTypeLoc, - ElaboratedTypeLoc, - ElaboratedType> { +struct ElaboratedLocInfo { + SourceLocation KeywordLoc; + SourceRange QualifierRange; +}; + +class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + ElaboratedTypeLoc, + ElaboratedType, + ElaboratedLocInfo> { +public: + SourceLocation getKeywordLoc() const { + return this->getLocalData()->KeywordLoc; + } + void setKeywordLoc(SourceLocation Loc) { + this->getLocalData()->KeywordLoc = Loc; + } + + SourceRange getQualifierRange() const { + return this->getLocalData()->QualifierRange; + } + void setQualifierRange(SourceRange Range) { + this->getLocalData()->QualifierRange = Range; + } + + SourceRange getSourceRange() const { + if (getKeywordLoc().isValid()) + if (getQualifierRange().getEnd().isValid()) + return SourceRange(getKeywordLoc(), getQualifierRange().getEnd()); + else + return SourceRange(getKeywordLoc()); + else + return getQualifierRange(); + } + + void initializeLocal(SourceLocation Loc) { + setKeywordLoc(Loc); + setQualifierRange(SourceRange(Loc)); + } + + TypeLoc getNamedTypeLoc() const { + return getInnerTypeLoc(); + } + + QualType getInnerType() const { + return getTypePtr()->getNamedType(); + } + + void copy(ElaboratedTypeLoc Loc) { + unsigned size = getFullDataSize(); + assert(size == Loc.getFullDataSize()); + memcpy(Data, Loc.Data, size); + } }; -// FIXME: locations for the typename keyword and nested name specifier. -class DependentNameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, - DependentNameTypeLoc, - DependentNameType> { +struct DependentNameLocInfo { + SourceLocation KeywordLoc; + SourceRange QualifierRange; + SourceLocation NameLoc; +}; + +class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + DependentNameTypeLoc, + DependentNameType, + DependentNameLocInfo> { +public: + SourceLocation getKeywordLoc() const { + return this->getLocalData()->KeywordLoc; + } + void setKeywordLoc(SourceLocation Loc) { + this->getLocalData()->KeywordLoc = Loc; + } + + SourceRange getQualifierRange() const { + return this->getLocalData()->QualifierRange; + } + void setQualifierRange(SourceRange Range) { + this->getLocalData()->QualifierRange = Range; + } + + SourceLocation getNameLoc() const { + return this->getLocalData()->NameLoc; + } + void setNameLoc(SourceLocation Loc) { + this->getLocalData()->NameLoc = Loc; + } + + SourceRange getSourceRange() const { + if (getKeywordLoc().isValid()) + return SourceRange(getKeywordLoc(), getNameLoc()); + else + return SourceRange(getQualifierRange().getBegin(), getNameLoc()); + } + + void copy(DependentNameTypeLoc Loc) { + unsigned size = getFullDataSize(); + assert(size == Loc.getFullDataSize()); + memcpy(Data, Loc.Data, size); + } + + void initializeLocal(SourceLocation Loc) { + setKeywordLoc(Loc); + setQualifierRange(SourceRange(Loc)); + setNameLoc(Loc); + } }; } diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index cca434ea8ba..88e9b9db180 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -2356,12 +2356,15 @@ void TypeLocReader::VisitTemplateSpecializationTypeLoc( Record, Idx)); } void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx)); } void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { + TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx)); TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index f8415cd0529..6887d847e98 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -397,12 +397,15 @@ void TypeLocWriter::VisitTemplateSpecializationTypeLoc( Writer.AddTemplateArgumentLoc(TL.getArgLoc(i), Record); } void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { - Writer.AddSourceLocation(TL.getNameLoc(), Record); + Writer.AddSourceLocation(TL.getKeywordLoc(), Record); + Writer.AddSourceRange(TL.getQualifierRange(), Record); } void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { + Writer.AddSourceLocation(TL.getKeywordLoc(), Record); + Writer.AddSourceRange(TL.getQualifierRange(), Record); Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 929b20cc3d4..ec485d2d964 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1877,7 +1877,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, if (Tok.is(tok::kw___attribute)) Attr.reset(ParseGNUAttributes()); - CXXScopeSpec SS; + CXXScopeSpec &SS = DS.getTypeSpecScope(); if (getLang().CPlusPlus) { if (ParseOptionalCXXScopeSpecifier(SS, 0, false)) return; diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index ed639350e52..4d9463f6523 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -3117,7 +3117,9 @@ public: QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo &II, - SourceRange Range); + SourceLocation KeywordLoc, + SourceRange NNSRange, + SourceLocation IILoc); TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T, SourceLocation Loc, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e0151d31010..30eaee423bd 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -90,8 +90,9 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, // We know from the grammar that this name refers to a type, so build a // DependentNameType node to describe the type. return CheckTypenameType(ETK_None, - (NestedNameSpecifier *)SS->getScopeRep(), - II, SS->getRange()).getAsOpaquePtr(); + (NestedNameSpecifier *)SS->getScopeRep(), II, + SourceLocation(), SS->getRange(), NameLoc + ).getAsOpaquePtr(); } return 0; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7fcc6ea886d..6682c661167 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1136,7 +1136,8 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, // specialization, we take it as a type name. BaseType = CheckTypenameType(ETK_None, (NestedNameSpecifier *)SS.getScopeRep(), - *MemberOrBase, SS.getRange()); + *MemberOrBase, SourceLocation(), + SS.getRange(), IdLoc); if (BaseType.isNull()) return true; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index f38bb1c96db..0737e9f151a 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -261,7 +261,8 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc, Range = SourceRange(NameLoc); } - return CheckTypenameType(ETK_None, NNS, II, Range).getAsOpaquePtr(); + return CheckTypenameType(ETK_None, NNS, II, SourceLocation(), + Range, NameLoc).getAsOpaquePtr(); } if (ObjectTypePtr) diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 9009b4d8977..5c908a00f68 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5184,16 +5184,19 @@ Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, static void FillTypeLoc(DependentNameTypeLoc TL, SourceLocation TypenameLoc, - SourceRange QualifierRange) { - // FIXME: typename, qualifier range - TL.setNameLoc(TypenameLoc); + SourceRange QualifierRange, + SourceLocation NameLoc) { + TL.setKeywordLoc(TypenameLoc); + TL.setQualifierRange(QualifierRange); + TL.setNameLoc(NameLoc); } static void FillTypeLoc(ElaboratedTypeLoc TL, SourceLocation TypenameLoc, SourceRange QualifierRange) { - // FIXME: typename, qualifier range - TL.setNameLoc(TypenameLoc); + // FIXME: inner locations. + TL.setKeywordLoc(TypenameLoc); + TL.setQualifierRange(QualifierRange); } Sema::TypeResult @@ -5205,7 +5208,7 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, return true; QualType T = CheckTypenameType(ETK_Typename, NNS, II, - SourceRange(TypenameLoc, IdLoc)); + TypenameLoc, SS.getRange(), IdLoc); if (T.isNull()) return true; @@ -5213,7 +5216,7 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, if (isa<DependentNameType>(T)) { DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); // FIXME: fill inner type loc - FillTypeLoc(TL, TypenameLoc, SS.getRange()); + FillTypeLoc(TL, TypenameLoc, SS.getRange(), IdLoc); } else { ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc()); // FIXME: fill inner type loc @@ -5249,7 +5252,7 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); // FIXME: fill inner type loc - FillTypeLoc(TL, TypenameLoc, SS.getRange()); + FillTypeLoc(TL, TypenameLoc, SS.getRange(), TemplateLoc); return CreateLocInfoType(T, TSI).getAsOpaquePtr(); } @@ -5258,10 +5261,11 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, QualType Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo &II, - SourceRange Range) { + SourceLocation KeywordLoc, SourceRange NNSRange, + SourceLocation IILoc) { CXXScopeSpec SS; SS.setScopeRep(NNS); - SS.setRange(Range); + SS.setRange(NNSRange); DeclContext *Ctx = computeDeclContext(SS); if (!Ctx) { @@ -5281,7 +5285,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, return QualType(); DeclarationName Name(&II); - LookupResult Result(*this, Name, Range.getEnd(), LookupOrdinaryName); + LookupResult Result(*this, Name, IILoc, LookupOrdinaryName); LookupQualifiedName(Result, Ctx); unsigned DiagID = 0; Decl *Referenced = 0; @@ -5321,7 +5325,9 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, // If we get here, it's because name lookup did not find a // type. Emit an appropriate diagnostic and return an error. - Diag(Range.getEnd(), DiagID) << Range << Name << Ctx; + SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : NNSRange.getBegin(), + IILoc); + Diag(IILoc, DiagID) << FullRange << Name << Ctx; if (Referenced) Diag(Referenced->getLocation(), diag::note_typename_refers_here) << Name; @@ -5393,7 +5399,7 @@ CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB, NestedNameSpecifier *NNS = TransformNestedNameSpecifier(T->getQualifier(), - /*FIXME:*/SourceRange(getBaseLocation()), + TL.getQualifierRange(), ObjectType); if (!NNS) return QualType(); @@ -5402,7 +5408,7 @@ CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB, // context corresponding to the nested-name-specifier, then this // typename type will not change; exit early. CXXScopeSpec SS; - SS.setRange(SourceRange(getBaseLocation())); + SS.setRange(TL.getQualifierRange()); SS.setScopeRep(NNS); QualType Result; @@ -5421,18 +5427,38 @@ CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB, NewTemplateId == QualType(TemplateId, 0)) Result = QualType(T, 0); else - Result = getDerived().RebuildDependentNameType(T->getKeyword(), + Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, NewTemplateId); } else - Result = getDerived().RebuildDependentNameType(T->getKeyword(), - NNS, T->getIdentifier(), - SourceRange(TL.getNameLoc())); + Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, + T->getIdentifier(), + TL.getKeywordLoc(), + TL.getQualifierRange(), + TL.getNameLoc()); if (Result.isNull()) return QualType(); - DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); + if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) { + QualType NamedT = ElabT->getNamedType(); + if (isa<TemplateSpecializationType>(NamedT)) { + TemplateSpecializationTypeLoc NamedTLoc + = TLB.push<TemplateSpecializationTypeLoc>(NamedT); + // FIXME: fill locations + NamedTLoc.initializeLocal(TL.getNameLoc()); + } else { + TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc()); + } + ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); + NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setQualifierRange(TL.getQualifierRange()); + } + else { + DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); + NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setQualifierRange(TL.getQualifierRange()); + NewTL.setNameLoc(TL.getNameLoc()); + } return Result; } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 9ade954375d..80fafb6ad25 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -25,6 +25,8 @@ #include "llvm/Support/ErrorHandling.h" using namespace clang; +#include <iostream> + /// \brief Perform adjustment on the parameter type of a function. /// /// This routine adjusts the given parameter type @p T to the actual @@ -1437,9 +1439,15 @@ namespace { return; } - TemplateSpecializationTypeLoc OldTL = - cast<TemplateSpecializationTypeLoc>(TInfo->getTypeLoc()); - TL.copy(OldTL); + TypeLoc OldTL = TInfo->getTypeLoc(); + if (TInfo->getType()->getAs<ElaboratedType>()) { + ElaboratedTypeLoc ElabTL = cast<ElaboratedTypeLoc>(OldTL); + TemplateSpecializationTypeLoc NamedTL = + cast<TemplateSpecializationTypeLoc>(ElabTL.getNamedTypeLoc()); + TL.copy(NamedTL); + } + else + TL.copy(cast<TemplateSpecializationTypeLoc>(OldTL)); } void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr); @@ -1470,6 +1478,44 @@ namespace { TL.setBuiltinLoc(DS.getTypeSpecWidthLoc()); } } + void VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { + ElaboratedTypeKeyword Keyword + = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType()); + if (Keyword == ETK_Typename) { + TypeSourceInfo *TInfo = 0; + Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo); + if (TInfo) { + TL.copy(cast<ElaboratedTypeLoc>(TInfo->getTypeLoc())); + return; + } + } + TL.setKeywordLoc(Keyword != ETK_None + ? DS.getTypeSpecTypeLoc() + : SourceLocation()); + const CXXScopeSpec& SS = DS.getTypeSpecScope(); + TL.setQualifierRange(SS.isEmpty() ? SourceRange(): SS.getRange()); + Visit(TL.getNextTypeLoc().getUnqualifiedLoc()); + } + void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { + ElaboratedTypeKeyword Keyword + = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType()); + if (Keyword == ETK_Typename) { + TypeSourceInfo *TInfo = 0; + Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo); + if (TInfo) { + TL.copy(cast<DependentNameTypeLoc>(TInfo->getTypeLoc())); + return; + } + } + TL.setKeywordLoc(Keyword != ETK_None + ? DS.getTypeSpecTypeLoc() + : SourceLocation()); + const CXXScopeSpec& SS = DS.getTypeSpecScope(); + TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange()); + // FIXME: load appropriate source location. + TL.setNameLoc(DS.getTypeSpecTypeLoc()); + } + void VisitTypeLoc(TypeLoc TL) { // FIXME: add other typespec types and change this to an assert. TL.initialize(DS.getTypeSpecTypeLoc()); @@ -2081,7 +2127,7 @@ QualType Sema::getElaboratedType(ElaboratedTypeKeyword Keyword, if (T.isNull()) return T; NestedNameSpecifier *NNS; - if (SS.isSet() && !SS.isInvalid()) + if (SS.isValid()) NNS = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); else { if (Keyword == ETK_None) diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index a8120b85cdd..69994cd1d2f 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -530,10 +530,9 @@ public: /// \brief Build a new typename type that refers to a template-id. /// - /// By default, builds a new DependentNameType type from the - /// nested-name-specifier - /// and the given type. Subclasses may override this routine to provide - /// different behavior. + /// By default, builds a new DependentNameType type from the + /// nested-name-specifier and the given type. Subclasses may override + /// this routine to provide different behavior. QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType T) { if (NNS->isDependent()) { @@ -551,15 +550,18 @@ public: /// \brief Build a new typename type that refers to an identifier. /// /// By default, performs semantic analysis when building the typename type - /// (or qualified name type). Subclasses may override this routine to provide + /// (or elaborated type). Subclasses may override this routine to provide /// different behavior. - QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, + QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Id, - SourceRange SR) { + SourceLocation KeywordLoc, + SourceRange NNSRange, + SourceLocation IdLoc) { CXXScopeSpec SS; SS.setScopeRep(NNS); - + SS.setRange(NNSRange); + if (NNS->isDependent()) { // If the name is still dependent, just build a new dependent name type. if (!SemaRef.computeDeclContext(SS)) @@ -567,14 +569,15 @@ public: } if (Keyword == ETK_None || Keyword == ETK_Typename) - return SemaRef.CheckTypenameType(Keyword, NNS, *Id, SR); + return SemaRef.CheckTypenameType(Keyword, NNS, *Id, + KeywordLoc, NNSRange, IdLoc); TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword); - // We had a dependent elaborated-type-specifier that as been transformed + // We had a dependent elaborated-type-specifier that has been transformed // into a non-dependent elaborated-type-specifier. Find the tag we're // referring to. - LookupResult Result(SemaRef, Id, SR.getEnd(), Sema::LookupTagName); + LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName); DeclContext *DC = SemaRef.computeDeclContext(SS, false); if (!DC) return QualType(); @@ -602,14 +605,13 @@ public: if (!Tag) { // FIXME: Would be nice to highlight just the source range. - SemaRef.Diag(SR.getEnd(), diag::err_not_tag_in_scope) + SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope) << Kind << Id << DC; return QualType(); } - // FIXME: Terrible location information - if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, SR.getEnd(), *Id)) { - SemaRef.Diag(SR.getBegin(), diag::err_use_with_wrong_tag) << Id; + if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, IdLoc, *Id)) { + SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id; SemaRef.Diag(Tag->getLocation(), diag::note_previous_use); return QualType(); } @@ -3237,27 +3239,45 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, // NOTE: the qualifier in an ElaboratedType is optional. if (T->getQualifier() != 0) { NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(), - SourceRange(), + TL.getQualifierRange(), ObjectType); if (!NNS) return QualType(); } - QualType Named = getDerived().TransformType(T->getNamedType()); - if (Named.isNull()) - return QualType(); + QualType NamedT; + // FIXME: this test is meant to workaround a problem (failing assertion) + // occurring if directly executing the code in the else branch. + if (isa<TemplateSpecializationTypeLoc>(TL.getNamedTypeLoc())) { + TemplateSpecializationTypeLoc OldNamedTL + = cast<TemplateSpecializationTypeLoc>(TL.getNamedTypeLoc()); + const TemplateSpecializationType* OldTST + = OldNamedTL.getType()->getAs<TemplateSpecializationType>(); + NamedT = TransformTemplateSpecializationType(OldTST, ObjectType); + if (NamedT.isNull()) + return QualType(); + TemplateSpecializationTypeLoc NewNamedTL + = TLB.push<TemplateSpecializationTypeLoc>(NamedT); + NewNamedTL.copy(OldNamedTL); + } + else { + NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc()); + if (NamedT.isNull()) + return QualType(); + } QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || NNS != T->getQualifier() || - Named != T->getNamedType()) { - Result = getDerived().RebuildElaboratedType(T->getKeyword(), NNS, Named); + NamedT != T->getNamedType()) { + Result = getDerived().RebuildElaboratedType(T->getKeyword(), NNS, NamedT); if (Result.isNull()) return QualType(); } ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); + NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setQualifierRange(TL.getQualifierRange()); return Result; } @@ -3268,11 +3288,9 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB, QualType ObjectType) { DependentNameType *T = TL.getTypePtr(); - /* FIXME: preserve source information better than this */ - SourceRange SR(TL.getNameLoc()); - NestedNameSpecifier *NNS - = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR, + = getDerived().TransformNestedNameSpecifier(T->getQualifier(), + TL.getQualifierRange(), ObjectType); if (!NNS) return QualType(); @@ -3290,18 +3308,38 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB, NewTemplateId == QualType(TemplateId, 0)) return QualType(T, 0); - Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, + Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, NewTemplateId); } else { - Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, - T->getIdentifier(), SR); + Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, + T->getIdentifier(), + TL.getKeywordLoc(), + TL.getQualifierRange(), + TL.getNameLoc()); } if (Result.isNull()) return QualType(); - DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - + if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) { + QualType NamedT = ElabT->getNamedType(); + if (isa<TemplateSpecializationType>(NamedT)) { + TemplateSpecializationTypeLoc NamedTLoc + = TLB.push<TemplateSpecializationTypeLoc>(NamedT); + // FIXME: fill locations + NamedTLoc.initializeLocal(TL.getNameLoc()); + } else { + TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc()); + } + ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); + NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setQualifierRange(TL.getQualifierRange()); + } + else { + DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); + NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setQualifierRange(TL.getQualifierRange()); + NewTL.setNameLoc(TL.getNameLoc()); + } return Result; } |