Skip to content

Commit ec2e457

Browse files
authored
Add new _Coroutine Keyword (#1)
* _Coroutine recognized by editor as its own type
1 parent 42be165 commit ec2e457

File tree

19 files changed

+67
-8
lines changed

19 files changed

+67
-8
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,4 @@ pythonenv*
7171
/clang/utils/analyzer/projects/*/RefScanBuildResults
7272
# automodapi puts generated documentation files here.
7373
/lldb/docs/python_api/
74+
llvm-project.code-workspace

clang/include/clang/AST/Decl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3768,7 +3768,7 @@ class TagDecl : public TypeDecl,
37683768

37693769
bool isStruct() const { return getTagKind() == TagTypeKind::Struct; }
37703770
bool isInterface() const { return getTagKind() == TagTypeKind::Interface; }
3771-
bool isClass() const { return getTagKind() == TagTypeKind::Class; }
3771+
bool isClass() const { return getTagKind() == TagTypeKind::Class || getTagKind() == TagTypeKind::Coroutine; }
37723772
bool isUnion() const { return getTagKind() == TagTypeKind::Union; }
37733773
bool isEnum() const { return getTagKind() == TagTypeKind::Enum; }
37743774

clang/include/clang/AST/Type.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6859,6 +6859,9 @@ enum class ElaboratedTypeKeyword {
68596859
/// \c typename T::type.
68606860
Typename,
68616861

6862+
/// The "Coroutine" keyword also introduces elaborated-type specifier
6863+
Coroutine,
6864+
68626865
/// No keyword precedes the qualified type name.
68636866
None
68646867
};
@@ -6878,7 +6881,10 @@ enum class TagTypeKind {
68786881
Class,
68796882

68806883
/// The "enum" keyword.
6881-
Enum
6884+
Enum,
6885+
6886+
/// The "_Coroutine" keyword.
6887+
Coroutine
68826888
};
68836889

68846890
/// A helper class for Type nodes having an ElaboratedTypeKeyword.

clang/include/clang/Basic/Specifiers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ namespace clang {
7979
TST_enum,
8080
TST_union,
8181
TST_struct,
82+
TST_coroutine,
8283
TST_class, // C++ class type
8384
TST_interface, // C++ (Microsoft-specific) __interface type
8485
TST_typename, // Typedef, C++ class-name or enum name, etc.

clang/include/clang/Basic/TokenKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ KEYWORD(_Atomic , KEYALL|KEYNOOPENCL)
336336
KEYWORD(_Bool , KEYNOCXX)
337337
KEYWORD(_Complex , KEYALL)
338338
KEYWORD(_Generic , KEYALL)
339+
KEYWORD(_Coroutine , KEYALL)
339340
// Note, C2y removed support for _Imaginary; we retain it as a keyword because
340341
// 1) it's a reserved identifier, so we're allowed to steal it, 2) there's no
341342
// good way to specify a keyword in earlier but not later language modes within

clang/include/clang/Sema/DeclSpec.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ class DeclSpec {
303303
static const TST TST_struct = clang::TST_struct;
304304
static const TST TST_interface = clang::TST_interface;
305305
static const TST TST_class = clang::TST_class;
306+
static const TST TST_coroutine = clang::TST_coroutine;
306307
static const TST TST_typename = clang::TST_typename;
307308
static const TST TST_typeofType = clang::TST_typeofType;
308309
static const TST TST_typeofExpr = clang::TST_typeofExpr;
@@ -469,7 +470,7 @@ class DeclSpec {
469470
static bool isDeclRep(TST T) {
470471
return (T == TST_enum || T == TST_struct ||
471472
T == TST_interface || T == TST_union ||
472-
T == TST_class);
473+
T == TST_class || T == TST_coroutine);
473474
}
474475
static bool isTransformTypeTrait(TST T) {
475476
constexpr std::array<TST, 16> Traits = {

clang/lib/AST/Type.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3159,6 +3159,8 @@ TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
31593159
return ElaboratedTypeKeyword::None;
31603160
case TST_typename:
31613161
return ElaboratedTypeKeyword::Typename;
3162+
case TST_coroutine:
3163+
return ElaboratedTypeKeyword::Coroutine;
31623164
case TST_class:
31633165
return ElaboratedTypeKeyword::Class;
31643166
case TST_struct:
@@ -3175,6 +3177,8 @@ TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
31753177
TagTypeKind
31763178
TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
31773179
switch(TypeSpec) {
3180+
case TST_coroutine:
3181+
return TagTypeKind::Coroutine;
31783182
case TST_class:
31793183
return TagTypeKind::Class;
31803184
case TST_struct:
@@ -3195,6 +3199,8 @@ TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {
31953199
switch (Kind) {
31963200
case TagTypeKind::Class:
31973201
return ElaboratedTypeKeyword::Class;
3202+
case TagTypeKind::Coroutine:
3203+
return ElaboratedTypeKeyword::Coroutine;
31983204
case TagTypeKind::Struct:
31993205
return ElaboratedTypeKeyword::Struct;
32003206
case TagTypeKind::Interface:
@@ -3212,6 +3218,8 @@ TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
32123218
switch (Keyword) {
32133219
case ElaboratedTypeKeyword::Class:
32143220
return TagTypeKind::Class;
3221+
case ElaboratedTypeKeyword::Coroutine:
3222+
return TagTypeKind::Coroutine;
32153223
case ElaboratedTypeKeyword::Struct:
32163224
return TagTypeKind::Struct;
32173225
case ElaboratedTypeKeyword::Interface:
@@ -3234,6 +3242,7 @@ TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
32343242
case ElaboratedTypeKeyword::Typename:
32353243
return false;
32363244
case ElaboratedTypeKeyword::Class:
3245+
case ElaboratedTypeKeyword::Coroutine:
32373246
case ElaboratedTypeKeyword::Struct:
32383247
case ElaboratedTypeKeyword::Interface:
32393248
case ElaboratedTypeKeyword::Union:
@@ -3259,6 +3268,8 @@ StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
32593268
return "union";
32603269
case ElaboratedTypeKeyword::Enum:
32613270
return "enum";
3271+
case ElaboratedTypeKeyword::Coroutine:
3272+
return "_Coroutine";
32623273
}
32633274

32643275
llvm_unreachable("Unknown elaborated type keyword.");

clang/lib/Index/USRGeneration.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {
529529
switch (D->getTagKind()) {
530530
case TagTypeKind::Interface:
531531
case TagTypeKind::Class:
532+
case TagTypeKind::Coroutine:
532533
case TagTypeKind::Struct:
533534
Out << "@ST";
534535
break;
@@ -546,6 +547,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {
546547
switch (D->getTagKind()) {
547548
case TagTypeKind::Interface:
548549
case TagTypeKind::Class:
550+
case TagTypeKind::Coroutine:
549551
case TagTypeKind::Struct:
550552
Out << "@SP";
551553
break;
@@ -563,6 +565,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {
563565
switch (D->getTagKind()) {
564566
case TagTypeKind::Interface:
565567
case TagTypeKind::Class:
568+
case TagTypeKind::Coroutine:
566569
case TagTypeKind::Struct:
567570
Out << "@S";
568571
break;

clang/lib/Parse/ParseDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3120,6 +3120,8 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
31203120
TagKind=tok::kw___interface;break;
31213121
case DeclSpec::TST_class:
31223122
TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;
3123+
case DeclSpec::TST_coroutine:
3124+
TagName="coroutine" ; FixitTagName = "coroutine "; TagKind=tok::kw__Coroutine; break;
31233125
}
31243126

31253127
if (TagName) {
@@ -4684,6 +4686,7 @@ void Parser::ParseDeclarationSpecifiers(
46844686

46854687
// class-specifier:
46864688
case tok::kw_class:
4689+
case tok::kw__Coroutine:
46874690
case tok::kw_struct:
46884691
case tok::kw___interface:
46894692
case tok::kw_union: {

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
#include "clang/Sema/Scope.h"
3030
#include "clang/Sema/SemaCodeCompletion.h"
3131
#include "llvm/ADT/SmallString.h"
32+
#include "llvm/Support/Error.h"
3233
#include "llvm/Support/TimeProfiler.h"
34+
#include "llvm/Support/raw_ostream.h"
3335
#include <optional>
3436

3537
using namespace clang;
@@ -1724,6 +1726,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
17241726
TagType = DeclSpec::TST_interface;
17251727
else if (TagTokKind == tok::kw_class)
17261728
TagType = DeclSpec::TST_class;
1729+
else if (TagTokKind == tok::kw__Coroutine) {
1730+
TagType = DeclSpec::TST_coroutine;
1731+
}
1732+
17271733
else {
17281734
assert(TagTokKind == tok::kw_union && "Not a class specifier");
17291735
TagType = DeclSpec::TST_union;
@@ -3755,7 +3761,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
37553761
unsigned TagType, Decl *TagDecl) {
37563762
assert((TagType == DeclSpec::TST_struct ||
37573763
TagType == DeclSpec::TST_interface ||
3758-
TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class) &&
3764+
TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class || TagType == DeclSpec::TST_coroutine) &&
37593765
"Invalid TagType!");
37603766

37613767
llvm::TimeTraceScope TimeScope("ParseClass", [&]() {
@@ -3932,7 +3938,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
39323938
// are public by default.
39333939
// HLSL: In HLSL members of a class are public by default.
39343940
AccessSpecifier CurAS;
3935-
if (TagType == DeclSpec::TST_class && !getLangOpts().HLSL)
3941+
if ((TagType == DeclSpec::TST_class || TagType == DeclSpec::TST_coroutine) && !getLangOpts().HLSL)
39363942
CurAS = AS_private;
39373943
else
39383944
CurAS = AS_public;

0 commit comments

Comments
 (0)