From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21435 invoked by alias); 28 Jan 2008 12:12:48 -0000 Received: (qmail 21416 invoked by uid 22791); 28 Jan 2008 12:12:47 -0000 X-Spam-Check-By: sourceware.org Received: from mercutio.sslaccess.com (HELO mercutio.sslaccess.com) (202.125.33.16) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 28 Jan 2008 12:12:15 +0000 Received: by mercutio.sslaccess.com (Postfix, from userid 1001) id 9D6033A40B8; Mon, 28 Jan 2008 22:07:39 +1000 (EST) Received: from mail3.sslaccess.com (mail3.sslaccess.com [202.125.33.7]) by mercutio.sslaccess.com (Postfix) with SMTP id E08823A41D0 for ; Mon, 28 Jan 2008 22:07:35 +1000 (EST) Received: (qmail 15295 invoked from network); 28 Jan 2008 12:12:07 -0000 Received: from unknown (HELO sid6170.sslaccess.com) (202.125.32.187) by titan.ozservers.com.au with SMTP; 28 Jan 2008 12:12:07 -0000 Received: (qmail 781 invoked from network); 28 Jan 2008 22:12:07 +1000 Received: from cust0701.vic01.dataco.com.au (HELO DEVELOPMENT) (202.63.38.189) by sid6170.sslaccess.com with SMTP; 28 Jan 2008 22:12:07 +1000 From: "Ron Kreymborg" To: "'Andrew Haley'" , "'Daniel Lohmann'" , "'Brian Dessent'" Cc: References: <000501c86069$07d63310$17829930$@com.au> <479DACC0.8000709@redhat.com> In-Reply-To: <479DACC0.8000709@redhat.com> Subject: RE: Mangle functions Date: Mon, 28 Jan 2008 19:25:00 -0000 Message-ID: <000c01c861a6$f57c5250$e074f6f0$@com.au> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Office Outlook 12.0 Content-Language: en-au Content-Disposition: X-PCToolsMIME: Updated by PC Tools Mime Parser 1.0.0.4 Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org X-SW-Source: 2008-01/txt/msg00288.txt.bz2 > Why not simply give the handlers C linkage? That's a much cleaner and > simpler > solution, and it's what everyone else does AFAIAA. That's the easy way and also the way I have done it in the past: ISR(TIMER0_OVF_vect) { Timer0.TimerOverflow(); } The ISR macro gives the vector "C" status so the linker can find the vectors, and the TimerOverflow method is public. But for just those reasons it is not the way it should work in C++. The interrupt handler should not be public. Nothing outside the driver class needs to or should know anything about interrupt handlers. The language should provide for entities like interrupt handlers. >> #define CLASS_ISR(theclassname, themethodname) \ >> ISR(theclassname) ISR_ALIASOF(gcc_mangle(theclassname, >> themethodname)); \ void theclassname::themethodname(void) > > As written this is impossible, since the mangling includes the number > and types of arguments. Interrupt routines never have parameters. > BTW: In your example you used a non-static method. You probably know > that you have to make sure that the this-pointer is passed accordingly > in this case. The interrupt class does not need a this pointer as it neither calls other methods in its class or accesses any private class data, so the interrupt method itself can correctly be non-static. Here is a barely useful example: //-------------------------------- class CTimer0Interrupt { public: CTimer0Interrupt(); ~CTimer0Interrupt(); private: void TIMER0_OVF_vect(void) __attribute__ ((signal, __INTR_ATTRS)); }; //-------------------------------- class CTimer0 { friend class CTimer0Interrupt; public: CTimer0(); ~CTimer0(); bool GetOverflowFlag(void); private: void SetOverflowFlag(void); private: volatile bool mOverflowFlag; CTimer0Interrupt mTimer0Interrupt; }; and the actual interrupt in the instance of CTimer0Interrupt using the macro above would be: //--------------------------------------------------- CLASS_ISR(CTimer0Interrupt, TIMER0_OVF_vect) { TCNT0 = TIMER0_TIMEOUT; // restart the timeout Timer0.SetOverflowFlag(); // tell our friend } Because it is a friend of the peripheral driver class, it can call methods in the driver class and thus cause consequences in that driver class. By itself it need only manage the various registers, etc concerned with configuring, managing, and releasing the interrupt hardware concerned, none of which require a this. > - a script that scans through a given set of source files for occurrences > of gcc_mangle, and runs the above showmangling.sh (or equivalent) with > the macro's args, and appends the results in the form of a #define to > the generated header. Yes, I am starting to think a pre- preprocessor is the only way. However, as I mentioned, in the version of gcc I am using (avr-gcc) interrupt functions are always mangled exactly the same way. The only unknowns are the number of characters in the class and interrupt vector names. The former could be done manually I suppose but the latter typically looks like __vector_1 or __vector_13, and different processors have different numbers of interrupting peripherals so the 9/10 boundary is not that easy. If I keep my macro: CLASS_ISR(theclassname, theinterruptname) { the preprocessor can look for this, look up the interrupt vector reference, compute the two lengths, and then build the correct statements for gcc as it re-writes the file. Something like: extern "C" void __vector_16(void) __attribute__((alias("_ZN16CTimer0Interrupt11__vector_16Ev"))); void CTimer0Interrupt::__vector_16(void) { Note that this declares the interrupt vector public and "C" for the linker, but not the class method - the latter is invisible within the C++ application. For versatility I could provide the mangle description as a command parameter, something like: -m _ZN%d%s%d%sEv Seems a lot of work for something the language should provide, and it depends on mangling always being done the same way, but I'll give it a go. I would be interested in any further comments. Ron Kreymborg E-mail message checked by Spyware Doctor (5.5.0.178) Database version: 5.09080 http://www.pctools.com/spyware-doctor/