C++ Antlr Code stopped working (antlrcpp::Any) - c++

I developed some ANTLR + LLVM parser code in spring. Since it is only a recreational project, I did not touch the code or see whether it compiles in the meantime. During that time, several system updates took place, which I assume caused my current problems:
When trying to compile the code today (with clang++), I suddenly got several error messages. Initially the std::any class was not found at all. I then played with "std=c++17" and "std=c++20" options. Now the main error (as I understand it) seems to be
error: no member named 'as' in 'std::any'
The error occurs whenever i do something like for instance
args.push_back(visit(*it).as<sarg>());
or, more stripped-down:
antlrcpp::Any myvar;
//...
myvar.as<some_type>();
I picked this up from Antlr tutorial codes where this seems to be the standard idiom to cast an antlrcpp::Any object to the type desired by the calling function.
I noticed that antlrcpp::Any apparently is merely a wrapper for std::any, which apparently really does not support this "as" method.
What can i do to make my code work again?

Related

DLL fails to load if unused ref class is removed

I'm running into a very strange problem trying to compile and use a windows runtime component within an UWP application (VS2017 community 15.9.13 with NetCore.UniversalWindowsPlatform 6.2.8, compiled without /clr but with /ZW).
It is basically something like the Grayscaletransform. The runtime component is actually working as expected, now I wanted to remove some unused code. However, as soon as I remove it from a particular file and recompile, it indeed compiles, links, but the DLL does not load any more.
Here's some example code that I have to put in:
ref class DummyU sealed
{
public:
DummyU() {}
};
DummyU^ CreateDummyU()
{
return ref new DummyU();
}
The code just makes it work, although it is a) not referenced at all and b) does not do anything useful.
The result of removing it:
Exception thrown at 0x0EFF322F (vccorlib140d_app.dll) in TestAppUWP.exe: 0xC0000005: Access violation reading location 0x00000000.
in
STDAPI DllGetActivationFactory(_In_ HSTRING activatibleClassId, _Deref_out_ IActivationFactory** ppFactory)
{
return Platform::Details::GetActivationFactory(Microsoft::WRL::Details::ModuleBase::module_, activatibleClassId, ppFactory);
}
function in dllexports.cpp which is part of VS. The module_ becomes NULL.
Does anyone have an idea if there are any known bugs with respect to the windows runtime not being initialized/used properly if there is no explicit instantiation of a ref class in a file?
EDIT 1:
Here's the link to the full source code:
What's happening here is that you're mixing modes a bit. Since you've compiled your C++ code with the /CX flag, you've told the compiler to enable winrt extensions to produce a WinRT DLL. In practice though, none of your code is actually using the CX extensions to implement classes. You're using WRL and standards C++. The compiler looks at the DLL, finds no CX-style WinRT classes, and doesn't set up the module, accordingly.
This is basically an untested & unsupported case, since you've chosen to say that you want to expose ref classes by picking a UWP component library project type, but then didn't actually provide any ref classes. It happens that under the hood, /CX effectively uses WRL, so you can nudge it along and initialize the state to work correctly, but you're kinda hacking the implementation details of the system.
There are two options I would recommend, either works: just make the project a non-CX Win32 DLL and init the module as described above. Or, better yet, flip over to C++ /WinRT, which will give you better support for the WinRT types than /CX and allow you to more easily mix in the classic COM types in your implementation. You can get started by just turning off the /CX flag in the compiler switches, then start updating the code accordingly.
Ben
You might have wrong .winmd file for your component. WinRT components made in C++ produce two outputs, dll and winmd. Both must match. It's possible you have them from different builds.
Another possible reason is error in manifest. The manifest of the app must include all referenced runtime components.
BTW, for native DLLs written in classic C++ and exposing C API, deployment is simpler, you include a DLL in the package and they just work, with [DllImport] if you're consuming them from C#.
Update: You can replace that ref class with the following code, works on my PC.
struct ModuleStaticInitialize
{
ModuleStaticInitialize()
{
Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();
}
};
static ModuleStaticInitialize s_moduleInit;
Probably a bug in Microsoft's runtime somewhere.

Code::blocks complaining about type of parameter

I am building a 3D Game Engine. I have build many in other languages, but finally decided to reap the speed benefits of C++ (despite not knowing it particularly well).
I have a class called EngineOptions that I use to store information about how the engine is to be initialized. The engine's main class, Monolith, then takes a const reference to the options instance like so:
monolith::EngineOptions options();
monolith::Monolith engine(options);
Monolith has a correct header file and a constructor like this:
Monolith::Monolith(const EngineOptions& options) : m_options(options)
{
m_window(m_options.windowWidth, m_options.windowHeight, m_options.windowTitle);
}
While I think this is correct, the compiler is complaining that there is:
no matching function for call to 'monolith::Monolith::Monolith(monolith::EngineOptions (&)())'
Excuse me if I'm being stupid, but I think this code is correct, am I wrong?
I am using the Code::Blocks IDE with the standard GCC toolchain provided on my system.
Remove the parentheses from this line:
monolith::EngineOptions options();
The compiler thinks you're declaring a function returning an EngineOptions instance.

Boost threads: in IOS, thread_info object is being destructed before the thread finishes executing

Our project uses a few boost 1.48 libraries on several platforms, including Windows, Mac, Android, and IOS.
We are able to consistently get the IOS version of the project to crash (nontrivially but reliably) when using IOS, and
from our investigation we see that ~thread_data_base is being called on the thread's thread_info while its thread is still running.
This seems to happen as a result of the smart pointer reaching a zero count, even though it is obviously still
in scope in the thread_proxy function which creates it and runs the requested function in the thread.
This seems to happen in various cases - the call stack is not identical between crashes, though there are a few
variations which are common.
Just to be clear - this often requires running code which is creating hundreds of threads, though there are
never more than about 30 running simultaneously. I have "been lucky" and got it very very early in the
run also, but that's rare.
I created a version of the destructor which actually catches the code red-handed:
in libs/thread/src/pthread/thread.cpp:
thread_data_base::~thread_data_base()
{
boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
void *void_thread_info = (void *) thread_info;
void *void_this = (void *) this;
// is somebody destructing the thread_data other than its own thread?
// (remember that its own which should no longer point to it anyway,
// because of the call to detail::set_current_thread_data(0) in thread_proxy)
if (void_thread_info) { // == void_this) {
__builtin_trap();
}
}
I should note that (as seen from the commented-out code) I had previously checked to see that void_thread_info == void_this because I
was only checking for the case where the thread's current thread_info was killing itself.
I have also seen cases where the value returned by get_current_thread_data is non-zero and
different from "this", which is really weird.
Also when I first wrote that version of the code, I wrote:
if (((void*)thread_info) == ((void*)this))
and at run-time I got some very weird exception that said I something about a virtual function table
or something like that - I don't remember. I decided that it was trying to call "==" for this object type
and was unhappy with that, so I rewrote as above, putting the conversions to void * as separate
lines of code. That in itself is quite suspicious to me. I am not one to run to rush to blame compilers, but...
I should also note that when we did catch this happening the trap, we saw the destructor for
~shared_count appear twice consecutively on the stack in Xcode source. Very doubleweird.
We tried to look at the disassembly, but couldn't make much out of it.
Again - it looks like this is always a result of the shared_count which seems to be owned by
the shared_ptr which owns the thread_info reaching zero too early.
Update: it seems that it is possible to get into situations which reach the above trap without the situation doing any harm. Since fixing the issue (see answer) I have seen it happen, but always after thread_info->run() has finished executing. Don't yet understand how...but it's working.
Some additional info:
I should note that the boost.sh from Pete Goodliffe (and modified by others) that is commonly used to compile boost for IOS
has the following note in the header:
: ${EXTRA_CPPFLAGS:="-DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS"}
# The EXTRA_CPPFLAGS definition works around a thread race issue in
# shared_ptr. I encountered this historically and have not verified that
# the fix is no longer required. Without using the posix thread primitives
# an invalid compare-and-swap ARM instruction (non-thread-safe) was used for the
# shared_ptr use count causing nasty and subtle bugs.
#
# Should perhaps also consider/use instead: -BOOST_SP_USE_PTHREADS
I use those flags, but to no avail.
I found the following which is very tantalizing - it looks like they had the same issue in std::thread:
http://llvm.org/bugs/show_bug.cgi?format=multiple&id=12730
That was suggestive of using an alternate implementation inside boost for arm processors which seems also to directly address this issue:
spinlock_gcc_arm.hpp
The version included with boost 1.48 uses outdated arm assembly.
I took the updated version from boost 1.52, but I'm having trouble compiling it.
I get the following error:
predicated instructions must be in IT block
I found a reference to what looks to be a similar use of this instruction here:
https://zeromq.jira.com/browse/LIBZMQ-414
I was able to use the same idea to get the 1.52 code to compile by modifying
the code as follows (I inserted an appropriate IT instruction)
__asm__ __volatile__(
"ldrex %0, [%2]; \n"
"cmp %0, %1; \n"
"it ne; \n"
"strexne %0, %1, [%2]; \n"
BOOST_SP_ARM_BARRIER :
"=&r"( r ): // outputs
"r"( 1 ), "r"( &v_ ): // inputs
"memory", "cc" );
But in any case, there are ifdefs in this file which look for the arm architecture, which is not defined that way in my environment. After I simply edited the file so that only ARM 7 code
was left, the compiler complains about the definition of BOOST_SP_ARM_BARRIER:
In file included from ./boost/smart_ptr/detail/spinlock.hpp:35:
./boost/smart_ptr/detail/spinlock_gcc_arm.hpp:39:13: error: instruction requires a CPU feature not currently enabled
BOOST_SP_ARM_BARRIER :
^
./boost/smart_ptr/detail/spinlock_gcc_arm.hpp:13:32: note: expanded from macro 'BOOST_SP_ARM_BARRIER'
# define BOOST_SP_ARM_BARRIER "dmb"
Any ideas??
Figured this out. It turns out that the boost.sh script that I mention in the question chose the incorrect boost flag to address this problem - instead of BOOST_SP_USE_PTHREADS (and the other flag there with it, BOOST_AC_USE_PTHREADS) it turns out that what is needed on IOS is BOOST_SP_USE_SPINLOCK. This ends up giving pretty much the identical solution used in the std::thread issue referred to in the question.
If you are compiling for any modern IOS device which uses ARM 7, but using an older boost (we are using 1.48), you need to copy the file spinlock_gcc_arm.hpp from a more recent boost (like 1.52). That file is #ifdef'd for the different arm architectures, but it is not clear to me that the defines it is looking for are defined in the IOS compile environment using the script. So you can either edit the file (violent but effective) or invest some time to figure out how to make this tidy and correct.
In any case, you may need to insert the extra assembly instruction that I did above in the question:
"it ne; \n"
I have not yet gone back to see if I can delete that now that I have my compile environment working problem.
However, we're not done yet. The code used in boost for this option includes, as discussed, ARM assembly language instructions. The ARM chips support two instruction sets which can't be mixed in a given module (not sure of the scope, but evidently file by file is an acceptable granularity when compiling). The instructions used in boost for this locking include non-Thumb instructions, but IOS by default uses the Thumb instruction set. The boost code, aware of the instruction set issue, checks to see that you have arm enabled but not thumb, but by default in IOS, thumb is on.
Getting the compiler to generate non-thumb ARM code depends on which compiler you are using in IOS - Apple's LLVM or LLVM GCC. GCC is deprecated, and Apple's LLVM is the default when you use XCode.
For the default Clang + Apple LLVM 4.1, you need to compile using the -mno-thumb flag. Also any files in your IOS app which use any part of boost which uses smart pointers will also have to be compiled using -mno-thumb.
To compile boost like this, I think you can just add -mno-thumb to the EXTRA_CPP_FLAGS in the script. (I modified the user-config.jam directly while experimenting and haven't yet gone back to clean up.)
For your app, in Xcode you need to select your target, then go into the Build Phases tab, and there select Compile sources. There you have the option of adding compile flags, so for each relevant file (which includes boost), add the -mno-thumb flag. You can do this directly in project.pbxproj also where each file has
settings = { COMPILER_FLAGS = ""; };
you just change this to
settings = { COMPILER_FLAGS = "-mno-thumb"; };
But there's a little more. You also have to modify the darwin.jam file in the tools/build/v2/tools directory. In boost 1.48, there is a code that says:
case arm :
{
options = -arch armv6;
}
This has to be modified to
case arm :
{
options = -arch armv7 ;
}
Finally, in the boost.sh script, in the function writeBjamUserConfig(), you should remove the references to -arch armv6.
If somebody knows how to do this a little more generally and cleanly, I'm sure we'd all benefit. For now, this is where I've gotten to, and I hope that this will help other IOS boost threads users. I hope that the various variants on the boost.sh IOS script out there will be updated. I plan to add some more links to this answer later.
Update: For a great article which describes the issue on the processor level,
see here:
http://preshing.com/20121019/this-is-why-they-call-it-a-weakly-ordered-cpu
Enjoy!
I use boost.asio, boost.thread, boost.smart_ptr etc. on iOS platform, the app always crash when run in release mode, which throws signal sigabrt. The crash call stack is :
__stack_chk_fail
boost::asio::detail::completion_handle
boost::asio::detail::task_ios_service_operation::complete
boost::asio::detail::task_io_service::do_run_one
boost::asio::detail::task_ios_service::run
boost::asio::io_service::run
![when create a asio work with creating new thread and io_service][1]
When trying to solve the problem, I found the following articles:
[boost-thread-threads-not-starting-on-the-iphone-ipad-in-release-build][2]
[The issue of spin_lock and thumb on iOS][3]
Then I try to add -mno-thumb to my project compile flag, and the problem occured in release mode is gone.
However, a new bug bring out : EXC_ARM_DA_ALIGN, which crashed at where I try to convert network data to host-endian.
As[this article][4] says, the ARM instructions strict that the memory data must be aligned.
And follow the article [Exc_arm_da_align][5], I fix it by using memcpy for the data convert, instead of directly converting from the pointer.
[1]: http://i.stack.imgur.com/3ijF4.png
[2]: http://stackoverflow.com/questions/4201262/boost-thread-threads-not-starting-on-the-iphone-ipad-in-release-builds/4245821#4245821
[3]: http://groups.google.com/group/boost-list/browse_thread/thread/7dc1e80659182ab3
[4]: https://brewx.qualcomm.com/bws/content/gi/common/appseng/en/knowledgebase/docs/kb95.html
[5]: http://www.cnblogs.com/unionfind/archive/2013/02/25/2932262.html

Problem using accessors in V8

I'm writing a wrapper class around the V8 engine so that eventually I'll be able to do something like this
script->createClass("Test");
script->getClass("Test")->addFunction("funct1",testfunct1);
script->getClass("Test")->addVariable("x",setter,getter);
So far I can create classes and add functions to them and it works perfectly, however I have encountered a problem with adding variables.
My class template is stored as such
Persistent<Object> classInstance;
and I try to add an Accessor like this:
this->classInstance->SetAccessor(String::New(variableName),setter,getter);
Compiling this code gives me the error that v8::Object doesn't have a SetAccessor function (though I've seen doxygen documentation that says otherwise).
So my question is: How can I fix this? Is it possible to cast an Object to an ObjectTemplate?
SetAccessor on Object is available as of V8 2.2.12, which was released May 2010. (Before that, it was indeed only available on ObjectTemplate.) You should probably update your copy of V8.

VS2008 internal compiler error

I'm consistently running into an internal compiler error while attempting to switch from MSVC6 to MSVC 2008. After much work commenting out different parts of the program, I've traced the error to two lines of code in two different CPP files. Both of these CPP files compile successfully, yet somehow have an effect on whether or not the error manifests in other files.
Both of those lines involve instantianting several complex, nested templates. They also appear to be the only places in the app that use an abstract class as one of the template parameters. That said, I'm far from certain that the issue involves either abstract classes or templates, it's just the most obvious thing I've noticed. I can't even be sure that these lines are significant at all. Here's what they look like, though:
m_phDSAttributes = new SObjDict<RWCString, SIDataSource>(&RWCString::hash);
So we've got SObjDict, a templatized dictionary class, SIDataSource, an abstract interface, and the parameter is a pointer to a static member function of RWCString.
I've been playing around with the code some, and I can occasionally get the error to move from one CPP file to another (for instance, I changed a bunch of template declarations from using class to typename), but I can't find any rhyme or reason to it.
I'm at a loss as to how to debug this issue further. The exact error output by the compiler (with the name of my source file changed) is below. There is no mention of it anywhere on the internet. I'm pretty desperate for any advice on how to proceed. I don't expect someone to say "oh, you just need to do XYZ", but a pointer on how to debug this sort of issue would be greatly appreciated.
1>d:\Dev\webapi.cpp : fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c', line 5905)
The trick seems to be disabling precompiled headers. I have no idea why that solves the problem, and it's very unfortunate since my build time for the affected project has gone from less than 30 secs to nearly 5 minutes, but at least I can progress forward.
It's a reasonable bet to assume that p2symtab.c is (part of) the symbol table code. This would immediately explain how the upgrade caused it; this code has been rewritten. (Remember the 255 character length warnings of VC6?)
In this case, there is no new entry in the symbol table, so it's likely a lookup in the symbol table failing spectactularly. It would be interesting to see if the context in which th name lookup happens affects the result. For instance, what happens if you change the code to
typedef SObjDict<RWCString, SIDataSource> SObjDict_RWCString_SIDataSource;
m_phDSAttributes = new SObjDict_RWCString_SIDataSource(&RWCString::hash);
This will force another symbol table entry to be created, for SObjDict_RWCString_SIDataSource. This entry is sort of a symbolic link to the template instantiation. The new name can (and must) be looked up on its own.
Start breaking it down into smaller parts. My first guess is the pointer to the static function is going to be the problem. Can you make a dummy non-template class with the same parameter in the constructor? Does it compile if you don't use an abstract class in the template?
Looks like I'm sending you in the wrong direction, the following compiles fine in 2008:
class thing {
public:
static void hash( short sht ) {
}
void hash( long lng ) {
}
};
class thing2 {
public:
thing2( void (short ) ){}
};
int _tmain(int argc, _TCHAR* argv[])
{
thing2* t = new thing2( &thing::hash );
delete t;
return 0;
}
The principle remains though, remove/replace complex elements until you have code that compiles and you'll know what is causing the problem.
fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c
i also observed the same error when i try to build my vs 2005 code to vs 2008. but it happen till i have not installed Service pack of VS 2008...
have you installed Service pack... i think this will resolved your issue....
This typically happens with template instantiation. Unfortunately it could be caused by many things, but 99% of the time your code is subtly invoking undefined behavior.