[CONCEPTS] Parsing of concept keyword
Summary: This change adds parsing for the concept keyword in a declaration and tracks the location. Diagnostic testing added for invalid use of concept keyword. Reviewers: faisalv, fraggamuffin, rsmith, hubert.reinterpretcast Reviewed By: rsmith, hubert.reinterpretcast Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D10528 Patch by Nathan Wilson! llvm-svn: 241060
This commit is contained in:
parent
a87af7a326
commit
375f00ad7b
|
@ -358,6 +358,9 @@ private:
|
|||
// constexpr-specifier
|
||||
unsigned Constexpr_specified : 1;
|
||||
|
||||
// concept-specifier
|
||||
unsigned Concept_specified : 1;
|
||||
|
||||
union {
|
||||
UnionParsedType TypeRep;
|
||||
Decl *DeclRep;
|
||||
|
@ -393,7 +396,7 @@ private:
|
|||
SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc;
|
||||
SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc;
|
||||
SourceLocation FS_forceinlineLoc;
|
||||
SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc;
|
||||
SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc, ConceptLoc;
|
||||
|
||||
WrittenBuiltinSpecs writtenBS;
|
||||
void SaveWrittenBuiltinSpecs();
|
||||
|
@ -437,6 +440,7 @@ public:
|
|||
FS_noreturn_specified(false),
|
||||
Friend_specified(false),
|
||||
Constexpr_specified(false),
|
||||
Concept_specified(false),
|
||||
Attrs(attrFactory),
|
||||
ProtocolQualifiers(nullptr),
|
||||
NumProtocolQualifiers(0),
|
||||
|
@ -688,6 +692,8 @@ public:
|
|||
unsigned &DiagID);
|
||||
bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
|
||||
unsigned &DiagID);
|
||||
bool SetConceptSpec(SourceLocation Loc, const char *&PrevSpec,
|
||||
unsigned &DiagID);
|
||||
|
||||
bool isFriendSpecified() const { return Friend_specified; }
|
||||
SourceLocation getFriendSpecLoc() const { return FriendLoc; }
|
||||
|
@ -698,11 +704,19 @@ public:
|
|||
bool isConstexprSpecified() const { return Constexpr_specified; }
|
||||
SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; }
|
||||
|
||||
bool isConceptSpecified() const { return Concept_specified; }
|
||||
SourceLocation getConceptSpecLoc() const { return ConceptLoc; }
|
||||
|
||||
void ClearConstexprSpec() {
|
||||
Constexpr_specified = false;
|
||||
ConstexprLoc = SourceLocation();
|
||||
}
|
||||
|
||||
void ClearConceptSpec() {
|
||||
Concept_specified = false;
|
||||
ConceptLoc = SourceLocation();
|
||||
}
|
||||
|
||||
AttributePool &getAttributePool() const {
|
||||
return Attrs.getPool();
|
||||
}
|
||||
|
|
|
@ -3192,6 +3192,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
|
||||
break;
|
||||
|
||||
// concept
|
||||
case tok::kw_concept:
|
||||
isInvalid = DS.SetConceptSpec(Loc, PrevSpec, DiagID);
|
||||
break;
|
||||
|
||||
// type-specifier
|
||||
case tok::kw_short:
|
||||
isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
|
||||
|
@ -4475,6 +4480,9 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
|
|||
case tok::annot_decltype:
|
||||
case tok::kw_constexpr:
|
||||
|
||||
// C++ Concepts TS - concept
|
||||
case tok::kw_concept:
|
||||
|
||||
// C11 _Atomic
|
||||
case tok::kw__Atomic:
|
||||
return true;
|
||||
|
|
|
@ -1213,9 +1213,11 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
|||
// 'friend'
|
||||
// 'typedef'
|
||||
// 'constexpr'
|
||||
// 'concept'
|
||||
case tok::kw_friend:
|
||||
case tok::kw_typedef:
|
||||
case tok::kw_constexpr:
|
||||
case tok::kw_concept:
|
||||
// storage-class-specifier
|
||||
case tok::kw_register:
|
||||
case tok::kw_static:
|
||||
|
|
|
@ -893,6 +893,18 @@ bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DeclSpec::SetConceptSpec(SourceLocation Loc, const char *&PrevSpec,
|
||||
unsigned &DiagID) {
|
||||
if (Concept_specified) {
|
||||
DiagID = diag::ext_duplicate_declspec;
|
||||
PrevSpec = "concept";
|
||||
return true;
|
||||
}
|
||||
Concept_specified = true;
|
||||
ConceptLoc = Loc;
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeclSpec::setProtocolQualifiers(Decl * const *Protos,
|
||||
unsigned NP,
|
||||
SourceLocation *ProtoLocs,
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
// Support parsing of function concepts and variable concepts
|
||||
|
||||
// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
|
||||
|
||||
template<typename T> concept bool C1 = true;
|
||||
|
||||
template<typename T> concept bool C2() { return true; }
|
||||
|
||||
template<typename T>
|
||||
struct A { typedef bool Boolean; };
|
||||
|
||||
template<int N>
|
||||
A<void>::Boolean concept C3(!0);
|
||||
|
||||
template<typename T, int = 0>
|
||||
concept auto C4(void) -> bool { return true; }
|
||||
|
||||
constexpr int One = 1;
|
||||
|
||||
template <typename>
|
||||
static concept decltype(!0) C5 { bool(One) };
|
||||
|
||||
template<typename T> concept concept bool C6 = true; // expected-warning {{duplicate 'concept' declaration specifier}}
|
||||
|
||||
template<typename T> concept concept bool C7() { return true; } // expected-warning {{duplicate 'concept' declaration specifier}}
|
||||
|
||||
concept D1 = true; // expected-error {{C++ requires a type specifier for all declarations}}
|
||||
|
||||
template<concept T> concept bool D2 = true; // expected-error {{unknown type name 'T'}}
|
Loading…
Reference in New Issue