diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-01-26 20:40:47 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-01-26 20:40:47 +0000 |
commit | 600b5261c4c5b8a1095a019396ed8771ea50f631 (patch) | |
tree | 8b843e1b9b46c2c7161a57e2545c9df46b91178c /clang/lib/AST/ASTContext.cpp | |
parent | b26530cd69d7d5c25c70bb4dc47ae0dd45becd9e (diff) | |
download | bcm5719-llvm-600b5261c4c5b8a1095a019396ed8771ea50f631.tar.gz bcm5719-llvm-600b5261c4c5b8a1095a019396ed8771ea50f631.zip |
PR0091R3: Implement parsing support for using templates as types.
This change adds a new type node, DeducedTemplateSpecializationType, to
represent a type template name that has been used as a type. This is modeled
around AutoType, and shares a common base class for representing a deduced
placeholder type.
We allow deduced class template types in a few more places than the standard
does: in conditions and for-range-declarators, and in new-type-ids. This is
consistent with GCC and with discussion on the core reflector. This patch
does not yet support deduced class template types being named in typename
specifiers.
llvm-svn: 293207
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 5624758670b..a8732d729ca 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1877,8 +1877,9 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { return getTypeInfo(cast<SubstTemplateTypeParmType>(T)-> getReplacementType().getTypePtr()); - case Type::Auto: { - const AutoType *A = cast<AutoType>(T); + case Type::Auto: + case Type::DeducedTemplateSpecialization: { + const DeducedType *A = cast<DeducedType>(T); assert(!A->getDeducedType().isNull() && "cannot request the size of an undeduced or dependent auto type"); return getTypeInfo(A->getDeducedType().getTypePtr()); @@ -2765,6 +2766,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const { case Type::TemplateTypeParm: case Type::SubstTemplateTypeParmPack: case Type::Auto: + case Type::DeducedTemplateSpecialization: case Type::PackExpansion: llvm_unreachable("type should never be variably-modified"); @@ -4435,6 +4437,28 @@ QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, return QualType(AT, 0); } +/// Return the uniqued reference to the deduced template specialization type +/// which has been deduced to the given type, or to the canonical undeduced +/// such type, or the canonical deduced-but-dependent such type. +QualType ASTContext::getDeducedTemplateSpecializationType( + TemplateName Template, QualType DeducedType, bool IsDependent) const { + // Look in the folding set for an existing type. + void *InsertPos = nullptr; + llvm::FoldingSetNodeID ID; + DeducedTemplateSpecializationType::Profile(ID, Template, DeducedType, + IsDependent); + if (DeducedTemplateSpecializationType *DTST = + DeducedTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos)) + return QualType(DTST, 0); + + DeducedTemplateSpecializationType *DTST = new (*this, TypeAlignment) + DeducedTemplateSpecializationType(Template, DeducedType, IsDependent); + Types.push_back(DTST); + if (InsertPos) + DeducedTemplateSpecializationTypes.InsertNode(DTST, InsertPos); + return QualType(DTST, 0); +} + /// getAtomicType - Return the uniqued reference to the atomic type for /// the given value type. QualType ASTContext::getAtomicType(QualType T) const { @@ -6333,6 +6357,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, // We could see an undeduced auto type here during error recovery. // Just ignore it. case Type::Auto: + case Type::DeducedTemplateSpecialization: return; case Type::Pipe: @@ -8132,6 +8157,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, llvm_unreachable("Non-canonical and dependent types shouldn't get here"); case Type::Auto: + case Type::DeducedTemplateSpecialization: case Type::LValueReference: case Type::RValueReference: case Type::MemberPointer: |