diff options
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 1001 |
1 files changed, 437 insertions, 564 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 6ce5535..1863e7f 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -591,12 +591,12 @@ public: /// By default, transforms the template name by transforming the declarations /// and nested-name-specifiers that occur within the template name. /// Subclasses may override this function to provide alternate behavior. - TemplateName - TransformTemplateName(CXXScopeSpec &SS, TemplateName Name, - SourceLocation NameLoc, - QualType ObjectType = QualType(), - NamedDecl *FirstQualifierInScope = nullptr, - bool AllowInjectedClassName = false); + TemplateName TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc, + SourceLocation TemplateKWLoc, + TemplateName Name, SourceLocation NameLoc, + QualType ObjectType = QualType(), + NamedDecl *FirstQualifierInScope = nullptr, + bool AllowInjectedClassName = false); /// Transform the given template argument. /// @@ -610,9 +610,9 @@ public: TemplateArgumentLoc &Output, bool Uneval = false); - TemplateArgument - TransformNamedTemplateTemplateArgument(CXXScopeSpec &SS, TemplateName Name, - SourceLocation NameLoc); + TemplateArgument TransformNamedTemplateTemplateArgument( + NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc, + TemplateName Name, SourceLocation NameLoc); /// Transform the given set of template arguments. /// @@ -697,20 +697,17 @@ public: StmtResult TransformSEHHandler(Stmt *Handler); - QualType - TransformTemplateSpecializationType(TypeLocBuilder &TLB, - TemplateSpecializationTypeLoc TL, - TemplateName Template); - - QualType - TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, - DependentTemplateSpecializationTypeLoc TL, + QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB, + TemplateSpecializationTypeLoc TL, TemplateName Template, CXXScopeSpec &SS); QualType TransformDependentTemplateSpecializationType( TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL, - CXXScopeSpec &SS); + QualType ObjectType, NamedDecl *UnqualLookup, + bool AllowInjectedClassName); + + QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL); /// Transforms the parameters of a function type into the /// given vectors. @@ -1020,16 +1017,22 @@ public: /// Rebuild an unresolved typename type, given the decl that /// the UnresolvedUsingTypenameDecl was transformed to. - QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D); + QualType RebuildUnresolvedUsingType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier Qualifier, + SourceLocation NameLoc, Decl *D); /// Build a new type found via an alias. - QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) { - return SemaRef.Context.getUsingType(Found, Underlying); + QualType RebuildUsingType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier Qualifier, UsingShadowDecl *D, + QualType UnderlyingType) { + return SemaRef.Context.getUsingType(Keyword, Qualifier, D, UnderlyingType); } /// Build a new typedef type. - QualType RebuildTypedefType(TypedefNameDecl *Typedef) { - return SemaRef.Context.getTypeDeclType(Typedef); + QualType RebuildTypedefType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier Qualifier, + TypedefNameDecl *Typedef) { + return SemaRef.Context.getTypedefType(Keyword, Qualifier, Typedef); } /// Build a new MacroDefined type. @@ -1038,14 +1041,14 @@ public: return SemaRef.Context.getMacroQualifiedType(T, MacroII); } - /// Build a new class/struct/union type. - QualType RebuildRecordType(RecordDecl *Record) { - return SemaRef.Context.getTypeDeclType(Record); + /// Build a new class/struct/union/enum type. + QualType RebuildTagType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier Qualifier, TagDecl *Tag) { + return SemaRef.Context.getTagType(Keyword, Qualifier, Tag, + /*OwnsTag=*/false); } - - /// Build a new Enum type. - QualType RebuildEnumType(EnumDecl *Enum) { - return SemaRef.Context.getTypeDeclType(Enum); + QualType RebuildCanonicalTagType(TagDecl *Tag) { + return SemaRef.Context.getCanonicalTagType(Tag); } /// Build a new typeof(expr) type. @@ -1094,10 +1097,10 @@ public: /// By default, builds a new DeducedTemplateSpecializationType with the given /// deduced type. - QualType RebuildDeducedTemplateSpecializationType(TemplateName Template, - QualType Deduced) { + QualType RebuildDeducedTemplateSpecializationType( + ElaboratedTypeKeyword Keyword, TemplateName Template, QualType Deduced) { return SemaRef.Context.getDeducedTemplateSpecializationType( - Template, Deduced, /*IsDependent*/ false); + Keyword, Template, Deduced, /*IsDependent*/ false); } /// Build a new template specialization type. @@ -1105,7 +1108,8 @@ public: /// By default, performs semantic analysis when building the template /// specialization type. Subclasses may override this routine to provide /// different behavior. - QualType RebuildTemplateSpecializationType(TemplateName Template, + QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword, + TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &Args); @@ -1117,41 +1121,22 @@ public: return SemaRef.BuildParenType(InnerType); } - /// Build a new qualified name type. - /// - /// By default, builds a new ElaboratedType type from the keyword, - /// the nested-name-specifier and the named type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildElaboratedType(SourceLocation KeywordLoc, - ElaboratedTypeKeyword Keyword, - NestedNameSpecifierLoc QualifierLoc, - QualType Named) { - return SemaRef.Context.getElaboratedType(Keyword, - QualifierLoc.getNestedNameSpecifier(), - Named); - } - /// 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. QualType RebuildDependentTemplateSpecializationType( - ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, - SourceLocation TemplateKWLoc, TemplateName Name, SourceLocation NameLoc, - TemplateArgumentListInfo &Args, bool AllowInjectedClassName) { + ElaboratedTypeKeyword Keyword, SourceLocation TemplateKWLoc, + TemplateName Name, SourceLocation NameLoc, TemplateArgumentListInfo &Args, + bool AllowInjectedClassName) { // If it's still dependent, make a dependent specialization. if (const DependentTemplateStorage *S = Name.getAsDependentTemplateName()) return SemaRef.Context.getDependentTemplateSpecializationType( Keyword, *S, Args.arguments()); - // Otherwise, make an elaborated type wrapping a non-dependent - // specialization. - QualType T = - getDerived().RebuildTemplateSpecializationType(Name, NameLoc, Args); - if (T.isNull()) - return QualType(); - return SemaRef.Context.getElaboratedType(Keyword, NNS, T); + return getDerived().RebuildTemplateSpecializationType(Keyword, Name, + NameLoc, Args); } /// Build a new typename type that refers to an identifier. @@ -1168,7 +1153,7 @@ public: CXXScopeSpec SS; SS.Adopt(QualifierLoc); - if (QualifierLoc.getNestedNameSpecifier()->isDependent()) { + if (QualifierLoc.getNestedNameSpecifier().isDependent()) { // If the name is still dependent, just build a new dependent name type. if (!SemaRef.computeDeclContext(SS)) return SemaRef.Context.getDependentNameType(Keyword, @@ -1238,19 +1223,14 @@ public: } return QualType(); } - if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false, IdLoc, Id)) { SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id; SemaRef.Diag(Tag->getLocation(), diag::note_previous_use); return QualType(); } - - // Build the elaborated-type-specifier type. - QualType T = SemaRef.Context.getTypeDeclType(Tag); - return SemaRef.Context.getElaboratedType(Keyword, - QualifierLoc.getNestedNameSpecifier(), - T); + return getDerived().RebuildTagType( + Keyword, QualifierLoc.getNestedNameSpecifier(), Tag); } /// Build a new pack expansion type. @@ -1303,7 +1283,6 @@ public: SourceLocation TemplateKWLoc, const IdentifierInfo &Name, SourceLocation NameLoc, QualType ObjectType, - NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName); /// Build a new template name given a nested name specifier and the @@ -1323,7 +1302,6 @@ public: SourceLocation TemplateKWLoc, IdentifierOrOverloadedOperator IO, SourceLocation NameLoc, QualType ObjectType, - NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName); /// Build a new template name given a template template parameter pack @@ -4012,8 +3990,8 @@ public: SemaRef.Context, TemplateArgument(Pattern.getArgument().getAsTemplate(), NumExpansions), - Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(), - EllipsisLoc); + Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(), + Pattern.getTemplateNameLoc(), EllipsisLoc); case TemplateArgument::Null: case TemplateArgument::Integral: @@ -4258,23 +4236,29 @@ public: } private: - TypeLoc TransformTypeInObjectScope(TypeLoc TL, - QualType ObjectType, - NamedDecl *FirstQualifierInScope, - CXXScopeSpec &SS); + QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL, + QualType ObjectType, + NamedDecl *FirstQualifierInScope); TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo, QualType ObjectType, - NamedDecl *FirstQualifierInScope, - CXXScopeSpec &SS); + NamedDecl *FirstQualifierInScope) { + if (getDerived().AlreadyTransformed(TSInfo->getType())) + return TSInfo; - TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType, - NamedDecl *FirstQualifierInScope, - CXXScopeSpec &SS); + TypeLocBuilder TLB; + QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(), + ObjectType, FirstQualifierInScope); + if (T.isNull()) + return nullptr; + return TLB.getTypeSourceInfo(SemaRef.Context, T); + } QualType TransformDependentNameType(TypeLocBuilder &TLB, DependentNameTypeLoc TL, - bool DeducibleTSTContext); + bool DeducibleTSTContext, + QualType ObjectType = QualType(), + NamedDecl *UnqualLookup = nullptr); llvm::SmallVector<OpenACCClause *> TransformOpenACCClauseList(OpenACCDirectiveKind DirKind, @@ -4603,7 +4587,7 @@ NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc( auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) { for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier; - Qualifier = Qualifier.getPrefix()) + Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix) Qualifiers.push_back(Qualifier); }; insertNNS(NNS); @@ -4611,76 +4595,87 @@ NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc( CXXScopeSpec SS; while (!Qualifiers.empty()) { NestedNameSpecifierLoc Q = Qualifiers.pop_back_val(); - NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier(); - - switch (QNNS->getKind()) { - case NestedNameSpecifier::Identifier: { - Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(), - Q.getLocalBeginLoc(), Q.getLocalEndLoc(), - ObjectType); - if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false, - SS, FirstQualifierInScope, false)) - return NestedNameSpecifierLoc(); - break; - } + NestedNameSpecifier QNNS = Q.getNestedNameSpecifier(); + + switch (QNNS.getKind()) { + case NestedNameSpecifier::Kind::Null: + llvm_unreachable("unexpected null nested name specifier"); - case NestedNameSpecifier::Namespace: { + case NestedNameSpecifier::Kind::Namespace: { auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl( - Q.getLocalBeginLoc(), QNNS->getAsNamespace())); + Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>( + QNNS.getAsNamespaceAndPrefix().Namespace))); SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc()); break; } - case NestedNameSpecifier::Global: + case NestedNameSpecifier::Kind::Global: // There is no meaningful transformation that one could perform on the // global scope. SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc()); break; - case NestedNameSpecifier::Super: { - CXXRecordDecl *RD = - cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( - SourceLocation(), QNNS->getAsRecordDecl())); - SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc()); + case NestedNameSpecifier::Kind::MicrosoftSuper: { + CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>( + getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl())); + SS.MakeMicrosoftSuper(SemaRef.Context, RD, Q.getBeginLoc(), + Q.getEndLoc()); break; } - case NestedNameSpecifier::TypeSpec: { - TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType, - FirstQualifierInScope, SS); - - if (!TL) - return NestedNameSpecifierLoc(); + case NestedNameSpecifier::Kind::Type: { + assert(SS.isEmpty()); + TypeLoc TL = Q.castAsTypeLoc(); + + if (auto DNT = TL.getAs<DependentNameTypeLoc>()) { + NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc(); + if (QualifierLoc) { + QualifierLoc = getDerived().TransformNestedNameSpecifierLoc( + QualifierLoc, ObjectType, FirstQualifierInScope); + if (!QualifierLoc) + return NestedNameSpecifierLoc(); + ObjectType = QualType(); + FirstQualifierInScope = nullptr; + } + SS.Adopt(QualifierLoc); + Sema::NestedNameSpecInfo IdInfo( + const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()), + DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType); + if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, + false, SS, + FirstQualifierInScope, false)) + return NestedNameSpecifierLoc(); + return SS.getWithLocInContext(SemaRef.Context); + } QualType T = TL.getType(); + TypeLocBuilder TLB; + if (!getDerived().AlreadyTransformed(T)) { + T = TransformTypeInObjectScope(TLB, TL, ObjectType, + FirstQualifierInScope); + if (T.isNull()) + return NestedNameSpecifierLoc(); + TL = TLB.getTypeLocInContext(SemaRef.Context, T); + } + if (T->isDependentType() || T->isRecordType() || (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) { if (T->isEnumeralType()) SemaRef.Diag(TL.getBeginLoc(), diag::warn_cxx98_compat_enum_nested_name_spec); - - if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) { - SS.Adopt(ETL.getQualifierLoc()); - TL = ETL.getNamedTypeLoc(); - } - - SS.Extend(SemaRef.Context, TL, Q.getLocalEndLoc()); + SS.Make(SemaRef.Context, TL, Q.getLocalEndLoc()); break; } // If the nested-name-specifier is an invalid type def, don't emit an // error because a previous error should have already been emitted. TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>(); - if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) { + if (!TTL || !TTL.getDecl()->isInvalidDecl()) { SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag) << T << SS.getRange(); } return NestedNameSpecifierLoc(); } } - - // The qualifier-in-scope and object type only apply to the leftmost entity. - FirstQualifierInScope = nullptr; - ObjectType = QualType(); } // Don't rebuild the nested-name-specifier if we don't have to. @@ -4766,30 +4761,32 @@ template <typename Derived> TemplateName TreeTransform<Derived>::RebuildTemplateName( CXXScopeSpec &SS, SourceLocation TemplateKWLoc, IdentifierOrOverloadedOperator IO, SourceLocation NameLoc, - QualType ObjectType, NamedDecl *FirstQualifierInScope, - bool AllowInjectedClassName) { - if (const IdentifierInfo *II = IO.getIdentifier()) { + QualType ObjectType, bool AllowInjectedClassName) { + if (const IdentifierInfo *II = IO.getIdentifier()) return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc, - ObjectType, FirstQualifierInScope, - AllowInjectedClassName); - } + ObjectType, AllowInjectedClassName); return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(), NameLoc, ObjectType, AllowInjectedClassName); } -template<typename Derived> -TemplateName -TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS, - TemplateName Name, - SourceLocation NameLoc, - QualType ObjectType, - NamedDecl *FirstQualifierInScope, - bool AllowInjectedClassName) { +template <typename Derived> +TemplateName TreeTransform<Derived>::TransformTemplateName( + NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc, + TemplateName Name, SourceLocation NameLoc, QualType ObjectType, + NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) { if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) { + // FIXME: Preserve UsingTemplateName. TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl(); assert(Template && "qualified template name must refer to a template"); + if (QualifierLoc) { + QualifierLoc = getDerived().TransformNestedNameSpecifierLoc( + QualifierLoc, ObjectType, FirstQualifierInScope); + if (!QualifierLoc) + return TemplateName(); + } + TemplateDecl *TransTemplate = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc, Template)); @@ -4797,41 +4794,67 @@ TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS, return TemplateName(); if (!getDerived().AlwaysRebuild() && - SS.getScopeRep() == QTN->getQualifier() && + QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() && TransTemplate == Template) return Name; - + CXXScopeSpec SS; + SS.Adopt(QualifierLoc); return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(), TransTemplate); } if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) { - if (SS.getScopeRep()) { - // These apply to the scope specifier, not the template. + if (QualifierLoc) { + QualifierLoc = getDerived().TransformNestedNameSpecifierLoc( + QualifierLoc, ObjectType, FirstQualifierInScope); + if (!QualifierLoc) + return TemplateName(); + // The qualifier-in-scope and object type only apply to the leftmost + // entity. ObjectType = QualType(); - FirstQualifierInScope = nullptr; } if (!getDerived().AlwaysRebuild() && - SS.getScopeRep() == DTN->getQualifier() && + QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() && ObjectType.isNull()) return Name; - // FIXME: Preserve the location of the "template" keyword. - SourceLocation TemplateKWLoc = NameLoc; - return getDerived().RebuildTemplateName( - SS, TemplateKWLoc, DTN->getName(), NameLoc, ObjectType, + CXXScopeSpec SS; + SS.Adopt(QualifierLoc); + return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(), + NameLoc, ObjectType, + AllowInjectedClassName); + } + + if (SubstTemplateTemplateParmStorage *S = + Name.getAsSubstTemplateTemplateParm()) { + TemplateName NewName = getDerived().TransformTemplateName( + QualifierLoc, TemplateKWLoc, S->getReplacement(), NameLoc, ObjectType, FirstQualifierInScope, AllowInjectedClassName); + if (NewName.isNull()) + return TemplateName(); + Decl *AssociatedDecl = + getDerived().TransformDecl(NameLoc, S->getAssociatedDecl()); + if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() && + AssociatedDecl == S->getAssociatedDecl()) + return Name; + return SemaRef.Context.getSubstTemplateTemplateParm( + NewName, AssociatedDecl, S->getIndex(), S->getPackIndex(), + S->getFinal()); } - // FIXME: Try to preserve more of the TemplateName. + assert(!Name.getAsDeducedTemplateName() && + "DeducedTemplateName should not escape partial ordering"); + if (TemplateDecl *Template = Name.getAsTemplateDecl()) { + assert(!QualifierLoc && "missed a Qualified Template"); TemplateDecl *TransTemplate = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc, Template)); if (!TransTemplate) return TemplateName(); + CXXScopeSpec SS; return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false, TransTemplate); } @@ -4849,8 +4872,10 @@ TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS, template <typename Derived> TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument( - CXXScopeSpec &SS, TemplateName Name, SourceLocation NameLoc) { - TemplateName TN = getDerived().TransformTemplateName(SS, Name, NameLoc); + NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc, + TemplateName Name, SourceLocation NameLoc) { + TemplateName TN = getDerived().TransformTemplateName( + QualifierLoc, TemplateKeywordLoc, Name, NameLoc); if (TN.isNull()) return TemplateArgument(); return TemplateArgument(TN); @@ -4932,21 +4957,14 @@ bool TreeTransform<Derived>::TransformTemplateArgument( case TemplateArgument::Template: { NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc(); - if (QualifierLoc) { - QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc); - if (!QualifierLoc) - return true; - } - - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument( - SS, Arg.getAsTemplate(), Input.getTemplateNameLoc()); + QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(), + Input.getTemplateNameLoc()); if (Out.isNull()) return true; - Output = TemplateArgumentLoc(SemaRef.Context, Out, QualifierLoc, - Input.getTemplateNameLoc()); + Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(), + QualifierLoc, Input.getTemplateNameLoc()); return false; } @@ -5380,85 +5398,37 @@ QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T, return SemaRef.BuildQualifiedType(T, Loc, Quals); } -template<typename Derived> -TypeLoc -TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL, - QualType ObjectType, - NamedDecl *UnqualLookup, - CXXScopeSpec &SS) { - if (getDerived().AlreadyTransformed(TL.getType())) - return TL; - - TypeSourceInfo *TSI = - TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS); - if (TSI) - return TSI->getTypeLoc(); - return TypeLoc(); -} - -template<typename Derived> -TypeSourceInfo * -TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo, - QualType ObjectType, - NamedDecl *UnqualLookup, - CXXScopeSpec &SS) { - if (getDerived().AlreadyTransformed(TSInfo->getType())) - return TSInfo; - - return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType, - UnqualLookup, SS); -} - template <typename Derived> -TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope( - TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup, - CXXScopeSpec &SS) { - QualType T = TL.getType(); - assert(!getDerived().AlreadyTransformed(T)); - - TypeLocBuilder TLB; - QualType Result; - - if (isa<TemplateSpecializationType>(T)) { - TemplateSpecializationTypeLoc SpecTL = - TL.castAs<TemplateSpecializationTypeLoc>(); - - TemplateName Template = getDerived().TransformTemplateName( - SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(), - ObjectType, UnqualLookup, /*AllowInjectedClassName*/true); - if (Template.isNull()) - return nullptr; - - Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL, - Template); - } else if (isa<DependentTemplateSpecializationType>(T)) { - DependentTemplateSpecializationTypeLoc SpecTL = - TL.castAs<DependentTemplateSpecializationTypeLoc>(); - - const IdentifierInfo *II = SpecTL.getTypePtr() - ->getDependentTemplateName() - .getName() - .getIdentifier(); - TemplateName Template = getDerived().RebuildTemplateName( - SS, SpecTL.getTemplateKeywordLoc(), *II, SpecTL.getTemplateNameLoc(), - ObjectType, UnqualLookup, - /*AllowInjectedClassName*/ true); - if (Template.isNull()) - return nullptr; +QualType TreeTransform<Derived>::TransformTypeInObjectScope( + TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType, + NamedDecl *UnqualLookup) { + assert(!getDerived().AlreadyTransformed(TL.getType())); - Result = getDerived().TransformDependentTemplateSpecializationType(TLB, - SpecTL, - Template, - SS); - } else { - // Nothing special needs to be done for these. - Result = getDerived().TransformType(TLB, TL); + switch (TL.getTypeLocClass()) { + case TypeLoc::DependentTemplateSpecialization: + return getDerived().TransformDependentTemplateSpecializationType( + TLB, TL.castAs<DependentTemplateSpecializationTypeLoc>(), ObjectType, + UnqualLookup, /*AllowInjectedClassName=*/true); + case TypeLoc::DependentName: { + return getDerived().TransformDependentNameType( + TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false, + ObjectType, UnqualLookup); + } + case TypeLoc::Typedef: + case TypeLoc::TemplateSpecialization: + case TypeLoc::SubstTemplateTypeParm: + case TypeLoc::PackIndexing: + case TypeLoc::Enum: + case TypeLoc::Record: + case TypeLoc::InjectedClassName: + case TypeLoc::TemplateTypeParm: + case TypeLoc::Decltype: + case TypeLoc::UnresolvedUsing: + case TypeLoc::Using: + return getDerived().TransformType(TLB, TL); + default: + llvm_unreachable("unexpected type class"); } - - if (Result.isNull()) - return nullptr; - - return TLB.getTypeSourceInfo(SemaRef.Context, Result); } template <class TyLoc> static inline @@ -6694,23 +6664,38 @@ QualType TreeTransform<Derived>::TransformFunctionNoProtoType( template <typename Derived> QualType TreeTransform<Derived>::TransformUnresolvedUsingType( TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) { + const UnresolvedUsingType *T = TL.getTypePtr(); - Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()); + bool Changed = false; + + NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc(); + if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) { + QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc); + if (!QualifierLoc) + return QualType(); + Changed |= QualifierLoc != OldQualifierLoc; + } + + auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()); if (!D) return QualType(); + Changed |= D != T->getDecl(); QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || D != T->getDecl()) { - Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D); + if (getDerived().AlwaysRebuild() || Changed) { + Result = getDerived().RebuildUnresolvedUsingType( + T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(), + D); if (Result.isNull()) return QualType(); } - // We might get an arbitrary type spec type back. We should at - // least always get a type spec type, though. - TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result); - NewTL.setNameLoc(TL.getNameLoc()); - + if (isa<UsingType>(Result)) + TLB.push<UsingTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(), + QualifierLoc, TL.getNameLoc()); + else + TLB.push<UnresolvedUsingTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(), + QualifierLoc, TL.getNameLoc()); return Result; } @@ -6718,25 +6703,37 @@ template <typename Derived> QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB, UsingTypeLoc TL) { const UsingType *T = TL.getTypePtr(); + bool Changed = false; + + NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc(); + if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) { + QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc); + if (!QualifierLoc) + return QualType(); + Changed |= QualifierLoc != OldQualifierLoc; + } - auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl( - TL.getLocalSourceRange().getBegin(), T->getFoundDecl())); - if (!Found) + auto *D = cast_or_null<UsingShadowDecl>( + getDerived().TransformDecl(TL.getNameLoc(), T->getDecl())); + if (!D) return QualType(); + Changed |= D != T->getDecl(); - QualType Underlying = getDerived().TransformType(T->desugar()); - if (Underlying.isNull()) + QualType UnderlyingType = getDerived().TransformType(T->desugar()); + if (UnderlyingType.isNull()) return QualType(); + Changed |= UnderlyingType != T->desugar(); QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() || - Underlying != T->getUnderlyingType()) { - Result = getDerived().RebuildUsingType(Found, Underlying); + if (getDerived().AlwaysRebuild() || Changed) { + Result = getDerived().RebuildUsingType( + T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D, + UnderlyingType); if (Result.isNull()) return QualType(); } - - TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc()); + TLB.push<UsingTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(), QualifierLoc, + TL.getNameLoc()); return Result; } @@ -6744,23 +6741,34 @@ template<typename Derived> QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) { const TypedefType *T = TL.getTypePtr(); - TypedefNameDecl *Typedef - = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(), - T->getDecl())); + bool Changed = false; + + NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc(); + if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) { + QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc); + if (!QualifierLoc) + return QualType(); + Changed |= QualifierLoc != OldQualifierLoc; + } + + auto *Typedef = cast_or_null<TypedefNameDecl>( + getDerived().TransformDecl(TL.getNameLoc(), T->getDecl())); if (!Typedef) return QualType(); + Changed |= Typedef != T->getDecl(); + + // FIXME: Transform the UnderlyingType if different from decl. QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - Typedef != T->getDecl()) { - Result = getDerived().RebuildTypedefType(Typedef); + if (getDerived().AlwaysRebuild() || Changed) { + Result = getDerived().RebuildTypedefType( + T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef); if (Result.isNull()) return QualType(); } - TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - + TLB.push<TypedefTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(), + QualifierLoc, TL.getNameLoc()); return Result; } @@ -6996,9 +7004,10 @@ QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType( TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) { const DeducedTemplateSpecializationType *T = TL.getTypePtr(); - CXXScopeSpec SS; + NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc(); TemplateName TemplateName = getDerived().TransformTemplateName( - SS, T->getTemplateName(), TL.getTemplateNameLoc()); + QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(), + TL.getTemplateNameLoc()); if (TemplateName.isNull()) return QualType(); @@ -7011,76 +7020,71 @@ QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType( } QualType Result = getDerived().RebuildDeducedTemplateSpecializationType( - TemplateName, NewDeduced); + T->getKeyword(), TemplateName, NewDeduced); if (Result.isNull()) return QualType(); - DeducedTemplateSpecializationTypeLoc NewTL = - TLB.push<DeducedTemplateSpecializationTypeLoc>(Result); + auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(Result); + NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - + NewTL.setQualifierLoc(QualifierLoc); return Result; } -template<typename Derived> -QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB, - RecordTypeLoc TL) { - const RecordType *T = TL.getTypePtr(); - RecordDecl *Record - = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(), - T->getDecl())); - if (!Record) +template <typename Derived> +QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB, + TagTypeLoc TL) { + const TagType *T = TL.getTypePtr(); + + NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc(); + if (QualifierLoc) { + QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc); + if (!QualifierLoc) + return QualType(); + } + + auto *TD = cast_or_null<TagDecl>( + getDerived().TransformDecl(TL.getNameLoc(), T->getOriginalDecl())); + if (!TD) return QualType(); QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - Record != T->getDecl()) { - Result = getDerived().RebuildRecordType(Record); + if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() || + TD != T->getOriginalDecl()) { + if (T->isCanonicalUnqualified()) + Result = getDerived().RebuildCanonicalTagType(TD); + else + Result = getDerived().RebuildTagType( + T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD); if (Result.isNull()) return QualType(); } - RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result); + TagTypeLoc NewTL = TLB.push<TagTypeLoc>(Result); + NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); + NewTL.setQualifierLoc(QualifierLoc); NewTL.setNameLoc(TL.getNameLoc()); return Result; } -template<typename Derived> +template <typename Derived> QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB, EnumTypeLoc TL) { - const EnumType *T = TL.getTypePtr(); - EnumDecl *Enum - = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(), - T->getDecl())); - if (!Enum) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - Enum != T->getDecl()) { - Result = getDerived().RebuildEnumType(Enum); - if (Result.isNull()) - return QualType(); - } - - EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); + return getDerived().TransformTagType(TLB, TL); +} - return Result; +template <typename Derived> +QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB, + RecordTypeLoc TL) { + return getDerived().TransformTagType(TLB, TL); } template<typename Derived> QualType TreeTransform<Derived>::TransformInjectedClassNameType( TypeLocBuilder &TLB, InjectedClassNameTypeLoc TL) { - Decl *D = getDerived().TransformDecl(TL.getNameLoc(), - TL.getTypePtr()->getDecl()); - if (!D) return QualType(); - - QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D)); - TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc()); - return T; + return getDerived().TransformTagType(TLB, TL); } template<typename Derived> @@ -7142,24 +7146,6 @@ QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType( } template<typename Derived> -QualType TreeTransform<Derived>::TransformTemplateSpecializationType( - TypeLocBuilder &TLB, - TemplateSpecializationTypeLoc TL) { - const TemplateSpecializationType *T = TL.getTypePtr(); - - // The nested-name-specifier never matters in a TemplateSpecializationType, - // because we can't have a dependent nested-name-specifier anyway. - CXXScopeSpec SS; - TemplateName Template - = getDerived().TransformTemplateName(SS, T->getTemplateName(), - TL.getTemplateNameLoc()); - if (Template.isNull()) - return QualType(); - - return getDerived().TransformTemplateSpecializationType(TLB, TL, Template); -} - -template<typename Derived> QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB, AtomicTypeLoc TL) { QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc()); @@ -7398,9 +7384,16 @@ QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB, template <typename Derived> QualType TreeTransform<Derived>::TransformTemplateSpecializationType( - TypeLocBuilder &TLB, - TemplateSpecializationTypeLoc TL, - TemplateName Template) { + TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) { + const TemplateSpecializationType *T = TL.getTypePtr(); + + NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc(); + TemplateName Template = getDerived().TransformTemplateName( + QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(), + TL.getTemplateNameLoc()); + if (Template.isNull()) + return QualType(); + TemplateArgumentListInfo NewTemplateArgs; NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); @@ -7415,10 +7408,9 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType( // original template changed. If the template changed, and even if the // arguments didn't change, these arguments might not correspond to their // respective parameters, therefore needing conversions. - QualType Result = - getDerived().RebuildTemplateSpecializationType(Template, - TL.getTemplateNameLoc(), - NewTemplateArgs); + QualType Result = getDerived().RebuildTemplateSpecializationType( + TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(), + NewTemplateArgs); if (!Result.isNull()) { // Specializations of template template parameters are represented as @@ -7428,8 +7420,8 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType( if (isa<DependentTemplateSpecializationType>(Result)) { DependentTemplateSpecializationTypeLoc NewTL = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); - NewTL.setElaboratedKeywordLoc(SourceLocation()); - NewTL.setQualifierLoc(NestedNameSpecifierLoc()); + NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); + NewTL.setQualifierLoc(QualifierLoc); NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); NewTL.setLAngleLoc(TL.getLAngleLoc()); @@ -7438,133 +7430,15 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType( NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); return Result; } - - TemplateSpecializationTypeLoc NewTL - = TLB.push<TemplateSpecializationTypeLoc>(Result); - NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - NewTL.setLAngleLoc(TL.getLAngleLoc()); - NewTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) - NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); + TLB.push<TemplateSpecializationTypeLoc>(Result).set( + TL.getElaboratedKeywordLoc(), QualifierLoc, TL.getTemplateKeywordLoc(), + TL.getTemplateNameLoc(), NewTemplateArgs); } return Result; } template <typename Derived> -QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType( - TypeLocBuilder &TLB, - DependentTemplateSpecializationTypeLoc TL, - TemplateName Template, - CXXScopeSpec &SS) { - TemplateArgumentListInfo NewTemplateArgs; - NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); - NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); - typedef TemplateArgumentLocContainerIterator< - DependentTemplateSpecializationTypeLoc> ArgIterator; - if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), - ArgIterator(TL, TL.getNumArgs()), - NewTemplateArgs)) - return QualType(); - - // FIXME: maybe don't rebuild if all the template arguments are the same. - - if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { - assert(DTN->getQualifier() == SS.getScopeRep()); - QualType Result = getSema().Context.getDependentTemplateSpecializationType( - TL.getTypePtr()->getKeyword(), *DTN, NewTemplateArgs.arguments()); - - DependentTemplateSpecializationTypeLoc NewTL - = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); - NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); - NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context)); - NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - NewTL.setLAngleLoc(TL.getLAngleLoc()); - NewTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) - NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); - return Result; - } - - QualType Result - = getDerived().RebuildTemplateSpecializationType(Template, - TL.getTemplateNameLoc(), - NewTemplateArgs); - - if (!Result.isNull()) { - /// FIXME: Wrap this in an elaborated-type-specifier? - TemplateSpecializationTypeLoc NewTL - = TLB.push<TemplateSpecializationTypeLoc>(Result); - NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - NewTL.setLAngleLoc(TL.getLAngleLoc()); - NewTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) - NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); - } - - return Result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, - ElaboratedTypeLoc TL) { - const ElaboratedType *T = TL.getTypePtr(); - - NestedNameSpecifierLoc QualifierLoc; - // NOTE: the qualifier in an ElaboratedType is optional. - if (TL.getQualifierLoc()) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); - if (!QualifierLoc) - return QualType(); - } - - QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc()); - if (NamedT.isNull()) - return QualType(); - - // C++0x [dcl.type.elab]p2: - // If the identifier resolves to a typedef-name or the simple-template-id - // resolves to an alias template specialization, the - // elaborated-type-specifier is ill-formed. - if (T->getKeyword() != ElaboratedTypeKeyword::None && - T->getKeyword() != ElaboratedTypeKeyword::Typename) { - if (const TemplateSpecializationType *TST = - NamedT->getAs<TemplateSpecializationType>()) { - TemplateName Template = TST->getTemplateName(); - if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>( - Template.getAsTemplateDecl())) { - SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(), - diag::err_tag_reference_non_tag) - << TAT << NonTagKind::TypeAliasTemplate - << ElaboratedType::getTagTypeKindForKeyword(T->getKeyword()); - SemaRef.Diag(TAT->getLocation(), diag::note_declared_at); - } - } - } - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - QualifierLoc != TL.getQualifierLoc() || - NamedT != T->getNamedType()) { - Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(), - T->getKeyword(), - QualifierLoc, NamedT); - if (Result.isNull()) - return QualType(); - } - - ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); - NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); - NewTL.setQualifierLoc(QualifierLoc); - return Result; -} - -template <typename Derived> QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB, AttributedTypeLoc TL) { const AttributedType *oldType = TL.getTypePtr(); @@ -7754,15 +7628,22 @@ QualType TreeTransform<Derived>::TransformDependentNameType( return TransformDependentNameType(TLB, TL, false); } -template<typename Derived> +template <typename Derived> QualType TreeTransform<Derived>::TransformDependentNameType( - TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) { + TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext, + QualType ObjectType, NamedDecl *UnqualLookup) { const DependentNameType *T = TL.getTypePtr(); - NestedNameSpecifierLoc QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); - if (!QualifierLoc) - return QualType(); + NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc(); + if (QualifierLoc) { + QualifierLoc = getDerived().TransformNestedNameSpecifierLoc( + QualifierLoc, ObjectType, UnqualLookup); + if (!QualifierLoc) + return QualType(); + } else { + assert((ObjectType.isNull() && !UnqualLookup) && + "must be transformed by TransformNestedNameSpecifierLoc"); + } QualType Result = getDerived().RebuildDependentNameType(T->getKeyword(), @@ -7774,13 +7655,19 @@ QualType TreeTransform<Derived>::TransformDependentNameType( if (Result.isNull()) return QualType(); - if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) { - QualType NamedT = ElabT->getNamedType(); - TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc()); - - ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); + if (isa<TagType>(Result)) { + auto NewTL = TLB.push<TagTypeLoc>(Result); NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); NewTL.setQualifierLoc(QualifierLoc); + NewTL.setNameLoc(TL.getNameLoc()); + } else if (isa<DeducedTemplateSpecializationType>(Result)) { + auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(Result); + NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); + NewTL.setTemplateNameLoc(TL.getNameLoc()); + NewTL.setQualifierLoc(QualifierLoc); + } else if (isa<TypedefType>(Result)) { + TLB.push<TypedefTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(), + QualifierLoc, TL.getNameLoc()); } else { DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); @@ -7790,33 +7677,34 @@ QualType TreeTransform<Derived>::TransformDependentNameType( return Result; } -template<typename Derived> -QualType TreeTransform<Derived>:: - TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, - DependentTemplateSpecializationTypeLoc TL) { - NestedNameSpecifierLoc QualifierLoc; - if (TL.getQualifierLoc()) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); - if (!QualifierLoc) - return QualType(); - } - - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - return getDerived().TransformDependentTemplateSpecializationType(TLB, TL, SS); +template <typename Derived> +QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType( + TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL) { + return getDerived().TransformDependentTemplateSpecializationType( + TLB, TL, QualType(), nullptr, false); } template <typename Derived> QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType( TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL, - CXXScopeSpec &SS) { + QualType ObjectType, NamedDecl *UnqualLookup, bool AllowInjectedClassName) { const DependentTemplateSpecializationType *T = TL.getTypePtr(); - TemplateArgumentListInfo NewTemplateArgs; - NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); - NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); + NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc(); + if (QualifierLoc) { + QualifierLoc = getDerived().TransformNestedNameSpecifierLoc( + QualifierLoc, ObjectType, UnqualLookup); + if (!QualifierLoc) + return QualType(); + // These only apply to the leftmost prefix. + ObjectType = QualType(); + UnqualLookup = nullptr; + } + CXXScopeSpec SS; + SS.Adopt(QualifierLoc); + TemplateArgumentListInfo NewTemplateArgs(TL.getLAngleLoc(), + TL.getRAngleLoc()); auto ArgsRange = llvm::make_range<TemplateArgumentLocContainerIterator< DependentTemplateSpecializationTypeLoc>>({TL, 0}, {TL, TL.getNumArgs()}); @@ -7833,43 +7721,27 @@ QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType( QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || SS.getScopeRep() != DTN.getQualifier() || - TemplateArgumentsChanged) { + TemplateArgumentsChanged || !ObjectType.isNull()) { TemplateName Name = getDerived().RebuildTemplateName( SS, TL.getTemplateKeywordLoc(), DTN.getName(), TL.getTemplateNameLoc(), - /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr, - /*AllowInjectedClassName=*/false); + ObjectType, AllowInjectedClassName); if (Name.isNull()) return QualType(); Result = getDerived().RebuildDependentTemplateSpecializationType( - T->getKeyword(), SS.getScopeRep(), TL.getTemplateKeywordLoc(), Name, + T->getKeyword(), TL.getTemplateKeywordLoc(), Name, TL.getTemplateNameLoc(), NewTemplateArgs, /*AllowInjectedClassName=*/false); if (Result.isNull()) return QualType(); } - NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(SemaRef.Context); - if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) { - QualType NamedT = ElabT->getNamedType(); - - // Copy information relevant to the template specialization. - TemplateSpecializationTypeLoc NamedTL - = TLB.push<TemplateSpecializationTypeLoc>(NamedT); - NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - NamedTL.setLAngleLoc(TL.getLAngleLoc()); - NamedTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) - NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo()); - - // Copy information relevant to the elaborated type. - ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); - NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); - NewTL.setQualifierLoc(QualifierLoc); + QualifierLoc = SS.getWithLocInContext(SemaRef.Context); + if (isa<TemplateSpecializationType>(Result)) { + TLB.push<TemplateSpecializationTypeLoc>(Result).set( + TL.getElaboratedKeywordLoc(), QualifierLoc, TL.getTemplateKeywordLoc(), + TL.getTemplateNameLoc(), NewTemplateArgs); } else { - assert(isa<DependentTemplateSpecializationType>(Result)); - DependentTemplateSpecializationTypeLoc SpecTL - = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); + auto SpecTL = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); SpecTL.setQualifierLoc(QualifierLoc); SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); @@ -8590,14 +8462,18 @@ TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) { DeclChanged = true; if (LSI) { - if (auto *TD = dyn_cast<TypeDecl>(Transformed)) - LSI->ContainsUnexpandedParameterPack |= - getSema() - .getASTContext() - .getTypeDeclType(TD) - .getSingleStepDesugaredType(getSema().getASTContext()) - ->containsUnexpandedParameterPack(); - + if (auto *TD = dyn_cast<TypeDecl>(Transformed)) { + if (auto *TN = dyn_cast<TypedefNameDecl>(TD)) { + LSI->ContainsUnexpandedParameterPack |= + TN->getUnderlyingType()->containsUnexpandedParameterPack(); + } else { + LSI->ContainsUnexpandedParameterPack |= + getSema() + .getASTContext() + .getTypeDeclType(TD) + ->containsUnexpandedParameterPack(); + } + } if (auto *VD = dyn_cast<VarDecl>(Transformed)) LSI->ContainsUnexpandedParameterPack |= VD->getType()->containsUnexpandedParameterPack(); @@ -11901,8 +11777,11 @@ void OpenACCClauseTransform<Derived>::VisitPrivateClause( if (InitRecipe) InitRecipes.push_back(InitRecipe); else - InitRecipes.push_back(Self.getSema().OpenACC().CreateInitRecipe( - OpenACCClauseKind::Private, VarRef.get())); + InitRecipes.push_back( + Self.getSema() + .OpenACC() + .CreateInitRecipe(OpenACCClauseKind::Private, VarRef.get()) + .first); } } ParsedClause.setVarListDetails(InstantiatedVarList, @@ -11942,7 +11821,7 @@ template <typename Derived> void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause( const OpenACCFirstPrivateClause &C) { llvm::SmallVector<Expr *> InstantiatedVarList; - llvm::SmallVector<VarDecl *> InitRecipes; + llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes; for (const auto [RefExpr, InitRecipe] : llvm::zip(C.getVarList(), C.getInitRecipes())) { @@ -11953,7 +11832,7 @@ void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause( // We only have to create a new one if it is dependent, and Sema won't // make one of these unless the type is non-dependent. - if (InitRecipe) + if (InitRecipe.RecipeDecl) InitRecipes.push_back(InitRecipe); else InitRecipes.push_back(Self.getSema().OpenACC().CreateInitRecipe( @@ -14350,7 +14229,7 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) { auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated; if (E->isGLValue()) if (auto *RecordT = Op->getType()->getAs<RecordType>()) - if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic()) + if (cast<CXXRecordDecl>(RecordT->getOriginalDecl())->isPolymorphic()) EvalCtx = SemaRef.ExprEvalContexts.back().Context; EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx, @@ -14590,7 +14469,8 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) { QualType ElementType = SemaRef.Context.getBaseElementType(E->getAllocatedType()); if (const RecordType *RecordT = ElementType->getAs<RecordType>()) { - CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl()); + CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getOriginalDecl()) + ->getDefinitionOrSelf(); if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) { SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor); } @@ -14660,7 +14540,9 @@ TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) { QualType Destroyed = SemaRef.Context.getBaseElementType( E->getDestroyedType()); if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) { - CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl()); + CXXRecordDecl *Record = + cast<CXXRecordDecl>(DestroyedRec->getOriginalDecl()) + ->getDefinitionOrSelf(); SemaRef.MarkFunctionReferenced(E->getBeginLoc(), SemaRef.LookupDestructor(Record)); } @@ -14704,9 +14586,9 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr( PseudoDestructorTypeStorage Destroyed; if (E->getDestroyedTypeInfo()) { - TypeSourceInfo *DestroyedTypeInfo - = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(), - ObjectType, nullptr, SS); + TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope( + E->getDestroyedTypeInfo(), ObjectType, + /*FirstQualifierInScope=*/nullptr); if (!DestroyedTypeInfo) return ExprError(); Destroyed = DestroyedTypeInfo; @@ -14730,9 +14612,8 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr( TypeSourceInfo *ScopeTypeInfo = nullptr; if (E->getScopeTypeInfo()) { - CXXScopeSpec EmptySS; ScopeTypeInfo = getDerived().TransformTypeInObjectScope( - E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS); + E->getScopeTypeInfo(), ObjectType, nullptr); if (!ScopeTypeInfo) return ExprError(); } @@ -15853,10 +15734,6 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { // parameters are dependent. DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy); Class->setLambdaDependencyKind(DependencyKind); - // Clean up the type cache created previously. Then, we re-create a type for - // such Decl with the new DependencyKind. - Class->setTypeForDecl(nullptr); - getSema().Context.getTypeDeclType(Class); return getDerived().RebuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(), &LSICopy); @@ -17359,9 +17236,10 @@ QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) { return SemaRef.Context.getFunctionNoProtoType(T); } -template<typename Derived> -QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc, - Decl *D) { +template <typename Derived> +QualType TreeTransform<Derived>::RebuildUnresolvedUsingType( + ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, + SourceLocation NameLoc, Decl *D) { assert(D && "no decl found"); if (D->isInvalidDecl()) return QualType(); @@ -17371,7 +17249,7 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc, // UsingDecls, but they must each have exactly one type, and it must be // the same type in every case. But we must have at least one expansion! if (UPD->expansions().empty()) { - getSema().Diag(Loc, diag::err_using_pack_expansion_empty) + getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty) << UPD->isCXXClassMember() << UPD; return QualType(); } @@ -17382,10 +17260,11 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc, QualType FallbackT; QualType T; for (auto *E : UPD->expansions()) { - QualType ThisT = RebuildUnresolvedUsingType(Loc, E); + QualType ThisT = + RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, E); if (ThisT.isNull()) continue; - else if (ThisT->getAs<UnresolvedUsingType>()) + if (ThisT->getAs<UnresolvedUsingType>()) FallbackT = ThisT; else if (T.isNull()) T = ThisT; @@ -17394,7 +17273,8 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc, "mismatched resolved types in using pack expansion"); } return T.isNull() ? FallbackT : T; - } else if (auto *Using = dyn_cast<UsingDecl>(D)) { + } + if (auto *Using = dyn_cast<UsingDecl>(D)) { assert(Using->hasTypename() && "UnresolvedUsingTypenameDecl transformed to non-typename using"); @@ -17402,17 +17282,14 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc, assert(++Using->shadow_begin() == Using->shadow_end()); UsingShadowDecl *Shadow = *Using->shadow_begin(); - if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc)) + if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), NameLoc)) return QualType(); - return SemaRef.Context.getUsingType( - Shadow, SemaRef.Context.getTypeDeclType( - cast<TypeDecl>(Shadow->getTargetDecl()))); - } else { - assert(isa<UnresolvedUsingTypenameDecl>(D) && - "UnresolvedUsingTypenameDecl transformed to non-using decl"); - return SemaRef.Context.getTypeDeclType( - cast<UnresolvedUsingTypenameDecl>(D)); + return SemaRef.Context.getUsingType(Keyword, Qualifier, Shadow); } + assert(isa<UnresolvedUsingTypenameDecl>(D) && + "UnresolvedUsingTypenameDecl transformed to non-using decl"); + return SemaRef.Context.getUnresolvedUsingType( + Keyword, Qualifier, cast<UnresolvedUsingTypenameDecl>(D)); } template <typename Derived> @@ -17448,12 +17325,12 @@ QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType, return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc); } -template<typename Derived> +template <typename Derived> QualType TreeTransform<Derived>::RebuildTemplateSpecializationType( - TemplateName Template, - SourceLocation TemplateNameLoc, - TemplateArgumentListInfo &TemplateArgs) { - return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs); + ElaboratedTypeKeyword Keyword, TemplateName Template, + SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) { + return SemaRef.CheckTemplateIdType(Keyword, Template, TemplateNameLoc, + TemplateArgs); } template<typename Derived> @@ -17496,15 +17373,10 @@ TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, TemplateName(Template)); } -template<typename Derived> -TemplateName -TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - const IdentifierInfo &Name, - SourceLocation NameLoc, - QualType ObjectType, - NamedDecl *FirstQualifierInScope, - bool AllowInjectedClassName) { +template <typename Derived> +TemplateName TreeTransform<Derived>::RebuildTemplateName( + CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name, + SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) { UnqualifiedId TemplateName; TemplateName.setIdentifier(&Name, NameLoc); Sema::TemplateTy Template; @@ -17646,15 +17518,16 @@ TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base, NameInfo.setNamedTypeInfo(DestroyedType); // The scope type is now known to be a valid nested name specifier - // component. Tack it on to the end of the nested name specifier. + // component. Tack it on to the nested name specifier. if (ScopeType) { - if (!ScopeType->getType()->getAs<TagType>()) { + if (!isa<TagType>(ScopeType->getType().getCanonicalType())) { getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(), diag::err_expected_class_or_namespace) << ScopeType->getType() << getSema().getLangOpts().CPlusPlus; return ExprError(); } - SS.Extend(SemaRef.Context, ScopeType->getTypeLoc(), CCLoc); + SS.clear(); + SS.Make(SemaRef.Context, ScopeType->getTypeLoc(), CCLoc); } SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. |