Whole Tomato Software Forums
Whole Tomato Software Forums
Main Site | Profile | Register | Active Topics | Members | Search | FAQ
User name:
Password:
Save Password
Forgot your password?

 All Forums
 Visual Assist
 Technical Support
 Macro-created functions not being recognized
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

keithoconor
New Member

6 Posts

Posted - Mar 05 2015 :  10:50:01 AM  Show Profile  Reply with Quote
Hi,

I'm creating function names through macros in C++, but they're not being recognized by VA. Here's a simplified repro:
#define SECOND_INDIRECT_DECLARE_FOO(Name) void Foo##Name(){}       
#define INDIRECT_DECLARE_FOO(Name) SECOND_INDIRECT_DECLARE_FOO(Name)
#define DECLARE_FOO() INDIRECT_DECLARE_FOO(Bar)

DECLARE_FOO()


The function FooBar() is still unknown to VA's autocomplete or syntax highlighting.

I've tried enabling deep macro evaluation (as described in http://docs.wholetomato.com/?W363), but it doesn't make any difference. Not constructing the function name with a macro argument (ie changing the first line to declare void FooBar(){}) works, so it's evaluating the macro alright, but just not recognizing the name created with the ## concatenation.

Interestingly, it works if I reverse the order of the defines. It also works if I remove one level of indirection. However neither of these are an option in the real-world case I'm dealing with.

I'm on Visual Studio 2012, VAX version 10.7.1940.0 which I understand is quite an old build. Is there any reason to believe this would be fixed in a newer one?

feline
Whole Tomato Software

United Kingdom
18749 Posts

Posted - Mar 05 2015 :  12:48:10 PM  Show Profile  Reply with Quote
Your example works correctly for me in VA 2059, without needing to turn on deep macro parsing. So it might well be worth trying VA 2059, it will run in trial mode when you install it, giving you plenty of time to see if this works well for you:

http://www.wholetomato.com/downloads/default.asp

alternatively, since simpler macros help, adding the simpler macros to a "va_stdafx.h" file, as described here:

http://docs.wholetomato.com/default.asp?W302

should help. This file is used to help our parser, but it is not part of your solution, so you are free to add helper / simplified macro definitions here, to help VA correctly handle things, without having to check that they compile, and without effecting any of your code.

zen is the art of being at one with the two'ness
Go to Top of Page

keithoconor
New Member

6 Posts

Posted - Mar 05 2015 :  2:58:05 PM  Show Profile  Reply with Quote
Thanks - I updated to the latest version my license covers (1949), and the above example started working. However the real-world case I have still doesn't, and I've identified another problem. Take this example:

#define TEST_FOO() TEST_INDIRECT(Foo)

#define TEST_INDIRECT(X) void Test##X##First(){}
    TEST_FOO()
#undef TEST_INDIRECT

#define TEST_INDIRECT(X) void Test##X##Second(){}
    TEST_FOO()
#undef TEST_INDIRECT


VA recognizes TestFooFirst(), but not TestFooSecond(). We rely heavily on this pattern for code generation.
Go to Top of Page

keithoconor
New Member

6 Posts

Posted - Mar 06 2015 :  09:42:27 AM  Show Profile  Reply with Quote
I've tried the latest version of VA but it behaves the same - if you have more than one definition of TEST_FOO(), it only picks up on the first one. Even if I try defining TEST_INDIRECT() in va_stdafx.h it doesn't help, because it only works with the first definition of TEST_FOO().

Unless you have any suggestions, I'm about ready to give up.
Go to Top of Page

sean
Whole Tomato Software

USA
2817 Posts

Posted - Mar 06 2015 :  1:01:08 PM  Show Profile  Reply with Quote
Thanks for the clear explanation. I'm sorry to report that as you've found, VA will not work in that scenario.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18749 Posts

Posted - Mar 06 2015 :  1:25:19 PM  Show Profile  Reply with Quote
Unfortunately we are not expecting, not really prepared to handle a macro who's definition keeps on changing. This is easy if you get to run a pre-processor first, since all of this gets expanded.

Do you have a lot of these macros, and a lot of different macros like this? Or is this only a small block of code? I am trying to figure out some form of solution, but so far all of my ideas require some form of change to your code, which is obviously not what we are looking for.

zen is the art of being at one with the two'ness
Go to Top of Page

keithoconor
New Member

6 Posts

Posted - Mar 06 2015 :  1:27:52 PM  Show Profile  Reply with Quote
It's just one specific class of macros (used to generate code for both shaders and C++) - I'll put together a simple example that is closer representation of the real usage.
Go to Top of Page

keithoconor
New Member

6 Posts

Posted - Mar 06 2015 :  2:11:53 PM  Show Profile  Reply with Quote
I can't upload files, so below is as simple a representative example as I can make. On my machine, the shader2 functions in main() get correct colouring, but they still have red underlines, and autocomplete doesn't work on any of them.

I'm ok with having to change code (up to a point) if it means I can get autocomplete working.


//main.cpp
//--------

struct Shader1
{
    #include "shader1.h"
};

struct Shader2
{
    #include "shader2.h"
};

int main(int argc, void* argv[])
{
    Shader1 shader1;
    shader1.SetShader1Float(1.f);
    shader1.SetShader1Int(1111);

    Shader2 shader2;
    shader2.SetShader2Float(2.f);
    shader2.SetShader2Int(2222);
    
    return 0;
}


//shader1.h
//---------

#pragma once

#define DECLARE_SHADER_CONSTANTS()  \    DECLARE_SHADERCONSTANT_FLOAT( Shader1Float ) \    DECLARE_SHADERCONSTANT_INT( Shader1Int ) \
#include "constantblockdefinition.h"


//shader2.h
//---------

#pragma once

#define DECLARE_SHADER_CONSTANTS()  \    DECLARE_SHADERCONSTANT_FLOAT( Shader2Float ) \    DECLARE_SHADERCONSTANT_INT( Shader2Int ) \
#include "constantblockdefinition.h"


//constantblockdefinition.h
//-------------------------

#define DECLARE_SHADERCONSTANT_FLOAT(Name)  DECLARE_SHADERCONSTANT(float, Name)
#define DECLARE_SHADERCONSTANT_INT(Name)    DECLARE_SHADERCONSTANT(int, Name)

#define DEFINE_CONSTANT_ACCESSORS(Type, Name)       \    inline void Set##Name(const Type& newValue){}   \    inline void Get##Name() const{}

#define DECLARE_SHADERCONSTANT(Type, Name) DEFINE_CONSTANT_ACCESSORS(Type, Name)
DECLARE_SHADER_CONSTANTS()

#undef DECLARE_SHADERCONSTANT
#undef DECLARE_SHADER_CONSTANTS
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18749 Posts

Posted - Mar 06 2015 :  5:07:28 PM  Show Profile  Reply with Quote
Based on your sample code I have worked out a solution, but it does require changing the code, but only the header files need changing, how you use this remains the same.

For both "shader1.h" and "shader2.h" I went FROM:

#define DECLARE_SHADER_CONSTANTS()  \    DECLARE_SHADERCONSTANT_FLOAT( Shader1Float ) \    DECLARE_SHADERCONSTANT_INT( Shader1Int ) \
#include "constantblockdefinition.h"


TO:

#include "constantblockdefinition.h"

DECLARE_SHADERCONSTANT_FLOAT( Shader1Float )
DECLARE_SHADERCONSTANT_INT( Shader1Int )


so I simply used the macros directly.

Then in "constantblockdefinition.h" I simply commented out the three lines:

DECLARE_SHADER_CONSTANTS()

#undef DECLARE_SHADERCONSTANT
#undef DECLARE_SHADER_CONSTANTS


There is no need to call "DECLARE_SHADER_CONSTANTS()" in "constantblockdefinition.h" since the macros are called in the shader files. Plus there is no need to actually undef anything, since these macros actually always have the same definition. All that changes is their parameters.

This code still compiles, and I am now getting suggestions and colouring in the main cpp file. Do you think you could make similar changes in your code base? If so, I would be interested to know if this works for you.

zen is the art of being at one with the two'ness
Go to Top of Page

keithoconor
New Member

6 Posts

Posted - Mar 07 2015 :  10:56:52 AM  Show Profile  Reply with Quote
Unfortunately it doesn't. As I said, that's a simplified example - I wouldn't be using the extra indirection of DECLARE_SHADER_CONSTANTS() if I didn't need to, otherwise I wouldn't have this problem in the first place! DECLARE_SHADER_CONSTANTS() is called multiple times in constantblockdefinition.h, each time with DECLARE_SHADERCONSTANT() defined as something different.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18749 Posts

Posted - Mar 08 2015 :  12:11:55 AM  Show Profile  Reply with Quote
I appreciate and understand that you cannot share the actual code, this is a common situation. Working with sample code normally works, but it depends on how well the sample demonstrates the problem.

How many times do you declare and undeclare DECLARE_SHADER_CONSTANTS() ? Is turning this into separate macros an option?

I am trying to find a way around redefining the macros, since this is what is causing the problems.

zen is the art of being at one with the two'ness
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
© 2023 Whole Tomato Software, LLC Go To Top Of Page
Snitz Forums 2000