diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 9927ae7edb..19b0e976b8 100644 --- a/include/clang/AST/TypeLoc.h +++ b/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()); } @@ -1231,18 +1241,75 @@ class DecltypeTypeLoc : public InheritingConcreteTypeLoc { }; -// FIXME: locations for the nested name specifier; at the very least, -// a SourceRange. -class ElaboratedTypeLoc : - public InheritingConcreteTypeLoc { +// FIXME: locations for the nested name specifier should be put in +// NestedNameSpecifier +struct ElaboratedLocInfo { + SourceLocation KeywordLoc; }; -// FIXME: locations for the typename keyword and nested name specifier. -class DependentNameTypeLoc : public InheritingConcreteTypeLoc { +class ElaboratedTypeLoc : public ConcreteTypeLoc { +public: + SourceLocation getKeywordLoc() const { + return this->getLocalData()->KeywordLoc; + } + void setKeywordLoc(SourceLocation Loc) { + this->getLocalData()->KeywordLoc = Loc; + } + + SourceRange getSourceRange() const { + return SourceRange(getKeywordLoc(), getKeywordLoc()); + } + + void initializeLocal(SourceLocation Loc) { + setKeywordLoc(Loc); + } + + TypeLoc getNamedTypeLoc() const { + return getInnerTypeLoc(); + } + + QualType getInnerType() const { + return getTypePtr()->getNamedType(); + } +}; + +// FIXME: locations for the nested name specifier should be put in +// NestedNameSpecifier +struct DependentNameLocInfo { + SourceLocation KeywordLoc; + SourceLocation NameLoc; +}; + +class DependentNameTypeLoc : public ConcreteTypeLoc { +public: + SourceLocation getKeywordLoc() const { + return this->getLocalData()->KeywordLoc; + } + void setKeywordLoc(SourceLocation Loc) { + this->getLocalData()->KeywordLoc = Loc; + } + + SourceLocation getNameLoc() const { + return this->getLocalData()->NameLoc; + } + void setNameLoc(SourceLocation Loc) { + this->getLocalData()->NameLoc = Loc; + } + + SourceRange getSourceRange() const { + return SourceRange(getKeywordLoc(), getNameLoc()); + } + + void initializeLocal(SourceLocation Loc) { + setKeywordLoc(Loc); + setNameLoc(Loc); + } }; } diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index c329f7b64f..4d5c001519 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -2354,12 +2354,13 @@ void TypeLocReader::VisitTemplateSpecializationTypeLoc( Record, Idx)); } void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setKeywordLoc(SourceLocation::getFromRawEncoding(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.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index b323dcf4b8..5d84ca6530 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -396,12 +396,13 @@ void TypeLocWriter::VisitTemplateSpecializationTypeLoc( Writer.AddTemplateArgumentLoc(TL.getArgLoc(i), Record); } void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { - Writer.AddSourceLocation(TL.getNameLoc(), Record); + Writer.AddSourceLocation(TL.getKeywordLoc(), Record); } void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { + Writer.AddSourceLocation(TL.getKeywordLoc(), Record); Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 9009b4d897..d8b00cc816 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -5184,16 +5184,18 @@ 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) { + // FIXME: qualifier range + TL.setKeywordLoc(TypenameLoc); + TL.setNameLoc(NameLoc); } static void FillTypeLoc(ElaboratedTypeLoc TL, SourceLocation TypenameLoc, SourceRange QualifierRange) { - // FIXME: typename, qualifier range - TL.setNameLoc(TypenameLoc); + // FIXME: qualifier range and inner locations. + TL.setKeywordLoc(TypenameLoc); } Sema::TypeResult @@ -5213,7 +5215,7 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, if (isa(T)) { DependentNameTypeLoc TL = cast(TSI->getTypeLoc()); // FIXME: fill inner type loc - FillTypeLoc(TL, TypenameLoc, SS.getRange()); + FillTypeLoc(TL, TypenameLoc, SS.getRange(), IdLoc); } else { ElaboratedTypeLoc TL = cast(TSI->getTypeLoc()); // FIXME: fill inner type loc @@ -5249,7 +5251,7 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); DependentNameTypeLoc TL = cast(TSI->getTypeLoc()); // FIXME: fill inner type loc - FillTypeLoc(TL, TypenameLoc, SS.getRange()); + FillTypeLoc(TL, TypenameLoc, SS.getRange(), TemplateLoc); return CreateLocInfoType(T, TSI).getAsOpaquePtr(); } @@ -5426,13 +5428,41 @@ CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB, } else Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, T->getIdentifier(), - SourceRange(TL.getNameLoc())); + TL.getSourceRange()); if (Result.isNull()) return QualType(); - DependentNameTypeLoc NewTL = TLB.push(Result); - NewTL.setNameLoc(TL.getNameLoc()); + if (const ElaboratedType* ElabT = Result->getAs()) { + QualType NamedT = ElabT->getNamedType(); + if (isa(NamedT)) { + TypedefTypeLoc NamedTLoc = TLB.push(NamedT); + NamedTLoc.setNameLoc(TL.getNameLoc()); + } + else if (isa(NamedT)) { + RecordTypeLoc NamedTLoc = TLB.push(NamedT); + NamedTLoc.setNameLoc(TL.getNameLoc()); + } + else if (isa(NamedT)) { + EnumTypeLoc NamedTLoc = TLB.push(NamedT); + NamedTLoc.setNameLoc(TL.getNameLoc()); + } + else if (isa(NamedT)) { + TemplateSpecializationTypeLoc NamedTLoc + = TLB.push(NamedT); + // FIXME: fill locations + NamedTLoc.initializeLocal(SourceLocation()); + } + else + llvm_unreachable("Unexpected type"); + ElaboratedTypeLoc NewTL = TLB.push(Result); + NewTL.setKeywordLoc(TL.getKeywordLoc()); + } + else { + DependentNameTypeLoc NewTL = TLB.push(Result); + NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setNameLoc(TL.getNameLoc()); + } return Result; } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index d926b9b61f..84348f1475 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1455,9 +1455,15 @@ namespace { return; } - TemplateSpecializationTypeLoc OldTL = - cast(TInfo->getTypeLoc()); - TL.copy(OldTL); + TypeLoc OldTL = TInfo->getTypeLoc(); + if (TInfo->getType()->getAs()) { + ElaboratedTypeLoc ElabTL = cast(OldTL); + TemplateSpecializationTypeLoc NamedTL = + cast(ElabTL.getNamedTypeLoc()); + TL.copy(NamedTL); + } + else + TL.copy(cast(OldTL)); } void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr); @@ -1488,6 +1494,23 @@ namespace { TL.setBuiltinLoc(DS.getTypeSpecWidthLoc()); } } + void VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { + ElaboratedTypeKeyword Keyword + = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType()); + TL.setKeywordLoc(Keyword != ETK_None + ? DS.getTypeSpecTypeLoc() + : SourceLocation()); + Visit(TL.getNextTypeLoc().getUnqualifiedLoc()); + } + void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { + ElaboratedTypeKeyword Keyword + = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType()); + TL.setKeywordLoc(Keyword != ETK_None + ? DS.getTypeSpecTypeLoc() + : SourceLocation()); + TL.setNameLoc(DS.getTypeSpecTypeLoc()); + } + void VisitTypeLoc(TypeLoc TL) { // FIXME: add other typespec types and change this to an assert. TL.initialize(DS.getTypeSpecTypeLoc()); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 3515261733..4929bf7ba3 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -3247,22 +3247,22 @@ QualType TreeTransform::TransformElaboratedType(TypeLocBuilder &TLB, ElaboratedTypeLoc TL, QualType ObjectType) { + QualType Named = getDerived().TransformType(TLB, TL.getNamedTypeLoc()); + if (Named.isNull()) + return QualType(); + ElaboratedType *T = TL.getTypePtr(); NestedNameSpecifier *NNS = 0; // NOTE: the qualifier in an ElaboratedType is optional. if (T->getQualifier() != 0) { NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(), - SourceRange(), + /* FIXME */ SourceRange(), ObjectType); if (!NNS) return QualType(); } - QualType Named = getDerived().TransformType(T->getNamedType()); - if (Named.isNull()) - return QualType(); - QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || NNS != T->getQualifier() || @@ -3273,7 +3273,7 @@ TreeTransform::TransformElaboratedType(TypeLocBuilder &TLB, } ElaboratedTypeLoc NewTL = TLB.push(Result); - NewTL.setNameLoc(TL.getNameLoc()); + NewTL.setKeywordLoc(TL.getKeywordLoc()); return Result; } @@ -3315,9 +3315,36 @@ QualType TreeTransform::TransformDependentNameType(TypeLocBuilder &TLB, if (Result.isNull()) return QualType(); - DependentNameTypeLoc NewTL = TLB.push(Result); - NewTL.setNameLoc(TL.getNameLoc()); - + if (const ElaboratedType* ElabT = Result->getAs()) { + QualType NamedT = ElabT->getNamedType(); + if (isa(NamedT)) { + TypedefTypeLoc NamedTLoc = TLB.push(NamedT); + NamedTLoc.setNameLoc(TL.getNameLoc()); + } + else if (isa(NamedT)) { + RecordTypeLoc NamedTLoc = TLB.push(NamedT); + NamedTLoc.setNameLoc(TL.getNameLoc()); + } + else if (isa(NamedT)) { + EnumTypeLoc NamedTLoc = TLB.push(NamedT); + NamedTLoc.setNameLoc(TL.getNameLoc()); + } + else if (isa(NamedT)) { + TemplateSpecializationTypeLoc NamedTLoc + = TLB.push(NamedT); + // FIXME: fill locations + NamedTLoc.initializeLocal(SourceLocation()); + } + else + llvm_unreachable("Unexpected type"); + ElaboratedTypeLoc NewTL = TLB.push(Result); + NewTL.setKeywordLoc(TL.getKeywordLoc()); + } + else { + DependentNameTypeLoc NewTL = TLB.push(Result); + NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setNameLoc(TL.getNameLoc()); + } return Result; }