spec.hlsl 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. // RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s
  2. // This file provides test cases that are cross-references to the HLSL
  3. // specification.
  4. // To test with the classic compiler, run
  5. // %sdxroot%\tools\x86\fxc.exe /T ps_5_1 spec.hlsl
  6. namespace ns_general {
  7. // * General
  8. // ** Scope
  9. // ** Normative references
  10. // ** Definitions
  11. // ** Implementation compliance
  12. // ** Structure of this specification
  13. // ** Syntax notation
  14. // ** The HLSL memory model
  15. // ** The HLSL object model
  16. // Objects can contain other objects, called subobjects. A subobject can be a
  17. // member subobject, a base class subobject, or an array element.
  18. void fn(inout uint a) { a += 2; }
  19. void subobjects() {
  20. class Class { uint field; };
  21. class SuperClass { Class C; uint field; };
  22. uint scalar = 0;
  23. Class C = { 0 };
  24. SuperClass SC = { 0, 0 };
  25. uint2 u2 = 0;
  26. uint arr2[2] = { 0, 0 };
  27. uint2x2 mat2 = 0;
  28. fn(scalar);
  29. fn(C.field);
  30. fn(SC.C.field);
  31. fn(u2.x);
  32. fn(mat2._11);
  33. }
  34. // ** Program execution
  35. // ** Multi-threaded executions and data races
  36. // ** Acknowledgments
  37. }
  38. namespace ns_lexical {
  39. // * Lexical Conventions
  40. // ** Separate translation
  41. // ** Phases of translation
  42. // ** Character sets
  43. // ** Trigraph sequences
  44. // ** Preprocessing tokens
  45. // ** Alternative tokens
  46. // ** Tokens
  47. // ** Comments
  48. // ** Header names
  49. // ** Preprocessing numbers
  50. // ** Identifiers
  51. // ** Keywords
  52. // ** Operators and punctuators
  53. // ** Literals
  54. }
  55. namespace ns_basic {
  56. // * Basic Concepts
  57. // ** Declarations and definitions
  58. // ** One definition rule
  59. // ** Scope
  60. // ** Name lookup
  61. // ** Program and linkage
  62. // ** Start and termination
  63. // ** Storage duration
  64. // ** Object lifetime
  65. // ** Types
  66. //extern int arr[]; // the type of arr is incomplete ; fxc-eerror {{error X3074: 'ns_basic::arr': implicit array missing initial value}}
  67. //typedef int UNKA[]; // UNKA is an incomplete type ; fxc-error {{error X3072: array dimensions of type must be explicit}}
  68. // cbuffer C; // fxc-error {{error X3000: syntax error: unexpected token ';'}}
  69. string s = "my string";
  70. int int_var;
  71. uint uint_var;
  72. dword dword_var;
  73. min16int min16int_var;
  74. min16uint mint6uint_var;
  75. int fn_dword_overload(dword d) { return 1; }
  76. void fn_void_conversions() {
  77. //(void)1; // fxc-error {{cannot convert from 'int' to 'void'}}
  78. }
  79. // ** Lvalues and rvalues
  80. // ** Alignment
  81. }
  82. namespace ns_std_conversions {
  83. // * Standard conversions
  84. struct s_mixed { int2 i2; float2 f2; };
  85. struct s_mixed2 { s_mixed s; int arr[4]; };
  86. struct s_i4i4 { int4 i4; int4 i4_2; };
  87. struct s_i4i4_2 { int4 i4; int4 i4_2; };
  88. void fn_mixed(s_mixed a) { }
  89. s_mixed fn_int_mixed(int a) { s_mixed r = {0,0,2,3}; return r; }
  90. void fn_foo(inout s_i4i4 v) { v.i4.z += 1; }
  91. void fn_init_or_assign() {
  92. // Standard conversions will occur as initialization including use of an
  93. // argument in a function call and expression in a return statement.
  94. //
  95. // Assignment has different rules (in particular, flattening does not occur).
  96. //
  97. // However, flattening occurs only for initialization lists, which are only
  98. // allowed variable initialization. So the distinction is moot.
  99. s_mixed s = { 1, 2, 1, 2 };
  100. s_mixed2 s2 = { s, 1, 2, 3, 4 };
  101. s_i4i4 si4i4 = { 1, 2, 3, 4, 1, 2, 3, 4 };
  102. si4i4 = (s_i4i4)s2;
  103. //TODO: Implicit casting must be between two structurally identical types (as
  104. //compared by flattening structure); explicit casting is required when the
  105. //right-hand type has more elements.
  106. s_i4i4_2 si4i42 = { 1, 2, 3, 4, 1, 2, 3, 4 };
  107. si4i4 = si4i42;
  108. // fn_foo((s_i4i4)s2); // cannot use casts on l-values
  109. float4 f4 = (float4)s;
  110. int2 i2 = (int2)s; // explicit cast
  111. int2 io = (int2)si4i4;
  112. }
  113. // ** Lvalue-to-rvalue conversion
  114. // ** Vector conversions
  115. void fn_f1(float1 a) { }
  116. void fn_f4(float4 b) { }
  117. void fn_u4(float4 b) { }
  118. void fn_f(float f) { }
  119. void fn_iof(inout float f) { f += 1; }
  120. void fn_iof1(inout float1 f) { f.x += 1; }
  121. void fn_vector_conversions() {
  122. float f = 1;
  123. int i = 1; uint u = 1;
  124. float1 f1 = f; uint1 u1 = { 1 };
  125. float3 f3 = { 1, 2, 3 };
  126. float4 f4 = { 1, 2, 3, 4}; uint4 u4 = { 1, 2, 3, 4 };
  127. fn_f1(f); // vector splat
  128. fn_f4(f); // vector splat
  129. fn_f1(i); // vector splat
  130. fn_f4(i); // vector splat
  131. fn_u4(f4); // vector element
  132. fn_f4(u4); // vector element
  133. f3 = f4; // vector truncate
  134. // f4 = f3; // fxc-error {{error X3017: cannot implicitly convert from 'float3' to 'float4'}}
  135. fn_iof(f1); // inout case (float1->float - vector single element conversion; float->float1 vector splat)
  136. fn_iof1(u); // inout case (uint->float1 - vector splat; float1->uint vector single element conversion)
  137. }
  138. struct struct_f44 { float4x4 f44; };
  139. void fn_f14(float1x4 a) { }
  140. void fn_f22(float2x2 a) { }
  141. void fn_f41(float4x1 a) { }
  142. void fn_f44(float4x4 a) { }
  143. void fn_matrix_conversions() {
  144. float f = 1; uint u = 1;
  145. float1 f1 = 1; uint1 u1 = 1;
  146. float2 f2 = { 1, 2 }; uint2 u2 = { 1, 2 };
  147. float3 f3 = 0; uint3 u3 = 0;
  148. float4 f4 = { 1, 2, 3, 4 }; uint4 u4 = { 1, 2, 3, 4 };
  149. struct_f44 s44 = {1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};
  150. float1x1 f11 = { 1 }; uint1x1 u11 = { 1 };
  151. float1x2 f12 = { 1, 2 };
  152. float1x3 f13 = 0;
  153. float2x2 f22 = f4; uint2x2 u22 = u4;
  154. float2x3 f23 = 0;
  155. float3x1 f31 = 0;
  156. float3x2 f32 = 0;
  157. float3x3 f33 = 0;
  158. float4x4 f44 = {1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};
  159. float1x4 f14 = {1,2,3,4}; uint1x4 u14 = {1,2,3,4};
  160. float4x1 f41 = {1,2,3,4}; uint4x1 u41 = {1,2,3,4};
  161. uint4x4 u44 = {1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};
  162. fn_f44(f); // matrix splat conversion
  163. //fn_f44(f4); // no matrix splat conversion fxc-error {{error X3017: cannot implicitly convert from 'float4' to 'float4x4'}}
  164. //fn_f44(s44); // no matrix splat conversion fxc-error {{error X3017: cannot convert from 'struct ns_std_conversions::struct_f44' to 'float4x4'}}
  165. fn_f14(f4); // matrix vector conversion
  166. fn_f22(f4); // matrix vector conversion (not vector-like, but still same element count)
  167. fn_f22(u4); // matrix vector conversion (with element implicit conversion)
  168. fn_f44(u44); // matrix element conversion
  169. // fn_f14(u41); // no matrix element conversion from different shape, even with same element count - fxc-error {{cannot implicitly convert from 'uint4x1' to 'float4'}}
  170. //fn_f41(u14); // no matrix element conversion from different shape, even with same element count - fxc-error {{cannot implicitly convert from 'uint4' to 'float4x1'}}
  171. //fn_f14(f41); // no matrix from a different shape, even with the same type and element count - fxc-error {{cannot implicitly convert from 'float4x1' to 'float4'}}
  172. fn_f14(1);
  173. u = f11; // matrix single element conversion
  174. u = f14; // matrix scalar truncation conversion
  175. u2 = f11; // matrix single element vector conversion
  176. u4 = f22; // matrix to vector conversion
  177. //u3 = f22; // cannot convert if target has less
  178. //u3 = f12; // cannot convert if target has more
  179. u44 = f44; // matrix element-type conversion
  180. u22 = f44; // can convert to smaller
  181. u22 = f33; // can convert to smaller
  182. f32 = f33; // can convert as long as each dimension is smaller
  183. //u44 = f22; // cannot convert to bigger
  184. }
  185. // ** Qualification conversions
  186. // ** Integral promotions
  187. // ** Floating point promotion
  188. // ** Integral conversions
  189. // ** Floating point conversions
  190. // ** Floating-integral conversions
  191. // ** Pointer conversions
  192. // ** Pointer to member conversions
  193. // ** Boolean conversions
  194. // ** Integer conversion rank
  195. }
  196. // * Expressions
  197. // ** Primary expressions
  198. // ** Postfix expressions
  199. // ** Unary expressions
  200. // ** Explicit type conversion (cast notation)
  201. // ** Pointer-to-member operators
  202. // ** Multiplicative operators
  203. // ** Additive operators
  204. // ** Shift operators
  205. // ** Relational operators
  206. // ** Equality operators
  207. // ** Bitwise AND operator
  208. // ** Bitwise exclusive OR operator
  209. // ** Bitwise inclusive OR operator
  210. // ** Logical AND operator
  211. // ** Logical OR operator
  212. // ** Conditional operator
  213. // ** Assignment and compound assignment operators
  214. // ** Comma operator
  215. // ** Constant expressions
  216. // * Statements
  217. // ** Labeled statement
  218. // ** Expression statement
  219. // ** Compound statement or block
  220. // ** Selection statements
  221. // ** Iteration statements
  222. // ** Jump statements
  223. // ** Declaration statement
  224. // ** Ambiguity resolution
  225. // * Declarations
  226. // ** Specifiers
  227. // ** Enumeration declarations
  228. // ** Namespaces
  229. // ** The asm declaration
  230. // ** Linkage specifications
  231. // ** Attributes
  232. // * Declarators
  233. // ** Type names
  234. // ** Ambiguity resolution
  235. // ** Meaning of declarators
  236. // ** Function definitions
  237. // ** Initializers
  238. // * Classes
  239. // ** Class names
  240. // ** Class members
  241. // ** Member functions
  242. // ** Static members
  243. // ** Unions
  244. // ** Bit-fields
  245. // ** Nested class declarations
  246. // ** Local class declarations
  247. // ** Nested type names
  248. // * Derived classes
  249. // ** Multiple base classes
  250. // ** Member name lookup
  251. // ** Virtual functions
  252. // ** Abstract classes
  253. // * Member access control
  254. // ** Access specifiers
  255. // ** Accessibility of base classes and base class members
  256. // ** Access declarations
  257. // ** Friends
  258. // ** Protected member access
  259. // ** Access to virtual functions
  260. // ** Multiple access
  261. // ** Nested classes
  262. // * Special member functions
  263. // ** Constructors
  264. // ** Temporary objects
  265. // ** Conversions
  266. // ** Destructors
  267. // ** Free store
  268. // ** Initialization
  269. // ** Construction and destruction
  270. // ** Copying and moving class objects
  271. // ** Inheriting Constructors
  272. namespace ns_overloading {
  273. // * Overloading
  274. // ** Overloadable declarations
  275. int f(int a) { return a; }
  276. int f(const int a) { return a; }
  277. int f_default_0(int a = 3);
  278. //int f_default_0(int a = 4); // error X3114: 'a': default parameters can only be provided in the first prototype
  279. int f_default(int a = 1) { return a; }
  280. int f_default(int a = 3); // TODO: after definition, declaration may provide default, and this is ignored
  281. // int f_default_args(int a, int b = 0);
  282. int f_default_args(int a = 0, int b);
  283. int f_default_args() { return 1; }
  284. int f_default_args_equiv(int a);
  285. int f_default_args_equiv(int a = 1);
  286. int f_default_args_equiv(int a) { return a; }
  287. // ** Declaration matching
  288. // ** Overload resolution
  289. // ** Address of overloaded function
  290. // ** Overloaded operators
  291. // ** Built-in operators
  292. float test() {
  293. int a = 1;
  294. // f(a); // error X3067: 'f': ambiguous function call
  295. return f_default_args_equiv();
  296. }
  297. }
  298. // * Templates
  299. // ** Template parameters
  300. // ** Names of template specializations
  301. // ** Template arguments
  302. // ** Type equivalence
  303. // ** Template declarations
  304. // ** Name resolution
  305. // ** Template instantiation and specialization
  306. // ** Function template specializations
  307. // * Exception handling
  308. // ** Throwing an exception
  309. // ** Constructors and destructors
  310. // ** Handling an exception
  311. // ** Exception specifications
  312. // ** Special functions
  313. // * Preprocessing directives
  314. // ** Conditional inclusion
  315. // ** Source file inclusion
  316. // ** Macro replacement
  317. // ** Line control
  318. // ** Error directive
  319. // ** Pragma directive
  320. // ** Null directive
  321. // ** Predefined macro names
  322. // ** Pragma operator
  323. // * Library introduction
  324. // ** General
  325. // ** The C standard library
  326. // ** Definitions
  327. // ** Additional definitions
  328. // ** Method of description (Informative)
  329. // ** Library-wide requirements
  330. // * Language support library
  331. // ** General
  332. // ** Types
  333. // ** Implementation properties
  334. // ** Integer types
  335. // ** Start and termination
  336. // ** Dynamic memory management
  337. // ** Type identification
  338. // ** Exception handling
  339. // ** Initializer lists
  340. // ** Other runtime support
  341. // * Diagnostics library
  342. // ** General
  343. // ** Exception classes
  344. // ** Assertions
  345. // ** Error numbers
  346. // ** System error support
  347. // * General utilities library
  348. // ** General
  349. // ** Requirements
  350. // ** Utility components
  351. // ** Tuples
  352. // ** Class template bitset
  353. // ** Compile-time rational arithmetic
  354. // ** Metaprogramming and type traits
  355. // ** Function objects
  356. // ** Memory
  357. // ** Time utilities
  358. // ** Date and time functions
  359. // ** Class type_index
  360. // * References
  361. // * Appendix - Grammar summary
  362. // ** Keywords
  363. // ** Lexical conventions
  364. // ** Basic concepts
  365. // ** Expressions
  366. // ** Statements
  367. // ** Declarations
  368. // ** Declarators
  369. // ** Classes
  370. // ** Derived classes
  371. // ** Special member functions
  372. // ** Overloading
  373. // ** Templates
  374. // ** Exception handling
  375. // ** Preprocessing directives
  376. struct main_output
  377. {
  378. float4 t0 : SV_Target0;
  379. //float4 p0 : SV_Position0;
  380. };
  381. main_output main() {
  382. main_output o;
  383. o.t0 = 0;
  384. o.t0.x = ns_overloading::test();
  385. ns_std_conversions::fn_init_or_assign();
  386. ns_std_conversions::fn_vector_conversions();
  387. ns_std_conversions::fn_matrix_conversions();
  388. return o;
  389. }