callback - Added workaround for IAR issue with type information

In the IAR ide, implicitly generated structures based on function
templates end up with missing type information. This has no effect
on using the IAR compiler standalone, but when used through the ide
the missing type information causes the ide to error.

As a workaround, moved the function attributes generated for the
Callback and Event classes into the class scope. This avoids the
syntax that confuses IAR.
pull/2898/head
Christopher Haster 2016-10-03 18:33:25 -05:00
parent 79fbf94d9c
commit abba0c2173
2 changed files with 324 additions and 264 deletions

View File

@ -47,41 +47,17 @@ public:
*/
template <typename F>
Event(EventQueue *q, F f) {
struct local {
static int post(struct event *e) {
typedef EventQueue::context00<F> C;
struct local {
static void call(void *p) { (*static_cast<C*>(p))(); }
static void dtor(void *p) { static_cast<C*>(p)->~C(); }
};
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*reinterpret_cast<F*>(e+1));
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &local::dtor);
return equeue_post(e->equeue, &local::call, p);
}
static void dtor(struct event *e) {
reinterpret_cast<F*>(e+1)->~F();
}
};
_event = static_cast<struct event *>(
equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F)));
if (_event) {
_event->equeue = &q->_equeue;
_event->id = 0;
_event->delay = 0;
_event->period = -1;
_event->post = &local::post;
_event->dtor = &local::dtor;
_event->post = &Event::event_post<F>;
_event->dtor = &Event::event_dtor<F>;
new (_event+1) F(f);
@ -222,6 +198,38 @@ private:
// F follows
} *_event;
// Event attributes
template <typename F>
static int event_post(struct event *e) {
typedef EventQueue::context00<F> C;
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*(F*)(e + 1));
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &Event::function_dtor<C>);
return equeue_post(e->equeue, &Event::function_call<C>, p);
}
template <typename F>
static void event_dtor(struct event *e) {
((F*)(e + 1))->~F();
}
// Function attributes
template <typename F>
static void function_call(void *p) {
(*(F*)p)();
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
public:
/** Create an event
* @see Event::Event
@ -443,41 +451,17 @@ public:
*/
template <typename F>
Event(EventQueue *q, F f) {
struct local {
static int post(struct event *e, A0 a0) {
typedef EventQueue::context10<F, A0> C;
struct local {
static void call(void *p) { (*static_cast<C*>(p))(); }
static void dtor(void *p) { static_cast<C*>(p)->~C(); }
};
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*reinterpret_cast<F*>(e+1), a0);
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &local::dtor);
return equeue_post(e->equeue, &local::call, p);
}
static void dtor(struct event *e) {
reinterpret_cast<F*>(e+1)->~F();
}
};
_event = static_cast<struct event *>(
equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F)));
if (_event) {
_event->equeue = &q->_equeue;
_event->id = 0;
_event->delay = 0;
_event->period = -1;
_event->post = &local::post;
_event->dtor = &local::dtor;
_event->post = &Event::event_post<F>;
_event->dtor = &Event::event_dtor<F>;
new (_event+1) F(f);
@ -618,6 +602,38 @@ private:
// F follows
} *_event;
// Event attributes
template <typename F>
static int event_post(struct event *e, A0 a0) {
typedef EventQueue::context10<F, A0> C;
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*(F*)(e + 1), a0);
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &Event::function_dtor<C>);
return equeue_post(e->equeue, &Event::function_call<C>, p);
}
template <typename F>
static void event_dtor(struct event *e) {
((F*)(e + 1))->~F();
}
// Function attributes
template <typename F>
static void function_call(void *p) {
(*(F*)p)();
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
public:
/** Create an event
* @see Event::Event
@ -839,41 +855,17 @@ public:
*/
template <typename F>
Event(EventQueue *q, F f) {
struct local {
static int post(struct event *e, A0 a0, A1 a1) {
typedef EventQueue::context20<F, A0, A1> C;
struct local {
static void call(void *p) { (*static_cast<C*>(p))(); }
static void dtor(void *p) { static_cast<C*>(p)->~C(); }
};
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*reinterpret_cast<F*>(e+1), a0, a1);
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &local::dtor);
return equeue_post(e->equeue, &local::call, p);
}
static void dtor(struct event *e) {
reinterpret_cast<F*>(e+1)->~F();
}
};
_event = static_cast<struct event *>(
equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F)));
if (_event) {
_event->equeue = &q->_equeue;
_event->id = 0;
_event->delay = 0;
_event->period = -1;
_event->post = &local::post;
_event->dtor = &local::dtor;
_event->post = &Event::event_post<F>;
_event->dtor = &Event::event_dtor<F>;
new (_event+1) F(f);
@ -1014,6 +1006,38 @@ private:
// F follows
} *_event;
// Event attributes
template <typename F>
static int event_post(struct event *e, A0 a0, A1 a1) {
typedef EventQueue::context20<F, A0, A1> C;
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*(F*)(e + 1), a0, a1);
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &Event::function_dtor<C>);
return equeue_post(e->equeue, &Event::function_call<C>, p);
}
template <typename F>
static void event_dtor(struct event *e) {
((F*)(e + 1))->~F();
}
// Function attributes
template <typename F>
static void function_call(void *p) {
(*(F*)p)();
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
public:
/** Create an event
* @see Event::Event
@ -1235,41 +1259,17 @@ public:
*/
template <typename F>
Event(EventQueue *q, F f) {
struct local {
static int post(struct event *e, A0 a0, A1 a1, A2 a2) {
typedef EventQueue::context30<F, A0, A1, A2> C;
struct local {
static void call(void *p) { (*static_cast<C*>(p))(); }
static void dtor(void *p) { static_cast<C*>(p)->~C(); }
};
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*reinterpret_cast<F*>(e+1), a0, a1, a2);
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &local::dtor);
return equeue_post(e->equeue, &local::call, p);
}
static void dtor(struct event *e) {
reinterpret_cast<F*>(e+1)->~F();
}
};
_event = static_cast<struct event *>(
equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F)));
if (_event) {
_event->equeue = &q->_equeue;
_event->id = 0;
_event->delay = 0;
_event->period = -1;
_event->post = &local::post;
_event->dtor = &local::dtor;
_event->post = &Event::event_post<F>;
_event->dtor = &Event::event_dtor<F>;
new (_event+1) F(f);
@ -1410,6 +1410,38 @@ private:
// F follows
} *_event;
// Event attributes
template <typename F>
static int event_post(struct event *e, A0 a0, A1 a1, A2 a2) {
typedef EventQueue::context30<F, A0, A1, A2> C;
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*(F*)(e + 1), a0, a1, a2);
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &Event::function_dtor<C>);
return equeue_post(e->equeue, &Event::function_call<C>, p);
}
template <typename F>
static void event_dtor(struct event *e) {
((F*)(e + 1))->~F();
}
// Function attributes
template <typename F>
static void function_call(void *p) {
(*(F*)p)();
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
public:
/** Create an event
* @see Event::Event
@ -1631,41 +1663,17 @@ public:
*/
template <typename F>
Event(EventQueue *q, F f) {
struct local {
static int post(struct event *e, A0 a0, A1 a1, A2 a2, A3 a3) {
typedef EventQueue::context40<F, A0, A1, A2, A3> C;
struct local {
static void call(void *p) { (*static_cast<C*>(p))(); }
static void dtor(void *p) { static_cast<C*>(p)->~C(); }
};
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*reinterpret_cast<F*>(e+1), a0, a1, a2, a3);
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &local::dtor);
return equeue_post(e->equeue, &local::call, p);
}
static void dtor(struct event *e) {
reinterpret_cast<F*>(e+1)->~F();
}
};
_event = static_cast<struct event *>(
equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F)));
if (_event) {
_event->equeue = &q->_equeue;
_event->id = 0;
_event->delay = 0;
_event->period = -1;
_event->post = &local::post;
_event->dtor = &local::dtor;
_event->post = &Event::event_post<F>;
_event->dtor = &Event::event_dtor<F>;
new (_event+1) F(f);
@ -1806,6 +1814,38 @@ private:
// F follows
} *_event;
// Event attributes
template <typename F>
static int event_post(struct event *e, A0 a0, A1 a1, A2 a2, A3 a3) {
typedef EventQueue::context40<F, A0, A1, A2, A3> C;
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*(F*)(e + 1), a0, a1, a2, a3);
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &Event::function_dtor<C>);
return equeue_post(e->equeue, &Event::function_call<C>, p);
}
template <typename F>
static void event_dtor(struct event *e) {
((F*)(e + 1))->~F();
}
// Function attributes
template <typename F>
static void function_call(void *p) {
(*(F*)p)();
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
public:
/** Create an event
* @see Event::Event
@ -2027,41 +2067,17 @@ public:
*/
template <typename F>
Event(EventQueue *q, F f) {
struct local {
static int post(struct event *e, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
typedef EventQueue::context50<F, A0, A1, A2, A3, A4> C;
struct local {
static void call(void *p) { (*static_cast<C*>(p))(); }
static void dtor(void *p) { static_cast<C*>(p)->~C(); }
};
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*reinterpret_cast<F*>(e+1), a0, a1, a2, a3, a4);
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &local::dtor);
return equeue_post(e->equeue, &local::call, p);
}
static void dtor(struct event *e) {
reinterpret_cast<F*>(e+1)->~F();
}
};
_event = static_cast<struct event *>(
equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F)));
if (_event) {
_event->equeue = &q->_equeue;
_event->id = 0;
_event->delay = 0;
_event->period = -1;
_event->post = &local::post;
_event->dtor = &local::dtor;
_event->post = &Event::event_post<F>;
_event->dtor = &Event::event_dtor<F>;
new (_event+1) F(f);
@ -2202,6 +2218,38 @@ private:
// F follows
} *_event;
// Event attributes
template <typename F>
static int event_post(struct event *e, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
typedef EventQueue::context50<F, A0, A1, A2, A3, A4> C;
void *p = equeue_alloc(e->equeue, sizeof(C));
if (!p) {
return 0;
}
new (p) C(*(F*)(e + 1), a0, a1, a2, a3, a4);
equeue_event_delay(p, e->delay);
equeue_event_period(p, e->period);
equeue_event_dtor(p, &Event::function_dtor<C>);
return equeue_post(e->equeue, &Event::function_call<C>, p);
}
template <typename F>
static void event_dtor(struct event *e) {
((F*)(e + 1))->~F();
}
// Function attributes
template <typename F>
static void function_call(void *p) {
(*(F*)p)();
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
public:
/** Create an event
* @see Event::Event

View File

@ -707,24 +707,10 @@ private:
// Generate operations for function object
template <typename F>
void generate(const F &f) {
struct local {
static R call(const void *p) {
return (*(F*)p)();
}
static void move(void *d, const void *p) {
new (d) F(*(F*)p);
}
static void dtor(void *p) {
((F*)p)->~F();
}
};
static const ops ops = {
&local::call,
&local::move,
&local::dtor,
&Callback::function_call<F>,
&Callback::function_move<F>,
&Callback::function_dtor<F>,
};
MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
@ -732,6 +718,22 @@ private:
_ops = &ops;
}
// Function attributes
template <typename F>
static R function_call(const void *p) {
return (*(F*)p)();
}
template <typename F>
static void function_move(void *d, const void *p) {
new (d) F(*(F*)p);
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
// Wrappers for functions with context
template <typename O, typename M>
struct method_context {
@ -1411,24 +1413,10 @@ private:
// Generate operations for function object
template <typename F>
void generate(const F &f) {
struct local {
static R call(const void *p, A0 a0) {
return (*(F*)p)(a0);
}
static void move(void *d, const void *p) {
new (d) F(*(F*)p);
}
static void dtor(void *p) {
((F*)p)->~F();
}
};
static const ops ops = {
&local::call,
&local::move,
&local::dtor,
&Callback::function_call<F>,
&Callback::function_move<F>,
&Callback::function_dtor<F>,
};
MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
@ -1436,6 +1424,22 @@ private:
_ops = &ops;
}
// Function attributes
template <typename F>
static R function_call(const void *p, A0 a0) {
return (*(F*)p)(a0);
}
template <typename F>
static void function_move(void *d, const void *p) {
new (d) F(*(F*)p);
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
// Wrappers for functions with context
template <typename O, typename M>
struct method_context {
@ -2115,24 +2119,10 @@ private:
// Generate operations for function object
template <typename F>
void generate(const F &f) {
struct local {
static R call(const void *p, A0 a0, A1 a1) {
return (*(F*)p)(a0, a1);
}
static void move(void *d, const void *p) {
new (d) F(*(F*)p);
}
static void dtor(void *p) {
((F*)p)->~F();
}
};
static const ops ops = {
&local::call,
&local::move,
&local::dtor,
&Callback::function_call<F>,
&Callback::function_move<F>,
&Callback::function_dtor<F>,
};
MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
@ -2140,6 +2130,22 @@ private:
_ops = &ops;
}
// Function attributes
template <typename F>
static R function_call(const void *p, A0 a0, A1 a1) {
return (*(F*)p)(a0, a1);
}
template <typename F>
static void function_move(void *d, const void *p) {
new (d) F(*(F*)p);
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
// Wrappers for functions with context
template <typename O, typename M>
struct method_context {
@ -2819,24 +2825,10 @@ private:
// Generate operations for function object
template <typename F>
void generate(const F &f) {
struct local {
static R call(const void *p, A0 a0, A1 a1, A2 a2) {
return (*(F*)p)(a0, a1, a2);
}
static void move(void *d, const void *p) {
new (d) F(*(F*)p);
}
static void dtor(void *p) {
((F*)p)->~F();
}
};
static const ops ops = {
&local::call,
&local::move,
&local::dtor,
&Callback::function_call<F>,
&Callback::function_move<F>,
&Callback::function_dtor<F>,
};
MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
@ -2844,6 +2836,22 @@ private:
_ops = &ops;
}
// Function attributes
template <typename F>
static R function_call(const void *p, A0 a0, A1 a1, A2 a2) {
return (*(F*)p)(a0, a1, a2);
}
template <typename F>
static void function_move(void *d, const void *p) {
new (d) F(*(F*)p);
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
// Wrappers for functions with context
template <typename O, typename M>
struct method_context {
@ -3523,24 +3531,10 @@ private:
// Generate operations for function object
template <typename F>
void generate(const F &f) {
struct local {
static R call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3) {
return (*(F*)p)(a0, a1, a2, a3);
}
static void move(void *d, const void *p) {
new (d) F(*(F*)p);
}
static void dtor(void *p) {
((F*)p)->~F();
}
};
static const ops ops = {
&local::call,
&local::move,
&local::dtor,
&Callback::function_call<F>,
&Callback::function_move<F>,
&Callback::function_dtor<F>,
};
MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
@ -3548,6 +3542,22 @@ private:
_ops = &ops;
}
// Function attributes
template <typename F>
static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3) {
return (*(F*)p)(a0, a1, a2, a3);
}
template <typename F>
static void function_move(void *d, const void *p) {
new (d) F(*(F*)p);
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
// Wrappers for functions with context
template <typename O, typename M>
struct method_context {
@ -4227,24 +4237,10 @@ private:
// Generate operations for function object
template <typename F>
void generate(const F &f) {
struct local {
static R call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
return (*(F*)p)(a0, a1, a2, a3, a4);
}
static void move(void *d, const void *p) {
new (d) F(*(F*)p);
}
static void dtor(void *p) {
((F*)p)->~F();
}
};
static const ops ops = {
&local::call,
&local::move,
&local::dtor,
&Callback::function_call<F>,
&Callback::function_move<F>,
&Callback::function_dtor<F>,
};
MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
@ -4252,6 +4248,22 @@ private:
_ops = &ops;
}
// Function attributes
template <typename F>
static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
return (*(F*)p)(a0, a1, a2, a3, a4);
}
template <typename F>
static void function_move(void *d, const void *p) {
new (d) F(*(F*)p);
}
template <typename F>
static void function_dtor(void *p) {
((F*)p)->~F();
}
// Wrappers for functions with context
template <typename O, typename M>
struct method_context {