[clang] [lld] [llvm] Add _Coroutine unit tests (PR #116561)

via cfe-commits cfe-commits at lists.llvm.org
Sun Nov 17 15:55:51 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-macho

@llvm/pr-subscribers-clang

Author: Abdur Javaid (abdurj)

<details>
<summary>Changes</summary>

Adds a simple FileCheck test for _Coroutine. For some reason, we broke a previous test but we can figure this out later.

## Testing:
`ninja -C build check-clang`

---

Patch is 21.79 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/116561.diff


21 Files Affected:

- (modified) .gitignore (+1) 
- (modified) clang/include/clang/AST/Decl.h (+1-1) 
- (modified) clang/include/clang/AST/Type.h (+7-1) 
- (modified) clang/include/clang/Basic/Specifiers.h (+1) 
- (modified) clang/include/clang/Basic/TokenKinds.def (+1) 
- (modified) clang/include/clang/Sema/DeclSpec.h (+2-1) 
- (modified) clang/lib/AST/Type.cpp (+11) 
- (modified) clang/lib/Index/USRGeneration.cpp (+3) 
- (modified) clang/lib/Parse/ParseDecl.cpp (+3) 
- (modified) clang/lib/Parse/ParseDeclCXX.cpp (+8-2) 
- (modified) clang/lib/Parse/Parser.cpp (+1) 
- (modified) clang/lib/Sema/DeclSpec.cpp (+2) 
- (modified) clang/lib/Sema/SemaCodeComplete.cpp (+11-1) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+8) 
- (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+1) 
- (modified) clang/lib/Sema/SemaType.cpp (+1) 
- (modified) clang/test/CodeCompletion/ordinary-name-cxx11.cpp (+1-1) 
- (modified) clang/test/CodeCompletion/ordinary-name.cpp (+1-1) 
- (modified) clang/utils/ClangVisualizers/clang.natvis (+2-2) 
- (modified) lld/test/MachO/compact-unwind-generated.test (+1) 
- (modified) llvm/test/tools/opt-viewer/lit.local.cfg (+2) 


``````````diff
diff --git a/.gitignore b/.gitignore
index 0e7c6c79001338..06ad856af2d175 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,3 +71,4 @@ pythonenv*
 /clang/utils/analyzer/projects/*/RefScanBuildResults
 # automodapi puts generated documentation files here.
 /lldb/docs/python_api/
+llvm-project.code-workspace
\ No newline at end of file
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 8c39ef3d5a9fa6..6d5dba6c88c5e8 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -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; }
 
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 1ed5c22361ca68..8bcd6172668b6d 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -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
 };
@@ -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.
diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h
index 9c089908fdc130..d39523cd90a009 100644
--- a/clang/include/clang/Basic/Specifiers.h
+++ b/clang/include/clang/Basic/Specifiers.h
@@ -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.
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 2c692c999bdff5..deac64dca22598 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -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
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 06243f2624876f..67be14d7ffa539 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -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;
@@ -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 = {
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 7ecb986e4dc2b5..c0779dc309dc05 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -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:
@@ -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:
@@ -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:
@@ -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:
@@ -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:
@@ -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.");
diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp
index 493123459a5a4d..a2acf9eb52565f 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -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;
@@ -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;
@@ -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;
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 31984453487aef..b5054f9b6db679 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -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) {
@@ -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: {
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 60aab1411a96c5..3b17ab4a44704b 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -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;
@@ -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;
@@ -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", [&]() {
@@ -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;
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 04c2f1d380bc48..84de31a063d94f 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -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;
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 12d2d3f6060c63..101468d12b3908 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -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:
@@ -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";
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 890ca96790acb5..b6ff96fda598b1 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -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);
@@ -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:
@@ -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;
@@ -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) {
@@ -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;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 07ac6a3bb4e5b1..c759c321daaa21 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -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;
       }
@@ -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;
@@ -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;
@@ -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 ||
@@ -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 ||
@@ -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);
@@ -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;
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 2ea2a368dd24cf..6dff76f7dfed94 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -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:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 4fac71ba095668..1f4cb9e71adf2e 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -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:
diff --git a/clang/test/CodeCompletion/ordinary-name-cxx11.cpp b/clang/test/CodeCompletion/ordinary-name-cxx11.cpp
index 7593d00210e7c7..b7fc7c87e9574f 100644
--- a/clang/test/CodeCompletion/ordinary-name-cxx11.cpp
+++ b/clang/test/CodeCompletion/ordinary-name-cxx11.cpp
@@ -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
@@ -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
diff --git a/clang/test/CodeCompletion/ordinary-name.cpp b/clang/test/CodeCompletion/ordinary-name.cpp
index 3c3d0c5d68831e..121507ffa33ed7 100644
--- a/clang/test/CodeCompletion/ordinary-name.cpp
+++ b/clang/test/CodeCompletion/ordinary-name.cpp
@@ -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
@@ -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
diff --git a/clang/utils/ClangVisualizers/clang.natvis b/clang/utils/ClangVisualizers/clang.natvis
index a7c70186bc46de..a3fab18d5c9ffb 100644
--- a/clang/utils/ClangVisualizers/clang.natvis
+++ b/clang/utils/ClangVisualizers/clang.natvis
@@ -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 ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/116561


More information about the cfe-commits mailing list