summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-10-18 09:09:24 +0000
committerJohn McCall <rjmccall@apple.com>2009-10-18 09:09:24 +0000
commitcebee16bc05ed6ca88041e916ef803b088f495f2 (patch)
treec0352965acb264ab0de2f219b33c20ab55dedaf2 /clang/lib/AST
parent0b8db2dab78f101acea99bfe0702d4668a7273e2 (diff)
downloadbcm5719-llvm-cebee16bc05ed6ca88041e916ef803b088f495f2.tar.gz
bcm5719-llvm-cebee16bc05ed6ca88041e916ef803b088f495f2.zip
When performing template-substitution into a type, don't just replace the
TemplateTypeParmType with the substituted type directly; instead, replace it with a SubstTemplateTypeParmType which will note that the type was originally written as a template type parameter. This makes it reasonable to preserve source information even through template substitution. Also define the new SubstTemplateTypeParmType class, obviously. For consistency with current behavior, we stringize these types as if they were the underlying type. I'm not sure this is the right thing to do. At any rate, I paled at adding yet another clause to the don't-desugar 'if' statement, so I extracted a function to do it. The new function also does The Right Thing more often, I think: e.g. if we have a chain of typedefs leading to a vector type, we will now desugar all but the last one. llvm-svn: 84412
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp28
-rw-r--r--clang/lib/AST/Type.cpp5
2 files changed, 33 insertions, 0 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 1b77bbe1dbd..c7e5752ec3c 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -747,6 +747,11 @@ ASTContext::getTypeInfo(const Type *T) {
break;
}
+ case Type::SubstTemplateTypeParm: {
+ return getTypeInfo(cast<SubstTemplateTypeParmType>(T)->
+ getReplacementType().getTypePtr());
+ }
+
case Type::Elaborated: {
return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType().getTypePtr());
}
@@ -1694,6 +1699,29 @@ QualType ASTContext::getTypedefType(TypedefDecl *Decl) {
return QualType(Decl->TypeForDecl, 0);
}
+/// \brief Retrieve a substitution-result type.
+QualType
+ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
+ QualType Replacement) {
+ assert(Replacement->isCanonical()
+ && "replacement types must always be canonical");
+
+ llvm::FoldingSetNodeID ID;
+ SubstTemplateTypeParmType::Profile(ID, Parm, Replacement);
+ void *InsertPos = 0;
+ SubstTemplateTypeParmType *SubstParm
+ = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
+
+ if (!SubstParm) {
+ SubstParm = new (*this, TypeAlignment)
+ SubstTemplateTypeParmType(Parm, Replacement);
+ Types.push_back(SubstParm);
+ SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);
+ }
+
+ return QualType(SubstParm, 0);
+}
+
/// \brief Retrieve the template type parameter type for a template
/// parameter or parameter pack with the given depth, index, and (optionally)
/// name.
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index bb9f57b6d1c..0922538f5e1 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -628,6 +628,7 @@ bool Type::isSpecifierType() const {
case TypeOfExpr:
case TypeOf:
case TemplateTypeParm:
+ case SubstTemplateTypeParm:
case TemplateSpecialization:
case QualifiedName:
case Typename:
@@ -1267,6 +1268,10 @@ void TemplateTypeParmType::getAsStringInternal(std::string &InnerString, const P
InnerString = Name->getName() + InnerString;
}
+void SubstTemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
+ getReplacementType().getAsStringInternal(InnerString, Policy);
+}
+
std::string
TemplateSpecializationType::PrintTemplateArgumentList(
const TemplateArgument *Args,
OpenPOWER on IntegriCloud