summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/DeclarationName.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-02-07 01:37:30 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-02-07 01:37:30 +0000
commit3584515018dae90848bc6d4edb156bc893b28083 (patch)
tree933f4ebae63400d49adb1951627a9c566cafc6db /clang/lib/AST/DeclarationName.cpp
parent8f844f39607f21daf7be93f7253d0e2eda83fb5f (diff)
downloadbcm5719-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.cpp98
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: {
OpenPOWER on IntegriCloud