diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-02-07 01:37:30 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-02-07 01:37:30 +0000 |
commit | 3584515018dae90848bc6d4edb156bc893b28083 (patch) | |
tree | 933f4ebae63400d49adb1951627a9c566cafc6db /clang/lib/AST/DeclarationName.cpp | |
parent | 8f844f39607f21daf7be93f7253d0e2eda83fb5f (diff) | |
download | bcm5719-llvm-3584515018dae90848bc6d4edb156bc893b28083.tar.gz bcm5719-llvm-3584515018dae90848bc6d4edb156bc893b28083.zip |
P0091R3: Implement basic parsing support for C++17 deduction-guides.
We model deduction-guides as functions with a new kind of name that identifies
the template whose deduction they guide; the bulk of this patch is adding the
new name kind. This gives us a clean way to attach an extensible list of guides
to a class template in a way that doesn't require any special handling in AST
files etc (and we're going to need these functions we come to performing
deduction).
llvm-svn: 294266
Diffstat (limited to 'clang/lib/AST/DeclarationName.cpp')
-rw-r--r-- | clang/lib/AST/DeclarationName.cpp | 98 |
1 files changed, 91 insertions, 7 deletions
diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp index 52791e51d2d..5f09b2701a1 100644 --- a/clang/lib/AST/DeclarationName.cpp +++ b/clang/lib/AST/DeclarationName.cpp @@ -14,6 +14,7 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeOrdering.h" @@ -43,6 +44,22 @@ public: } }; +/// Contains extra information for the name of a C++ deduction guide. +class CXXDeductionGuideNameExtra : public DeclarationNameExtra, + public llvm::FoldingSetNode { +public: + /// The template named by the deduction guide. + TemplateDecl *Template; + + /// FETokenInfo - Extra information associated with this operator + /// name that can be used by the front end. + void *FETokenInfo; + + void Profile(llvm::FoldingSetNodeID &ID) { + ID.AddPointer(Template); + } +}; + /// CXXOperatorIdName - Contains extra information for the name of an /// overloaded operator in C++, such as "operator+. class CXXOperatorIdName : public DeclarationNameExtra { @@ -122,7 +139,13 @@ int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType())) return 1; return 0; - + + case DeclarationName::CXXDeductionGuideName: + // We never want to compare deduction guide names for templates from + // different scopes, so just compare the template-name. + return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(), + RHS.getCXXDeductionGuideTemplate()->getDeclName()); + case DeclarationName::CXXOperatorName: return compareInt(LHS.getCXXOverloadedOperator(), RHS.getCXXOverloadedOperator()); @@ -179,6 +202,9 @@ void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) { return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); } + case DeclarationName::CXXDeductionGuideName: + return getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy); + case DeclarationName::CXXOperatorName: { static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = { nullptr, @@ -243,6 +269,9 @@ DeclarationName::NameKind DeclarationName::getNameKind() const { case DeclarationNameExtra::CXXDestructor: return CXXDestructorName; + case DeclarationNameExtra::CXXDeductionGuide: + return CXXDeductionGuideName; + case DeclarationNameExtra::CXXConversionFunction: return CXXConversionFunctionName; @@ -268,7 +297,15 @@ DeclarationName::NameKind DeclarationName::getNameKind() const { bool DeclarationName::isDependentName() const { QualType T = getCXXNameType(); - return !T.isNull() && T->isDependentType(); + if (!T.isNull() && T->isDependentType()) + return true; + + // A class-scope deduction guide in a dependent context has a dependent name. + auto *TD = getCXXDeductionGuideTemplate(); + if (TD && TD->getDeclContext()->isDependentContext()) + return true; + + return false; } std::string DeclarationName::getAsString() const { @@ -285,6 +322,12 @@ QualType DeclarationName::getCXXNameType() const { return QualType(); } +TemplateDecl *DeclarationName::getCXXDeductionGuideTemplate() const { + if (auto *Guide = getAsCXXDeductionGuideNameExtra()) + return Guide->Template; + return nullptr; +} + OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { unsigned value @@ -312,6 +355,9 @@ void *DeclarationName::getFETokenInfoAsVoidSlow() const { case CXXConversionFunctionName: return getAsCXXSpecialName()->FETokenInfo; + case CXXDeductionGuideName: + return getAsCXXDeductionGuideNameExtra()->FETokenInfo; + case CXXOperatorName: return getAsCXXOperatorIdName()->FETokenInfo; @@ -335,6 +381,10 @@ void DeclarationName::setFETokenInfo(void *T) { getAsCXXSpecialName()->FETokenInfo = T; break; + case CXXDeductionGuideName: + getAsCXXDeductionGuideNameExtra()->FETokenInfo = T; + break; + case CXXOperatorName: getAsCXXOperatorIdName()->FETokenInfo = T; break; @@ -366,6 +416,7 @@ LLVM_DUMP_METHOD void DeclarationName::dump() const { DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; + CXXDeductionGuideNames = new llvm::FoldingSet<CXXDeductionGuideNameExtra>; // Initialize the overloaded operator names. CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; @@ -377,14 +428,18 @@ DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { } DeclarationNameTable::~DeclarationNameTable() { - llvm::FoldingSet<CXXSpecialName> *SpecialNames = - static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); - llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames - = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> - (CXXLiteralOperatorNames); + auto *SpecialNames = + static_cast<llvm::FoldingSet<CXXSpecialName> *>(CXXSpecialNamesImpl); + auto *LiteralNames = + static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName> *>( + CXXLiteralOperatorNames); + auto *DeductionGuideNames = + static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>( + CXXDeductionGuideNames); delete SpecialNames; delete LiteralNames; + delete DeductionGuideNames; } DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) { @@ -398,6 +453,30 @@ DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) { } DeclarationName +DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) { + Template = cast<TemplateDecl>(Template->getCanonicalDecl()); + + auto *DeductionGuideNames = + static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>( + CXXDeductionGuideNames); + + llvm::FoldingSetNodeID ID; + ID.AddPointer(Template); + + void *InsertPos = nullptr; + if (auto *Name = DeductionGuideNames->FindNodeOrInsertPos(ID, InsertPos)) + return DeclarationName(Name); + + auto *Name = new (Ctx) CXXDeductionGuideNameExtra; + Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide; + Name->Template = Template; + Name->FETokenInfo = nullptr; + + DeductionGuideNames->InsertNode(Name, InsertPos); + return DeclarationName(Name); +} + +DeclarationName DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) { return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty); } @@ -477,6 +556,7 @@ DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { switch (Name.getNameKind()) { case DeclarationName::Identifier: + case DeclarationName::CXXDeductionGuideName: break; case DeclarationName::CXXConstructorName: case DeclarationName::CXXDestructorName: @@ -509,6 +589,7 @@ bool DeclarationNameInfo::containsUnexpandedParameterPack() const { case DeclarationName::CXXOperatorName: case DeclarationName::CXXLiteralOperatorName: case DeclarationName::CXXUsingDirective: + case DeclarationName::CXXDeductionGuideName: return false; case DeclarationName::CXXConstructorName: @@ -531,6 +612,7 @@ bool DeclarationNameInfo::isInstantiationDependent() const { case DeclarationName::CXXOperatorName: case DeclarationName::CXXLiteralOperatorName: case DeclarationName::CXXUsingDirective: + case DeclarationName::CXXDeductionGuideName: return false; case DeclarationName::CXXConstructorName: @@ -560,6 +642,7 @@ void DeclarationNameInfo::printName(raw_ostream &OS) const { case DeclarationName::CXXOperatorName: case DeclarationName::CXXLiteralOperatorName: case DeclarationName::CXXUsingDirective: + case DeclarationName::CXXDeductionGuideName: OS << Name; return; @@ -585,6 +668,7 @@ void DeclarationNameInfo::printName(raw_ostream &OS) const { SourceLocation DeclarationNameInfo::getEndLoc() const { switch (Name.getNameKind()) { case DeclarationName::Identifier: + case DeclarationName::CXXDeductionGuideName: return NameLoc; case DeclarationName::CXXOperatorName: { |