Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,4 @@ pythonenv*
/clang/utils/analyzer/projects/*/RefScanBuildResults
# automodapi puts generated documentation files here.
/lldb/docs/python_api/
llvm-project.code-workspace
2 changes: 1 addition & 1 deletion clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3768,7 +3768,7 @@ class TagDecl : public TypeDecl,

bool isStruct() const { return getTagKind() == TagTypeKind::Struct; }
bool isInterface() const { return getTagKind() == TagTypeKind::Interface; }
bool isClass() const { return getTagKind() == TagTypeKind::Class; }
bool isClass() const { return getTagKind() == TagTypeKind::Class || getTagKind() == TagTypeKind::Coroutine; }
bool isUnion() const { return getTagKind() == TagTypeKind::Union; }
bool isEnum() const { return getTagKind() == TagTypeKind::Enum; }

Expand Down
8 changes: 7 additions & 1 deletion clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -6859,6 +6859,9 @@ enum class ElaboratedTypeKeyword {
/// \c typename T::type.
Typename,

/// The "Coroutine" keyword also introduces elaborated-type specifier
Coroutine,

/// No keyword precedes the qualified type name.
None
};
Expand All @@ -6878,7 +6881,10 @@ enum class TagTypeKind {
Class,

/// The "enum" keyword.
Enum
Enum,

/// The "_Coroutine" keyword.
Coroutine
};

/// A helper class for Type nodes having an ElaboratedTypeKeyword.
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/Specifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ namespace clang {
TST_enum,
TST_union,
TST_struct,
TST_coroutine,
TST_class, // C++ class type
TST_interface, // C++ (Microsoft-specific) __interface type
TST_typename, // Typedef, C++ class-name or enum name, etc.
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ KEYWORD(_Atomic , KEYALL|KEYNOOPENCL)
KEYWORD(_Bool , KEYNOCXX)
KEYWORD(_Complex , KEYALL)
KEYWORD(_Generic , KEYALL)
KEYWORD(_Coroutine , KEYALL)
// Note, C2y removed support for _Imaginary; we retain it as a keyword because
// 1) it's a reserved identifier, so we're allowed to steal it, 2) there's no
// good way to specify a keyword in earlier but not later language modes within
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Sema/DeclSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ class DeclSpec {
static const TST TST_struct = clang::TST_struct;
static const TST TST_interface = clang::TST_interface;
static const TST TST_class = clang::TST_class;
static const TST TST_coroutine = clang::TST_coroutine;
static const TST TST_typename = clang::TST_typename;
static const TST TST_typeofType = clang::TST_typeofType;
static const TST TST_typeofExpr = clang::TST_typeofExpr;
Expand Down Expand Up @@ -469,7 +470,7 @@ class DeclSpec {
static bool isDeclRep(TST T) {
return (T == TST_enum || T == TST_struct ||
T == TST_interface || T == TST_union ||
T == TST_class);
T == TST_class || T == TST_coroutine);
}
static bool isTransformTypeTrait(TST T) {
constexpr std::array<TST, 16> Traits = {
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3159,6 +3159,8 @@ TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
return ElaboratedTypeKeyword::None;
case TST_typename:
return ElaboratedTypeKeyword::Typename;
case TST_coroutine:
return ElaboratedTypeKeyword::Coroutine;
case TST_class:
return ElaboratedTypeKeyword::Class;
case TST_struct:
Expand All @@ -3175,6 +3177,8 @@ TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
TagTypeKind
TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
switch(TypeSpec) {
case TST_coroutine:
return TagTypeKind::Coroutine;
case TST_class:
return TagTypeKind::Class;
case TST_struct:
Expand All @@ -3195,6 +3199,8 @@ TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {
switch (Kind) {
case TagTypeKind::Class:
return ElaboratedTypeKeyword::Class;
case TagTypeKind::Coroutine:
return ElaboratedTypeKeyword::Coroutine;
case TagTypeKind::Struct:
return ElaboratedTypeKeyword::Struct;
case TagTypeKind::Interface:
Expand All @@ -3212,6 +3218,8 @@ TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
switch (Keyword) {
case ElaboratedTypeKeyword::Class:
return TagTypeKind::Class;
case ElaboratedTypeKeyword::Coroutine:
return TagTypeKind::Coroutine;
case ElaboratedTypeKeyword::Struct:
return TagTypeKind::Struct;
case ElaboratedTypeKeyword::Interface:
Expand All @@ -3234,6 +3242,7 @@ TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
case ElaboratedTypeKeyword::Typename:
return false;
case ElaboratedTypeKeyword::Class:
case ElaboratedTypeKeyword::Coroutine:
case ElaboratedTypeKeyword::Struct:
case ElaboratedTypeKeyword::Interface:
case ElaboratedTypeKeyword::Union:
Expand All @@ -3259,6 +3268,8 @@ StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
return "union";
case ElaboratedTypeKeyword::Enum:
return "enum";
case ElaboratedTypeKeyword::Coroutine:
return "_Coroutine";
}

llvm_unreachable("Unknown elaborated type keyword.");
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Index/USRGeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {
switch (D->getTagKind()) {
case TagTypeKind::Interface:
case TagTypeKind::Class:
case TagTypeKind::Coroutine:
case TagTypeKind::Struct:
Out << "@ST";
break;
Expand All @@ -546,6 +547,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {
switch (D->getTagKind()) {
case TagTypeKind::Interface:
case TagTypeKind::Class:
case TagTypeKind::Coroutine:
case TagTypeKind::Struct:
Out << "@SP";
break;
Expand All @@ -563,6 +565,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) {
switch (D->getTagKind()) {
case TagTypeKind::Interface:
case TagTypeKind::Class:
case TagTypeKind::Coroutine:
case TagTypeKind::Struct:
Out << "@S";
break;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3120,6 +3120,8 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
TagKind=tok::kw___interface;break;
case DeclSpec::TST_class:
TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;
case DeclSpec::TST_coroutine:
TagName="coroutine" ; FixitTagName = "coroutine "; TagKind=tok::kw__Coroutine; break;
}

if (TagName) {
Expand Down Expand Up @@ -4684,6 +4686,7 @@ void Parser::ParseDeclarationSpecifiers(

// class-specifier:
case tok::kw_class:
case tok::kw__Coroutine:
case tok::kw_struct:
case tok::kw___interface:
case tok::kw_union: {
Expand Down
10 changes: 8 additions & 2 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCodeCompletion.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>

using namespace clang;
Expand Down Expand Up @@ -1724,6 +1726,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
TagType = DeclSpec::TST_interface;
else if (TagTokKind == tok::kw_class)
TagType = DeclSpec::TST_class;
else if (TagTokKind == tok::kw__Coroutine) {
TagType = DeclSpec::TST_coroutine;
}

else {
assert(TagTokKind == tok::kw_union && "Not a class specifier");
TagType = DeclSpec::TST_union;
Expand Down Expand Up @@ -3755,7 +3761,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
unsigned TagType, Decl *TagDecl) {
assert((TagType == DeclSpec::TST_struct ||
TagType == DeclSpec::TST_interface ||
TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class) &&
TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class || TagType == DeclSpec::TST_coroutine) &&
"Invalid TagType!");

llvm::TimeTraceScope TimeScope("ParseClass", [&]() {
Expand Down Expand Up @@ -3932,7 +3938,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
// are public by default.
// HLSL: In HLSL members of a class are public by default.
AccessSpecifier CurAS;
if (TagType == DeclSpec::TST_class && !getLangOpts().HLSL)
if ((TagType == DeclSpec::TST_class || TagType == DeclSpec::TST_coroutine) && !getLangOpts().HLSL)
CurAS = AS_private;
else
CurAS = AS_public;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Parse/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(
assert(DeclSpec::isDeclRep(TKind));
switch(TKind) {
case DeclSpec::TST_class:
case DeclSpec::TST_coroutine:
return 5;
case DeclSpec::TST_struct:
return 6;
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Sema/DeclSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ bool Declarator::isDeclarationOfFunction() const {
case TST_char16:
case TST_char32:
case TST_class:
case TST_coroutine:
case TST_decimal128:
case TST_decimal32:
case TST_decimal64:
Expand Down Expand Up @@ -585,6 +586,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
case DeclSpec::TST_decimal128: return "_Decimal128";
case DeclSpec::TST_enum: return "enum";
case DeclSpec::TST_class: return "class";
case DeclSpec::TST_coroutine: return "coroutine";
case DeclSpec::TST_union: return "union";
case DeclSpec::TST_struct: return "struct";
case DeclSpec::TST_interface: return "__interface";
Expand Down
12 changes: 11 additions & 1 deletion clang/lib/Sema/SemaCodeComplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1819,8 +1819,13 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Results.AddResult(
Result("bool", CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0)));
Results.AddResult(Result("class", CCP_Type));
Results.AddResult(Result("_Coroutine", CCP_Type));
Results.AddResult(Result("wchar_t", CCP_Type));

Builder.AddTypedTextChunk("_Coroutine");
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddInformativeChunk("A Coroutine, as defined by concurrency course.");

// typename name
Builder.AddTypedTextChunk("typename");
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Expand Down Expand Up @@ -2034,6 +2039,8 @@ static const char *GetCompletionTypeString(QualType T, ASTContext &Context,
return "__interface <anonymous>";
case TagTypeKind::Class:
return "class <anonymous>";
case TagTypeKind::Coroutine:
return "class <anonymous>";
case TagTypeKind::Union:
return "union <anonymous>";
case TagTypeKind::Enum:
Expand Down Expand Up @@ -4181,6 +4188,7 @@ CXCursorKind clang::getCursorKindForDecl(const Decl *D) {
case TagTypeKind::Struct:
return CXCursor_StructDecl;
case TagTypeKind::Class:
case TagTypeKind::Coroutine:
return CXCursor_ClassDecl;
case TagTypeKind::Union:
return CXCursor_UnionDecl;
Expand Down Expand Up @@ -4533,7 +4541,8 @@ void SemaCodeCompletion::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
if (getLangOpts().CPlusPlus) {
if (getLangOpts().CPlusPlus11 &&
(DS.getTypeSpecType() == DeclSpec::TST_class ||
DS.getTypeSpecType() == DeclSpec::TST_struct))
DS.getTypeSpecType() == DeclSpec::TST_struct ||
DS.getTypeSpecType() == DeclSpec::TST_coroutine))
Results.AddResult("final");

if (AllowNonIdentifiers) {
Expand Down Expand Up @@ -5923,6 +5932,7 @@ void SemaCodeCompletion::CodeCompleteTag(Scope *S, unsigned TagSpec) {

case DeclSpec::TST_struct:
case DeclSpec::TST_class:
case DeclSpec::TST_coroutine:
case DeclSpec::TST_interface:
Filter = &ResultBuilder::IsClassOrStruct;
ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,8 @@ DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {
return DeclSpec::TST_union;
case TagTypeKind::Class:
return DeclSpec::TST_class;
case TagTypeKind::Coroutine:
return DeclSpec::TST_coroutine;
case TagTypeKind::Enum:
return DeclSpec::TST_enum;
}
Expand Down Expand Up @@ -819,6 +821,7 @@ static bool isTagTypeWithMissingTag(Sema &SemaRef, LookupResult &Result,
if (TagDecl *Tag = R.getAsSingle<TagDecl>()) {
StringRef FixItTagName;
switch (Tag->getTagKind()) {
case TagTypeKind::Coroutine:
case TagTypeKind::Class:
FixItTagName = "class ";
break;
Expand Down Expand Up @@ -4989,6 +4992,7 @@ static unsigned GetDiagnosticTypeSpecifierID(const DeclSpec &DS) {
DeclSpec::TST T = DS.getTypeSpecType();
switch (T) {
case DeclSpec::TST_class:
case DeclSpec::TST_coroutine:
return 0;
case DeclSpec::TST_struct:
return 1;
Expand Down Expand Up @@ -5019,6 +5023,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
Decl *TagD = nullptr;
TagDecl *Tag = nullptr;
if (DS.getTypeSpecType() == DeclSpec::TST_class ||
DS.getTypeSpecType() == DeclSpec::TST_coroutine ||
DS.getTypeSpecType() == DeclSpec::TST_struct ||
DS.getTypeSpecType() == DeclSpec::TST_interface ||
DS.getTypeSpecType() == DeclSpec::TST_union ||
Expand Down Expand Up @@ -5243,6 +5248,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
if (!DS.getAttributes().empty() || !DeclAttrs.empty()) {
DeclSpec::TST TypeSpecType = DS.getTypeSpecType();
if (TypeSpecType == DeclSpec::TST_class ||
TypeSpecType == DeclSpec::TST_coroutine ||
TypeSpecType == DeclSpec::TST_struct ||
TypeSpecType == DeclSpec::TST_interface ||
TypeSpecType == DeclSpec::TST_union ||
Expand Down Expand Up @@ -16799,6 +16805,7 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
case TST_struct:
case TST_interface:
case TST_union:
case TST_coroutine:
case TST_class: {
TagDecl *tagFromDeclSpec = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
setTagNameForLinkagePurposes(tagFromDeclSpec, NewTD);
Expand Down Expand Up @@ -16904,6 +16911,7 @@ Sema::NonTagKind Sema::getNonTagTypeDeclKind(const Decl *PrevDecl,
case TagTypeKind::Struct:
case TagTypeKind::Interface:
case TagTypeKind::Class:
case TagTypeKind::Coroutine:
return getLangOpts().CPlusPlus ? NTK_NonClass : NTK_NonStruct;
case TagTypeKind::Union:
return NTK_NonUnion;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaTemplateVariadic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
case TST_struct:
case TST_interface:
case TST_class:
case TST_coroutine:
case TST_auto:
case TST_auto_type:
case TST_decltype_auto:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
declarator.setInvalidType(true);
break;
case DeclSpec::TST_class:
case DeclSpec::TST_coroutine:
case DeclSpec::TST_enum:
case DeclSpec::TST_union:
case DeclSpec::TST_struct:
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeCompletion/ordinary-name-cxx11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ typedef struct t TYPEDEF;
void foo() {
int y = 17;
// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -code-completion-patterns -code-completion-at=%s:6:14 -std=gnu++11 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: COMPLETION: Pattern : _Coroutine [#A Coroutine, as defined by concurrency course.#]typename <#name#>
// CHECK-CC1: COMPLETION: bool
// CHECK-CC1-NEXT: COMPLETION: char
// CHECK-CC1-NEXT: COMPLETION: char16
Expand Down Expand Up @@ -57,7 +58,6 @@ void foo() {
// CHECK-CC1: COMPLETION: TYPEDEF : TYPEDEF
// CHECK-CC1-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>;
// CHECK-CC1-NEXT: COMPLETION: Pattern : [#std::type_info#]typeid(<#expression-or-type#>)
// CHECK-CC1-NEXT: COMPLETION: Pattern : typename <#name#>
// CHECK-CC1-NEXT: COMPLETION: Pattern : typeof <#expression#>
// CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#type#>)
// CHECK-CC1-NEXT: COMPLETION: union
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeCompletion/ordinary-name.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ typedef struct t TYPEDEF;
void foo() {
int y = 17;
// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -code-completion-patterns -code-completion-at=%s:6:14 -std=gnu++98 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: COMPLETION: Pattern : _Coroutine [#A Coroutine, as defined by concurrency course.#]typename <#name#>
// CHECK-CC1: COMPLETION: bool
// CHECK-CC1-NEXT: COMPLETION: char
// CHECK-CC1-NEXT: COMPLETION: class
Expand Down Expand Up @@ -54,7 +55,6 @@ void foo() {
// CHECK-CC1: COMPLETION: TYPEDEF : TYPEDEF
// CHECK-CC1-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>;
// CHECK-CC1-NEXT: COMPLETION: Pattern : [#std::type_info#]typeid(<#expression-or-type#>)
// CHECK-CC1-NEXT: COMPLETION: Pattern : typename <#name#>
// CHECK-CC1-NEXT: COMPLETION: Pattern : typeof <#expression#>
// CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#type#>)
// CHECK-CC1-NEXT: COMPLETION: union
Expand Down
4 changes: 2 additions & 2 deletions clang/utils/ClangVisualizers/clang.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ For later versions of Visual Studio, no setup is required-->
<DisplayString IncludeView="extra" Condition="TypeSpecType == TST_typeofExpr || TypeSpecType == TST_decltype">
, [{ExprRep}]
</DisplayString>
<DisplayString IncludeView="extra" Condition="TypeSpecType == TST_enum || TypeSpecType == TST_struct || TypeSpecType == TST_interface || TypeSpecType == TST_union || TypeSpecType == TST_class">
<DisplayString IncludeView="extra" Condition="TypeSpecType == TST_enum || TypeSpecType == TST_struct || TypeSpecType == TST_interface || TypeSpecType == TST_union || TypeSpecType == TST_class || TypeSpecType == TST_coroutine">
, [{DeclRep}]
</DisplayString>
<DisplayString IncludeView="extra"></DisplayString>
Expand All @@ -868,7 +868,7 @@ For later versions of Visual Studio, no setup is required-->
<Item Name="ExprRep" Condition="TypeSpecType == TST_typeofExpr || TypeSpecType == TST_decltype">
ExprRep
</Item>
<Item Name="DeclRep" Condition="TypeSpecType == TST_enum || TypeSpecType == TST_struct || TypeSpecType == TST_interface || TypeSpecType == TST_union || TypeSpecType == TST_class">
<Item Name="DeclRep" Condition="TypeSpecType == TST_enum || TypeSpecType == TST_struct || TypeSpecType == TST_interface || TypeSpecType == TST_union || TypeSpecType == TST_class || TypeSpecType == TST_coroutine">
DeclRep
</Item>

Expand Down
Loading
Loading