diff options
author | John McCall <rjmccall@apple.com> | 2010-06-11 00:33:02 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-06-11 00:33:02 +0000 |
commit | c392f37ae81d99a29c95dafb964e52492f2e0f37 (patch) | |
tree | 256ac4ce11a58388766a1dd709d81551395e8efa /clang/lib/Sema | |
parent | d85248be7abb5c707ea1b3457a0692f240b40dda (diff) | |
download | bcm5719-llvm-c392f37ae81d99a29c95dafb964e52492f2e0f37.tar.gz bcm5719-llvm-c392f37ae81d99a29c95dafb964e52492f2e0f37.zip |
Split DependentNameType into two types. DependentNameType represents the
case of an elaborated-type-specifier like 'typename A<T>::foo', and
DependentTemplateSpecializationType represents the case of an
elaborated-type-specifier like 'typename A<T>::template B<T>'. The TypeLoc
representation of a DependentTST conveniently exactly matches that of an
ElaboratedType wrapping a TST.
Kill off the explicit rebuild methods for RebuildInCurrentInstantiation;
the standard implementations work fine because the nested name specifier
is computable in the newly-entered context.
llvm-svn: 105801
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 106 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 127 |
5 files changed, 143 insertions, 134 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1a8f7aa481c..6bad5da9c45 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -87,8 +87,8 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, if (!isClassName) return 0; - // We know from the grammar that this name refers to a type, so build a - // DependentNameType node to describe the type. + // We know from the grammar that this name refers to a type, + // so build a dependent node to describe the type. return CheckTypenameType(ETK_None, (NestedNameSpecifier *)SS->getScopeRep(), II, SourceLocation(), SS->getRange(), NameLoc @@ -196,12 +196,6 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) { T = Context.getObjCInterfaceType(IDecl); - } else if (UnresolvedUsingTypenameDecl *UUDecl = - dyn_cast<UnresolvedUsingTypenameDecl>(IIDecl)) { - // FIXME: preserve source structure information. - T = Context.getDependentNameType(ETK_None, - UUDecl->getTargetNestedNameSpecifier(), - &II); } else { // If it's not plausibly a type, suppress diagnostics. Result.suppressDiagnostics(); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 2f18711e246..5208f28ca69 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5288,15 +5288,31 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, return CreateLocInfoType(T, TSI).getAsOpaquePtr(); } - T = Context.getDependentNameType(ETK_Typename, NNS, - cast<TemplateSpecializationType>(T)); + // TODO: it's really silly that we make a template specialization + // type earlier only to drop it again here. + TemplateSpecializationType *TST = cast<TemplateSpecializationType>(T); + DependentTemplateName *DTN = + TST->getTemplateName().getAsDependentTemplateName(); + assert(DTN && "dependent template has non-dependent name?"); + T = Context.getDependentTemplateSpecializationType(ETK_Typename, NNS, + DTN->getIdentifier(), + TST->getNumArgs(), + TST->getArgs()); TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); - DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); + DependentTemplateSpecializationTypeLoc TL = + cast<DependentTemplateSpecializationTypeLoc>(TSI->getTypeLoc()); + if (InnerTSI) { + TemplateSpecializationTypeLoc TSTL = + cast<TemplateSpecializationTypeLoc>(InnerTSI->getTypeLoc()); + TL.setLAngleLoc(TSTL.getLAngleLoc()); + TL.setRAngleLoc(TSTL.getRAngleLoc()); + for (unsigned I = 0, E = TST->getNumArgs(); I != E; ++I) + TL.setArgLocInfo(I, TSTL.getArgLocInfo(I)); + } else { + TL.initializeLocal(SourceLocation()); + } TL.setKeywordLoc(TypenameLoc); TL.setQualifierRange(SS.getRange()); - - // FIXME: the inner type is a template here; remember its full source info - TL.setNameLoc(InnerTSI ? InnerTSI->getTypeLoc().getBeginLoc() : TemplateLoc); return CreateLocInfoType(T, TSI).getAsOpaquePtr(); } @@ -5425,87 +5441,9 @@ namespace { Sema::OwningExprResult TransformExpr(Expr *E) { return getSema().Owned(E->Retain()); } - - /// \brief Transforms a typename type by determining whether the type now - /// refers to a member of the current instantiation, and then - /// type-checking and building an ElaboratedType (when possible). - QualType TransformDependentNameType(TypeLocBuilder &TLB, - DependentNameTypeLoc TL, - QualType ObjectType); }; } -QualType -CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB, - DependentNameTypeLoc TL, - QualType ObjectType) { - DependentNameType *T = TL.getTypePtr(); - - NestedNameSpecifier *NNS - = TransformNestedNameSpecifier(T->getQualifier(), - TL.getQualifierRange(), - ObjectType); - if (!NNS) - return QualType(); - - // If the nested-name-specifier did not change, and we cannot compute the - // context corresponding to the nested-name-specifier, then this - // typename type will not change; exit early. - CXXScopeSpec SS; - SS.setRange(TL.getQualifierRange()); - SS.setScopeRep(NNS); - - QualType Result; - if (NNS == T->getQualifier() && getSema().computeDeclContext(SS) == 0) - Result = QualType(T, 0); - - // Rebuild the typename type, which will probably turn into a - // ElaboratedType. - else if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) { - QualType NewTemplateId - = TransformType(QualType(TemplateId, 0)); - if (NewTemplateId.isNull()) - return QualType(); - - if (NNS == T->getQualifier() && - NewTemplateId == QualType(TemplateId, 0)) - Result = QualType(T, 0); - else - Result = getDerived().RebuildDependentNameType(T->getKeyword(), - NNS, NewTemplateId); - } else - Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, - T->getIdentifier(), - TL.getKeywordLoc(), - TL.getQualifierRange(), - TL.getNameLoc()); - - if (Result.isNull()) - return QualType(); - - 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; -} - /// \brief Rebuilds a type within the context of the current instantiation. /// /// The type \p T is part of the type of an out-of-line member definition of diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 88ceeca58a6..403d5543a64 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2624,6 +2624,18 @@ MarkUsedTemplateParameters(Sema &SemaRef, QualType T, OnlyDeduced, Depth, Used); break; + case Type::DependentTemplateSpecialization: { + const DependentTemplateSpecializationType *Spec + = cast<DependentTemplateSpecializationType>(T); + if (!OnlyDeduced) + MarkUsedTemplateParameters(SemaRef, Spec->getQualifier(), + OnlyDeduced, Depth, Used); + for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I) + MarkUsedTemplateParameters(SemaRef, Spec->getArg(I), OnlyDeduced, Depth, + Used); + break; + } + case Type::TypeOf: if (!OnlyDeduced) MarkUsedTemplateParameters(SemaRef, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index bec929dabf0..48c17cde435 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1492,6 +1492,28 @@ namespace { // FIXME: load appropriate source location. TL.setNameLoc(DS.getTypeSpecTypeLoc()); } + void VisitDependentTemplateSpecializationTypeLoc( + DependentTemplateSpecializationTypeLoc TL) { + ElaboratedTypeKeyword Keyword + = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType()); + if (Keyword == ETK_Typename) { + TypeSourceInfo *TInfo = 0; + Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo); + if (TInfo) { + TL.copy(cast<DependentTemplateSpecializationTypeLoc>( + TInfo->getTypeLoc())); + return; + } + } + TL.initializeLocal(SourceLocation()); + 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. diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 26caaadd499..100ddcb141c 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -533,16 +533,27 @@ public: /// 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()) { - // If the name is still dependent, just build a new dependent name type. - CXXScopeSpec SS; - SS.setScopeRep(NNS); - if (!SemaRef.computeDeclContext(SS)) - return SemaRef.Context.getDependentNameType(Keyword, NNS, - cast<TemplateSpecializationType>(T)); - } + QualType RebuildDependentTemplateSpecializationType( + ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, + const IdentifierInfo *Name, + SourceLocation NameLoc, + const TemplateArgumentListInfo &Args) { + // Rebuild the template name. + // TODO: avoid TemplateName abstraction + TemplateName InstName = + getDerived().RebuildTemplateName(NNS, *Name, QualType()); + + // If it's still dependent, make a dependent specialization. + if (InstName.getAsDependentTemplateName()) + return SemaRef.Context.getDependentTemplateSpecializationType( + Keyword, NNS, Name, Args); + + // Otherwise, make an elaborated type wrapping a non-dependent + // specialization. + QualType T = + getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args); + if (T.isNull()) return QualType(); return SemaRef.Context.getElaboratedType(Keyword, NNS, T); } @@ -3298,46 +3309,23 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB, if (!NNS) return QualType(); - QualType Result; - - if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) { - QualType NewTemplateId - = getDerived().TransformType(QualType(TemplateId, 0)); - if (NewTemplateId.isNull()) - return QualType(); - - if (!getDerived().AlwaysRebuild() && - NNS == T->getQualifier() && - NewTemplateId == QualType(TemplateId, 0)) - return QualType(T, 0); - - Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, - NewTemplateId); - } else { - Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, - T->getIdentifier(), - TL.getKeywordLoc(), - TL.getQualifierRange(), - TL.getNameLoc()); - } + QualType Result + = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, + T->getIdentifier(), + TL.getKeywordLoc(), + TL.getQualifierRange(), + TL.getNameLoc()); if (Result.isNull()) return QualType(); 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()); - } + TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc()); + ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); NewTL.setKeywordLoc(TL.getKeywordLoc()); NewTL.setQualifierRange(TL.getQualifierRange()); - } - else { + } else { DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); NewTL.setKeywordLoc(TL.getKeywordLoc()); NewTL.setQualifierRange(TL.getQualifierRange()); @@ -3347,6 +3335,61 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB, } template<typename Derived> +QualType TreeTransform<Derived>:: + TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, + DependentTemplateSpecializationTypeLoc TL, + QualType ObjectType) { + DependentTemplateSpecializationType *T = TL.getTypePtr(); + + NestedNameSpecifier *NNS + = getDerived().TransformNestedNameSpecifier(T->getQualifier(), + TL.getQualifierRange(), + ObjectType); + if (!NNS) + return QualType(); + + TemplateArgumentListInfo NewTemplateArgs; + NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); + NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); + + for (unsigned I = 0, E = T->getNumArgs(); I != E; ++I) { + TemplateArgumentLoc Loc; + if (getDerived().TransformTemplateArgument(TL.getArgLoc(I), Loc)) + return QualType(); + NewTemplateArgs.addArgument(Loc); + } + + QualType Result = getDerived().RebuildDependentTemplateSpecializationType( + T->getKeyword(), + NNS, + T->getIdentifier(), + TL.getNameLoc(), + NewTemplateArgs); + if (Result.isNull()) + return QualType(); + + 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.setLAngleLoc(TL.getLAngleLoc()); + NamedTL.setRAngleLoc(TL.getRAngleLoc()); + for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) + NamedTL.setArgLocInfo(I, TL.getArgLocInfo(I)); + + // Copy information relevant to the elaborated type. + ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); + NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setQualifierRange(TL.getQualifierRange()); + } else { + TLB.pushFullCopy(TL); + } + return Result; +} + +template<typename Derived> QualType TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB, ObjCInterfaceTypeLoc TL, |