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@+5 {{expected ';' after top level declarator}}
-// expected-error@+4 {{expected ')'}}
-// expected-note@+3 {{to match this '('}}
-// expected-error@+2 {{a type specifier is required for all declarations}}
-// expected-error@+1 {{illegal storage class on file-scoped variable}}
+// expected-error@+1 {{invalid resource class specifier 'c' used; expected 
'b', 's', 't', or 'u'}}
 float a : register(c0, space1);
 
 // expected-error@+1 {{invalid resource class specifier 'i' used; expected 
'b', 's', 't', or 'u'}}
@@ -36,3 +32,29 @@ cbuffer C : register(b 2) {}
 // expected-error@+2 {{wrong argument format for hlsl attribute, use b2 
instead}}
 // expected-error@+1 {{wrong argument format for hlsl attribute, use space3 
instead}}
 cbuffer D : register(b 2, space 3) {}
+
+// expected-warning@+1 {{'register' attribute only applies to cbuffer/tbuffer 
and external global variables}}
+static RWBuffer<float> U : register(u5);
+
+void foo() {
+  // expected-warning@+1 {{'register' attribute only applies to 
cbuffer/tbuffer and external global variables}}
+  RWBuffer<float> U : register(u3);
+}
+void foo2() {
+  // expected-warning@+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@+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@+1 {{expected expression}}
+  RWBuffer<float> U : register(u3);
+};


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to