Skip to content

Commit 2a8ab8f

Browse files
author
git apple-llvm automerger
committed
Merge commit 'b481f028144c' from llvm.org/master into apple/master
2 parents 89247eb + b481f02 commit 2a8ab8f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1871
-362
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class AtomicExpr;
8888
class BlockExpr;
8989
class BuiltinTemplateDecl;
9090
class CharUnits;
91+
class ConceptDecl;
9192
class CXXABI;
9293
class CXXConstructorDecl;
9394
class CXXMethodDecl;
@@ -211,7 +212,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
211212
mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
212213
mutable llvm::FoldingSet<DependentUnaryTransformType>
213214
DependentUnaryTransformTypes;
214-
mutable llvm::FoldingSet<AutoType> AutoTypes;
215+
mutable llvm::ContextualFoldingSet<AutoType, ASTContext&> AutoTypes;
215216
mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
216217
DeducedTemplateSpecializationTypes;
217218
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
@@ -1545,7 +1546,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
15451546

15461547
/// C++11 deduced auto type.
15471548
QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
1548-
bool IsDependent, bool IsPack = false) const;
1549+
bool IsDependent, bool IsPack = false,
1550+
ConceptDecl *TypeConstraintConcept = nullptr,
1551+
ArrayRef<TemplateArgument> TypeConstraintArgs ={}) const;
15491552

15501553
/// C++11 deduction pattern for 'auto' type.
15511554
QualType getAutoDeductType() const;

clang/include/clang/AST/ASTNodeTraverser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,8 +548,8 @@ class ASTNodeTraverser
548548
}
549549

550550
void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
551-
if (const auto *TC = D->getPlaceholderTypeConstraint())
552-
Visit(TC->getImmediatelyDeclaredConstraint());
551+
if (const auto *E = D->getPlaceholderTypeConstraint())
552+
Visit(E);
553553
if (D->hasDefaultArgument())
554554
Visit(D->getDefaultArgument(), SourceRange(),
555555
D->getDefaultArgStorage().getInheritedFrom(),

clang/include/clang/AST/DeclTemplate.h

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,17 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl {
11021102
/// template.
11031103
ArrayRef<TemplateArgument> getInjectedTemplateArgs();
11041104

1105+
/// Return whether this function template is an abbreviated function template,
1106+
/// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1107+
bool isAbbreviated() const {
1108+
// Since the invented template parameters generated from 'auto' parameters
1109+
// are either appended to the end of the explicit template parameter list or
1110+
// form a new template paramter list, we can simply observe the last
1111+
// parameter to determine if such a thing happened.
1112+
const TemplateParameterList *TPL = getTemplateParameters();
1113+
return TPL->getParam(TPL->size() - 1)->isImplicit();
1114+
}
1115+
11051116
/// Merge \p Prev with our RedeclarableTemplateDecl::Common.
11061117
void mergePrevDecl(FunctionTemplateDecl *Prev);
11071118

@@ -1215,7 +1226,6 @@ class TemplateTypeParmDecl final : public TypeDecl,
12151226
bool ParameterPack,
12161227
bool HasTypeConstraint = false,
12171228
Optional<unsigned> NumExpanded = None);
1218-
12191229
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
12201230
unsigned ID);
12211231
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
@@ -1374,7 +1384,8 @@ class NonTypeTemplateParmDecl final
13741384
: public DeclaratorDecl,
13751385
protected TemplateParmPosition,
13761386
private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1377-
std::pair<QualType, TypeSourceInfo *>> {
1387+
std::pair<QualType, TypeSourceInfo *>,
1388+
Expr *> {
13781389
friend class ASTDeclReader;
13791390
friend TrailingObjects;
13801391

@@ -1429,10 +1440,12 @@ class NonTypeTemplateParmDecl final
14291440
ArrayRef<TypeSourceInfo *> ExpandedTInfos);
14301441

14311442
static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1432-
unsigned ID);
1443+
unsigned ID,
1444+
bool HasTypeConstraint);
14331445
static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
14341446
unsigned ID,
1435-
unsigned NumExpandedTypes);
1447+
unsigned NumExpandedTypes,
1448+
bool HasTypeConstraint);
14361449

14371450
using TemplateParmPosition::getDepth;
14381451
using TemplateParmPosition::setDepth;
@@ -1543,20 +1556,22 @@ class NonTypeTemplateParmDecl final
15431556
return TypesAndInfos[I].second;
15441557
}
15451558

1546-
/// Return the type-constraint in the placeholder type of this non-type
1559+
/// Return the constraint introduced by the placeholder type of this non-type
15471560
/// template parameter (if any).
1548-
TypeConstraint *getPlaceholderTypeConstraint() const {
1549-
// TODO: Concepts: Implement once we have actual placeholders with type
1550-
// constraints.
1551-
return nullptr;
1561+
Expr *getPlaceholderTypeConstraint() const {
1562+
return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1563+
nullptr;
1564+
}
1565+
1566+
void setPlaceholderTypeConstraint(Expr *E) {
1567+
*getTrailingObjects<Expr *>() = E;
15521568
}
15531569

15541570
/// Determine whether this non-type template parameter's type has a
15551571
/// placeholder with a type-constraint.
15561572
bool hasPlaceholderTypeConstraint() const {
1557-
// TODO: Concepts: Implement once we have actual placeholders with type
1558-
// constraints.
1559-
return false;
1573+
auto *AT = getType()->getContainedAutoType();
1574+
return AT && AT->isConstrained();
15601575
}
15611576

15621577
/// \brief Get the associated-constraints of this template parameter.
@@ -1566,8 +1581,8 @@ class NonTypeTemplateParmDecl final
15661581
/// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
15671582
/// concepts APIs that accept an ArrayRef of constraint expressions.
15681583
void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
1569-
if (TypeConstraint *TC = getPlaceholderTypeConstraint())
1570-
AC.push_back(TC->getImmediatelyDeclaredConstraint());
1584+
if (Expr *E = getPlaceholderTypeConstraint())
1585+
AC.push_back(E);
15711586
}
15721587

15731588
// Implement isa/cast/dyncast/etc.

clang/include/clang/AST/PropertiesBase.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
9999
SubclassPropertyType<"TagDecl", DeclRef>;
100100
def TemplateDeclRef :
101101
SubclassPropertyType<"TemplateDecl", DeclRef>;
102+
def ConceptDeclRef :
103+
SubclassPropertyType<"ConceptDecl", DeclRef>;
102104
def TemplateTypeParmDeclRef :
103105
SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
104106
def TemplateTemplateParmDeclRef :

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,13 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
10401040
TRY_TO(TraverseType(T->getUnderlyingType()));
10411041
})
10421042

1043-
DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
1043+
DEF_TRAVERSE_TYPE(AutoType, {
1044+
TRY_TO(TraverseType(T->getDeducedType()));
1045+
if (T->isConstrained()) {
1046+
TRY_TO(TraverseDecl(T->getTypeConstraintConcept()));
1047+
TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
1048+
}
1049+
})
10441050
DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
10451051
TRY_TO(TraverseTemplateName(T->getTemplateName()));
10461052
TRY_TO(TraverseType(T->getDeducedType()));
@@ -1287,6 +1293,12 @@ DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
12871293

12881294
DEF_TRAVERSE_TYPELOC(AutoType, {
12891295
TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
1296+
if (TL.isConstrained()) {
1297+
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()));
1298+
TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo()));
1299+
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
1300+
TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1301+
}
12901302
})
12911303

12921304
DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {

clang/include/clang/AST/TemplateBase.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ struct ASTTemplateArgumentListInfo final
637637
}
638638

639639
static const ASTTemplateArgumentListInfo *
640-
Create(ASTContext &C, const TemplateArgumentListInfo &List);
640+
Create(const ASTContext &C, const TemplateArgumentListInfo &List);
641641
};
642642

643643
/// Represents an explicit template argument list in C++, e.g.,
@@ -702,6 +702,11 @@ inline const TemplateArgument &
702702
return getArgs()[Idx];
703703
}
704704

705+
inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
706+
assert(Idx < getNumArgs() && "Template argument out of range");
707+
return getArgs()[Idx];
708+
}
709+
705710
} // namespace clang
706711

707712
#endif // LLVM_CLANG_AST_TEMPLATEBASE_H

clang/include/clang/AST/Type.h

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ namespace clang {
5858

5959
class ExtQuals;
6060
class QualType;
61+
class ConceptDecl;
6162
class TagDecl;
6263
class Type;
6364

@@ -1827,6 +1828,15 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
18271828
/// Was this placeholder type spelled as 'auto', 'decltype(auto)',
18281829
/// or '__auto_type'? AutoTypeKeyword value.
18291830
unsigned Keyword : 2;
1831+
1832+
/// The number of template arguments in the type-constraints, which is
1833+
/// expected to be able to hold at least 1024 according to [implimits].
1834+
/// However as this limit is somewhat easy to hit with template
1835+
/// metaprogramming we'd prefer to keep it as large as possible.
1836+
/// At the moment it has been left as a non-bitfield since this type
1837+
/// safely fits in 64 bits as an unsigned, so there is no reason to
1838+
/// introduce the performance impact of a bitfield.
1839+
unsigned NumArgs;
18301840
};
18311841

18321842
class SubstTemplateTypeParmPackTypeBitfields {
@@ -4958,8 +4968,7 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
49584968

49594969
/// Common base class for placeholders for types that get replaced by
49604970
/// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced
4961-
/// class template types, and (eventually) constrained type names from the C++
4962-
/// Concepts TS.
4971+
/// class template types, and constrained type names.
49634972
///
49644973
/// These types are usually a placeholder for a deduced type. However, before
49654974
/// the initializer is attached, or (usually) if the initializer is
@@ -5004,18 +5013,50 @@ class DeducedType : public Type {
50045013
}
50055014
};
50065015

5007-
/// Represents a C++11 auto or C++14 decltype(auto) type.
5008-
class AutoType : public DeducedType, public llvm::FoldingSetNode {
5016+
/// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained
5017+
/// by a type-constraint.
5018+
class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode {
50095019
friend class ASTContext; // ASTContext creates these
50105020

5021+
ConceptDecl *TypeConstraintConcept;
5022+
50115023
AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
5012-
bool IsDeducedAsDependent, bool IsDeducedAsPack)
5013-
: DeducedType(Auto, DeducedAsType, IsDeducedAsDependent,
5014-
IsDeducedAsDependent, IsDeducedAsPack) {
5015-
AutoTypeBits.Keyword = (unsigned)Keyword;
5024+
bool IsDeducedAsDependent, bool IsDeducedAsPack, ConceptDecl *CD,
5025+
ArrayRef<TemplateArgument> TypeConstraintArgs);
5026+
5027+
const TemplateArgument *getArgBuffer() const {
5028+
return reinterpret_cast<const TemplateArgument*>(this+1);
5029+
}
5030+
5031+
TemplateArgument *getArgBuffer() {
5032+
return reinterpret_cast<TemplateArgument*>(this+1);
50165033
}
50175034

50185035
public:
5036+
/// Retrieve the template arguments.
5037+
const TemplateArgument *getArgs() const {
5038+
return getArgBuffer();
5039+
}
5040+
5041+
/// Retrieve the number of template arguments.
5042+
unsigned getNumArgs() const {
5043+
return AutoTypeBits.NumArgs;
5044+
}
5045+
5046+
const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
5047+
5048+
ArrayRef<TemplateArgument> getTypeConstraintArguments() const {
5049+
return {getArgs(), getNumArgs()};
5050+
}
5051+
5052+
ConceptDecl *getTypeConstraintConcept() const {
5053+
return TypeConstraintConcept;
5054+
}
5055+
5056+
bool isConstrained() const {
5057+
return TypeConstraintConcept != nullptr;
5058+
}
5059+
50195060
bool isDecltypeAuto() const {
50205061
return getKeyword() == AutoTypeKeyword::DecltypeAuto;
50215062
}
@@ -5024,18 +5065,15 @@ class AutoType : public DeducedType, public llvm::FoldingSetNode {
50245065
return (AutoTypeKeyword)AutoTypeBits.Keyword;
50255066
}
50265067

5027-
void Profile(llvm::FoldingSetNodeID &ID) {
5028-
Profile(ID, getDeducedType(), getKeyword(), isDependentType(),
5029-
containsUnexpandedParameterPack());
5068+
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
5069+
Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
5070+
getTypeConstraintConcept(), getTypeConstraintArguments());
50305071
}
50315072

5032-
static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced,
5033-
AutoTypeKeyword Keyword, bool IsDependent, bool IsPack) {
5034-
ID.AddPointer(Deduced.getAsOpaquePtr());
5035-
ID.AddInteger((unsigned)Keyword);
5036-
ID.AddBoolean(IsDependent);
5037-
ID.AddBoolean(IsPack);
5038-
}
5073+
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
5074+
QualType Deduced, AutoTypeKeyword Keyword,
5075+
bool IsDependent, ConceptDecl *CD,
5076+
ArrayRef<TemplateArgument> Arguments);
50395077

50405078
static bool classof(const Type *T) {
50415079
return T->getTypeClass() == Auto;

0 commit comments

Comments
 (0)