aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-02-25 02:25:35 +0000
committerDouglas Gregor <dgregor@apple.com>2011-02-25 02:25:35 +0000
commitc22b5fff39a7520207f165fb16a27a34b944bd9c (patch)
treec79ab64b51bd9c1b5fe807aa689003dc23d2f128 /lib
parent7decebfc7b9dc841f228c93cc2e41e3e62911ff8 (diff)
Use NestedNameSpecifierLoc within out-of-line variables, function, and
tag definitions. Also, add support for template instantiation of NestedNameSpecifierLocs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126470 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTImporter.cpp48
-rw-r--r--lib/AST/Decl.cpp20
-rw-r--r--lib/Sema/DeclSpec.cpp3
-rw-r--r--lib/Sema/SemaDecl.cpp7
-rw-r--r--lib/Sema/SemaDeclAttr.cpp4
-rw-r--r--lib/Sema/SemaTemplate.cpp3
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp11
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp102
-rw-r--r--lib/Sema/TreeTransform.h176
-rw-r--r--lib/Serialization/ASTReader.cpp3
-rw-r--r--lib/Serialization/ASTWriter.cpp3
11 files changed, 264 insertions, 116 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 65c0a3bb61..21f10fb7ad 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -2097,11 +2097,7 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
D->isScoped(), D->isScopedUsingClassTag(),
D->isFixed());
// Import the qualifier, if any.
- if (D->getQualifier()) {
- NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
- SourceRange NNSRange = Importer.Import(D->getQualifierRange());
- D2->setQualifierInfo(NNS, NNSRange);
- }
+ D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
D2->setAccess(D->getAccess());
D2->setLexicalDeclContext(LexicalDC);
Importer.Imported(D, D2);
@@ -2225,12 +2221,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
Name.getAsIdentifierInfo(),
Importer.Import(D->getTagKeywordLoc()));
}
- // Import the qualifier, if any.
- if (D->getQualifier()) {
- NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
- SourceRange NNSRange = Importer.Import(D->getQualifierRange());
- D2->setQualifierInfo(NNS, NNSRange);
- }
+
+ D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
D2->setLexicalDeclContext(LexicalDC);
LexicalDC->addDecl(D2);
}
@@ -2408,11 +2400,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
// Import the qualifier, if any.
- if (D->getQualifier()) {
- NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
- SourceRange NNSRange = Importer.Import(D->getQualifierRange());
- ToFunction->setQualifierInfo(NNS, NNSRange);
- }
+ ToFunction->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
ToFunction->setAccess(D->getAccess());
ToFunction->setLexicalDeclContext(LexicalDC);
ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
@@ -2666,12 +2654,7 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
Name.getAsIdentifierInfo(), T, TInfo,
D->getStorageClass(),
D->getStorageClassAsWritten());
- // Import the qualifier, if any.
- if (D->getQualifier()) {
- NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
- SourceRange NNSRange = Importer.Import(D->getQualifierRange());
- ToVar->setQualifierInfo(NNS, NNSRange);
- }
+ ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
ToVar->setAccess(D->getAccess());
ToVar->setLexicalDeclContext(LexicalDC);
Importer.Imported(D, ToVar);
@@ -3591,14 +3574,7 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
Name.getAsIdentifierInfo(),
Importer.Import(DTemplated->getTagKeywordLoc()));
D2Templated->setAccess(DTemplated->getAccess());
-
-
- // Import the qualifier, if any.
- if (DTemplated->getQualifier()) {
- NestedNameSpecifier *NNS = Importer.Import(DTemplated->getQualifier());
- SourceRange NNSRange = Importer.Import(DTemplated->getQualifierRange());
- D2Templated->setQualifierInfo(NNS, NNSRange);
- }
+ D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc()));
D2Templated->setLexicalDeclContext(LexicalDC);
// Create the class template declaration itself.
@@ -3703,12 +3679,7 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
ClassTemplate->AddSpecialization(D2, InsertPos);
// Import the qualifier, if any.
- if (D->getQualifier()) {
- NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
- SourceRange NNSRange = Importer.Import(D->getQualifierRange());
- D2->setQualifierInfo(NNS, NNSRange);
- }
-
+ D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
// Add the specialization to this context.
D2->setLexicalDeclContext(LexicalDC);
@@ -4067,6 +4038,11 @@ NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
return 0;
}
+NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
+ // FIXME: Implement!
+ return NestedNameSpecifierLoc();
+}
+
TemplateName ASTImporter::Import(TemplateName From) {
switch (From.getKind()) {
case TemplateName::Template:
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index ccc883e944..d7e389e616 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -935,9 +935,8 @@ SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
return SourceLocation();
}
-void DeclaratorDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange) {
- if (Qualifier) {
+void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
+ if (QualifierLoc) {
// Make sure the extended decl info is allocated.
if (!hasExtInfo()) {
// Save (non-extended) type source info pointer.
@@ -948,12 +947,10 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
getExtInfo()->TInfo = savedTInfo;
}
// Set qualifier info.
- getExtInfo()->NNS = Qualifier;
- getExtInfo()->NNSRange = QualifierRange;
+ getExtInfo()->QualifierLoc = QualifierLoc;
}
else {
// Here Qualifier == 0, i.e., we are removing the qualifier (if any).
- assert(QualifierRange.isInvalid());
if (hasExtInfo()) {
// Save type source info pointer.
TypeSourceInfo *savedTInfo = getExtInfo()->TInfo;
@@ -975,7 +972,7 @@ QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
TemplateParameterList **TPLists) {
assert((NumTPLists == 0 || TPLists != 0) &&
"Empty array of template parameters with positive size!");
- assert((NumTPLists == 0 || NNS) &&
+ assert((NumTPLists == 0 || QualifierLoc) &&
"Nonempty array of template parameters with no qualifier!");
// Free previous template parameters (if any).
@@ -2027,19 +2024,16 @@ TagDecl* TagDecl::getDefinition() const {
return 0;
}
-void TagDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange) {
- if (Qualifier) {
+void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
+ if (QualifierLoc) {
// Make sure the extended qualifier info is allocated.
if (!hasExtInfo())
TypedefDeclOrQualifier = new (getASTContext()) ExtInfo;
// Set qualifier info.
- getExtInfo()->NNS = Qualifier;
- getExtInfo()->NNSRange = QualifierRange;
+ getExtInfo()->QualifierLoc = QualifierLoc;
}
else {
// Here Qualifier == 0, i.e., we are removing the qualifier (if any).
- assert(QualifierRange.isInvalid());
if (hasExtInfo()) {
getASTContext().Deallocate(getExtInfo());
TypedefDeclOrQualifier = (TypedefDecl*) 0;
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),
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 93e3606942..c3953ba554 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -4480,8 +4480,7 @@ void ASTReader::ReadDeclarationNameInfo(PerFileData &F,
void ASTReader::ReadQualifierInfo(PerFileData &F, QualifierInfo &Info,
const RecordData &Record, unsigned &Idx) {
- Info.NNS = ReadNestedNameSpecifier(Record, Idx);
- Info.NNSRange = ReadSourceRange(F, Record, Idx);
+ Info.QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx);
unsigned NumTPLists = Record[Idx++];
Info.NumTemplParamLists = NumTPLists;
if (NumTPLists) {
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index ba2494b5c5..383ca3dffc 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -3443,8 +3443,7 @@ void ASTWriter::AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
void ASTWriter::AddQualifierInfo(const QualifierInfo &Info,
RecordDataImpl &Record) {
- AddNestedNameSpecifier(Info.NNS, Record);
- AddSourceRange(Info.NNSRange, Record);
+ AddNestedNameSpecifierLoc(Info.QualifierLoc, Record);
Record.push_back(Info.NumTemplParamLists);
for (unsigned i=0, e=Info.NumTemplParamLists; i != e; ++i)
AddTemplateParameterList(Info.TemplParamLists[i], Record);