1f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Copyright 2016 The Chromium Authors. All rights reserved.
2f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// found in the LICENSE file.
4f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Identifiers in macros should never be rewritten, as the risk of things
6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// breaking is extremely high.
7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define DEFINE_TYPE_CASTS(thisType, argumentType, argumentName, predicate) \
9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  inline thisType* to##thisType(argumentType* argumentName) {              \
10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (!predicate)                                                        \
11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      asm("int 3");                                                        \
12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return static_cast<thisType*>(argumentName);                           \
13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }                                                                        \
14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  inline long long ToInt(argumentType* argumentName) {                     \
15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return reinterpret_cast<long long>(argumentName);                      \
16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define LIKELY(x) x
19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace blink {
21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct Base {};
23f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct Derived : public Base {};
24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochDEFINE_TYPE_CASTS(Derived, Base, object, true);
26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid F() {
28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Base* base_ptr = new Derived;
29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 'toDerived' should not be renamed, since the definition lives inside
30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // a macro invocation.
31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Derived* derived_ptr = toDerived(base_ptr);
32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  long long as_int = ToInt(base_ptr);
33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 'derivedPtr' should be renamed: it's a reference to a declaration defined
34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // outside a macro invocation.
35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (LIKELY(derived_ptr)) {
36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    delete derived_ptr;
37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define CALL_METHOD_FROM_MACRO()           \
41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void CallMethodFromMacro() { Method(); } \
42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void Pmethod() override {}
43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct WithMacroP {
45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual void Pmethod() {}
46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct WithMacro : public WithMacroP {
49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void Method() {}
50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CALL_METHOD_FROM_MACRO();
51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace blink
54