[clang] 15aa643 - [HLSL] Support register binding attribute on global variable

Xiang Li via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 5 09:25:58 PDT 2022


Author: Xiang Li
Date: 2022-10-05T09:23:35-07:00
New Revision: 15aa64301ab146dec7c6ffcd0418ed834bf099e2

URL: https://github.com/llvm/llvm-project/commit/15aa64301ab146dec7c6ffcd0418ed834bf099e2
DIFF: https://github.com/llvm/llvm-project/commit/15aa64301ab146dec7c6ffcd0418ed834bf099e2.diff

LOG: [HLSL] Support register binding attribute on global variable

Allow register binding attribute on variables.

Report warning when register binding attribute applies to local variable or static variable.
It will be ignored in this case.

Type check for register binding is tracked with https://github.com/llvm/llvm-project/issues/57886.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D134617

Added: 
    

Modified: 
    clang/include/clang/Basic/Attr.td
    clang/include/clang/Parse/Parser.h
    clang/lib/Parse/ParseDecl.cpp
    clang/test/AST/HLSL/resource_binding_attr.hlsl
    clang/test/SemaHLSL/resource_binding_attr_error.hlsl

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 1bfe4b6c48a2b..fa718b51d8134 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -133,6 +133,12 @@ def SharedVar : SubsetSubject<Var,
 def GlobalVar : SubsetSubject<Var,
                              [{S->hasGlobalStorage()}], "global variables">;
 
+def ExternalGlobalVar : SubsetSubject<Var,
+                             [{S->hasGlobalStorage() &&
+                               S->getStorageClass()!=StorageClass::SC_Static &&
+                               !S->isLocalExternDecl()}],
+                             "external global variables">;
+
 def InlineFunction : SubsetSubject<Function,
                              [{S->isInlineSpecified()}], "inline functions">;
 
@@ -3992,7 +3998,7 @@ def HLSLSV_GroupIndex: HLSLAnnotationAttr {
 
 def HLSLResourceBinding: InheritableAttr {
   let Spellings = [HLSLSemantic<"register">];
-  let Subjects = SubjectList<[HLSLBufferObj, GlobalVar]>;
+  let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar]>;
   let LangOpts = [HLSL];
   let Args = [StringArgument<"Slot">, StringArgument<"Space", 1>];
   let Documentation = [HLSLResourceBindingDocs];

diff  --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index cb396b8b54122..c518ce5487bd8 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2881,8 +2881,19 @@ class Parser : public CodeCompletionHandler {
       Sema::AttributeCompletion Completion = Sema::AttributeCompletion::None,
       const IdentifierInfo *EnclosingScope = nullptr);
 
+  void MaybeParseHLSLSemantics(Declarator &D,
+                               SourceLocation *EndLoc = nullptr) {
+    assert(getLangOpts().HLSL && "MaybeParseHLSLSemantics is for HLSL only");
+    if (Tok.is(tok::colon)) {
+      ParsedAttributes Attrs(AttrFactory);
+      ParseHLSLSemantics(Attrs, EndLoc);
+      D.takeAttributes(Attrs);
+    }
+  }
+
   void MaybeParseHLSLSemantics(ParsedAttributes &Attrs,
                                SourceLocation *EndLoc = nullptr) {
+    assert(getLangOpts().HLSL && "MaybeParseHLSLSemantics is for HLSL only");
     if (getLangOpts().HLSL && Tok.is(tok::colon))
       ParseHLSLSemantics(Attrs, EndLoc);
   }

diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index dfedbf5b2d779..ddb83a8c6694d 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2054,6 +2054,9 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
     return nullptr;
   }
 
+  if (getLangOpts().HLSL)
+    MaybeParseHLSLSemantics(D);
+
   if (Tok.is(tok::kw_requires))
     ParseTrailingRequiresClause(D);
 
@@ -2223,6 +2226,10 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
       DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
 
     ParseDeclarator(D);
+
+    if (getLangOpts().HLSL)
+      MaybeParseHLSLSemantics(D);
+
     if (!D.isInvalidType()) {
       // C++2a [dcl.decl]p1
       //    init-declarator:
@@ -7165,7 +7172,8 @@ void Parser::ParseParameterDeclarationClause(
 
     // Parse GNU attributes, if present.
     MaybeParseGNUAttributes(ParmDeclarator);
-    MaybeParseHLSLSemantics(DS.getAttributes());
+    if (getLangOpts().HLSL)
+      MaybeParseHLSLSemantics(DS.getAttributes());
 
     if (Tok.is(tok::kw_requires)) {
       // User tried to define a requires clause in a parameter declaration,

diff  --git a/clang/test/AST/HLSL/resource_binding_attr.hlsl b/clang/test/AST/HLSL/resource_binding_attr.hlsl
index ecb7e3ab98db5..6836071971111 100644
--- a/clang/test/AST/HLSL/resource_binding_attr.hlsl
+++ b/clang/test/AST/HLSL/resource_binding_attr.hlsl
@@ -22,3 +22,16 @@ float foo() {
 // CHECK-NEXT: DeclRefExpr 0x{{[0-9a-f]+}} <col:14> 'float' lvalue Var 0x[[B]] 'b' 'float'
   return a + b;
 }
+
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <{{.*}}> col:17 UAV 'RWBuffer<float>':'hlsl::RWBuffer<>' callinit
+// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:17> 'RWBuffer<float>':'hlsl::RWBuffer<>' 'void ()'
+// CHECK-NEXT:-HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:23> "u3" "space0"
+RWBuffer<float> UAV : register(u3);
+
+// CHECK: -VarDecl 0x{{[0-9a-f]+}} <{{.*}}> col:17 UAV1 'RWBuffer<float>':'hlsl::RWBuffer<>' callinit
+// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:17> 'RWBuffer<float>':'hlsl::RWBuffer<>' 'void ()'
+// CHECK-NEXT:-HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:24> "u2" "space0"
+// CHECK-NEXT:-VarDecl 0x{{[0-9a-f]+}} <col:1, col:38> col:38 UAV2 'RWBuffer<float>':'hlsl::RWBuffer<>' callinit
+// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:38> 'RWBuffer<float>':'hlsl::RWBuffer<>' 'void ()'
+// CHECK-NEXT:-HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:45> "u4" "space0"
+RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4);

diff  --git a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl
index 2c3f52c0caec8..95774472aaea0 100644
--- a/clang/test/SemaHLSL/resource_binding_attr_error.hlsl
+++ b/clang/test/SemaHLSL/resource_binding_attr_error.hlsl
@@ -1,10 +1,6 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - -fsyntax-only %s -verify
 
-// expected-error at +5 {{expected ';' after top level declarator}}
-// expected-error at +4 {{expected ')'}}
-// expected-note at +3 {{to match this '('}}
-// expected-error at +2 {{a type specifier is required for all declarations}}
-// expected-error at +1 {{illegal storage class on file-scoped variable}}
+// expected-error at +1 {{invalid resource class specifier 'c' used; expected 'b', 's', 't', or 'u'}}
 float a : register(c0, space1);
 
 // expected-error at +1 {{invalid resource class specifier 'i' used; expected 'b', 's', 't', or 'u'}}
@@ -36,3 +32,29 @@ cbuffer C : register(b 2) {}
 // expected-error at +2 {{wrong argument format for hlsl attribute, use b2 instead}}
 // expected-error at +1 {{wrong argument format for hlsl attribute, use space3 instead}}
 cbuffer D : register(b 2, space 3) {}
+
+// expected-warning at +1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}}
+static RWBuffer<float> U : register(u5);
+
+void foo() {
+  // expected-warning at +1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}}
+  RWBuffer<float> U : register(u3);
+}
+void foo2() {
+  // expected-warning at +1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}}
+  extern RWBuffer<float> U2 : register(u5);
+}
+// FIXME: expect-error once fix https://github.com/llvm/llvm-project/issues/57886.
+float b : register(u0, space1);
+
+// expected-warning at +1 {{'register' attribute only applies to cbuffer/tbuffer and external global variables}}
+void bar(RWBuffer<float> U : register(u3)) {
+
+}
+
+struct S {
+  // FIXME: generate better error when support semantic on struct field.
+  // See https://github.com/llvm/llvm-project/issues/57889.
+  // expected-error at +1 {{expected expression}}
+  RWBuffer<float> U : register(u3);
+};


        


More information about the cfe-commits mailing list