Revamp our representation of C++ nested-name-specifiers. We now have a
uniqued representation that should both save some memory and make it
far easier to properly build canonical types for types involving
dependent nested-name-specifiers, e.g., "typename T::Nested::type".
This approach will greatly simplify the representation of
CXXScopeSpec. That'll be next.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67799 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index f6e36bf..52f87b9 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -768,33 +768,52 @@
ClassTemplateSpec->getNumTemplateArgs());
}
-/// \brief Instantiate a sequence of nested-name-specifiers into a
-/// scope specifier.
-CXXScopeSpec
-Sema::InstantiateScopeSpecifier(const NestedNameSpecifier *Components,
- unsigned NumComponents,
- SourceRange Range,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs) {
- CXXScopeSpec SS;
- for (unsigned Comp = 0; Comp < NumComponents; ++Comp) {
- if (Type *T = Components[Comp].getAsType()) {
- QualType NewT = InstantiateType(QualType(T, 0), TemplateArgs,
- NumTemplateArgs, Range.getBegin(),
- DeclarationName());
- if (NewT.isNull())
- return SS;
- NestedNameSpecifier NNS(NewT.getTypePtr());
- SS.addScopeRep(NNS.getAsOpaquePtr());
- } else {
- DeclContext *DC = Components[Comp].getAsDeclContext();
- // FIXME: injected-class-name might be dependent, and therefore
- // would need instantiation.
- NestedNameSpecifier NNS(DC);
- SS.addScopeRep(NNS.getAsOpaquePtr());
- }
+/// \brief Instantiate a nested-name-specifier.
+NestedNameSpecifier *
+Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
+ SourceRange Range,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs) {
+ // Instantiate the prefix of this nested name specifier.
+ NestedNameSpecifier *Prefix = NNS->getPrefix();
+ if (Prefix) {
+ Prefix = InstantiateNestedNameSpecifier(Prefix, Range, TemplateArgs,
+ NumTemplateArgs);
+ if (!Prefix)
+ return 0;
}
- SS.setRange(Range);
- return SS;
+ switch (NNS->getKind()) {
+ case NestedNameSpecifier::Identifier:
+ // FIXME: Implement this lookup!
+ assert(false && "Cannot instantiate this nested-name-specifier");
+ break;
+
+ case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::Global:
+ return NNS;
+
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ case NestedNameSpecifier::TypeSpec: {
+ QualType T = QualType(NNS->getAsType(), 0);
+ if (!T->isDependentType())
+ return NNS;
+
+ T = InstantiateType(T, TemplateArgs, NumTemplateArgs, Range.getBegin(),
+ DeclarationName());
+ if (T.isNull())
+ return 0;
+
+ // Note that T.getTypePtr(), below, strips cv-qualifiers. This is
+ // perfectly reasonable, since cv-qualified types in
+ // nested-name-specifiers don't matter.
+ // FIXME: we need to perform more checking on this type.
+ return NestedNameSpecifier::Create(Context, Prefix,
+ NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
+ T.getTypePtr());
+ }
+ }
+
+ // Required to silence GCC warning.
+ return 0;
}