[clang-tools-extra] [clang] [Attributes][HLSL] Teach EnumArgument to refer to an external enum (PR #70835)

Justin Bogner via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 31 14:58:11 PDT 2023


https://github.com/bogner updated https://github.com/llvm/llvm-project/pull/70835

>From fcbcac28116562e181ece169840e7cce50be6cdf Mon Sep 17 00:00:00 2001
From: Justin Bogner <mail at justinbogner.com>
Date: Mon, 30 Oct 2023 18:26:02 -0700
Subject: [PATCH 1/7] [Attributes][HLSL] Teach EnumArgument to refer to an
 external enum

Rather than write a bunch of logic to shepherd between enums with the
same sets of values, add the ability for EnumArgument to refer to an
external enum in the first place.
---
 .../modularize/ModularizeUtilities.cpp        |  6 +-
 clang/include/clang/AST/Attr.h                |  3 +-
 clang/include/clang/Basic/Attr.td             | 83 +++++++++--------
 clang/lib/CodeGen/CGHLSLRuntime.cpp           | 59 +-----------
 clang/lib/Sema/HLSLExternalSemaSource.cpp     |  9 +-
 clang/unittests/Sema/SemaNoloadLookupTest.cpp |  2 +-
 clang/utils/TableGen/ClangAttrEmitter.cpp     | 91 +++++++++++--------
 7 files changed, 109 insertions(+), 144 deletions(-)

diff --git a/clang-tools-extra/modularize/ModularizeUtilities.cpp b/clang-tools-extra/modularize/ModularizeUtilities.cpp
index 043f6f5b20b80f2..089f52f52ec4d34 100644
--- a/clang-tools-extra/modularize/ModularizeUtilities.cpp
+++ b/clang-tools-extra/modularize/ModularizeUtilities.cpp
@@ -322,7 +322,7 @@ std::error_code ModularizeUtilities::loadModuleMap(
 // Walks the modules and collects referenced headers into
 // HeaderFileNames.
 bool ModularizeUtilities::collectModuleMapHeaders(clang::ModuleMap *ModMap) {
-  SmallVector<std::pair<StringRef, const Module *>, 0> Vec;
+  SmallVector<std::pair<StringRef, const clang::Module *>, 0> Vec;
   for (auto &M : ModMap->modules())
     Vec.emplace_back(M.first(), M.second);
   llvm::sort(Vec, llvm::less_first());
@@ -349,14 +349,14 @@ bool ModularizeUtilities::collectModuleHeaders(const clang::Module &Mod) {
   for (auto *Submodule : Mod.submodules())
     collectModuleHeaders(*Submodule);
 
-  if (std::optional<Module::Header> UmbrellaHeader =
+  if (std::optional<clang::Module::Header> UmbrellaHeader =
           Mod.getUmbrellaHeaderAsWritten()) {
     std::string HeaderPath = getCanonicalPath(UmbrellaHeader->Entry.getName());
     // Collect umbrella header.
     HeaderFileNames.push_back(HeaderPath);
 
     // FUTURE: When needed, umbrella header header collection goes here.
-  } else if (std::optional<Module::DirectoryName> UmbrellaDir =
+  } else if (std::optional<clang::Module::DirectoryName> UmbrellaDir =
                  Mod.getUmbrellaDirAsWritten()) {
     // If there normal headers, assume these are umbrellas and skip collection.
     if (Mod.Headers->size() == 0) {
diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h
index 793732cd26b02ff..8884bd5a90de198 100644
--- a/clang/include/clang/AST/Attr.h
+++ b/clang/include/clang/AST/Attr.h
@@ -19,11 +19,12 @@
 #include "clang/AST/Type.h"
 #include "clang/Basic/AttrKinds.h"
 #include "clang/Basic/AttributeCommonInfo.h"
-#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/OpenMPKinds.h"
 #include "clang/Basic/Sanitizers.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/Frontend/HLSL/HLSLResource.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/VersionTuple.h"
 #include "llvm/Support/raw_ostream.h"
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 25231c5b82b907c..ac4210fffd22010 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -279,12 +279,13 @@ class DefaultIntArgument<string name, int default> : IntArgument<name, 1> {
 
 // This argument is more complex, it includes the enumerator type name,
 // a list of strings to accept, and a list of enumerators to map them to.
-class EnumArgument<string name, string type, list<string> values,
+class EnumArgument<string name, string type, bit ext, list<string> values,
                    list<string> enums, bit opt = 0, bit fake = 0>
     : Argument<name, opt, fake> {
   string Type = type;
   list<string> Values = values;
   list<string> Enums = enums;
+  bit External = ext;
 }
 
 // FIXME: There should be a VariadicArgument type that takes any other type
@@ -890,7 +891,7 @@ def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
   // MSP430Interrupt's, MipsInterrupt's and AnyX86Interrupt's spellings
   // must match.
   let Spellings = [GCC<"interrupt">];
-  let Args = [EnumArgument<"Interrupt", "InterruptType",
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*ext=*/0,
                            ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
                            ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
                            1>];
@@ -1015,7 +1016,8 @@ def ExternalSourceSymbol : InheritableAttr {
 
 def Blocks : InheritableAttr {
   let Spellings = [Clang<"blocks">];
-  let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
+  let Args = [EnumArgument<"Type", "BlockType", /*ext=*/0,
+                           ["byref"], ["ByRef"]>];
   let Documentation = [Undocumented];
 }
 
@@ -1553,7 +1555,7 @@ def FlagEnum : InheritableAttr {
 def EnumExtensibility : InheritableAttr {
   let Spellings = [Clang<"enum_extensibility">];
   let Subjects = SubjectList<[Enum]>;
-  let Args = [EnumArgument<"Extensibility", "Kind",
+  let Args = [EnumArgument<"Extensibility", "Kind", /*ext=*/0,
               ["closed", "open"], ["Closed", "Open"]>];
   let Documentation = [EnumExtensibilityDocs];
 }
@@ -1719,7 +1721,7 @@ def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips32> {
   // must match.
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
-  let Args = [EnumArgument<"Interrupt", "InterruptType",
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*ext=*/0,
                            ["vector=sw0", "vector=sw1", "vector=hw0",
                             "vector=hw1", "vector=hw2", "vector=hw3",
                             "vector=hw4", "vector=hw5", "eic", ""],
@@ -1907,7 +1909,7 @@ def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> {
 def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
-  let Args = [EnumArgument<"Interrupt", "InterruptType",
+  let Args = [EnumArgument<"Interrupt", "InterruptType", /*ext=*/0,
                            ["supervisor", "machine"],
                            ["supervisor", "machine"],
                            1>];
@@ -2269,7 +2271,7 @@ def ObjCException : InheritableAttr {
 def ObjCMethodFamily : InheritableAttr {
   let Spellings = [Clang<"objc_method_family">];
   let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
-  let Args = [EnumArgument<"Family", "FamilyKind",
+  let Args = [EnumArgument<"Family", "FamilyKind", /*ext=*/0,
                ["none", "alloc", "copy", "init", "mutableCopy", "new"],
                ["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init",
                 "OMF_mutableCopy", "OMF_new"]>];
@@ -2443,7 +2445,7 @@ def IntelOclBicc : DeclOrTypeAttr {
 
 def Pcs : DeclOrTypeAttr {
   let Spellings = [GCC<"pcs">];
-  let Args = [EnumArgument<"PCS", "PCSType",
+  let Args = [EnumArgument<"PCS", "PCSType", /*ext=*/0,
                            ["aapcs", "aapcs-vfp"],
                            ["AAPCS", "AAPCS_VFP"]>];
 //  let Subjects = [Function, ObjCMethod];
@@ -2552,7 +2554,7 @@ def SwiftObjCMembers : Attr {
 def SwiftError : InheritableAttr {
   let Spellings = [GNU<"swift_error">];
   let Args = [
-      EnumArgument<"Convention", "ConventionKind",
+      EnumArgument<"Convention", "ConventionKind", /*ext=*/0,
                    ["none", "nonnull_error", "null_result", "zero_result", "nonzero_result"],
                    ["None", "NonNullError", "NullResult", "ZeroResult", "NonZeroResult"]>
   ];
@@ -2568,7 +2570,7 @@ def SwiftName : InheritableAttr {
 
 def SwiftNewType : InheritableAttr {
   let Spellings = [GNU<"swift_newtype">, GNU<"swift_wrapper">];
-  let Args = [EnumArgument<"NewtypeKind", "NewtypeKind",
+  let Args = [EnumArgument<"NewtypeKind", "NewtypeKind", /*ext=*/0,
                            ["struct", "enum"], ["NK_Struct", "NK_Enum"]>];
   let Subjects = SubjectList<[TypedefName], ErrorDiag>;
   let Documentation = [SwiftNewTypeDocs];
@@ -2726,7 +2728,7 @@ def SwiftIndirectResult : ParameterABIAttr {
 def SwiftAsync : InheritableAttr {
   let Spellings = [Clang<"swift_async">];
   let Subjects = SubjectList<[Function, ObjCMethod]>;
-  let Args = [EnumArgument<"Kind", "Kind",
+  let Args = [EnumArgument<"Kind", "Kind", /*ext=*/0,
                 ["none", "swift_private", "not_swift_private"],
                 ["None", "SwiftPrivate", "NotSwiftPrivate"]>,
               ParamIdxArgument<"CompletionHandlerIndex", /*opt=*/1>];
@@ -2736,7 +2738,7 @@ def SwiftAsync : InheritableAttr {
 def SwiftAsyncError : InheritableAttr {
   let Spellings = [Clang<"swift_async_error">];
   let Subjects = SubjectList<[Function, ObjCMethod]>;
-  let Args = [EnumArgument<"Convention", "ConventionKind",
+  let Args = [EnumArgument<"Convention", "ConventionKind", /*ext=*/0,
               ["none", "nonnull_error", "zero_argument", "nonzero_argument"],
               ["None", "NonNullError", "ZeroArgument", "NonZeroArgument"]>,
               UnsignedArgument<"HandlerParamIdx", /*opt=*/1>];
@@ -2773,7 +2775,7 @@ def ZeroCallUsedRegs : InheritableAttr {
   let Spellings = [GCC<"zero_call_used_regs">];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let Args = [
-    EnumArgument<"ZeroCallUsedRegs", "ZeroCallUsedRegsKind",
+    EnumArgument<"ZeroCallUsedRegs", "ZeroCallUsedRegsKind", /*ext=*/0,
                  ["skip", "used-gpr-arg", "used-gpr", "used-arg", "used",
                   "all-gpr-arg", "all-gpr", "all-arg", "all"],
                  ["Skip", "UsedGPRArg", "UsedGPR", "UsedArg", "Used",
@@ -2939,7 +2941,7 @@ def TransparentUnion : InheritableAttr {
 def Unavailable : InheritableAttr {
   let Spellings = [Clang<"unavailable">];
   let Args = [StringArgument<"Message", 1>,
-              EnumArgument<"ImplicitReason", "ImplicitReason",
+              EnumArgument<"ImplicitReason", "ImplicitReason", /*ext=*/0,
                 ["", "", "", ""],
                 ["IR_None",
                  "IR_ARCForbiddenType",
@@ -2959,8 +2961,7 @@ def DiagnoseIf : InheritableAttr {
   let Spellings = [GNU<"diagnose_if">];
   let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
   let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
-              EnumArgument<"DiagnosticType",
-                           "DiagnosticType",
+              EnumArgument<"DiagnosticType", "DiagnosticType", /*ext=*/0,
                            ["error", "warning"],
                            ["DT_Error", "DT_Warning"]>,
               BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
@@ -3062,7 +3063,7 @@ def MatrixType : TypeAttr {
 def Visibility : InheritableAttr {
   let Clone = 0;
   let Spellings = [GCC<"visibility">];
-  let Args = [EnumArgument<"Visibility", "VisibilityType",
+  let Args = [EnumArgument<"Visibility", "VisibilityType", /*ext=*/0,
                            ["default", "hidden", "internal", "protected"],
                            ["Default", "Hidden", "Hidden", "Protected"]>];
   let MeaningfulToClassTemplateDefinition = 1;
@@ -3072,7 +3073,7 @@ def Visibility : InheritableAttr {
 def TypeVisibility : InheritableAttr {
   let Clone = 0;
   let Spellings = [Clang<"type_visibility">];
-  let Args = [EnumArgument<"Visibility", "VisibilityType",
+  let Args = [EnumArgument<"Visibility", "VisibilityType", /*ext=*/0,
                            ["default", "hidden", "internal", "protected"],
                            ["Default", "Hidden", "Hidden", "Protected"]>];
 //  let Subjects = [Tag, ObjCInterface, Namespace];
@@ -3470,7 +3471,7 @@ def Consumable : InheritableAttr {
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"consumable", 0>];
   let Subjects = SubjectList<[CXXRecord]>;
-  let Args = [EnumArgument<"DefaultState", "ConsumedState",
+  let Args = [EnumArgument<"DefaultState", "ConsumedState", /*ext=*/0,
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
   let Documentation = [ConsumableDocs];
@@ -3514,7 +3515,7 @@ def ParamTypestate : InheritableAttr {
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"param_typestate", 0>];
   let Subjects = SubjectList<[ParmVar]>;
-  let Args = [EnumArgument<"ParamState", "ConsumedState",
+  let Args = [EnumArgument<"ParamState", "ConsumedState", /*ext=*/0,
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
   let Documentation = [ParamTypestateDocs];
@@ -3526,7 +3527,7 @@ def ReturnTypestate : InheritableAttr {
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"return_typestate", 0>];
   let Subjects = SubjectList<[Function, ParmVar]>;
-  let Args = [EnumArgument<"State", "ConsumedState",
+  let Args = [EnumArgument<"State", "ConsumedState", /*ext=*/0,
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
   let Documentation = [ReturnTypestateDocs];
@@ -3538,7 +3539,7 @@ def SetTypestate : InheritableAttr {
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"set_typestate", 0>];
   let Subjects = SubjectList<[CXXMethod]>;
-  let Args = [EnumArgument<"NewState", "ConsumedState",
+  let Args = [EnumArgument<"NewState", "ConsumedState", /*ext=*/0,
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
   let Documentation = [SetTypestateDocs];
@@ -3550,7 +3551,7 @@ def TestTypestate : InheritableAttr {
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"test_typestate", 0>];
   let Subjects = SubjectList<[CXXMethod]>;
-  let Args = [EnumArgument<"TestState", "ConsumedState",
+  let Args = [EnumArgument<"TestState", "ConsumedState", /*ext=*/0,
                            ["consumed", "unconsumed"],
                            ["Consumed", "Unconsumed"]>];
   let Documentation = [TestTypestateDocs];
@@ -3619,7 +3620,7 @@ def CFGuard : InheritableAttr, TargetSpecificAttr<TargetWindows> {
   // we might also want to support __declspec(guard(suppress)).
   let Spellings = [Declspec<"guard">, Clang<"guard">];
   let Subjects = SubjectList<[Function]>;
-  let Args = [EnumArgument<"Guard", "GuardArg", ["nocf"], ["nocf"]>];
+  let Args = [EnumArgument<"Guard", "GuardArg", /*ext=*/0, ["nocf"], ["nocf"]>];
   let Documentation = [CFGuardDocs];
 }
 
@@ -3775,7 +3776,7 @@ def LoopHint : Attr {
                    Pragma<"", "nounroll_and_jam">];
 
   /// State of the loop optimization specified by the spelling.
-  let Args = [EnumArgument<"Option", "OptionType",
+  let Args = [EnumArgument<"Option", "OptionType", /*ext=*/0,
                           ["vectorize", "vectorize_width", "interleave", "interleave_count",
                            "unroll", "unroll_count", "unroll_and_jam", "unroll_and_jam_count",
                            "pipeline", "pipeline_initiation_interval", "distribute",
@@ -3784,7 +3785,7 @@ def LoopHint : Attr {
                            "Unroll", "UnrollCount", "UnrollAndJam", "UnrollAndJamCount",
                            "PipelineDisabled", "PipelineInitiationInterval", "Distribute",
                            "VectorizePredicate"]>,
-              EnumArgument<"State", "LoopHintState",
+              EnumArgument<"State", "LoopHintState", /*ext=*/0,
                            ["enable", "disable", "numeric", "fixed_width",
                             "scalable_width", "assume_safety", "full"],
                            ["Enable", "Disable", "Numeric", "FixedWidth",
@@ -3873,7 +3874,7 @@ def OMPDeclareSimdDecl : Attr {
   let HasCustomParsing = 1;
   let Documentation = [OMPDeclareSimdDocs];
   let Args = [
-    EnumArgument<"BranchState", "BranchStateTy",
+    EnumArgument<"BranchState", "BranchStateTy", /*ext=*/0,
                  [ "", "inbranch", "notinbranch" ],
                  [ "BS_Undefined", "BS_Inbranch", "BS_Notinbranch" ]>,
     ExprArgument<"Simdlen">, VariadicExprArgument<"Uniforms">,
@@ -3893,10 +3894,10 @@ def OMPDeclareTargetDecl : InheritableAttr {
   let Subjects = SubjectList<[Function, SharedVar]>;
   let Documentation = [OMPDeclareTargetDocs];
   let Args = [
-    EnumArgument<"MapType", "MapTypeTy",
+    EnumArgument<"MapType", "MapTypeTy", /*ext=*/0,
                  [ "to", "enter", "link" ],
                  [ "MT_To", "MT_Enter", "MT_Link" ]>,
-    EnumArgument<"DevType", "DevTypeTy",
+    EnumArgument<"DevType", "DevTypeTy", /*ext=*/0,
                  [ "host", "nohost", "any" ],
                  [ "DT_Host", "DT_NoHost", "DT_Any" ]>,
     ExprArgument<"IndirectExpr">,
@@ -3918,7 +3919,7 @@ def OMPAllocateDecl : InheritableAttr {
   let Spellings = [];
   let SemaHandler = 0;
   let Args = [
-    EnumArgument<"AllocatorType", "AllocatorTypeTy",
+    EnumArgument<"AllocatorType", "AllocatorTypeTy", /*ext=*/0,
                  [
                    "omp_null_allocator", "omp_default_mem_alloc",
                    "omp_large_cap_mem_alloc", "omp_const_mem_alloc",
@@ -4167,7 +4168,7 @@ def HLSLShader : InheritableAttr {
   let Subjects = SubjectList<[HLSLEntry]>;
   let LangOpts = [HLSL];
   let Args = [
-    EnumArgument<"Type", "ShaderType",
+    EnumArgument<"Type", "ShaderType", /*ext=*/0,
                  ["pixel", "vertex", "geometry", "hull", "domain", "compute",
                   "raygeneration", "intersection", "anyhit", "closesthit",
                   "miss", "callable", "mesh", "amplification"],
@@ -4182,25 +4183,27 @@ def HLSLResource : InheritableAttr {
   let Spellings = [];
   let Subjects = SubjectList<[Struct]>;
   let LangOpts = [HLSL];
-  let Args = [EnumArgument<"ResourceType", "ResourceClass",
+  let Args = [EnumArgument<"ResourceClass",
+                           "llvm::hlsl::ResourceClass", /*ext=*/1,
                            ["SRV", "UAV", "CBuffer", "Sampler"],
                            ["SRV", "UAV", "CBuffer", "Sampler"]
                            >,
-              EnumArgument<"ResourceShape", "ResourceKind",
+              EnumArgument<"ResourceKind",
+                           "llvm::hlsl::ResourceKind", /*ext=*/1,
                            ["Texture1D", "Texture2D", "Texture2DMS",
                             "Texture3D", "TextureCube", "Texture1DArray",
                             "Texture2DArray", "Texture2DMSArray",
                             "TextureCubeArray", "TypedBuffer", "RawBuffer",
-                            "StructuredBuffer", "CBufferKind", "SamplerKind",
-                            "TBuffer", "RTAccelerationStructure", "FeedbackTexture2D",
-                            "FeedbackTexture2DArray"],
+                            "StructuredBuffer", "CBuffer", "Sampler",
+                            "TBuffer", "RTAccelerationStructure",
+                            "FeedbackTexture2D", "FeedbackTexture2DArray"],
                            ["Texture1D", "Texture2D", "Texture2DMS",
                             "Texture3D", "TextureCube", "Texture1DArray",
                             "Texture2DArray", "Texture2DMSArray",
                             "TextureCubeArray", "TypedBuffer", "RawBuffer",
-                            "StructuredBuffer", "CBufferKind", "SamplerKind",
-                            "TBuffer", "RTAccelerationStructure", "FeedbackTexture2D",
-                            "FeedbackTexture2DArray"]
+                            "StructuredBuffer", "CBuffer", "Sampler",
+                            "TBuffer", "RTAccelerationStructure",
+                            "FeedbackTexture2D", "FeedbackTexture2DArray"]
                             >
               ];
   let Documentation = [InternalOnly];
@@ -4230,7 +4233,7 @@ def : MutualExclusions<[RandomizeLayout, NoRandomizeLayout]>;
 def FunctionReturnThunks : InheritableAttr,
     TargetSpecificAttr<TargetAnyX86> {
   let Spellings = [GCC<"function_return">];
-  let Args = [EnumArgument<"ThunkType", "Kind",
+  let Args = [EnumArgument<"ThunkType", "Kind", /*ext=*/0,
     ["keep", "thunk-extern"],
     ["Keep", "Extern"]
   >];
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index e9fa273f21cc8d0..c239bc17ef267e8 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -223,56 +223,6 @@ void CGHLSLRuntime::addBufferResourceAnnotation(llvm::GlobalVariable *GV,
   ResourceMD->addOperand(Res.getMetadata());
 }
 
-static llvm::hlsl::ResourceKind
-castResourceShapeToResourceKind(HLSLResourceAttr::ResourceKind RK) {
-  switch (RK) {
-  case HLSLResourceAttr::ResourceKind::Texture1D:
-    return llvm::hlsl::ResourceKind::Texture1D;
-  case HLSLResourceAttr::ResourceKind::Texture2D:
-    return llvm::hlsl::ResourceKind::Texture2D;
-  case HLSLResourceAttr::ResourceKind::Texture2DMS:
-    return llvm::hlsl::ResourceKind::Texture2DMS;
-  case HLSLResourceAttr::ResourceKind::Texture3D:
-    return llvm::hlsl::ResourceKind::Texture3D;
-  case HLSLResourceAttr::ResourceKind::TextureCube:
-    return llvm::hlsl::ResourceKind::TextureCube;
-  case HLSLResourceAttr::ResourceKind::Texture1DArray:
-    return llvm::hlsl::ResourceKind::Texture1DArray;
-  case HLSLResourceAttr::ResourceKind::Texture2DArray:
-    return llvm::hlsl::ResourceKind::Texture2DArray;
-  case HLSLResourceAttr::ResourceKind::Texture2DMSArray:
-    return llvm::hlsl::ResourceKind::Texture2DMSArray;
-  case HLSLResourceAttr::ResourceKind::TextureCubeArray:
-    return llvm::hlsl::ResourceKind::TextureCubeArray;
-  case HLSLResourceAttr::ResourceKind::TypedBuffer:
-    return llvm::hlsl::ResourceKind::TypedBuffer;
-  case HLSLResourceAttr::ResourceKind::RawBuffer:
-    return llvm::hlsl::ResourceKind::RawBuffer;
-  case HLSLResourceAttr::ResourceKind::StructuredBuffer:
-    return llvm::hlsl::ResourceKind::StructuredBuffer;
-  case HLSLResourceAttr::ResourceKind::CBufferKind:
-    return llvm::hlsl::ResourceKind::CBuffer;
-  case HLSLResourceAttr::ResourceKind::SamplerKind:
-    return llvm::hlsl::ResourceKind::Sampler;
-  case HLSLResourceAttr::ResourceKind::TBuffer:
-    return llvm::hlsl::ResourceKind::TBuffer;
-  case HLSLResourceAttr::ResourceKind::RTAccelerationStructure:
-    return llvm::hlsl::ResourceKind::RTAccelerationStructure;
-  case HLSLResourceAttr::ResourceKind::FeedbackTexture2D:
-    return llvm::hlsl::ResourceKind::FeedbackTexture2D;
-  case HLSLResourceAttr::ResourceKind::FeedbackTexture2DArray:
-    return llvm::hlsl::ResourceKind::FeedbackTexture2DArray;
-  }
-  // Make sure to update HLSLResourceAttr::ResourceKind when add new Kind to
-  // hlsl::ResourceKind. Assume FeedbackTexture2DArray is the last enum for
-  // HLSLResourceAttr::ResourceKind.
-  static_assert(
-      static_cast<uint32_t>(
-          HLSLResourceAttr::ResourceKind::FeedbackTexture2DArray) ==
-      (static_cast<uint32_t>(llvm::hlsl::ResourceKind::NumEntries) - 2));
-  llvm_unreachable("all switch cases should be covered");
-}
-
 void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) {
   const Type *Ty = D->getType()->getPointeeOrArrayElementType();
   if (!Ty)
@@ -284,15 +234,12 @@ void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) {
   if (!Attr)
     return;
 
-  HLSLResourceAttr::ResourceClass RC = Attr->getResourceType();
-  llvm::hlsl::ResourceKind RK =
-      castResourceShapeToResourceKind(Attr->getResourceShape());
+  llvm::hlsl::ResourceClass RC = Attr->getResourceClass();
+  llvm::hlsl::ResourceKind RK = Attr->getResourceKind();
 
   QualType QT(Ty, 0);
   BufferResBinding Binding(D->getAttr<HLSLResourceBindingAttr>());
-  addBufferResourceAnnotation(GV, QT.getAsString(),
-                              static_cast<llvm::hlsl::ResourceClass>(RC), RK,
-                              Binding);
+  addBufferResourceAnnotation(GV, QT.getAsString(), RC, RK, Binding);
 }
 
 CGHLSLRuntime::BufferResBinding::BufferResBinding(
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index fd86a5f8b49c0a1..7e6c07b37925ca5 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -115,9 +115,8 @@ struct BuiltinTypeDeclBuilder {
     return addMemberVariable("h", Ty, Access);
   }
 
-  BuiltinTypeDeclBuilder &
-  annotateResourceClass(HLSLResourceAttr::ResourceClass RC,
-                        HLSLResourceAttr::ResourceKind RK) {
+  BuiltinTypeDeclBuilder &annotateResourceClass(ResourceClass RC,
+                                                ResourceKind RK) {
     if (Record->isCompleteDefinition())
       return *this;
     Record->addAttr(
@@ -503,7 +502,7 @@ void HLSLExternalSemaSource::completeBufferType(CXXRecordDecl *Record) {
       .addHandleMember()
       .addDefaultHandleConstructor(*SemaPtr, ResourceClass::UAV)
       .addArraySubscriptOperators()
-      .annotateResourceClass(HLSLResourceAttr::UAV,
-                             HLSLResourceAttr::TypedBuffer)
+      .annotateResourceClass(ResourceClass::UAV,
+                             ResourceKind::TypedBuffer)
       .completeDefinition();
 }
diff --git a/clang/unittests/Sema/SemaNoloadLookupTest.cpp b/clang/unittests/Sema/SemaNoloadLookupTest.cpp
index 2e74ad3a30a93b6..b24c72cba407f3a 100644
--- a/clang/unittests/Sema/SemaNoloadLookupTest.cpp
+++ b/clang/unittests/Sema/SemaNoloadLookupTest.cpp
@@ -118,7 +118,7 @@ class NoloadLookupConsumer : public SemaConsumer {
     if (!ID)
       return true;
 
-    Module *M = ID->getImportedModule();
+    clang::Module *M = ID->getImportedModule();
     assert(M);
     if (M->Name != "R")
       return true;
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 45e2fa7b283e18d..1032028fd8071f6 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -898,15 +898,21 @@ namespace {
   }
 
   class EnumArgument : public Argument {
-    std::string type;
+    std::string fullType;
+    StringRef shortType;
     std::vector<StringRef> values, enums, uniques;
+    bool isExternal;
 
   public:
     EnumArgument(const Record &Arg, StringRef Attr)
-        : Argument(Arg, Attr), type(std::string(Arg.getValueAsString("Type"))),
-          values(Arg.getValueAsListOfStrings("Values")),
+        : Argument(Arg, Attr), values(Arg.getValueAsListOfStrings("Values")),
           enums(Arg.getValueAsListOfStrings("Enums")),
-          uniques(uniqueEnumsInOrder(enums)) {
+          uniques(uniqueEnumsInOrder(enums)),
+          isExternal(Arg.getValueAsBit("External")) {
+      StringRef Type = Arg.getValueAsString("Type");
+      shortType = isExternal ? getAttrName().rsplit("::").second : Type;
+      fullType = isExternal ? Type : (getAttrName() + "Attr::" + Type).str();
+
       // FIXME: Emit a proper error
       assert(!uniques.empty());
     }
@@ -914,7 +920,7 @@ namespace {
     bool isEnumArg() const override { return true; }
 
     void writeAccessors(raw_ostream &OS) const override {
-      OS << "  " << type << " get" << getUpperName() << "() const {\n";
+      OS << "  " << fullType << " get" << getUpperName() << "() const {\n";
       OS << "    return " << getLowerName() << ";\n";
       OS << "  }";
     }
@@ -930,30 +936,32 @@ namespace {
       OS << getLowerName() << "(" << getUpperName() << ")";
     }
     void writeCtorDefaultInitializers(raw_ostream &OS) const override {
-      OS << getLowerName() << "(" << type << "(0))";
+      OS << getLowerName() << "(" << fullType << "(0))";
     }
     void writeCtorParameters(raw_ostream &OS) const override {
-      OS << type << " " << getUpperName();
+      OS << fullType << " " << getUpperName();
     }
     void writeDeclarations(raw_ostream &OS) const override {
-      auto i = uniques.cbegin(), e = uniques.cend();
-      // The last one needs to not have a comma.
-      --e;
+      if (!isExternal) {
+        auto i = uniques.cbegin(), e = uniques.cend();
+        // The last one needs to not have a comma.
+        --e;
+
+        OS << "public:\n";
+        OS << "  enum " << shortType << " {\n";
+        for (; i != e; ++i)
+          OS << "    " << *i << ",\n";
+        OS << "    " << *e << "\n";
+        OS << "  };\n";
+      }
 
-      OS << "public:\n";
-      OS << "  enum " << type << " {\n";
-      for (; i != e; ++i)
-        OS << "    " << *i << ",\n";
-      OS << "    " << *e << "\n";
-      OS << "  };\n";
       OS << "private:\n";
-      OS << "  " << type << " " << getLowerName() << ";";
+      OS << "  " << fullType << " " << getLowerName() << ";";
     }
 
     void writePCHReadDecls(raw_ostream &OS) const override {
-      OS << "    " << getAttrName() << "Attr::" << type << " " << getLowerName()
-         << "(static_cast<" << getAttrName() << "Attr::" << type
-         << ">(Record.readInt()));\n";
+      OS << "    " << fullType << " " << getLowerName()
+         << "(static_cast<" << fullType << ">(Record.readInt()));\n";
     }
 
     void writePCHReadArgs(raw_ostream &OS) const override {
@@ -961,46 +969,50 @@ namespace {
     }
 
     void writePCHWrite(raw_ostream &OS) const override {
-      OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
+      OS << "Record.push_back(static_cast<uint64_t>(SA->get" << getUpperName()
+         << "()));\n";
     }
 
     void writeValue(raw_ostream &OS) const override {
       // FIXME: this isn't 100% correct -- some enum arguments require printing
       // as a string literal, while others require printing as an identifier.
       // Tablegen currently does not distinguish between the two forms.
-      OS << "\\\"\" << " << getAttrName() << "Attr::Convert" << type << "ToStr(get"
-         << getUpperName() << "()) << \"\\\"";
+      OS << "\\\"\" << " << getAttrName() << "Attr::Convert" << shortType
+         << "ToStr(get" << getUpperName() << "()) << \"\\\"";
     }
 
     void writeDump(raw_ostream &OS) const override {
       OS << "    switch(SA->get" << getUpperName() << "()) {\n";
       for (const auto &I : uniques) {
-        OS << "    case " << getAttrName() << "Attr::" << I << ":\n";
+        OS << "    case " << fullType << "::" << I << ":\n";
         OS << "      OS << \" " << I << "\";\n";
         OS << "      break;\n";
       }
+      if (isExternal) {
+        OS << "    default:\n";
+        OS << "      llvm_unreachable(\"Invalid attribute value\");\n";
+      }
       OS << "    }\n";
     }
 
     void writeConversion(raw_ostream &OS, bool Header) const {
       if (Header) {
-        OS << "  static bool ConvertStrTo" << type << "(StringRef Val, " << type
-           << " &Out);\n";
-        OS << "  static const char *Convert" << type << "ToStr(" << type
-           << " Val);\n";
+        OS << "  static bool ConvertStrTo" << shortType << "(StringRef Val, "
+           << fullType << " &Out);\n";
+        OS << "  static const char *Convert" << shortType << "ToStr("
+           << fullType << " Val);\n";
         return;
       }
 
-      OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << type
-         << "(StringRef Val, " << type << " &Out) {\n";
-      OS << "  std::optional<" << type
-         << "> R = llvm::StringSwitch<std::optional<";
-      OS << type << ">>(Val)\n";
+      OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << shortType
+         << "(StringRef Val, " << fullType << " &Out) {\n";
+      OS << "  std::optional<" << fullType << "> "
+         << "R = llvm::StringSwitch<std::optional<" << fullType << ">>(Val)\n";
       for (size_t I = 0; I < enums.size(); ++I) {
         OS << "    .Case(\"" << values[I] << "\", ";
-        OS << getAttrName() << "Attr::" << enums[I] << ")\n";
+        OS << fullType << "::" << enums[I] << ")\n";
       }
-      OS << "    .Default(std::optional<" << type << ">());\n";
+      OS << "    .Default(std::optional<" << fullType << ">());\n";
       OS << "  if (R) {\n";
       OS << "    Out = *R;\n      return true;\n    }\n";
       OS << "  return false;\n";
@@ -1010,15 +1022,18 @@ namespace {
       // trivial because some enumeration values have multiple named
       // enumerators, such as type_visibility(internal) and
       // type_visibility(hidden) both mapping to TypeVisibilityAttr::Hidden.
-      OS << "const char *" << getAttrName() << "Attr::Convert" << type
-         << "ToStr(" << type << " Val) {\n"
+      OS << "const char *" << getAttrName() << "Attr::Convert" << shortType
+         << "ToStr(" << fullType << " Val) {\n"
          << "  switch(Val) {\n";
       SmallDenseSet<StringRef, 8> Uniques;
       for (size_t I = 0; I < enums.size(); ++I) {
         if (Uniques.insert(enums[I]).second)
-          OS << "  case " << getAttrName() << "Attr::" << enums[I]
+          OS << "  case " << fullType << "::" << enums[I]
              << ": return \"" << values[I] << "\";\n";
       }
+      if (isExternal) {
+        OS << "  default: llvm_unreachable(\"Invalid attribute value\");\n";
+      }
       OS << "  }\n"
          << "  llvm_unreachable(\"No enumerator with that value\");\n"
          << "}\n";

>From 88752181f3e3af3c88622d0e1b9c0eb0994ebb36 Mon Sep 17 00:00:00 2001
From: Justin Bogner <mail at justinbogner.com>
Date: Tue, 31 Oct 2023 10:31:47 -0700
Subject: [PATCH 2/7] fixup! [Attributes][HLSL] Teach EnumArgument to refer to
 an external enum

clang-format bot suggestions
---
 clang/lib/Sema/HLSLExternalSemaSource.cpp | 3 +--
 clang/utils/TableGen/ClangAttrEmitter.cpp | 8 ++++----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 7e6c07b37925ca5..0be76d4b36e046c 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -502,7 +502,6 @@ void HLSLExternalSemaSource::completeBufferType(CXXRecordDecl *Record) {
       .addHandleMember()
       .addDefaultHandleConstructor(*SemaPtr, ResourceClass::UAV)
       .addArraySubscriptOperators()
-      .annotateResourceClass(ResourceClass::UAV,
-                             ResourceKind::TypedBuffer)
+      .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer)
       .completeDefinition();
 }
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 1032028fd8071f6..fa5d95a074ec64f 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -960,8 +960,8 @@ namespace {
     }
 
     void writePCHReadDecls(raw_ostream &OS) const override {
-      OS << "    " << fullType << " " << getLowerName()
-         << "(static_cast<" << fullType << ">(Record.readInt()));\n";
+      OS << "    " << fullType << " " << getLowerName() << "(static_cast<"
+         << fullType << ">(Record.readInt()));\n";
     }
 
     void writePCHReadArgs(raw_ostream &OS) const override {
@@ -1028,8 +1028,8 @@ namespace {
       SmallDenseSet<StringRef, 8> Uniques;
       for (size_t I = 0; I < enums.size(); ++I) {
         if (Uniques.insert(enums[I]).second)
-          OS << "  case " << fullType << "::" << enums[I]
-             << ": return \"" << values[I] << "\";\n";
+          OS << "  case " << fullType << "::" << enums[I] << ": return \""
+             << values[I] << "\";\n";
       }
       if (isExternal) {
         OS << "  default: llvm_unreachable(\"Invalid attribute value\");\n";

>From accc869969703991aba3230cfd77cb997635b25a Mon Sep 17 00:00:00 2001
From: Justin Bogner <mail at justinbogner.com>
Date: Tue, 31 Oct 2023 11:05:34 -0700
Subject: [PATCH 3/7] fixup! [Attributes][HLSL] Teach EnumArgument to refer to
 an external enum

Move `external` to the end of EnumArgument's arg list and default it
off. Also improve comment.
---
 clang/include/clang/Basic/Attr.td | 80 ++++++++++++++++---------------
 1 file changed, 41 insertions(+), 39 deletions(-)

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index ac4210fffd22010..9a95faec1791364 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -277,15 +277,17 @@ class DefaultIntArgument<string name, int default> : IntArgument<name, 1> {
   int Default = default;
 }
 
-// This argument is more complex, it includes the enumerator type name,
-// a list of strings to accept, and a list of enumerators to map them to.
-class EnumArgument<string name, string type, bit ext, list<string> values,
-                   list<string> enums, bit opt = 0, bit fake = 0>
+// This argument is more complex, it includes the enumerator type
+// name, whether the enum type is externally defined, a list of
+// strings to accept, and a list of enumerators to map them to.
+class EnumArgument<string name, string type, list<string> values,
+                   list<string> enums, bit opt = 0, bit fake = 0,
+                   bit external = 0>
     : Argument<name, opt, fake> {
   string Type = type;
   list<string> Values = values;
   list<string> Enums = enums;
-  bit External = ext;
+  bit External = external;
 }
 
 // FIXME: There should be a VariadicArgument type that takes any other type
@@ -891,7 +893,7 @@ def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
   // MSP430Interrupt's, MipsInterrupt's and AnyX86Interrupt's spellings
   // must match.
   let Spellings = [GCC<"interrupt">];
-  let Args = [EnumArgument<"Interrupt", "InterruptType", /*ext=*/0,
+  let Args = [EnumArgument<"Interrupt", "InterruptType",
                            ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
                            ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
                            1>];
@@ -1016,7 +1018,7 @@ def ExternalSourceSymbol : InheritableAttr {
 
 def Blocks : InheritableAttr {
   let Spellings = [Clang<"blocks">];
-  let Args = [EnumArgument<"Type", "BlockType", /*ext=*/0,
+  let Args = [EnumArgument<"Type", "BlockType",
                            ["byref"], ["ByRef"]>];
   let Documentation = [Undocumented];
 }
@@ -1555,7 +1557,7 @@ def FlagEnum : InheritableAttr {
 def EnumExtensibility : InheritableAttr {
   let Spellings = [Clang<"enum_extensibility">];
   let Subjects = SubjectList<[Enum]>;
-  let Args = [EnumArgument<"Extensibility", "Kind", /*ext=*/0,
+  let Args = [EnumArgument<"Extensibility", "Kind",
               ["closed", "open"], ["Closed", "Open"]>];
   let Documentation = [EnumExtensibilityDocs];
 }
@@ -1721,7 +1723,7 @@ def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips32> {
   // must match.
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
-  let Args = [EnumArgument<"Interrupt", "InterruptType", /*ext=*/0,
+  let Args = [EnumArgument<"Interrupt", "InterruptType",
                            ["vector=sw0", "vector=sw1", "vector=hw0",
                             "vector=hw1", "vector=hw2", "vector=hw3",
                             "vector=hw4", "vector=hw5", "eic", ""],
@@ -1909,7 +1911,7 @@ def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> {
 def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
   let Spellings = [GCC<"interrupt">];
   let Subjects = SubjectList<[Function]>;
-  let Args = [EnumArgument<"Interrupt", "InterruptType", /*ext=*/0,
+  let Args = [EnumArgument<"Interrupt", "InterruptType",
                            ["supervisor", "machine"],
                            ["supervisor", "machine"],
                            1>];
@@ -2271,7 +2273,7 @@ def ObjCException : InheritableAttr {
 def ObjCMethodFamily : InheritableAttr {
   let Spellings = [Clang<"objc_method_family">];
   let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
-  let Args = [EnumArgument<"Family", "FamilyKind", /*ext=*/0,
+  let Args = [EnumArgument<"Family", "FamilyKind",
                ["none", "alloc", "copy", "init", "mutableCopy", "new"],
                ["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init",
                 "OMF_mutableCopy", "OMF_new"]>];
@@ -2445,7 +2447,7 @@ def IntelOclBicc : DeclOrTypeAttr {
 
 def Pcs : DeclOrTypeAttr {
   let Spellings = [GCC<"pcs">];
-  let Args = [EnumArgument<"PCS", "PCSType", /*ext=*/0,
+  let Args = [EnumArgument<"PCS", "PCSType",
                            ["aapcs", "aapcs-vfp"],
                            ["AAPCS", "AAPCS_VFP"]>];
 //  let Subjects = [Function, ObjCMethod];
@@ -2554,7 +2556,7 @@ def SwiftObjCMembers : Attr {
 def SwiftError : InheritableAttr {
   let Spellings = [GNU<"swift_error">];
   let Args = [
-      EnumArgument<"Convention", "ConventionKind", /*ext=*/0,
+      EnumArgument<"Convention", "ConventionKind",
                    ["none", "nonnull_error", "null_result", "zero_result", "nonzero_result"],
                    ["None", "NonNullError", "NullResult", "ZeroResult", "NonZeroResult"]>
   ];
@@ -2570,7 +2572,7 @@ def SwiftName : InheritableAttr {
 
 def SwiftNewType : InheritableAttr {
   let Spellings = [GNU<"swift_newtype">, GNU<"swift_wrapper">];
-  let Args = [EnumArgument<"NewtypeKind", "NewtypeKind", /*ext=*/0,
+  let Args = [EnumArgument<"NewtypeKind", "NewtypeKind",
                            ["struct", "enum"], ["NK_Struct", "NK_Enum"]>];
   let Subjects = SubjectList<[TypedefName], ErrorDiag>;
   let Documentation = [SwiftNewTypeDocs];
@@ -2728,7 +2730,7 @@ def SwiftIndirectResult : ParameterABIAttr {
 def SwiftAsync : InheritableAttr {
   let Spellings = [Clang<"swift_async">];
   let Subjects = SubjectList<[Function, ObjCMethod]>;
-  let Args = [EnumArgument<"Kind", "Kind", /*ext=*/0,
+  let Args = [EnumArgument<"Kind", "Kind",
                 ["none", "swift_private", "not_swift_private"],
                 ["None", "SwiftPrivate", "NotSwiftPrivate"]>,
               ParamIdxArgument<"CompletionHandlerIndex", /*opt=*/1>];
@@ -2738,7 +2740,7 @@ def SwiftAsync : InheritableAttr {
 def SwiftAsyncError : InheritableAttr {
   let Spellings = [Clang<"swift_async_error">];
   let Subjects = SubjectList<[Function, ObjCMethod]>;
-  let Args = [EnumArgument<"Convention", "ConventionKind", /*ext=*/0,
+  let Args = [EnumArgument<"Convention", "ConventionKind",
               ["none", "nonnull_error", "zero_argument", "nonzero_argument"],
               ["None", "NonNullError", "ZeroArgument", "NonZeroArgument"]>,
               UnsignedArgument<"HandlerParamIdx", /*opt=*/1>];
@@ -2775,7 +2777,7 @@ def ZeroCallUsedRegs : InheritableAttr {
   let Spellings = [GCC<"zero_call_used_regs">];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let Args = [
-    EnumArgument<"ZeroCallUsedRegs", "ZeroCallUsedRegsKind", /*ext=*/0,
+    EnumArgument<"ZeroCallUsedRegs", "ZeroCallUsedRegsKind",
                  ["skip", "used-gpr-arg", "used-gpr", "used-arg", "used",
                   "all-gpr-arg", "all-gpr", "all-arg", "all"],
                  ["Skip", "UsedGPRArg", "UsedGPR", "UsedArg", "Used",
@@ -2941,7 +2943,7 @@ def TransparentUnion : InheritableAttr {
 def Unavailable : InheritableAttr {
   let Spellings = [Clang<"unavailable">];
   let Args = [StringArgument<"Message", 1>,
-              EnumArgument<"ImplicitReason", "ImplicitReason", /*ext=*/0,
+              EnumArgument<"ImplicitReason", "ImplicitReason",
                 ["", "", "", ""],
                 ["IR_None",
                  "IR_ARCForbiddenType",
@@ -2961,7 +2963,7 @@ def DiagnoseIf : InheritableAttr {
   let Spellings = [GNU<"diagnose_if">];
   let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
   let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
-              EnumArgument<"DiagnosticType", "DiagnosticType", /*ext=*/0,
+              EnumArgument<"DiagnosticType", "DiagnosticType",
                            ["error", "warning"],
                            ["DT_Error", "DT_Warning"]>,
               BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
@@ -3063,7 +3065,7 @@ def MatrixType : TypeAttr {
 def Visibility : InheritableAttr {
   let Clone = 0;
   let Spellings = [GCC<"visibility">];
-  let Args = [EnumArgument<"Visibility", "VisibilityType", /*ext=*/0,
+  let Args = [EnumArgument<"Visibility", "VisibilityType",
                            ["default", "hidden", "internal", "protected"],
                            ["Default", "Hidden", "Hidden", "Protected"]>];
   let MeaningfulToClassTemplateDefinition = 1;
@@ -3073,7 +3075,7 @@ def Visibility : InheritableAttr {
 def TypeVisibility : InheritableAttr {
   let Clone = 0;
   let Spellings = [Clang<"type_visibility">];
-  let Args = [EnumArgument<"Visibility", "VisibilityType", /*ext=*/0,
+  let Args = [EnumArgument<"Visibility", "VisibilityType",
                            ["default", "hidden", "internal", "protected"],
                            ["Default", "Hidden", "Hidden", "Protected"]>];
 //  let Subjects = [Tag, ObjCInterface, Namespace];
@@ -3471,7 +3473,7 @@ def Consumable : InheritableAttr {
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"consumable", 0>];
   let Subjects = SubjectList<[CXXRecord]>;
-  let Args = [EnumArgument<"DefaultState", "ConsumedState", /*ext=*/0,
+  let Args = [EnumArgument<"DefaultState", "ConsumedState",
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
   let Documentation = [ConsumableDocs];
@@ -3515,7 +3517,7 @@ def ParamTypestate : InheritableAttr {
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"param_typestate", 0>];
   let Subjects = SubjectList<[ParmVar]>;
-  let Args = [EnumArgument<"ParamState", "ConsumedState", /*ext=*/0,
+  let Args = [EnumArgument<"ParamState", "ConsumedState",
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
   let Documentation = [ParamTypestateDocs];
@@ -3527,7 +3529,7 @@ def ReturnTypestate : InheritableAttr {
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"return_typestate", 0>];
   let Subjects = SubjectList<[Function, ParmVar]>;
-  let Args = [EnumArgument<"State", "ConsumedState", /*ext=*/0,
+  let Args = [EnumArgument<"State", "ConsumedState",
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
   let Documentation = [ReturnTypestateDocs];
@@ -3539,7 +3541,7 @@ def SetTypestate : InheritableAttr {
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"set_typestate", 0>];
   let Subjects = SubjectList<[CXXMethod]>;
-  let Args = [EnumArgument<"NewState", "ConsumedState", /*ext=*/0,
+  let Args = [EnumArgument<"NewState", "ConsumedState",
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
   let Documentation = [SetTypestateDocs];
@@ -3551,7 +3553,7 @@ def TestTypestate : InheritableAttr {
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"test_typestate", 0>];
   let Subjects = SubjectList<[CXXMethod]>;
-  let Args = [EnumArgument<"TestState", "ConsumedState", /*ext=*/0,
+  let Args = [EnumArgument<"TestState", "ConsumedState",
                            ["consumed", "unconsumed"],
                            ["Consumed", "Unconsumed"]>];
   let Documentation = [TestTypestateDocs];
@@ -3620,7 +3622,7 @@ def CFGuard : InheritableAttr, TargetSpecificAttr<TargetWindows> {
   // we might also want to support __declspec(guard(suppress)).
   let Spellings = [Declspec<"guard">, Clang<"guard">];
   let Subjects = SubjectList<[Function]>;
-  let Args = [EnumArgument<"Guard", "GuardArg", /*ext=*/0, ["nocf"], ["nocf"]>];
+  let Args = [EnumArgument<"Guard", "GuardArg", ["nocf"], ["nocf"]>];
   let Documentation = [CFGuardDocs];
 }
 
@@ -3776,7 +3778,7 @@ def LoopHint : Attr {
                    Pragma<"", "nounroll_and_jam">];
 
   /// State of the loop optimization specified by the spelling.
-  let Args = [EnumArgument<"Option", "OptionType", /*ext=*/0,
+  let Args = [EnumArgument<"Option", "OptionType",
                           ["vectorize", "vectorize_width", "interleave", "interleave_count",
                            "unroll", "unroll_count", "unroll_and_jam", "unroll_and_jam_count",
                            "pipeline", "pipeline_initiation_interval", "distribute",
@@ -3785,7 +3787,7 @@ def LoopHint : Attr {
                            "Unroll", "UnrollCount", "UnrollAndJam", "UnrollAndJamCount",
                            "PipelineDisabled", "PipelineInitiationInterval", "Distribute",
                            "VectorizePredicate"]>,
-              EnumArgument<"State", "LoopHintState", /*ext=*/0,
+              EnumArgument<"State", "LoopHintState",
                            ["enable", "disable", "numeric", "fixed_width",
                             "scalable_width", "assume_safety", "full"],
                            ["Enable", "Disable", "Numeric", "FixedWidth",
@@ -3874,7 +3876,7 @@ def OMPDeclareSimdDecl : Attr {
   let HasCustomParsing = 1;
   let Documentation = [OMPDeclareSimdDocs];
   let Args = [
-    EnumArgument<"BranchState", "BranchStateTy", /*ext=*/0,
+    EnumArgument<"BranchState", "BranchStateTy",
                  [ "", "inbranch", "notinbranch" ],
                  [ "BS_Undefined", "BS_Inbranch", "BS_Notinbranch" ]>,
     ExprArgument<"Simdlen">, VariadicExprArgument<"Uniforms">,
@@ -3894,10 +3896,10 @@ def OMPDeclareTargetDecl : InheritableAttr {
   let Subjects = SubjectList<[Function, SharedVar]>;
   let Documentation = [OMPDeclareTargetDocs];
   let Args = [
-    EnumArgument<"MapType", "MapTypeTy", /*ext=*/0,
+    EnumArgument<"MapType", "MapTypeTy",
                  [ "to", "enter", "link" ],
                  [ "MT_To", "MT_Enter", "MT_Link" ]>,
-    EnumArgument<"DevType", "DevTypeTy", /*ext=*/0,
+    EnumArgument<"DevType", "DevTypeTy",
                  [ "host", "nohost", "any" ],
                  [ "DT_Host", "DT_NoHost", "DT_Any" ]>,
     ExprArgument<"IndirectExpr">,
@@ -3919,7 +3921,7 @@ def OMPAllocateDecl : InheritableAttr {
   let Spellings = [];
   let SemaHandler = 0;
   let Args = [
-    EnumArgument<"AllocatorType", "AllocatorTypeTy", /*ext=*/0,
+    EnumArgument<"AllocatorType", "AllocatorTypeTy",
                  [
                    "omp_null_allocator", "omp_default_mem_alloc",
                    "omp_large_cap_mem_alloc", "omp_const_mem_alloc",
@@ -4168,7 +4170,7 @@ def HLSLShader : InheritableAttr {
   let Subjects = SubjectList<[HLSLEntry]>;
   let LangOpts = [HLSL];
   let Args = [
-    EnumArgument<"Type", "ShaderType", /*ext=*/0,
+    EnumArgument<"Type", "ShaderType",
                  ["pixel", "vertex", "geometry", "hull", "domain", "compute",
                   "raygeneration", "intersection", "anyhit", "closesthit",
                   "miss", "callable", "mesh", "amplification"],
@@ -4184,12 +4186,12 @@ def HLSLResource : InheritableAttr {
   let Subjects = SubjectList<[Struct]>;
   let LangOpts = [HLSL];
   let Args = [EnumArgument<"ResourceClass",
-                           "llvm::hlsl::ResourceClass", /*ext=*/1,
+                           "llvm::hlsl::ResourceClass",
                            ["SRV", "UAV", "CBuffer", "Sampler"],
                            ["SRV", "UAV", "CBuffer", "Sampler"]
-                           >,
+                           /*opt=*/0, /*fake=*/0, /*external=*/1>,
               EnumArgument<"ResourceKind",
-                           "llvm::hlsl::ResourceKind", /*ext=*/1,
+                           "llvm::hlsl::ResourceKind",
                            ["Texture1D", "Texture2D", "Texture2DMS",
                             "Texture3D", "TextureCube", "Texture1DArray",
                             "Texture2DArray", "Texture2DMSArray",
@@ -4204,7 +4206,7 @@ def HLSLResource : InheritableAttr {
                             "StructuredBuffer", "CBuffer", "Sampler",
                             "TBuffer", "RTAccelerationStructure",
                             "FeedbackTexture2D", "FeedbackTexture2DArray"]
-                            >
+                           /*opt=*/0, /*fake=*/0, /*external=*/1>
               ];
   let Documentation = [InternalOnly];
 }
@@ -4233,7 +4235,7 @@ def : MutualExclusions<[RandomizeLayout, NoRandomizeLayout]>;
 def FunctionReturnThunks : InheritableAttr,
     TargetSpecificAttr<TargetAnyX86> {
   let Spellings = [GCC<"function_return">];
-  let Args = [EnumArgument<"ThunkType", "Kind", /*ext=*/0,
+  let Args = [EnumArgument<"ThunkType", "Kind",
     ["keep", "thunk-extern"],
     ["Keep", "Extern"]
   >];

>From ad8176937280709540d9037001c1e8dfd395ca83 Mon Sep 17 00:00:00 2001
From: Justin Bogner <mail at justinbogner.com>
Date: Tue, 31 Oct 2023 12:05:25 -0700
Subject: [PATCH 4/7] fixup! [Attributes][HLSL] Teach EnumArgument to refer to
 an external enum

Fix typo
---
 clang/include/clang/Basic/Attr.td | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 9a95faec1791364..6f8ecf5becdad91 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4188,7 +4188,7 @@ def HLSLResource : InheritableAttr {
   let Args = [EnumArgument<"ResourceClass",
                            "llvm::hlsl::ResourceClass",
                            ["SRV", "UAV", "CBuffer", "Sampler"],
-                           ["SRV", "UAV", "CBuffer", "Sampler"]
+                           ["SRV", "UAV", "CBuffer", "Sampler"],
                            /*opt=*/0, /*fake=*/0, /*external=*/1>,
               EnumArgument<"ResourceKind",
                            "llvm::hlsl::ResourceKind",
@@ -4205,7 +4205,7 @@ def HLSLResource : InheritableAttr {
                             "TextureCubeArray", "TypedBuffer", "RawBuffer",
                             "StructuredBuffer", "CBuffer", "Sampler",
                             "TBuffer", "RTAccelerationStructure",
-                            "FeedbackTexture2D", "FeedbackTexture2DArray"]
+                            "FeedbackTexture2D", "FeedbackTexture2DArray"],
                            /*opt=*/0, /*fake=*/0, /*external=*/1>
               ];
   let Documentation = [InternalOnly];

>From 05a376621c95317776c2a198fc9f10a46590e43e Mon Sep 17 00:00:00 2001
From: Justin Bogner <mail at justinbogner.com>
Date: Tue, 31 Oct 2023 13:13:10 -0700
Subject: [PATCH 5/7] fixup! [Attributes][HLSL] Teach EnumArgument to refer to
 an external enum

Add "External" to VariadicEnumArgument
---
 clang/include/clang/Basic/Attr.td         |  4 +-
 clang/utils/TableGen/ClangAttrEmitter.cpp | 81 ++++++++++++++---------
 2 files changed, 51 insertions(+), 34 deletions(-)

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 6f8ecf5becdad91..0d83f83bd3632b8 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -293,10 +293,12 @@ class EnumArgument<string name, string type, list<string> values,
 // FIXME: There should be a VariadicArgument type that takes any other type
 //        of argument and generates the appropriate type.
 class VariadicEnumArgument<string name, string type, list<string> values,
-                           list<string> enums> : Argument<name, 1>  {
+                           list<string> enums, bit external = 0>
+    : Argument<name, 1>  {
   string Type = type;
   list<string> Values = values;
   list<string> Enums = enums;
+  bit External = external;
 }
 
 // This handles one spelling of an attribute.
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index fa5d95a074ec64f..203bb1ba2c3e5af 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -910,7 +910,11 @@ namespace {
           uniques(uniqueEnumsInOrder(enums)),
           isExternal(Arg.getValueAsBit("External")) {
       StringRef Type = Arg.getValueAsString("Type");
-      shortType = isExternal ? getAttrName().rsplit("::").second : Type;
+      shortType = isExternal ? Type.rsplit("::").second : Type;
+      // If shortType didn't contain :: at all rsplit will give us an empty
+      // string.
+      if (shortType.empty())
+        shortType = Type;
       fullType = isExternal ? Type : (getAttrName() + "Attr::" + Type).str();
 
       // FIXME: Emit a proper error
@@ -1041,27 +1045,36 @@ namespace {
   };
 
   class VariadicEnumArgument: public VariadicArgument {
-    std::string type, QualifiedTypeName;
+    std::string fullType;
+    StringRef shortType;
     std::vector<StringRef> values, enums, uniques;
+    bool isExternal;
 
   protected:
     void writeValueImpl(raw_ostream &OS) const override {
       // FIXME: this isn't 100% correct -- some enum arguments require printing
       // as a string literal, while others require printing as an identifier.
       // Tablegen currently does not distinguish between the two forms.
-      OS << "    OS << \"\\\"\" << " << getAttrName() << "Attr::Convert" << type
-         << "ToStr(Val)" << "<< \"\\\"\";\n";
+      OS << "    OS << \"\\\"\" << " << getAttrName() << "Attr::Convert"
+         << shortType << "ToStr(Val)"
+         << "<< \"\\\"\";\n";
     }
 
   public:
     VariadicEnumArgument(const Record &Arg, StringRef Attr)
         : VariadicArgument(Arg, Attr,
                            std::string(Arg.getValueAsString("Type"))),
-          type(std::string(Arg.getValueAsString("Type"))),
           values(Arg.getValueAsListOfStrings("Values")),
           enums(Arg.getValueAsListOfStrings("Enums")),
-          uniques(uniqueEnumsInOrder(enums)) {
-      QualifiedTypeName = getAttrName().str() + "Attr::" + type;
+          uniques(uniqueEnumsInOrder(enums)),
+          isExternal(Arg.getValueAsBit("External")) {
+      StringRef Type = Arg.getValueAsString("Type");
+      shortType = isExternal ? Type.rsplit("::").second : Type;
+      // If shortType didn't contain :: at all rsplit will give us an empty
+      // string.
+      if (shortType.empty())
+        shortType = Type;
+      fullType = isExternal ? Type : (getAttrName() + "Attr::" + Type).str();
 
       // FIXME: Emit a proper error
       assert(!uniques.empty());
@@ -1070,16 +1083,18 @@ namespace {
     bool isVariadicEnumArg() const override { return true; }
 
     void writeDeclarations(raw_ostream &OS) const override {
-      auto i = uniques.cbegin(), e = uniques.cend();
-      // The last one needs to not have a comma.
-      --e;
+      if (!isExternal) {
+        auto i = uniques.cbegin(), e = uniques.cend();
+        // The last one needs to not have a comma.
+        --e;
 
-      OS << "public:\n";
-      OS << "  enum " << type << " {\n";
-      for (; i != e; ++i)
-        OS << "    " << *i << ",\n";
-      OS << "    " << *e << "\n";
-      OS << "  };\n";
+        OS << "public:\n";
+        OS << "  enum " << shortType << " {\n";
+        for (; i != e; ++i)
+          OS << "    " << *i << ",\n";
+        OS << "    " << *e << "\n";
+        OS << "  };\n";
+      }
       OS << "private:\n";
 
       VariadicArgument::writeDeclarations(OS);
@@ -1091,7 +1106,7 @@ namespace {
          << getLowerName() << "_end(); I != E; ++I) {\n";
       OS << "      switch(*I) {\n";
       for (const auto &UI : uniques) {
-        OS << "    case " << getAttrName() << "Attr::" << UI << ":\n";
+        OS << "    case " << fullType << "::" << UI << ":\n";
         OS << "      OS << \" " << UI << "\";\n";
         OS << "      break;\n";
       }
@@ -1101,13 +1116,13 @@ namespace {
 
     void writePCHReadDecls(raw_ostream &OS) const override {
       OS << "    unsigned " << getLowerName() << "Size = Record.readInt();\n";
-      OS << "    SmallVector<" << QualifiedTypeName << ", 4> " << getLowerName()
+      OS << "    SmallVector<" << fullType << ", 4> " << getLowerName()
          << ";\n";
       OS << "    " << getLowerName() << ".reserve(" << getLowerName()
          << "Size);\n";
       OS << "    for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
       OS << "      " << getLowerName() << ".push_back(" << "static_cast<"
-         << QualifiedTypeName << ">(Record.readInt()));\n";
+         << fullType << ">(Record.readInt()));\n";
     }
 
     void writePCHWrite(raw_ostream &OS) const override {
@@ -1115,41 +1130,41 @@ namespace {
       OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
          << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
          << getLowerName() << "_end(); i != e; ++i)\n";
-      OS << "      " << WritePCHRecord(QualifiedTypeName, "(*i)");
+      OS << "      " << WritePCHRecord(fullType, "(*i)");
     }
 
     void writeConversion(raw_ostream &OS, bool Header) const {
       if (Header) {
-        OS << "  static bool ConvertStrTo" << type << "(StringRef Val, " << type
-           << " &Out);\n";
-        OS << "  static const char *Convert" << type << "ToStr(" << type
-           << " Val);\n";
+        OS << "  static bool ConvertStrTo" << shortType << "(StringRef Val, "
+           << fullType << " &Out);\n";
+        OS << "  static const char *Convert" << shortType << "ToStr("
+           << fullType << " Val);\n";
         return;
       }
 
-      OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << type
+      OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << shortType
          << "(StringRef Val, ";
-      OS << type << " &Out) {\n";
-      OS << "  std::optional<" << type
+      OS << fullType << " &Out) {\n";
+      OS << "  std::optional<" << fullType
          << "> R = llvm::StringSwitch<std::optional<";
-      OS << type << ">>(Val)\n";
+      OS << fullType << ">>(Val)\n";
       for (size_t I = 0; I < enums.size(); ++I) {
         OS << "    .Case(\"" << values[I] << "\", ";
-        OS << getAttrName() << "Attr::" << enums[I] << ")\n";
+        OS << fullType << "::" << enums[I] << ")\n";
       }
-      OS << "    .Default(std::optional<" << type << ">());\n";
+      OS << "    .Default(std::optional<" << fullType << ">());\n";
       OS << "  if (R) {\n";
       OS << "    Out = *R;\n      return true;\n    }\n";
       OS << "  return false;\n";
       OS << "}\n\n";
 
-      OS << "const char *" << getAttrName() << "Attr::Convert" << type
-         << "ToStr(" << type << " Val) {\n"
+      OS << "const char *" << getAttrName() << "Attr::Convert" << shortType
+         << "ToStr(" << fullType << " Val) {\n"
          << "  switch(Val) {\n";
       SmallDenseSet<StringRef, 8> Uniques;
       for (size_t I = 0; I < enums.size(); ++I) {
         if (Uniques.insert(enums[I]).second)
-          OS << "  case " << getAttrName() << "Attr::" << enums[I]
+          OS << "  case " << fullType << "::" << enums[I]
              << ": return \"" << values[I] << "\";\n";
       }
       OS << "  }\n"

>From 6a2e6c3abfa98a5a61ede3bd0dfe329b255f8b68 Mon Sep 17 00:00:00 2001
From: Justin Bogner <mail at justinbogner.com>
Date: Tue, 31 Oct 2023 13:48:11 -0700
Subject: [PATCH 6/7] fixup! [Attributes][HLSL] Teach EnumArgument to refer to
 an external enum

undo spurious formatting
---
 clang/include/clang/Basic/Attr.td | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 0d83f83bd3632b8..85655bae1d28561 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1020,8 +1020,7 @@ def ExternalSourceSymbol : InheritableAttr {
 
 def Blocks : InheritableAttr {
   let Spellings = [Clang<"blocks">];
-  let Args = [EnumArgument<"Type", "BlockType",
-                           ["byref"], ["ByRef"]>];
+  let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
   let Documentation = [Undocumented];
 }
 
@@ -2965,7 +2964,8 @@ def DiagnoseIf : InheritableAttr {
   let Spellings = [GNU<"diagnose_if">];
   let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
   let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
-              EnumArgument<"DiagnosticType", "DiagnosticType",
+              EnumArgument<"DiagnosticType",
+                           "DiagnosticType",
                            ["error", "warning"],
                            ["DT_Error", "DT_Warning"]>,
               BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
@@ -4187,13 +4187,11 @@ def HLSLResource : InheritableAttr {
   let Spellings = [];
   let Subjects = SubjectList<[Struct]>;
   let LangOpts = [HLSL];
-  let Args = [EnumArgument<"ResourceClass",
-                           "llvm::hlsl::ResourceClass",
+  let Args = [EnumArgument<"ResourceClass", "llvm::hlsl::ResourceClass",
                            ["SRV", "UAV", "CBuffer", "Sampler"],
                            ["SRV", "UAV", "CBuffer", "Sampler"],
                            /*opt=*/0, /*fake=*/0, /*external=*/1>,
-              EnumArgument<"ResourceKind",
-                           "llvm::hlsl::ResourceKind",
+              EnumArgument<"ResourceKind", "llvm::hlsl::ResourceKind",
                            ["Texture1D", "Texture2D", "Texture2DMS",
                             "Texture3D", "TextureCube", "Texture1DArray",
                             "Texture2DArray", "Texture2DMSArray",

>From 6725fa744d33cc0907bfd490ff9fc743449a747d Mon Sep 17 00:00:00 2001
From: Justin Bogner <mail at justinbogner.com>
Date: Tue, 31 Oct 2023 14:57:47 -0700
Subject: [PATCH 7/7] fixup! [Attributes][HLSL] Teach EnumArgument to refer to
 an external enum

Appease clang-format
---
 clang/utils/TableGen/ClangAttrEmitter.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 203bb1ba2c3e5af..ec04c34d613ea9e 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -1121,8 +1121,8 @@ namespace {
       OS << "    " << getLowerName() << ".reserve(" << getLowerName()
          << "Size);\n";
       OS << "    for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
-      OS << "      " << getLowerName() << ".push_back(" << "static_cast<"
-         << fullType << ">(Record.readInt()));\n";
+      OS << "      " << getLowerName() << ".push_back("
+         << "static_cast<" << fullType << ">(Record.readInt()));\n";
     }
 
     void writePCHWrite(raw_ostream &OS) const override {
@@ -1164,8 +1164,8 @@ namespace {
       SmallDenseSet<StringRef, 8> Uniques;
       for (size_t I = 0; I < enums.size(); ++I) {
         if (Uniques.insert(enums[I]).second)
-          OS << "  case " << fullType << "::" << enums[I]
-             << ": return \"" << values[I] << "\";\n";
+          OS << "  case " << fullType << "::" << enums[I] << ": return \""
+             << values[I] << "\";\n";
       }
       OS << "  }\n"
          << "  llvm_unreachable(\"No enumerator with that value\");\n"



More information about the cfe-commits mailing list