summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorSaar Raz <saar@raz.email>2020-01-09 15:07:51 +0200
committerSaar Raz <saar@raz.email>2020-01-09 15:07:51 +0200
commitb65b1f322bd88513586a4539d2b5f18aeb698f3f (patch)
treea5d8eb911df5b6d857675415efc125270826a740 /clang/lib/AST
parent9c91d79dadc660cb6a0ec736389341debd8cd118 (diff)
downloadbcm5719-llvm-b65b1f322bd88513586a4539d2b5f18aeb698f3f.tar.gz
bcm5719-llvm-b65b1f322bd88513586a4539d2b5f18aeb698f3f.zip
[Concepts] Function trailing requires clauses
Function trailing requires clauses now parsed, supported in overload resolution and when calling, referencing and taking the address of functions or function templates. Differential Revision: https://reviews.llvm.org/D43357
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTImporter.cpp20
-rw-r--r--clang/lib/AST/Decl.cpp43
-rw-r--r--clang/lib/AST/DeclCXX.cpp38
-rw-r--r--clang/lib/AST/DeclPrinter.cpp5
-rwxr-xr-xclang/lib/AST/DeclTemplate.cpp11
5 files changed, 76 insertions, 41 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 567d2bf7d22..f6c3aa1a3c1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3279,10 +3279,12 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
TypeSourceInfo *TInfo;
SourceLocation ToInnerLocStart, ToEndLoc;
NestedNameSpecifierLoc ToQualifierLoc;
+ Expr *TrailingRequiresClause;
if (auto Imp = importSeq(
FromTy, D->getTypeSourceInfo(), D->getInnerLocStart(),
- D->getQualifierLoc(), D->getEndLoc()))
- std::tie(T, TInfo, ToInnerLocStart, ToQualifierLoc, ToEndLoc) = *Imp;
+ D->getQualifierLoc(), D->getEndLoc(), D->getTrailingRequiresClause()))
+ std::tie(T, TInfo, ToInnerLocStart, ToQualifierLoc, ToEndLoc,
+ TrailingRequiresClause) = *Imp;
else
return Imp.takeError();
@@ -3311,7 +3313,10 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
ExplicitSpecifier(
ExplicitExpr,
FromConstructor->getExplicitSpecifier().getKind()),
- D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind()))
+ D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind(),
+ InheritedConstructor(), // FIXME: Properly import inherited
+ // constructor info
+ TrailingRequiresClause))
return ToFunction;
} else if (CXXDestructorDecl *FromDtor = dyn_cast<CXXDestructorDecl>(D)) {
@@ -3329,7 +3334,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (GetImportedOrCreateDecl<CXXDestructorDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
- D->isImplicit(), D->getConstexprKind()))
+ D->isImplicit(), D->getConstexprKind(), TrailingRequiresClause))
return ToFunction;
CXXDestructorDecl *ToDtor = cast<CXXDestructorDecl>(ToFunction);
@@ -3349,20 +3354,21 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
ExplicitSpecifier(ExplicitExpr,
FromConversion->getExplicitSpecifier().getKind()),
- D->getConstexprKind(), SourceLocation()))
+ D->getConstexprKind(), SourceLocation(), TrailingRequiresClause))
return ToFunction;
} else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) {
if (GetImportedOrCreateDecl<CXXMethodDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
ToInnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(),
Method->isInlineSpecified(), D->getConstexprKind(),
- SourceLocation()))
+ SourceLocation(), TrailingRequiresClause))
return ToFunction;
} else {
if (GetImportedOrCreateDecl(
ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart,
NameInfo, T, TInfo, D->getStorageClass(), D->isInlineSpecified(),
- D->hasWrittenPrototype(), D->getConstexprKind()))
+ D->hasWrittenPrototype(), D->getConstexprKind(),
+ TrailingRequiresClause))
return ToFunction;
}
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 6cfd4c2a2a2..e760fff2ff6 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1839,21 +1839,25 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
}
// Set qualifier info.
getExtInfo()->QualifierLoc = QualifierLoc;
- } else {
+ } else if (hasExtInfo()) {
// Here Qualifier == 0, i.e., we are removing the qualifier (if any).
- if (hasExtInfo()) {
- if (getExtInfo()->NumTemplParamLists == 0) {
- // Save type source info pointer.
- TypeSourceInfo *savedTInfo = getExtInfo()->TInfo;
- // Deallocate the extended decl info.
- getASTContext().Deallocate(getExtInfo());
- // Restore savedTInfo into (non-extended) decl info.
- DeclInfo = savedTInfo;
- }
- else
- getExtInfo()->QualifierLoc = QualifierLoc;
- }
+ getExtInfo()->QualifierLoc = QualifierLoc;
+ }
+}
+
+void DeclaratorDecl::setTrailingRequiresClause(Expr *TrailingRequiresClause) {
+ assert(TrailingRequiresClause);
+ // Make sure the extended decl info is allocated.
+ if (!hasExtInfo()) {
+ // Save (non-extended) type source info pointer.
+ auto *savedTInfo = DeclInfo.get<TypeSourceInfo*>();
+ // Allocate external info struct.
+ DeclInfo = new (getASTContext()) ExtInfo;
+ // Restore savedTInfo into (extended) decl info.
+ getExtInfo()->TInfo = savedTInfo;
}
+ // Set requires clause info.
+ getExtInfo()->TrailingRequiresClause = TrailingRequiresClause;
}
void DeclaratorDecl::setTemplateParameterListsInfo(
@@ -2777,7 +2781,8 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, StorageClass S,
bool isInlineSpecified,
- ConstexprSpecKind ConstexprKind)
+ ConstexprSpecKind ConstexprKind,
+ Expr *TrailingRequiresClause)
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
StartLoc),
DeclContext(DK), redeclarable_base(C), Body(), ODRHash(0),
@@ -2807,6 +2812,8 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
FunctionDeclBits.IsMultiVersion = false;
FunctionDeclBits.IsCopyDeductionCandidate = false;
FunctionDeclBits.HasODRHash = false;
+ if (TrailingRequiresClause)
+ setTrailingRequiresClause(TrailingRequiresClause);
}
void FunctionDecl::getNameForDiagnostic(
@@ -4683,10 +4690,12 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
QualType T, TypeSourceInfo *TInfo,
StorageClass SC, bool isInlineSpecified,
bool hasWrittenPrototype,
- ConstexprSpecKind ConstexprKind) {
+ ConstexprSpecKind ConstexprKind,
+ Expr *TrailingRequiresClause) {
FunctionDecl *New =
new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo,
- SC, isInlineSpecified, ConstexprKind);
+ SC, isInlineSpecified, ConstexprKind,
+ TrailingRequiresClause);
New->setHasWrittenPrototype(hasWrittenPrototype);
return New;
}
@@ -4694,7 +4703,7 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) FunctionDecl(Function, C, nullptr, SourceLocation(),
DeclarationNameInfo(), QualType(), nullptr,
- SC_None, false, CSK_unspecified);
+ SC_None, false, CSK_unspecified, nullptr);
}
BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index caa60408b5b..bc75c4e544d 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -2041,16 +2041,19 @@ CXXMethodDecl *CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
QualType T, TypeSourceInfo *TInfo,
StorageClass SC, bool isInline,
ConstexprSpecKind ConstexprKind,
- SourceLocation EndLocation) {
+ SourceLocation EndLocation,
+ Expr *TrailingRequiresClause) {
return new (C, RD)
CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo, T, TInfo, SC,
- isInline, ConstexprKind, EndLocation);
+ isInline, ConstexprKind, EndLocation,
+ TrailingRequiresClause);
}
CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) CXXMethodDecl(
CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(),
- QualType(), nullptr, SC_None, false, CSK_unspecified, SourceLocation());
+ QualType(), nullptr, SC_None, false, CSK_unspecified, SourceLocation(),
+ nullptr);
}
CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
@@ -2431,9 +2434,11 @@ CXXConstructorDecl::CXXConstructorDecl(
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
- ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited)
+ ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited,
+ Expr *TrailingRequiresClause)
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, ConstexprKind, SourceLocation()) {
+ SC_None, isInline, ConstexprKind, SourceLocation(),
+ TrailingRequiresClause) {
setNumCtorInitializers(0);
setInheritingConstructor(static_cast<bool>(Inherited));
setImplicit(isImplicitlyDeclared);
@@ -2457,7 +2462,7 @@ CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C,
auto *Result = new (C, ID, Extra)
CXXConstructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(),
QualType(), nullptr, ExplicitSpecifier(), false, false,
- CSK_unspecified, InheritedConstructor());
+ CSK_unspecified, InheritedConstructor(), nullptr);
Result->setInheritingConstructor(isInheritingConstructor);
Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier =
hasTraillingExplicit;
@@ -2469,7 +2474,8 @@ CXXConstructorDecl *CXXConstructorDecl::Create(
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
- ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited) {
+ ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited,
+ Expr *TrailingRequiresClause) {
assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXConstructorName &&
"Name must refer to a constructor");
@@ -2478,7 +2484,8 @@ CXXConstructorDecl *CXXConstructorDecl::Create(
Inherited ? 1 : 0, ES.getExpr() ? 1 : 0);
return new (C, RD, Extra)
CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, ES, isInline,
- isImplicitlyDeclared, ConstexprKind, Inherited);
+ isImplicitlyDeclared, ConstexprKind, Inherited,
+ TrailingRequiresClause);
}
CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() const {
@@ -2599,19 +2606,22 @@ CXXDestructorDecl *
CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID)
CXXDestructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(),
- QualType(), nullptr, false, false, CSK_unspecified);
+ QualType(), nullptr, false, false, CSK_unspecified,
+ nullptr);
}
CXXDestructorDecl *CXXDestructorDecl::Create(
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind) {
+ bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
+ Expr *TrailingRequiresClause) {
assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXDestructorName &&
"Name must refer to a destructor");
return new (C, RD)
CXXDestructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, isInline,
- isImplicitlyDeclared, ConstexprKind);
+ isImplicitlyDeclared, ConstexprKind,
+ TrailingRequiresClause);
}
void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) {
@@ -2630,20 +2640,20 @@ CXXConversionDecl *
CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) CXXConversionDecl(
C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
- false, ExplicitSpecifier(), CSK_unspecified, SourceLocation());
+ false, ExplicitSpecifier(), CSK_unspecified, SourceLocation(), nullptr);
}
CXXConversionDecl *CXXConversionDecl::Create(
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
- SourceLocation EndLocation) {
+ SourceLocation EndLocation, Expr *TrailingRequiresClause) {
assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXConversionFunctionName &&
"Name must refer to a conversion function");
return new (C, RD)
CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo, isInline, ES,
- ConstexprKind, EndLocation);
+ ConstexprKind, EndLocation, TrailingRequiresClause);
}
bool CXXConversionDecl::isLambdaToBlockPointerConversion() const {
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 6b17dd4dde7..68cc8b7a0eb 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -740,6 +740,11 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
Proto.clear();
}
Out << Proto;
+
+ if (Expr *TrailingRequiresClause = D->getTrailingRequiresClause()) {
+ Out << " requires ";
+ TrailingRequiresClause->printPretty(Out, nullptr, SubPolicy, Indentation);
+ }
} else {
Ty.print(Out, Policy, Proto);
}
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 23734396b76..59fa7faad92 100755
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -171,13 +171,18 @@ void TemplateDecl::anchor() {}
void TemplateDecl::
getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
- // TODO: Concepts: Append function trailing requires clause.
TemplateParams->getAssociatedConstraints(AC);
+ if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
+ if (const Expr *TRC = FD->getTrailingRequiresClause())
+ AC.push_back(TRC);
}
bool TemplateDecl::hasAssociatedConstraints() const {
- // TODO: Concepts: Regard function trailing requires clause.
- return TemplateParams->hasAssociatedConstraints();
+ if (TemplateParams->hasAssociatedConstraints())
+ return true;
+ if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
+ return FD->getTrailingRequiresClause();
+ return false;
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud