diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 102 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 176 |
7 files changed, 243 insertions, 63 deletions
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 2d85374280..037594a44a 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -265,7 +265,8 @@ void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) { BufferCapacity = 0; } -NestedNameSpecifierLoc CXXScopeSpec::getWithLocInContext(ASTContext &Context) { +NestedNameSpecifierLoc +CXXScopeSpec::getWithLocInContext(ASTContext &Context) const { if (isEmpty() || isInvalid()) return NestedNameSpecifierLoc(); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 75e7c6f2d9..d6efd7a6c9 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2895,8 +2895,7 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC, static void SetNestedNameSpecifier(DeclaratorDecl *DD, Declarator &D) { CXXScopeSpec &SS = D.getCXXScopeSpec(); if (!SS.isSet()) return; - DD->setQualifierInfo(static_cast<NestedNameSpecifier*>(SS.getScopeRep()), - SS.getRange()); + DD->setQualifierInfo(SS.getWithLocInContext(DD->getASTContext())); } NamedDecl* @@ -6445,9 +6444,7 @@ CreateNewDecl: // Maybe add qualifier info. if (SS.isNotEmpty()) { if (SS.isSet()) { - NestedNameSpecifier *NNS - = static_cast<NestedNameSpecifier*>(SS.getScopeRep()); - New->setQualifierInfo(NNS, SS.getRange()); + New->setQualifierInfo(SS.getWithLocInContext(Context)); if (NumMatchedTemplateParamLists > 0) { New->setTemplateParameterListsInfo(Context, NumMatchedTemplateParamLists, diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index bef1bb451f..893cf6ac26 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2841,7 +2841,7 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { FD->getType(), FD->getTypeSourceInfo()); if (FD->getQualifier()) { FunctionDecl *NewFD = cast<FunctionDecl>(NewD); - NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); + NewFD->setQualifierInfo(FD->getQualifierLoc()); } } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), @@ -2851,7 +2851,7 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { VD->getStorageClassAsWritten()); if (VD->getQualifier()) { VarDecl *NewVD = cast<VarDecl>(NewD); - NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); + NewVD->setQualifierInfo(VD->getQualifierLoc()); } } return NewD; diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 8f7b7da6f3..5b09dfcee1 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -783,8 +783,7 @@ Sema::ActOnTemplateParameterList(unsigned Depth, static void SetNestedNameSpecifier(TagDecl *T, const CXXScopeSpec &SS) { if (SS.isSet()) - T->setQualifierInfo(static_cast<NestedNameSpecifier*>(SS.getScopeRep()), - SS.getRange()); + T->setQualifierInfo(SS.getWithLocInContext(T->getASTContext())); } DeclResult diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 44f5913d55..ae0ac9cbe3 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -2140,6 +2140,17 @@ Sema::SubstNestedNameSpecifier(NestedNameSpecifier *NNS, return Instantiator.TransformNestedNameSpecifier(NNS, Range); } +NestedNameSpecifierLoc +Sema::SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, + const MultiLevelTemplateArgumentList &TemplateArgs) { + if (!NNS) + return NestedNameSpecifierLoc(); + + TemplateInstantiator Instantiator(*this, TemplateArgs, NNS.getBeginLoc(), + DeclarationName()); + return Instantiator.TransformNestedNameSpecifierLoc(NNS); +} + /// \brief Do template substitution on declaration name info. DeclarationNameInfo Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo, diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index e1a7065197..f437cd3092 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -27,33 +27,33 @@ using namespace clang; bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl, DeclaratorDecl *NewDecl) { - NestedNameSpecifier *OldQual = OldDecl->getQualifier(); - if (!OldQual) return false; - - SourceRange QualRange = OldDecl->getQualifierRange(); - - NestedNameSpecifier *NewQual - = SemaRef.SubstNestedNameSpecifier(OldQual, QualRange, TemplateArgs); - if (!NewQual) + if (!OldDecl->getQualifierLoc()) + return false; + + NestedNameSpecifierLoc NewQualifierLoc + = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), + TemplateArgs); + + if (!NewQualifierLoc) return true; - - NewDecl->setQualifierInfo(NewQual, QualRange); + + NewDecl->setQualifierInfo(NewQualifierLoc); return false; } bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl, TagDecl *NewDecl) { - NestedNameSpecifier *OldQual = OldDecl->getQualifier(); - if (!OldQual) return false; - - SourceRange QualRange = OldDecl->getQualifierRange(); - - NestedNameSpecifier *NewQual - = SemaRef.SubstNestedNameSpecifier(OldQual, QualRange, TemplateArgs); - if (!NewQual) + if (!OldDecl->getQualifierLoc()) + return false; + + NestedNameSpecifierLoc NewQualifierLoc + = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), + TemplateArgs); + + if (!NewQualifierLoc) return true; - - NewDecl->setQualifierInfo(NewQual, QualRange); + + NewDecl->setQualifierInfo(NewQualifierLoc); return false; } @@ -642,12 +642,12 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { // Instantiate the qualifier. We have to do this first in case // we're a friend declaration, because if we are then we need to put // the new declaration in the appropriate context. - NestedNameSpecifier *Qualifier = Pattern->getQualifier(); - if (Qualifier) { - Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier, - Pattern->getQualifierRange(), - TemplateArgs); - if (!Qualifier) return 0; + NestedNameSpecifierLoc QualifierLoc = Pattern->getQualifierLoc(); + if (QualifierLoc) { + QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, + TemplateArgs); + if (!QualifierLoc) + return 0; } CXXRecordDecl *PrevDecl = 0; @@ -668,9 +668,9 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { // the appropriate context. DeclContext *DC = Owner; if (isFriend) { - if (Qualifier) { + if (QualifierLoc) { CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, Qualifier, Pattern->getQualifierRange()); + SS.Adopt(QualifierLoc); DC = SemaRef.computeDeclContext(SS); if (!DC) return 0; } else { @@ -691,10 +691,10 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { PrevDecl = PrevClassTemplate->getTemplatedDecl(); } - if (!PrevClassTemplate && Qualifier) { + if (!PrevClassTemplate && QualifierLoc) { SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope) << D->getTemplatedDecl()->getTagKind() << Pattern->getDeclName() << DC - << Pattern->getQualifierRange(); + << QualifierLoc.getSourceRange(); return 0; } @@ -755,8 +755,8 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { Pattern->getTagKeywordLoc(), PrevDecl, /*DelayTypeCreation=*/true); - if (Qualifier) - RecordInst->setQualifierInfo(Qualifier, Pattern->getQualifierRange()); + if (QualifierLoc) + RecordInst->setQualifierInfo(QualifierLoc); ClassTemplateDecl *Inst = ClassTemplateDecl::Create(SemaRef.Context, DC, D->getLocation(), @@ -968,12 +968,12 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, return 0; QualType T = TInfo->getType(); - NestedNameSpecifier *Qualifier = D->getQualifier(); - if (Qualifier) { - Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier, - D->getQualifierRange(), - TemplateArgs); - if (!Qualifier) return 0; + NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); + if (QualifierLoc) { + QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, + TemplateArgs); + if (!QualifierLoc) + return 0; } // If we're instantiating a local function declaration, put the result @@ -981,9 +981,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, DeclContext *DC; if (D->getDeclContext()->isFunctionOrMethod()) DC = Owner; - else if (isFriend && Qualifier) { + else if (isFriend && QualifierLoc) { CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, Qualifier, D->getQualifierRange()); + SS.Adopt(QualifierLoc); DC = SemaRef.computeDeclContext(SS); if (!DC) return 0; } else { @@ -997,8 +997,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, D->getStorageClass(), D->getStorageClassAsWritten(), D->isInlineSpecified(), D->hasWrittenPrototype()); - if (Qualifier) - Function->setQualifierInfo(Qualifier, D->getQualifierRange()); + if (QualifierLoc) + Function->setQualifierInfo(QualifierLoc); DeclContext *LexicalDC = Owner; if (!isFriend && D->isOutOfLine()) { @@ -1260,19 +1260,19 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, return 0; } - NestedNameSpecifier *Qualifier = D->getQualifier(); - if (Qualifier) { - Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier, - D->getQualifierRange(), + NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); + if (QualifierLoc) { + QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgs); - if (!Qualifier) return 0; + if (!QualifierLoc) + return 0; } DeclContext *DC = Owner; if (isFriend) { - if (Qualifier) { + if (QualifierLoc) { CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, Qualifier, D->getQualifierRange()); + SS.Adopt(QualifierLoc); DC = SemaRef.computeDeclContext(SS); if (DC && SemaRef.RequireCompleteDeclContext(SS, DC)) @@ -1315,8 +1315,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, D->isInlineSpecified()); } - if (Qualifier) - Method->setQualifierInfo(Qualifier, D->getQualifierRange()); + if (QualifierLoc) + Method->setQualifierInfo(QualifierLoc); if (TemplateParams) { // Our resulting instantiation is actually a function template, since we diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index fa0c2b97d4..641df425ad 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -385,6 +385,17 @@ public: QualType ObjectType = QualType(), NamedDecl *FirstQualifierInScope = 0); + /// \brief Transform the given nested-name-specifier with source-location + /// information. + /// + /// By default, transforms all of the types and declarations within the + /// nested-name-specifier. Subclasses may override this function to provide + /// alternate behavior. + NestedNameSpecifierLoc TransformNestedNameSpecifierLoc( + NestedNameSpecifierLoc NNS, + QualType ObjectType = QualType(), + NamedDecl *FirstQualifierInScope = 0); + /// \brief Transform the given declaration name. /// /// By default, transforms the types of conversion function, constructor, @@ -2264,6 +2275,11 @@ private: QualType ObjectType, NamedDecl *FirstQualifierInScope, NestedNameSpecifier *Prefix); + + TypeLoc TransformTypeInObjectScope(TypeLoc TL, + QualType ObjectType, + NamedDecl *FirstQualifierInScope, + CXXScopeSpec &SS); }; template<typename Derived> @@ -2504,6 +2520,105 @@ TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS, } template<typename Derived> +NestedNameSpecifierLoc +TreeTransform<Derived>::TransformNestedNameSpecifierLoc( + NestedNameSpecifierLoc NNS, + QualType ObjectType, + NamedDecl *FirstQualifierInScope) { + llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers; + for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier; + Qualifier = Qualifier.getPrefix()) + Qualifiers.push_back(Qualifier); + + CXXScopeSpec SS; + while (!Qualifiers.empty()) { + NestedNameSpecifierLoc Q = Qualifiers.pop_back_val(); + NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier(); + + switch (QNNS->getKind()) { + case NestedNameSpecifier::Identifier: + if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/0, + *QNNS->getAsIdentifier(), + Q.getLocalBeginLoc(), + Q.getLocalEndLoc(), + ObjectType, false, SS, + FirstQualifierInScope, false)) + return NestedNameSpecifierLoc(); + + break; + + case NestedNameSpecifier::Namespace: { + NamespaceDecl *NS + = cast_or_null<NamespaceDecl>( + getDerived().TransformDecl( + Q.getLocalBeginLoc(), + QNNS->getAsNamespace())); + SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc()); + break; + } + + case NestedNameSpecifier::NamespaceAlias: { + NamespaceAliasDecl *Alias + = cast_or_null<NamespaceAliasDecl>( + getDerived().TransformDecl(Q.getLocalBeginLoc(), + QNNS->getAsNamespaceAlias())); + SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(), + Q.getLocalEndLoc()); + break; + } + + case NestedNameSpecifier::Global: + // There is no meaningful transformation that one could perform on the + // global scope. + SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc()); + break; + + case NestedNameSpecifier::TypeSpecWithTemplate: + case NestedNameSpecifier::TypeSpec: { + TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType, + FirstQualifierInScope, SS); + + if (!TL) + return NestedNameSpecifierLoc(); + + if (TL.getType()->isDependentType() || TL.getType()->isRecordType() || + (SemaRef.getLangOptions().CPlusPlus0x && + TL.getType()->isEnumeralType())) { + assert(!TL.getType().hasLocalQualifiers() && + "Can't get cv-qualifiers here"); + SS.Extend(SemaRef.Context, /*FIXME:*/SourceLocation(), TL, + Q.getLocalEndLoc()); + break; + } + + SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag) + << TL.getType() << SS.getRange(); + return NestedNameSpecifierLoc(); + } + } + + // The object type and qualifier-in-scope really apply to the + // leftmost entity. + ObjectType = QualType(); + FirstQualifierInScope = 0; + } + + // Don't rebuild the nested-name-specifier if we don't have to. + if (SS.getScopeRep() == NNS.getNestedNameSpecifier() && + !getDerived().AlwaysRebuild()) + return NNS; + + // If we can re-use the source-location data from the original + // nested-name-specifier, do so. + if (SS.location_size() == NNS.getDataLength() && + memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0) + return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData()); + + // Allocate new nested-name-specifier location information. + return SS.getWithLocInContext(SemaRef.Context); +} + +template<typename Derived> DeclarationNameInfo TreeTransform<Derived> ::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) { @@ -3099,7 +3214,7 @@ TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSI, QualType ObjectType, NamedDecl *UnqualLookup, NestedNameSpecifier *Prefix) { - // TODO: in some cases, we might be some verification to do here. + // TODO: in some cases, we might have some verification to do here. if (ObjectType.isNull()) return getDerived().TransformType(TSI); @@ -3136,6 +3251,62 @@ TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSI, return TLB.getTypeSourceInfo(SemaRef.Context, Result); } +template<typename Derived> +TypeLoc +TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL, + QualType ObjectType, + NamedDecl *UnqualLookup, + CXXScopeSpec &SS) { + // FIXME: Painfully copy-paste from the above! + + // TODO: in some cases, we might have some verification to do here. + if (ObjectType.isNull()) { + TypeLocBuilder TLB; + TLB.reserve(TL.getFullDataSize()); + QualType Result = getDerived().TransformType(TLB, TL); + if (Result.isNull()) + return TypeLoc(); + + return TLB.getTypeSourceInfo(SemaRef.Context, Result)->getTypeLoc(); + } + + QualType T = TL.getType(); + if (getDerived().AlreadyTransformed(T)) + return TL; + + TypeLocBuilder TLB; + QualType Result; + + if (isa<TemplateSpecializationType>(T)) { + TemplateSpecializationTypeLoc SpecTL + = cast<TemplateSpecializationTypeLoc>(TL); + + TemplateName Template = + getDerived().TransformTemplateName(SpecTL.getTypePtr()->getTemplateName(), + ObjectType, UnqualLookup); + if (Template.isNull()) + return TypeLoc(); + + Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL, + Template); + } else if (isa<DependentTemplateSpecializationType>(T)) { + DependentTemplateSpecializationTypeLoc SpecTL + = cast<DependentTemplateSpecializationTypeLoc>(TL); + + Result = getDerived().TransformDependentTemplateSpecializationType(TLB, + SpecTL, + SS.getScopeRep()); + } else { + // Nothing special needs to be done for these. + Result = getDerived().TransformType(TLB, TL); + } + + if (Result.isNull()) + return TypeLoc(); + + return TLB.getTypeSourceInfo(SemaRef.Context, Result)->getTypeLoc(); +} + template <class TyLoc> static inline QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) { TyLoc NewT = TLB.push<TyLoc>(T.getType()); @@ -4351,7 +4522,8 @@ QualType TreeTransform<Derived>:: TemplateArgumentListInfo NewTemplateArgs; NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); - + + // FIXME: Nested-name-specifier source location info! typedef TemplateArgumentLocContainerIterator< DependentTemplateSpecializationTypeLoc> ArgIterator; if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), |