Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Argument macro expansion in token-pasting operator #1005

Closed
antiagainst opened this issue Jan 16, 2018 · 4 comments
Closed

Argument macro expansion in token-pasting operator #1005

antiagainst opened this issue Jan 16, 2018 · 4 comments

Comments

@antiagainst
Copy link
Contributor

fxc and dxc have different behaviors when handling token-pasting operator (##). fxc does macro expansion on its arguments before concatenating, but dxc does not.

For the following HLSL source code:

#define SET_INDEX0                10
#define BINDING_INDEX0            5

#define SET(INDEX)                SET_INDEX##INDEX
#define BINDING(INDEX)            BINDING_INDEX##INDEX
#define SET_BIND(NAME,SET,BIND)   resource_set_##SET##_bind_##BIND##_##NAME
#define RESOURCE(NAME,INDEX)      SET_BIND(NAME, SET(INDEX), BINDING(INDEX))

#ifdef C_PROGRAM

const int resource_set_10_bind_5_val = 5;

int main() {
    return RESOURCE(val, 0);
}

#else

Texture2D<float4> resource_set_10_bind_5_tex;

float4 main() : SV_Target {
    return RESOURCE(tex, 0)[uint2(1, 2)];
}

#endif

fxc accepts it but dxc rejects it.

I think dxc is just following clang's handling of token-pasting operator. In C, token-pasting operator arguments are not macro-expanded first:

http://en.cppreference.com/w/cpp/preprocessor/replace
https://msdn.microsoft.com/en-us/library/09dwwt6y.aspx

(cl.exe /TC /DC_PROGRAM rejects the above program.)

Just wanted to raise this issue to see how we should proceed with this behavior mismatch. Do we want to mimic the fxc way in dxc?

@antiagainst
Copy link
Contributor Author

cc @ehsannas @chaoticbob

@tafuri
Copy link
Contributor

tafuri commented Jan 17, 2018

Interesting, I just recently run into this exact issue. But decided work around it since I could not find any documentation on how a HLSL preprocessor is expected to behave.

@MRozaNixxes
Copy link

I ran into this issue as well. We have a multiplatform engine that supports multiple languages. For constant buffers we have the following define:

#define CONSTANT_BUFFER(name, index) cbuffer name : register(b##index)

which is used as follows:

#define CB_INDEX 1

CONSTANT_BUFFER(Buffer, CB_INDEX)

This fails because it will not replace CB_INDEX with 1. I have the following workaround that works:

#define CONCAT(a, b) a##b
#define bCB(index) CONCAT(b, index)
#define CONSTANT_BUFFER(name, index) cbuffer name : register(bCB(index))

antiagainst added a commit that referenced this issue Feb 9, 2018
The fxc compiler evaluates both operands before performing the
token-pasting operation. But the default Clang way is to follow
C standard, which token-pastes operands as-is, without any
pre-expanding.

This commit adds support for the fxc behavior via the command
line option: -flegacy-macro-expansion.

Fixes #1005
@antiagainst
Copy link
Contributor Author

We now have the -flegacy-macro-expansion option to let dxc to follow fxc's macro expansion behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants