Improve the representation of template names in the AST. This
representation handles the various ways in which one can name a
template, including unqualified references ("vector"), qualified
references ("std::vector"), and dependent template names
("MetaFun::template apply").
One immediate effect of this change is that the representation of
nested-name-specifiers in type names for class template
specializations (e.g., std::vector<int>) is more accurate. Rather than
representing std::vector<int> as
std::(vector<int>)
we represent it as
(std::vector)<int>
which more closely follows the C++ grammar.
Additionally, templates are no longer represented as declarations
(DeclPtrTy) in Parse-Sema interactions. Instead, I've introduced a new
OpaquePtr type (TemplateTy) that holds the representation of a
TemplateName. This will simplify the handling of dependent
template-names, once we get there.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68074 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 0a3e8f9..6922dcc 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -93,8 +93,8 @@
return TOE->getUnderlyingExpr()->getType().getDesugaredType();
if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this))
return TOT->getUnderlyingType().getDesugaredType();
- if (const ClassTemplateSpecializationType *Spec
- = dyn_cast<ClassTemplateSpecializationType>(this))
+ if (const TemplateSpecializationType *Spec
+ = dyn_cast<TemplateSpecializationType>(this))
return Spec->getCanonicalTypeInternal().getDesugaredType();
if (const QualifiedNameType *QualName = dyn_cast<QualifiedNameType>(this))
return QualName->getNamedType().getDesugaredType();
@@ -549,11 +549,11 @@
return dyn_cast<TemplateTypeParmType>(CanonicalType);
}
-const ClassTemplateSpecializationType *
-Type::getAsClassTemplateSpecializationType() const {
+const TemplateSpecializationType *
+Type::getAsTemplateSpecializationType() const {
// There is no sugar for class template specialization types, so
// just return the canonical type pointer if it is the right class.
- return dyn_cast<ClassTemplateSpecializationType>(CanonicalType);
+ return dyn_cast<TemplateSpecializationType>(CanonicalType);
}
bool Type::isIntegerType() const {
@@ -972,7 +972,7 @@
}
bool
-ClassTemplateSpecializationType::
+TemplateSpecializationType::
anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
for (unsigned Idx = 0; Idx < NumArgs; ++Idx) {
switch (Args[Idx].getKind()) {
@@ -997,17 +997,16 @@
return false;
}
-ClassTemplateSpecializationType::
-ClassTemplateSpecializationType(TemplateDecl *T, const TemplateArgument *Args,
- unsigned NumArgs, QualType Canon)
- : Type(ClassTemplateSpecialization,
+TemplateSpecializationType::
+TemplateSpecializationType(TemplateName T, const TemplateArgument *Args,
+ unsigned NumArgs, QualType Canon)
+ : Type(TemplateSpecialization,
Canon.isNull()? QualType(this, 0) : Canon,
- /*FIXME: Check for dependent template */
- anyDependentTemplateArguments(Args, NumArgs)),
+ T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)),
Template(T), NumArgs(NumArgs)
{
assert((!Canon.isNull() ||
- anyDependentTemplateArguments(Args, NumArgs)) &&
+ T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) &&
"No canonical type for non-dependent class template specialization");
TemplateArgument *TemplateArgs
@@ -1016,7 +1015,7 @@
new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]);
}
-void ClassTemplateSpecializationType::Destroy(ASTContext& C) {
+void TemplateSpecializationType::Destroy(ASTContext& C) {
for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
// FIXME: Not all expressions get cloned, so we can't yet perform
// this destruction.
@@ -1025,24 +1024,23 @@
}
}
-ClassTemplateSpecializationType::iterator
-ClassTemplateSpecializationType::end() const {
+TemplateSpecializationType::iterator
+TemplateSpecializationType::end() const {
return begin() + getNumArgs();
}
const TemplateArgument &
-ClassTemplateSpecializationType::getArg(unsigned Idx) const {
+TemplateSpecializationType::getArg(unsigned Idx) const {
assert(Idx < getNumArgs() && "Template argument out of range");
return getArgs()[Idx];
}
void
-ClassTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
- TemplateDecl *T,
- const TemplateArgument *Args,
- unsigned NumArgs) {
- ID.AddPointer(T);
-
+TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
+ TemplateName T,
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ T.Profile(ID);
for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
Args[Idx].Profile(ID);
}
@@ -1351,7 +1349,7 @@
InnerString = Name->getName() + InnerString;
}
-std::string ClassTemplateSpecializationType::PrintTemplateArgumentList(
+std::string TemplateSpecializationType::PrintTemplateArgumentList(
const TemplateArgument *Args,
unsigned NumArgs) {
std::string SpecString;
@@ -1403,9 +1401,15 @@
}
void
-ClassTemplateSpecializationType::
+TemplateSpecializationType::
getAsStringInternal(std::string &InnerString) const {
- std::string SpecString = Template->getNameAsString();
+ std::string SpecString;
+
+ {
+ llvm::raw_string_ostream OS(SpecString);
+ Template.Print(OS);
+ }
+
SpecString += PrintTemplateArgumentList(getArgs(), getNumArgs());
if (InnerString.empty())
InnerString.swap(SpecString);
@@ -1515,7 +1519,7 @@
if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(getDecl())) {
std::string TemplateArgs
- = ClassTemplateSpecializationType::PrintTemplateArgumentList(
+ = TemplateSpecializationType::PrintTemplateArgumentList(
Spec->getTemplateArgs(),
Spec->getNumTemplateArgs());
InnerString = TemplateArgs + InnerString;
@@ -1534,7 +1538,7 @@
} else if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
std::string TemplateArgs
- = ClassTemplateSpecializationType::PrintTemplateArgumentList(
+ = TemplateSpecializationType::PrintTemplateArgumentList(
Spec->getTemplateArgs(),
Spec->getNumTemplateArgs());
MyPart = Spec->getIdentifier()->getName() + TemplateArgs;