Browse Source

Merge branch 'master' into cmake

Sam Edwards 8 years ago
parent
commit
ed4725afa2
98 changed files with 2499 additions and 2240 deletions
  1. 7 7
      README.md
  2. 1 1
      direct/src/directtools/DirectCameraControl.py
  3. 3 3
      direct/src/directtools/DirectManipulation.py
  4. 1 1
      direct/src/directtools/DirectSession.py
  5. 2 2
      direct/src/tkpanels/DirectSessionPanel.py
  6. 1 1
      direct/src/tkwidgets/MemoryExplorer.py
  7. 483 469
      dtool/src/cppparser/cppBison.cxx.prebuilt
  8. 198 194
      dtool/src/cppparser/cppBison.h.prebuilt
  9. 183 38
      dtool/src/cppparser/cppBison.yxx
  10. 4 0
      dtool/src/cppparser/cppBisonDefs.h
  11. 196 0
      dtool/src/cppparser/cppClosureType.cxx
  12. 65 0
      dtool/src/cppparser/cppClosureType.h
  13. 8 0
      dtool/src/cppparser/cppDeclaration.cxx
  14. 6 0
      dtool/src/cppparser/cppDeclaration.h
  15. 97 3
      dtool/src/cppparser/cppExpression.cxx
  16. 6 0
      dtool/src/cppparser/cppExpression.h
  17. 53 8
      dtool/src/cppparser/cppFunctionType.cxx
  18. 2 0
      dtool/src/cppparser/cppFunctionType.h
  19. 70 5
      dtool/src/cppparser/cppPreprocessor.cxx
  20. 2 0
      dtool/src/cppparser/cppPreprocessor.h
  21. 8 0
      dtool/src/cppparser/cppToken.cxx
  22. 1 0
      dtool/src/cppparser/p3cppParser_composite1.cxx
  23. 4 4
      dtool/src/dtoolbase/deletedBufferChain.cxx
  24. 60 85
      dtool/src/dtoolbase/deletedChain.T
  25. 6 0
      dtool/src/dtoolbase/dtoolbase.h
  26. 34 4
      dtool/src/dtoolbase/dtoolbase_cc.h
  27. 36 67
      dtool/src/dtoolbase/memoryHook.I
  28. 29 17
      dtool/src/dtoolbase/memoryHook.cxx
  29. 19 2
      dtool/src/dtoolbase/memoryHook.h
  30. 3 17
      dtool/src/dtoolbase/mutexDummyImpl.I
  31. 9 5
      dtool/src/dtoolbase/mutexDummyImpl.h
  32. 8 10
      dtool/src/dtoolbase/mutexPosixImpl.I
  33. 15 1
      dtool/src/dtoolbase/mutexPosixImpl.h
  34. 2 10
      dtool/src/dtoolbase/mutexSpinlockImpl.I
  35. 6 2
      dtool/src/dtoolbase/mutexSpinlockImpl.h
  36. 5 0
      dtool/src/dtoolbase/mutexWin32Impl.h
  37. 25 26
      dtool/src/dtoolbase/pallocator.T
  38. 4 4
      dtool/src/dtoolbase/pallocator.h
  39. 0 1
      dtool/src/dtoolbase/pdeque.h
  40. 0 1
      dtool/src/dtoolbase/plist.h
  41. 0 4
      dtool/src/dtoolbase/pmap.h
  42. 0 4
      dtool/src/dtoolbase/pset.h
  43. 0 15
      dtool/src/dtoolbase/pvector.h
  44. 0 21
      dtool/src/dtoolbase/typedObject.I
  45. 37 17
      dtool/src/dtoolbase/typedObject.h
  46. 10 1
      dtool/src/interrogate/functionRemap.cxx
  47. 1 0
      dtool/src/interrogate/functionRemap.h
  48. 32 11
      dtool/src/interrogate/interfaceMakerPythonNative.cxx
  49. 3 0
      dtool/src/prc/streamWrapper.h
  50. 1 1
      dtool/src/prckeys/makePrcKey.cxx
  51. 14 0
      dtool/src/pystub/pystub.cxx
  52. 145 128
      makepanda/makepanda.py
  53. 21 17
      makepanda/makepandacore.py
  54. 21 73
      panda/src/display/displayInformation.cxx
  55. 5 13
      panda/src/display/displayInformation.h
  56. 157 16
      panda/src/display/graphicsPipe.cxx
  57. 2 2
      panda/src/display/graphicsPipe.h
  58. 5 2
      panda/src/display/graphicsStateGuardian.cxx
  59. 8 0
      panda/src/downloader/httpChannel.cxx
  60. 4 27
      panda/src/express/datagramIterator.I
  61. 0 3
      panda/src/express/datagramIterator.h
  62. 0 7
      panda/src/express/hashGeneratorBase.I
  63. 0 1
      panda/src/express/hashGeneratorBase.h
  64. 0 29
      panda/src/express/namable.I
  65. 0 6
      panda/src/express/namable.h
  66. 0 20
      panda/src/express/nodePointerTo.I
  67. 0 2
      panda/src/express/nodePointerTo.h
  68. 0 70
      panda/src/express/ordered_vector.I
  69. 0 7
      panda/src/express/ordered_vector.h
  70. 18 34
      panda/src/express/pointerTo.I
  71. 55 41
      panda/src/express/pointerTo.h
  72. 22 0
      panda/src/express/pointerToArray.I
  73. 2 0
      panda/src/express/pointerToArray.h
  74. 4 13
      panda/src/express/pointerToArrayBase.I
  75. 1 2
      panda/src/express/pointerToArrayBase.h
  76. 1 1
      panda/src/express/pointerToBase.h
  77. 8 17
      panda/src/express/pointerToVoid.I
  78. 4 4
      panda/src/express/pointerToVoid.h
  79. 3 10
      panda/src/express/weakPointerToVoid.I
  80. 0 1
      panda/src/express/weakPointerToVoid.h
  81. 18 10
      panda/src/gobj/vertexDataBuffer.I
  82. 2 2
      panda/src/parametrics/parametricCurveCollection.h
  83. 2 0
      panda/src/pgraph/nodePath.h
  84. 216 0
      panda/src/pgraph/nodePath_ext.cxx
  85. 2 0
      panda/src/pgraph/nodePath_ext.h
  86. 3 0
      panda/src/pgraph/shaderAttrib.h
  87. 0 27
      panda/src/putil/bitArray.I
  88. 0 4
      panda/src/putil/bitArray.h
  89. 0 28
      panda/src/putil/bitMask.I
  90. 0 4
      panda/src/putil/bitMask.h
  91. 0 7
      panda/src/putil/buttonHandle.I
  92. 0 1
      panda/src/putil/buttonHandle.h
  93. 4 6
      panda/src/putil/iterator_types.h
  94. 3 28
      panda/src/putil/sparseArray.I
  95. 0 4
      panda/src/putil/sparseArray.h
  96. 0 16
      panda/src/putil/writableParam.I
  97. 1 2
      panda/src/putil/writableParam.h
  98. 2 493
      panda/src/windisplay/winGraphicsPipe.cxx

+ 7 - 7
README.md

@@ -31,8 +31,8 @@ are included as part of the Windows 7.1 SDK.
 You will also need to have the third-party dependency libraries available for
 You will also need to have the third-party dependency libraries available for
 the build scripts to use.  These are available from one of these two URLs,
 the build scripts to use.  These are available from one of these two URLs,
 depending on whether you are on a 32-bit or 64-bit system:
 depending on whether you are on a 32-bit or 64-bit system:
-https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-win32.zip
-https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-win64.zip
+https://www.panda3d.org/download/panda3d-1.9.3/panda3d-1.9.3-tools-win32.zip
+https://www.panda3d.org/download/panda3d-1.9.3/panda3d-1.9.3-tools-win64.zip
 
 
 After acquiring these dependencies, you may simply build Panda3D from the
 After acquiring these dependencies, you may simply build Panda3D from the
 command prompt using the following command:
 command prompt using the following command:
@@ -93,11 +93,11 @@ may have to use the installpanda.py script instead, which will directly copy the
 files into the appropriate locations on your computer.  You may have to run the
 files into the appropriate locations on your computer.  You may have to run the
 `ldconfig` tool in order to update your library cache after installing Panda3D.
 `ldconfig` tool in order to update your library cache after installing Panda3D.
 
 
-Mac OS X
---------
+macOS
+-----
 
 
-On Mac OS X, you will need to download a set of precompiled thirdparty packages in order to
-compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-mac.tar.gz).
+On macOS, you will need to download a set of precompiled thirdparty packages in order to
+compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.3/panda3d-1.9.3-tools-mac.tar.gz).
 
 
 After placing the thirdparty directory inside the panda3d source directory,
 After placing the thirdparty directory inside the panda3d source directory,
 you may build Panda3D using a command like the following:
 you may build Panda3D using a command like the following:
@@ -107,7 +107,7 @@ python makepanda/makepanda.py --everything --installer
 ```
 ```
 
 
 In order to make a universal build, pass the --universal flag.  You may also
 In order to make a universal build, pass the --universal flag.  You may also
-target a specific minimum Mac OS X version using the --osxtarget flag followed
+target a specific minimum macOS version using the --osxtarget flag followed
 by the release number, eg. 10.6 or 10.7.
 by the release number, eg. 10.6 or 10.7.
 
 
 If the build was successful, makepanda will have generated a .dmg file in
 If the build was successful, makepanda will have generated a .dmg file in

+ 1 - 1
direct/src/directtools/DirectCameraControl.py

@@ -413,7 +413,7 @@ class DirectCameraControl(DirectObject):
                 np = NodePath('temp')
                 np = NodePath('temp')
                 np.setPos(base.direct.camera, hitPt)
                 np.setPos(base.direct.camera, hitPt)
                 self.coaMarkerPos = np.getPos()
                 self.coaMarkerPos = np.getPos()
-                np.remove()
+                np.removeNode()
                 self.coaMarker.setPos(self.coaMarkerPos)
                 self.coaMarker.setPos(self.coaMarkerPos)
 
 
             iRay.collisionNodePath.removeNode()
             iRay.collisionNodePath.removeNode()

+ 3 - 3
direct/src/directtools/DirectManipulation.py

@@ -186,7 +186,7 @@ class DirectManipulationControl(DirectObject):
 
 
     def drawMarquee(self, startX, startY):
     def drawMarquee(self, startX, startY):
         if self.marquee:
         if self.marquee:
-            self.marquee.remove()
+            self.marquee.removeNode()
             self.marquee = None
             self.marquee = None
 
 
         if base.direct.cameraControl.useMayaCamControls and base.direct.fAlt:
         if base.direct.cameraControl.useMayaCamControls and base.direct.fAlt:
@@ -228,7 +228,7 @@ class DirectManipulationControl(DirectObject):
             skipFlags |= SKIP_CAMERA * (1 - base.getControl())
             skipFlags |= SKIP_CAMERA * (1 - base.getControl())
 
 
             if self.marquee:
             if self.marquee:
-                self.marquee.remove()
+                self.marquee.removeNode()
                 self.marquee = None
                 self.marquee = None
                 base.direct.deselectAll()
                 base.direct.deselectAll()
 
 
@@ -1691,7 +1691,7 @@ class ObjectHandles(NodePath, DirectObject):
         np.setPos(base.direct.camera, hitPt)
         np.setPos(base.direct.camera, hitPt)
         resultPt = Point3(0)
         resultPt = Point3(0)
         resultPt.assign(np.getPos())
         resultPt.assign(np.getPos())
-        np.remove()
+        np.removeNode()
         del iRay
         del iRay
         return resultPt
         return resultPt
 
 

+ 1 - 1
direct/src/directtools/DirectSession.py

@@ -900,7 +900,7 @@ class DirectSession(DirectObject):
             # If nothing specified, try selected node path
             # If nothing specified, try selected node path
             nodePath = self.selected.last
             nodePath = self.selected.last
         if nodePath:
         if nodePath:
-            nodePath.remove()
+            nodePath.removeNode()
 
 
     def removeAllSelected(self):
     def removeAllSelected(self):
         self.selected.removeAll()
         self.selected.removeAll()

+ 2 - 2
direct/src/tkpanels/DirectSessionPanel.py

@@ -177,8 +177,8 @@ class DirectSessionPanel(AppShell):
             sgeFrame, nodePath = render,
             sgeFrame, nodePath = render,
             scrolledCanvas_hull_width = 250,
             scrolledCanvas_hull_width = 250,
             scrolledCanvas_hull_height = 300)
             scrolledCanvas_hull_height = 300)
-        self.SGE.pack(fill = BOTH, expand = 0)
-        sgeFrame.pack(side = LEFT, fill = 'both', expand = 0)
+        self.SGE.pack(fill = BOTH, expand = 1)
+        sgeFrame.pack(side = LEFT, fill = 'both', expand = 1)
 
 
         # Create the notebook pages
         # Create the notebook pages
         notebook = Pmw.NoteBook(notebookFrame)
         notebook = Pmw.NoteBook(notebookFrame)

+ 1 - 1
direct/src/tkwidgets/MemoryExplorer.py

@@ -284,7 +284,7 @@ class MemoryExplorerItem:
     def getNumChildren(self):
     def getNumChildren(self):
         return len(self.children)
         return len(self.children)
 
 
-    def getChildrenAsList(self):
+    def getChildren(self):
         return self.children
         return self.children
 
 
     def getName(self):
     def getName(self):

File diff suppressed because it is too large
+ 483 - 469
dtool/src/cppparser/cppBison.cxx.prebuilt


+ 198 - 194
dtool/src/cppparser/cppBison.h.prebuilt

@@ -89,103 +89,105 @@ extern int cppyydebug;
     XOREQUAL = 299,
     XOREQUAL = 299,
     LSHIFTEQUAL = 300,
     LSHIFTEQUAL = 300,
     RSHIFTEQUAL = 301,
     RSHIFTEQUAL = 301,
-    KW_ALIGNAS = 302,
-    KW_ALIGNOF = 303,
-    KW_AUTO = 304,
-    KW_BEGIN_PUBLISH = 305,
-    KW_BLOCKING = 306,
-    KW_BOOL = 307,
-    KW_CATCH = 308,
-    KW_CHAR = 309,
-    KW_CHAR16_T = 310,
-    KW_CHAR32_T = 311,
-    KW_CLASS = 312,
-    KW_CONST = 313,
-    KW_CONSTEXPR = 314,
-    KW_CONST_CAST = 315,
-    KW_DECLTYPE = 316,
-    KW_DEFAULT = 317,
-    KW_DELETE = 318,
-    KW_DOUBLE = 319,
-    KW_DYNAMIC_CAST = 320,
-    KW_ELSE = 321,
-    KW_END_PUBLISH = 322,
-    KW_ENUM = 323,
-    KW_EXTENSION = 324,
-    KW_EXTERN = 325,
-    KW_EXPLICIT = 326,
-    KW_PUBLISHED = 327,
-    KW_FALSE = 328,
-    KW_FINAL = 329,
-    KW_FLOAT = 330,
-    KW_FRIEND = 331,
-    KW_FOR = 332,
-    KW_GOTO = 333,
-    KW_HAS_VIRTUAL_DESTRUCTOR = 334,
-    KW_IF = 335,
-    KW_INLINE = 336,
-    KW_INT = 337,
-    KW_IS_ABSTRACT = 338,
-    KW_IS_BASE_OF = 339,
-    KW_IS_CLASS = 340,
-    KW_IS_CONSTRUCTIBLE = 341,
-    KW_IS_CONVERTIBLE_TO = 342,
-    KW_IS_DESTRUCTIBLE = 343,
-    KW_IS_EMPTY = 344,
-    KW_IS_ENUM = 345,
-    KW_IS_FINAL = 346,
-    KW_IS_FUNDAMENTAL = 347,
-    KW_IS_POD = 348,
-    KW_IS_POLYMORPHIC = 349,
-    KW_IS_STANDARD_LAYOUT = 350,
-    KW_IS_TRIVIAL = 351,
-    KW_IS_UNION = 352,
-    KW_LONG = 353,
-    KW_MAKE_MAP_PROPERTY = 354,
-    KW_MAKE_PROPERTY = 355,
-    KW_MAKE_PROPERTY2 = 356,
-    KW_MAKE_SEQ = 357,
-    KW_MAKE_SEQ_PROPERTY = 358,
-    KW_MUTABLE = 359,
-    KW_NAMESPACE = 360,
-    KW_NEW = 361,
-    KW_NOEXCEPT = 362,
-    KW_NULLPTR = 363,
-    KW_OPERATOR = 364,
-    KW_OVERRIDE = 365,
-    KW_PRIVATE = 366,
-    KW_PROTECTED = 367,
-    KW_PUBLIC = 368,
-    KW_REGISTER = 369,
-    KW_REINTERPRET_CAST = 370,
-    KW_RETURN = 371,
-    KW_SHORT = 372,
-    KW_SIGNED = 373,
-    KW_SIZEOF = 374,
-    KW_STATIC = 375,
-    KW_STATIC_ASSERT = 376,
-    KW_STATIC_CAST = 377,
-    KW_STRUCT = 378,
-    KW_TEMPLATE = 379,
-    KW_THREAD_LOCAL = 380,
-    KW_THROW = 381,
-    KW_TRUE = 382,
-    KW_TRY = 383,
-    KW_TYPEDEF = 384,
-    KW_TYPEID = 385,
-    KW_TYPENAME = 386,
-    KW_UNDERLYING_TYPE = 387,
-    KW_UNION = 388,
-    KW_UNSIGNED = 389,
-    KW_USING = 390,
-    KW_VIRTUAL = 391,
-    KW_VOID = 392,
-    KW_VOLATILE = 393,
-    KW_WCHAR_T = 394,
-    KW_WHILE = 395,
-    START_CPP = 396,
-    START_CONST_EXPR = 397,
-    START_TYPE = 398
+    ATTR_LEFT = 302,
+    ATTR_RIGHT = 303,
+    KW_ALIGNAS = 304,
+    KW_ALIGNOF = 305,
+    KW_AUTO = 306,
+    KW_BEGIN_PUBLISH = 307,
+    KW_BLOCKING = 308,
+    KW_BOOL = 309,
+    KW_CATCH = 310,
+    KW_CHAR = 311,
+    KW_CHAR16_T = 312,
+    KW_CHAR32_T = 313,
+    KW_CLASS = 314,
+    KW_CONST = 315,
+    KW_CONSTEXPR = 316,
+    KW_CONST_CAST = 317,
+    KW_DECLTYPE = 318,
+    KW_DEFAULT = 319,
+    KW_DELETE = 320,
+    KW_DOUBLE = 321,
+    KW_DYNAMIC_CAST = 322,
+    KW_ELSE = 323,
+    KW_END_PUBLISH = 324,
+    KW_ENUM = 325,
+    KW_EXTENSION = 326,
+    KW_EXTERN = 327,
+    KW_EXPLICIT = 328,
+    KW_PUBLISHED = 329,
+    KW_FALSE = 330,
+    KW_FINAL = 331,
+    KW_FLOAT = 332,
+    KW_FRIEND = 333,
+    KW_FOR = 334,
+    KW_GOTO = 335,
+    KW_HAS_VIRTUAL_DESTRUCTOR = 336,
+    KW_IF = 337,
+    KW_INLINE = 338,
+    KW_INT = 339,
+    KW_IS_ABSTRACT = 340,
+    KW_IS_BASE_OF = 341,
+    KW_IS_CLASS = 342,
+    KW_IS_CONSTRUCTIBLE = 343,
+    KW_IS_CONVERTIBLE_TO = 344,
+    KW_IS_DESTRUCTIBLE = 345,
+    KW_IS_EMPTY = 346,
+    KW_IS_ENUM = 347,
+    KW_IS_FINAL = 348,
+    KW_IS_FUNDAMENTAL = 349,
+    KW_IS_POD = 350,
+    KW_IS_POLYMORPHIC = 351,
+    KW_IS_STANDARD_LAYOUT = 352,
+    KW_IS_TRIVIAL = 353,
+    KW_IS_UNION = 354,
+    KW_LONG = 355,
+    KW_MAKE_MAP_PROPERTY = 356,
+    KW_MAKE_PROPERTY = 357,
+    KW_MAKE_PROPERTY2 = 358,
+    KW_MAKE_SEQ = 359,
+    KW_MAKE_SEQ_PROPERTY = 360,
+    KW_MUTABLE = 361,
+    KW_NAMESPACE = 362,
+    KW_NEW = 363,
+    KW_NOEXCEPT = 364,
+    KW_NULLPTR = 365,
+    KW_OPERATOR = 366,
+    KW_OVERRIDE = 367,
+    KW_PRIVATE = 368,
+    KW_PROTECTED = 369,
+    KW_PUBLIC = 370,
+    KW_REGISTER = 371,
+    KW_REINTERPRET_CAST = 372,
+    KW_RETURN = 373,
+    KW_SHORT = 374,
+    KW_SIGNED = 375,
+    KW_SIZEOF = 376,
+    KW_STATIC = 377,
+    KW_STATIC_ASSERT = 378,
+    KW_STATIC_CAST = 379,
+    KW_STRUCT = 380,
+    KW_TEMPLATE = 381,
+    KW_THREAD_LOCAL = 382,
+    KW_THROW = 383,
+    KW_TRUE = 384,
+    KW_TRY = 385,
+    KW_TYPEDEF = 386,
+    KW_TYPEID = 387,
+    KW_TYPENAME = 388,
+    KW_UNDERLYING_TYPE = 389,
+    KW_UNION = 390,
+    KW_UNSIGNED = 391,
+    KW_USING = 392,
+    KW_VIRTUAL = 393,
+    KW_VOID = 394,
+    KW_VOLATILE = 395,
+    KW_WCHAR_T = 396,
+    KW_WHILE = 397,
+    START_CPP = 398,
+    START_CONST_EXPR = 399,
+    START_TYPE = 400
   };
   };
 #endif
 #endif
 /* Tokens.  */
 /* Tokens.  */
@@ -233,103 +235,105 @@ extern int cppyydebug;
 #define XOREQUAL 299
 #define XOREQUAL 299
 #define LSHIFTEQUAL 300
 #define LSHIFTEQUAL 300
 #define RSHIFTEQUAL 301
 #define RSHIFTEQUAL 301
-#define KW_ALIGNAS 302
-#define KW_ALIGNOF 303
-#define KW_AUTO 304
-#define KW_BEGIN_PUBLISH 305
-#define KW_BLOCKING 306
-#define KW_BOOL 307
-#define KW_CATCH 308
-#define KW_CHAR 309
-#define KW_CHAR16_T 310
-#define KW_CHAR32_T 311
-#define KW_CLASS 312
-#define KW_CONST 313
-#define KW_CONSTEXPR 314
-#define KW_CONST_CAST 315
-#define KW_DECLTYPE 316
-#define KW_DEFAULT 317
-#define KW_DELETE 318
-#define KW_DOUBLE 319
-#define KW_DYNAMIC_CAST 320
-#define KW_ELSE 321
-#define KW_END_PUBLISH 322
-#define KW_ENUM 323
-#define KW_EXTENSION 324
-#define KW_EXTERN 325
-#define KW_EXPLICIT 326
-#define KW_PUBLISHED 327
-#define KW_FALSE 328
-#define KW_FINAL 329
-#define KW_FLOAT 330
-#define KW_FRIEND 331
-#define KW_FOR 332
-#define KW_GOTO 333
-#define KW_HAS_VIRTUAL_DESTRUCTOR 334
-#define KW_IF 335
-#define KW_INLINE 336
-#define KW_INT 337
-#define KW_IS_ABSTRACT 338
-#define KW_IS_BASE_OF 339
-#define KW_IS_CLASS 340
-#define KW_IS_CONSTRUCTIBLE 341
-#define KW_IS_CONVERTIBLE_TO 342
-#define KW_IS_DESTRUCTIBLE 343
-#define KW_IS_EMPTY 344
-#define KW_IS_ENUM 345
-#define KW_IS_FINAL 346
-#define KW_IS_FUNDAMENTAL 347
-#define KW_IS_POD 348
-#define KW_IS_POLYMORPHIC 349
-#define KW_IS_STANDARD_LAYOUT 350
-#define KW_IS_TRIVIAL 351
-#define KW_IS_UNION 352
-#define KW_LONG 353
-#define KW_MAKE_MAP_PROPERTY 354
-#define KW_MAKE_PROPERTY 355
-#define KW_MAKE_PROPERTY2 356
-#define KW_MAKE_SEQ 357
-#define KW_MAKE_SEQ_PROPERTY 358
-#define KW_MUTABLE 359
-#define KW_NAMESPACE 360
-#define KW_NEW 361
-#define KW_NOEXCEPT 362
-#define KW_NULLPTR 363
-#define KW_OPERATOR 364
-#define KW_OVERRIDE 365
-#define KW_PRIVATE 366
-#define KW_PROTECTED 367
-#define KW_PUBLIC 368
-#define KW_REGISTER 369
-#define KW_REINTERPRET_CAST 370
-#define KW_RETURN 371
-#define KW_SHORT 372
-#define KW_SIGNED 373
-#define KW_SIZEOF 374
-#define KW_STATIC 375
-#define KW_STATIC_ASSERT 376
-#define KW_STATIC_CAST 377
-#define KW_STRUCT 378
-#define KW_TEMPLATE 379
-#define KW_THREAD_LOCAL 380
-#define KW_THROW 381
-#define KW_TRUE 382
-#define KW_TRY 383
-#define KW_TYPEDEF 384
-#define KW_TYPEID 385
-#define KW_TYPENAME 386
-#define KW_UNDERLYING_TYPE 387
-#define KW_UNION 388
-#define KW_UNSIGNED 389
-#define KW_USING 390
-#define KW_VIRTUAL 391
-#define KW_VOID 392
-#define KW_VOLATILE 393
-#define KW_WCHAR_T 394
-#define KW_WHILE 395
-#define START_CPP 396
-#define START_CONST_EXPR 397
-#define START_TYPE 398
+#define ATTR_LEFT 302
+#define ATTR_RIGHT 303
+#define KW_ALIGNAS 304
+#define KW_ALIGNOF 305
+#define KW_AUTO 306
+#define KW_BEGIN_PUBLISH 307
+#define KW_BLOCKING 308
+#define KW_BOOL 309
+#define KW_CATCH 310
+#define KW_CHAR 311
+#define KW_CHAR16_T 312
+#define KW_CHAR32_T 313
+#define KW_CLASS 314
+#define KW_CONST 315
+#define KW_CONSTEXPR 316
+#define KW_CONST_CAST 317
+#define KW_DECLTYPE 318
+#define KW_DEFAULT 319
+#define KW_DELETE 320
+#define KW_DOUBLE 321
+#define KW_DYNAMIC_CAST 322
+#define KW_ELSE 323
+#define KW_END_PUBLISH 324
+#define KW_ENUM 325
+#define KW_EXTENSION 326
+#define KW_EXTERN 327
+#define KW_EXPLICIT 328
+#define KW_PUBLISHED 329
+#define KW_FALSE 330
+#define KW_FINAL 331
+#define KW_FLOAT 332
+#define KW_FRIEND 333
+#define KW_FOR 334
+#define KW_GOTO 335
+#define KW_HAS_VIRTUAL_DESTRUCTOR 336
+#define KW_IF 337
+#define KW_INLINE 338
+#define KW_INT 339
+#define KW_IS_ABSTRACT 340
+#define KW_IS_BASE_OF 341
+#define KW_IS_CLASS 342
+#define KW_IS_CONSTRUCTIBLE 343
+#define KW_IS_CONVERTIBLE_TO 344
+#define KW_IS_DESTRUCTIBLE 345
+#define KW_IS_EMPTY 346
+#define KW_IS_ENUM 347
+#define KW_IS_FINAL 348
+#define KW_IS_FUNDAMENTAL 349
+#define KW_IS_POD 350
+#define KW_IS_POLYMORPHIC 351
+#define KW_IS_STANDARD_LAYOUT 352
+#define KW_IS_TRIVIAL 353
+#define KW_IS_UNION 354
+#define KW_LONG 355
+#define KW_MAKE_MAP_PROPERTY 356
+#define KW_MAKE_PROPERTY 357
+#define KW_MAKE_PROPERTY2 358
+#define KW_MAKE_SEQ 359
+#define KW_MAKE_SEQ_PROPERTY 360
+#define KW_MUTABLE 361
+#define KW_NAMESPACE 362
+#define KW_NEW 363
+#define KW_NOEXCEPT 364
+#define KW_NULLPTR 365
+#define KW_OPERATOR 366
+#define KW_OVERRIDE 367
+#define KW_PRIVATE 368
+#define KW_PROTECTED 369
+#define KW_PUBLIC 370
+#define KW_REGISTER 371
+#define KW_REINTERPRET_CAST 372
+#define KW_RETURN 373
+#define KW_SHORT 374
+#define KW_SIGNED 375
+#define KW_SIZEOF 376
+#define KW_STATIC 377
+#define KW_STATIC_ASSERT 378
+#define KW_STATIC_CAST 379
+#define KW_STRUCT 380
+#define KW_TEMPLATE 381
+#define KW_THREAD_LOCAL 382
+#define KW_THROW 383
+#define KW_TRUE 384
+#define KW_TRY 385
+#define KW_TYPEDEF 386
+#define KW_TYPEID 387
+#define KW_TYPENAME 388
+#define KW_UNDERLYING_TYPE 389
+#define KW_UNION 390
+#define KW_UNSIGNED 391
+#define KW_USING 392
+#define KW_VIRTUAL 393
+#define KW_VOID 394
+#define KW_VOLATILE 395
+#define KW_WCHAR_T 396
+#define KW_WHILE 397
+#define START_CPP 398
+#define START_CONST_EXPR 399
+#define START_TYPE 400
 
 
 /* Value type.  */
 /* Value type.  */
 
 

+ 183 - 38
dtool/src/cppparser/cppBison.yxx

@@ -8,6 +8,7 @@
 
 
 #include "cppBisonDefs.h"
 #include "cppBisonDefs.h"
 #include "cppParser.h"
 #include "cppParser.h"
+#include "cppClosureType.h"
 #include "cppExpression.h"
 #include "cppExpression.h"
 #include "cppSimpleType.h"
 #include "cppSimpleType.h"
 #include "cppExtensionType.h"
 #include "cppExtensionType.h"
@@ -44,6 +45,7 @@ static CPPEnumType *current_enum = NULL;
 static int current_storage_class = 0;
 static int current_storage_class = 0;
 static CPPType *current_type = NULL;
 static CPPType *current_type = NULL;
 static CPPExpression *current_expr = NULL;
 static CPPExpression *current_expr = NULL;
+static CPPClosureType *current_closure = NULL;
 static int publish_nest_level = 0;
 static int publish_nest_level = 0;
 static CPPVisibility publish_previous;
 static CPPVisibility publish_previous;
 static YYLTYPE publish_loc;
 static YYLTYPE publish_loc;
@@ -247,6 +249,8 @@ pop_struct() {
 %token XOREQUAL
 %token XOREQUAL
 %token LSHIFTEQUAL
 %token LSHIFTEQUAL
 %token RSHIFTEQUAL
 %token RSHIFTEQUAL
+%token ATTR_LEFT
+%token ATTR_RIGHT
 
 
 %token KW_ALIGNAS
 %token KW_ALIGNAS
 %token KW_ALIGNOF
 %token KW_ALIGNOF
@@ -363,6 +367,8 @@ pop_struct() {
 %type <u.param_list> function_parameters
 %type <u.param_list> function_parameters
 %type <u.param_list> formal_parameter_list
 %type <u.param_list> formal_parameter_list
 %type <u.param_list> formal_parameters
 %type <u.param_list> formal_parameters
+%type <u.closure_type> capture_list
+%type <u.capture> capture
 %type <u.expr> template_parameter_maybe_initialize
 %type <u.expr> template_parameter_maybe_initialize
 %type <u.expr> maybe_initialize
 %type <u.expr> maybe_initialize
 %type <u.expr> maybe_initialize_or_constructor_body
 %type <u.expr> maybe_initialize_or_constructor_body
@@ -870,10 +876,18 @@ storage_class:
 {
 {
   $$ = $2 | (int)CPPInstance::SC_thread_local;
   $$ = $2 | (int)CPPInstance::SC_thread_local;
 }
 }
-        | '[' '[' attribute_specifiers ']' ']' storage_class
+        | ATTR_LEFT attribute_specifiers ATTR_RIGHT storage_class
 {
 {
   // Ignore attribute specifiers for now.
   // Ignore attribute specifiers for now.
-  $$ = $6;
+  $$ = $4;
+}
+        | KW_ALIGNAS '(' const_expr ')' storage_class
+{
+  $$ = $5;
+}
+        | KW_ALIGNAS '(' type_decl ')' storage_class
+{
+  $$ = $5;
 }
 }
         ;
         ;
 
 
@@ -885,6 +899,7 @@ attribute_specifiers:
 attribute_specifier:
 attribute_specifier:
         name
         name
         | name '(' formal_parameter_list ')'
         | name '(' formal_parameter_list ')'
+        | KW_USING name ':' attribute_specifier
         ;
         ;
 
 
 type_like_declaration:
 type_like_declaration:
@@ -1221,6 +1236,15 @@ function_post:
 {
 {
   $$ = $1 | (int)CPPFunctionType::F_noexcept;
   $$ = $1 | (int)CPPFunctionType::F_noexcept;
 }
 }
+/*        | function_post KW_NOEXCEPT '(' const_expr ')'
+{
+  CPPExpression::Result result = $4->evaluate();
+  if (result._type == CPPExpression::RT_error) {
+    yywarning("noexcept requires a constant expression", @4);
+  } else if (result.as_boolean()) {
+    $$ = $1 | (int)CPPFunctionType::F_noexcept;
+  }
+}*/
         | function_post KW_FINAL
         | function_post KW_FINAL
 {
 {
   $$ = $1 | (int)CPPFunctionType::F_final;
   $$ = $1 | (int)CPPFunctionType::F_final;
@@ -1241,6 +1265,11 @@ function_post:
 {
 {
   // Used for lambdas, currently ignored.
   // Used for lambdas, currently ignored.
   $$ = $1;
   $$ = $1;
+}
+        | function_post KW_CONSTEXPR
+{
+  // Used for lambdas in C++17, currently ignored.
+  $$ = $1;
 }
 }
         | function_post KW_THROW '(' ')'
         | function_post KW_THROW '(' ')'
 {
 {
@@ -1254,10 +1283,10 @@ function_post:
 {
 {
   $$ = $1;
   $$ = $1;
 }
 }
-/*        | function_post '[' '[' attribute_specifiers ']' ']'
+        | function_post ATTR_LEFT attribute_specifiers ATTR_RIGHT
 {
 {
   $$ = $1;
   $$ = $1;
-}*/
+}
         ;
         ;
 
 
 function_operator:
 function_operator:
@@ -1422,10 +1451,12 @@ function_operator:
 more_template_declaration:
 more_template_declaration:
         type_like_declaration
         type_like_declaration
         | template_declaration
         | template_declaration
+        | friend_declaration
         ;
         ;
 
 
 template_declaration:
 template_declaration:
-        KW_TEMPLATE
+        KW_EXTERN template_declaration
+        | KW_TEMPLATE
 {
 {
   push_scope(new CPPTemplateScope(current_scope));
   push_scope(new CPPTemplateScope(current_scope));
 }
 }
@@ -1433,7 +1464,8 @@ template_declaration:
 {
 {
   pop_scope();
   pop_scope();
 }
 }
-	| KW_TEMPLATE type_like_declaration
+        | KW_TEMPLATE type_like_declaration
+        | KW_TEMPLATE friend_declaration
         ;
         ;
 
 
 template_formal_parameters:
 template_formal_parameters:
@@ -1885,6 +1917,10 @@ function_parameter:
         | KW_REGISTER function_parameter
         | KW_REGISTER function_parameter
 {
 {
   $$ = $2;
   $$ = $2;
+}
+        | ATTR_LEFT attribute_specifiers ATTR_RIGHT function_parameter
+{
+  $$ = $4;
 }
 }
         ;
         ;
 
 
@@ -2228,16 +2264,16 @@ type:
 {
 {
   $$ = CPPType::new_type($1);
   $$ = CPPType::new_type($1);
 }
 }
-        | struct_keyword name
+        | struct_keyword struct_attributes name
 {
 {
-  CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
+  CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
   if (type != NULL) {
   if (type != NULL) {
     $$ = type;
     $$ = type;
   } else {
   } else {
     CPPExtensionType *et =
     CPPExtensionType *et =
-      CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
+      CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
       ->as_extension_type();
       ->as_extension_type();
-    CPPScope *scope = $2->get_scope(current_scope, global_scope);
+    CPPScope *scope = $3->get_scope(current_scope, global_scope);
     if (scope != NULL) {
     if (scope != NULL) {
       scope->define_extension_type(et);
       scope->define_extension_type(et);
     }
     }
@@ -2268,6 +2304,10 @@ type:
     str << *$3;
     str << *$3;
     yyerror("could not determine type of " + str.str(), @3);
     yyerror("could not determine type of " + str.str(), @3);
   }
   }
+}
+        | KW_DECLTYPE '(' KW_AUTO ')'
+{
+  $$ = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto));
 }
 }
         | KW_UNDERLYING_TYPE '(' full_type ')'
         | KW_UNDERLYING_TYPE '(' full_type ')'
 {
 {
@@ -2325,16 +2365,16 @@ type_decl:
 {
 {
   $$ = new CPPTypeDeclaration(CPPType::new_type($1));
   $$ = new CPPTypeDeclaration(CPPType::new_type($1));
 }
 }
-        | struct_keyword name
+        | struct_keyword struct_attributes name
 {
 {
-  CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
+  CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
   if (type != NULL) {
   if (type != NULL) {
     $$ = type;
     $$ = type;
   } else {
   } else {
     CPPExtensionType *et =
     CPPExtensionType *et =
-      CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
+      CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
       ->as_extension_type();
       ->as_extension_type();
-    CPPScope *scope = $2->get_scope(current_scope, global_scope);
+    CPPScope *scope = $3->get_scope(current_scope, global_scope);
     if (scope != NULL) {
     if (scope != NULL) {
       scope->define_extension_type(et);
       scope->define_extension_type(et);
     }
     }
@@ -2383,6 +2423,10 @@ type_decl:
     str << *$3;
     str << *$3;
     yyerror("could not determine type of " + str.str(), @3);
     yyerror("could not determine type of " + str.str(), @3);
   }
   }
+}
+        | KW_DECLTYPE '(' KW_AUTO ')'
+{
+  $$ = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto));
 }
 }
         | KW_UNDERLYING_TYPE '(' full_type ')'
         | KW_UNDERLYING_TYPE '(' full_type ')'
 {
 {
@@ -2417,16 +2461,16 @@ predefined_type:
 {
 {
   $$ = CPPType::new_type(new CPPTBDType($2));
   $$ = CPPType::new_type(new CPPTBDType($2));
 }
 }
-        | struct_keyword name
+        | struct_keyword struct_attributes name
 {
 {
-  CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
+  CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
   if (type != NULL) {
   if (type != NULL) {
     $$ = type;
     $$ = type;
   } else {
   } else {
     CPPExtensionType *et =
     CPPExtensionType *et =
-      CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
+      CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
       ->as_extension_type();
       ->as_extension_type();
-    CPPScope *scope = $2->get_scope(current_scope, global_scope);
+    CPPScope *scope = $3->get_scope(current_scope, global_scope);
     if (scope != NULL) {
     if (scope != NULL) {
       scope->define_extension_type(et);
       scope->define_extension_type(et);
     }
     }
@@ -2507,8 +2551,15 @@ full_type:
 }
 }
         ;
         ;
 
 
+struct_attributes:
+        empty
+        | struct_attributes ATTR_LEFT attribute_specifiers ATTR_RIGHT
+        | struct_attributes KW_ALIGNAS '(' const_expr ')'
+        | struct_attributes KW_ALIGNAS '(' type_decl ')'
+        ;
+
 anonymous_struct:
 anonymous_struct:
-        struct_keyword '{'
+        struct_keyword struct_attributes '{'
 {
 {
   CPPVisibility starting_vis =
   CPPVisibility starting_vis =
   ($1 == CPPExtensionType::T_class) ? V_private : V_public;
   ($1 == CPPExtensionType::T_class) ? V_private : V_public;
@@ -2532,19 +2583,19 @@ anonymous_struct:
         ;
         ;
 
 
 named_struct:
 named_struct:
-        struct_keyword name_no_final
+        struct_keyword struct_attributes name_no_final
 {
 {
   CPPVisibility starting_vis =
   CPPVisibility starting_vis =
   ($1 == CPPExtensionType::T_class) ? V_private : V_public;
   ($1 == CPPExtensionType::T_class) ? V_private : V_public;
 
 
-  CPPScope *scope = $2->get_scope(current_scope, global_scope, current_lexer);
+  CPPScope *scope = $3->get_scope(current_scope, global_scope, current_lexer);
   if (scope == NULL) {
   if (scope == NULL) {
     scope = current_scope;
     scope = current_scope;
   }
   }
-  CPPScope *new_scope = new CPPScope(scope, $2->_names.back(),
+  CPPScope *new_scope = new CPPScope(scope, $3->_names.back(),
                                      starting_vis);
                                      starting_vis);
 
 
-  CPPStructType *st = new CPPStructType($1, $2, current_scope,
+  CPPStructType *st = new CPPStructType($1, $3, current_scope,
                                         new_scope, @1.file);
                                         new_scope, @1.file);
   new_scope->set_struct_type(st);
   new_scope->set_struct_type(st);
   current_scope->define_extension_type(st);
   current_scope->define_extension_type(st);
@@ -2927,6 +2978,7 @@ element:
         | SCOPE | PLUSPLUS | MINUSMINUS
         | SCOPE | PLUSPLUS | MINUSMINUS
         | TIMESEQUAL | DIVIDEEQUAL | MODEQUAL | PLUSEQUAL | MINUSEQUAL
         | TIMESEQUAL | DIVIDEEQUAL | MODEQUAL | PLUSEQUAL | MINUSEQUAL
         | OREQUAL | ANDEQUAL | XOREQUAL | LSHIFTEQUAL | RSHIFTEQUAL
         | OREQUAL | ANDEQUAL | XOREQUAL | LSHIFTEQUAL | RSHIFTEQUAL
+        | ATTR_LEFT | ATTR_RIGHT
         | KW_ALIGNAS | KW_ALIGNOF | KW_AUTO | KW_BOOL | KW_CATCH
         | KW_ALIGNAS | KW_ALIGNOF | KW_AUTO | KW_BOOL | KW_CATCH
         | KW_CHAR | KW_CHAR16_T | KW_CHAR32_T | KW_CLASS | KW_CONST
         | KW_CHAR | KW_CHAR16_T | KW_CHAR32_T | KW_CLASS | KW_CONST
         | KW_CONSTEXPR | KW_CONST_CAST | KW_DECLTYPE | KW_DEFAULT
         | KW_CONSTEXPR | KW_CONST_CAST | KW_DECLTYPE | KW_DEFAULT
@@ -3010,6 +3062,18 @@ no_angle_bracket_const_expr:
         | KW_SIZEOF '(' full_type ')' %prec UNARY
         | KW_SIZEOF '(' full_type ')' %prec UNARY
 {
 {
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
+}
+        | KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
+{
+  CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
+  if (arg == (CPPDeclaration *)NULL) {
+    yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
+  } else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
+    CPPInstance *inst = arg->as_instance();
+    $$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
+  } else {
+    $$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
+  }
 }
 }
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
 {
 {
@@ -3172,6 +3236,16 @@ const_expr:
   }
   }
   assert(type != NULL);
   assert(type != NULL);
   $$ = new CPPExpression(CPPExpression::construct_op(type, $3));
   $$ = new CPPExpression(CPPExpression::construct_op(type, $3));
+}
+        | TYPENAME_IDENTIFIER '{' optional_const_expr_comma '}'
+{
+  // Aggregate initialization.
+  CPPType *type = $1->find_type(current_scope, global_scope, false, current_lexer);
+  if (type == NULL) {
+    yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
+  }
+  assert(type != NULL);
+  $$ = new CPPExpression(CPPExpression::aggregate_init_op(type, $3));
 }
 }
         | KW_INT '(' optional_const_expr_comma ')'
         | KW_INT '(' optional_const_expr_comma ')'
 {
 {
@@ -3252,6 +3326,18 @@ const_expr:
         | KW_SIZEOF '(' full_type ')' %prec UNARY
         | KW_SIZEOF '(' full_type ')' %prec UNARY
 {
 {
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
+}
+        | KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
+{
+  CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
+  if (arg == (CPPDeclaration *)NULL) {
+    yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
+  } else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
+    CPPInstance *inst = arg->as_instance();
+    $$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
+  } else {
+    $$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
+  }
 }
 }
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
 {
 {
@@ -3468,11 +3554,16 @@ const_operand:
 }
 }
         | '[' capture_list ']' function_post maybe_trailing_return_type '{' code '}'
         | '[' capture_list ']' function_post maybe_trailing_return_type '{' code '}'
 {
 {
-  $$ = NULL;
+  $2->_flags = $4;
+  $2->_return_type = $5;
+  $$ = new CPPExpression(CPPExpression::lambda($2));
 }
 }
         | '[' capture_list ']' '(' function_parameter_list ')' function_post maybe_trailing_return_type '{' code '}'
         | '[' capture_list ']' '(' function_parameter_list ')' function_post maybe_trailing_return_type '{' code '}'
 {
 {
-  $$ = NULL;
+  $2->_parameters = $5;
+  $2->_flags = $7;
+  $2->_return_type = $8;
+  $$ = new CPPExpression(CPPExpression::lambda($2));
 }
 }
         | KW_HAS_VIRTUAL_DESTRUCTOR '(' full_type ')'
         | KW_HAS_VIRTUAL_DESTRUCTOR '(' full_type ')'
 {
 {
@@ -3579,6 +3670,18 @@ formal_const_expr:
         | KW_SIZEOF '(' full_type ')' %prec UNARY
         | KW_SIZEOF '(' full_type ')' %prec UNARY
 {
 {
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
+}
+        | KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
+{
+  CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
+  if (arg == (CPPDeclaration *)NULL) {
+    yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
+  } else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
+    CPPInstance *inst = arg->as_instance();
+    $$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
+  } else {
+    $$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
+  }
 }
 }
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
 {
 {
@@ -3794,15 +3897,65 @@ formal_const_operand:
 /* The contents of the [] list preceding a lambda expression. */
 /* The contents of the [] list preceding a lambda expression. */
 capture_list:
 capture_list:
         empty
         empty
-        | capture
-        | capture ',' capture_list
+{
+  $$ = new CPPClosureType();
+}
+        | '='
+{
+  $$ = new CPPClosureType(CPPClosureType::CT_by_value);
+}
+        | '&'
+{
+  $$ = new CPPClosureType(CPPClosureType::CT_by_reference);
+}
+        | capture maybe_initialize
+{
+  $$ = new CPPClosureType();
+  $1->_initializer = $2;
+  $$->_captures.push_back(*$1);
+  delete $1;
+}
+        | capture_list ',' capture maybe_initialize
+{
+  $$ = $1;
+  $3->_initializer = $4;
+  $$->_captures.push_back(*$3);
+  delete $3;
+}
         ;
         ;
 
 
 capture:
 capture:
-        '&'
-        | '='
-        | '&' name
+        '&' name
+{
+  $$ = new CPPClosureType::Capture;
+  $$->_name = $2->get_simple_name();
+  $$->_type = CPPClosureType::CT_by_reference;
+}
+        | '&' name ELLIPSIS
+{
+  $$ = new CPPClosureType::Capture;
+  $$->_name = $2->get_simple_name();
+  $$->_type = CPPClosureType::CT_by_reference;
+}
         | name
         | name
+{
+  $$ = new CPPClosureType::Capture;
+  $$->_name = $1->get_simple_name();
+  if ($$->_name == "this") {
+    $$->_type = CPPClosureType::CT_by_reference;
+  } else {
+    $$->_type = CPPClosureType::CT_by_value;
+  }
+}
+        | '*' name
+{
+  $$ = new CPPClosureType::Capture;
+  $$->_name = $2->get_simple_name();
+  $$->_type = CPPClosureType::CT_by_value;
+  if ($$->_name != "this") {
+    yywarning("only capture name 'this' may be preceded by an asterisk", @2);
+  }
+}
         ;
         ;
 
 
 class_derivation_name:
 class_derivation_name:
@@ -3813,14 +3966,6 @@ class_derivation_name:
     type = CPPType::new_type(new CPPTBDType($1));
     type = CPPType::new_type(new CPPTBDType($1));
   }
   }
   $$ = type;
   $$ = type;
-}
-        | struct_keyword name
-{
-  CPPType *type = $2->find_type(current_scope, global_scope, true, current_lexer);
-  if (type == NULL) {
-    type = CPPType::new_type(new CPPTBDType($2));
-  }
-  $$ = type;
 }
 }
         | KW_TYPENAME name
         | KW_TYPENAME name
 {
 {

+ 4 - 0
dtool/src/cppparser/cppBisonDefs.h

@@ -23,6 +23,7 @@
 
 
 #include <string>
 #include <string>
 
 
+#include "cppClosureType.h"
 #include "cppExtensionType.h"
 #include "cppExtensionType.h"
 #include "cppFile.h"
 #include "cppFile.h"
 
 
@@ -42,6 +43,7 @@ class CPPParameterList;
 class CPPTemplateParameterList;
 class CPPTemplateParameterList;
 class CPPScope;
 class CPPScope;
 class CPPIdentifier;
 class CPPIdentifier;
+class CPPCaptureType;
 
 
 void parse_cpp(CPPParser *cp);
 void parse_cpp(CPPParser *cp);
 CPPExpression *parse_const_expr(CPPPreprocessor *pp,
 CPPExpression *parse_const_expr(CPPPreprocessor *pp,
@@ -81,6 +83,8 @@ public:
     CPPExtensionType::Type extension_enum;
     CPPExtensionType::Type extension_enum;
     CPPExpression *expr;
     CPPExpression *expr;
     CPPIdentifier *identifier;
     CPPIdentifier *identifier;
+    CPPClosureType *closure_type;
+    CPPClosureType::Capture *capture;
   } u;
   } u;
 };
 };
 #define YYSTYPE cppyystype
 #define YYSTYPE cppyystype

+ 196 - 0
dtool/src/cppparser/cppClosureType.cxx

@@ -0,0 +1,196 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file cppClosureType.cxx
+ * @author rdb
+ * @date 2017-01-14
+ */
+
+#include "cppClosureType.h"
+#include "cppParameterList.h"
+#include "cppExpression.h"
+
+/**
+ *
+ */
+CPPClosureType::
+CPPClosureType(CaptureType default_capture) :
+  CPPFunctionType(NULL, NULL, 0),
+  _default_capture(default_capture) {
+}
+
+/**
+ *
+ */
+CPPClosureType::
+CPPClosureType(const CPPClosureType &copy) :
+  CPPFunctionType(copy),
+  _captures(copy._captures),
+  _default_capture(copy._default_capture)
+{
+}
+
+/**
+ *
+ */
+void CPPClosureType::
+operator = (const CPPClosureType &copy) {
+  CPPFunctionType::operator = (copy);
+  _captures = copy._captures;
+  _default_capture = copy._default_capture;
+}
+
+/**
+ * Adds a new capture to the beginning of the capture list.
+ */
+void CPPClosureType::
+add_capture(string name, CaptureType type, CPPExpression *initializer) {
+  if (type == CT_none) {
+    if (name == "this") {
+      type = CT_by_reference;
+    } else {
+      type = CT_by_value;
+    }
+  }
+
+  Capture capture = {move(name), type, initializer};
+  _captures.insert(_captures.begin(), move(capture));
+}
+
+/**
+ * Returns true if this declaration is an actual, factual declaration, or
+ * false if some part of the declaration depends on a template parameter which
+ * has not yet been instantiated.
+ */
+bool CPPClosureType::
+is_fully_specified() const {
+  return CPPFunctionType::is_fully_specified();
+}
+
+/**
+ * Returns true if the type is default-constructible.
+ */
+bool CPPClosureType::
+is_default_constructible() const {
+  return false;
+}
+
+/**
+ * Returns true if the type is copy-constructible.
+ */
+bool CPPClosureType::
+is_copy_constructible() const {
+  return true;
+}
+
+/**
+ * Returns true if the type is destructible.
+ */
+bool CPPClosureType::
+is_destructible() const {
+  return true;
+}
+
+/**
+ *
+ */
+void CPPClosureType::
+output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
+  out.put('[');
+
+  bool have_capture = false;
+  switch (_default_capture) {
+  case CT_none:
+    break;
+  case CT_by_reference:
+    out.put('&');
+    have_capture = true;
+    break;
+  case CT_by_value:
+    out.put('=');
+    have_capture = true;
+    break;
+  }
+
+  Captures::const_iterator it;
+  for (it = _captures.begin(); it != _captures.end(); ++it) {
+    const Capture &capture = *it;
+    if (have_capture) {
+      out << ", ";
+    }
+    if (capture._name == "this") {
+      if (capture._type == CT_by_value) {
+        out.put('*');
+      }
+    } else {
+      if (capture._type == CT_by_reference) {
+        out.put('&');
+      }
+    }
+    out << capture._name;
+
+    if (capture._initializer != NULL) {
+      out << " = " << *capture._initializer;
+    }
+
+    have_capture = true;
+  }
+  out.put(']');
+
+  if (_parameters != NULL) {
+    out.put('(');
+    _parameters->output(out, scope, true, -1);
+    out.put(')');
+  }
+
+  if (_flags & F_noexcept) {
+    out << " noexcept";
+  }
+
+  if (_return_type != NULL) {
+    out << " -> ";
+    _return_type->output(out, indent_level, scope, false);
+  }
+
+  out << " {}";
+}
+
+/**
+ *
+ */
+CPPDeclaration::SubType CPPClosureType::
+get_subtype() const {
+  return ST_closure;
+}
+
+/**
+ *
+ */
+CPPClosureType *CPPClosureType::
+as_closure_type() {
+  return this;
+}
+
+/**
+ * Called by CPPDeclaration() to determine whether this type is equivalent to
+ * another type of the same type.
+ */
+bool CPPClosureType::
+is_equal(const CPPDeclaration *other) const {
+  return (this == other);
+}
+
+
+/**
+ * Called by CPPDeclaration() to determine whether this type should be ordered
+ * before another type of the same type, in an arbitrary but fixed ordering.
+ */
+bool CPPClosureType::
+is_less(const CPPDeclaration *other) const {
+  return (this < other);
+}

+ 65 - 0
dtool/src/cppparser/cppClosureType.h

@@ -0,0 +1,65 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file cppClosureType.h
+ * @author rdb
+ * @date 2017-01-14
+ */
+
+#ifndef CPPCLOSURETYPE_H
+#define CPPCLOSURETYPE_H
+
+#include "dtoolbase.h"
+
+#include "cppFunctionType.h"
+
+/**
+ * The type of a lambda expression.  This is like a function, but with
+ * additional captures defined.
+ */
+class CPPClosureType : public CPPFunctionType {
+public:
+  enum CaptureType {
+    CT_none,
+    CT_by_reference,
+    CT_by_value,
+  };
+
+  CPPClosureType(CaptureType default_capture = CT_none);
+  CPPClosureType(const CPPClosureType &copy);
+  void operator = (const CPPClosureType &copy);
+
+  struct Capture {
+    string _name;
+    CaptureType _type;
+    CPPExpression *_initializer;
+  };
+  typedef vector<Capture> Captures;
+  Captures _captures;
+
+  CaptureType _default_capture;
+
+  void add_capture(string name, CaptureType type, CPPExpression *initializer = NULL);
+
+  virtual bool is_fully_specified() const;
+
+  virtual bool is_default_constructible() const;
+  virtual bool is_copy_constructible() const;
+  virtual bool is_destructible() const;
+
+  virtual void output(ostream &out, int indent_level, CPPScope *scope,
+                      bool complete) const;
+  virtual SubType get_subtype() const;
+  virtual CPPClosureType *as_closure_type();
+
+protected:
+  virtual bool is_equal(const CPPDeclaration *other) const;
+  virtual bool is_less(const CPPDeclaration *other) const;
+};
+
+#endif

+ 8 - 0
dtool/src/cppparser/cppDeclaration.cxx

@@ -311,6 +311,14 @@ as_make_seq() {
   return (CPPMakeSeq *)NULL;
   return (CPPMakeSeq *)NULL;
 }
 }
 
 
+/**
+ *
+ */
+CPPClosureType *CPPDeclaration::
+as_closure_type() {
+  return (CPPClosureType *)NULL;
+}
+
 /**
 /**
  * Called by CPPDeclaration to determine whether this type is equivalent to
  * Called by CPPDeclaration to determine whether this type is equivalent to
  * another type of the same type.
  * another type of the same type.

+ 6 - 0
dtool/src/cppparser/cppDeclaration.h

@@ -48,6 +48,7 @@ class CPPEnumType;
 class CPPTypeProxy;
 class CPPTypeProxy;
 class CPPMakeProperty;
 class CPPMakeProperty;
 class CPPMakeSeq;
 class CPPMakeSeq;
+class CPPClosureType;
 class CPPClassTemplateParameter;
 class CPPClassTemplateParameter;
 class CPPTBDType;
 class CPPTBDType;
 class CPPScope;
 class CPPScope;
@@ -85,6 +86,7 @@ public:
     ST_tbd,
     ST_tbd,
     ST_type_proxy,
     ST_type_proxy,
     ST_typedef,
     ST_typedef,
+    ST_closure,
   };
   };
 
 
   CPPDeclaration(const CPPFile &file);
   CPPDeclaration(const CPPFile &file);
@@ -140,6 +142,7 @@ public:
   virtual CPPTypeProxy *as_type_proxy();
   virtual CPPTypeProxy *as_type_proxy();
   virtual CPPMakeProperty *as_make_property();
   virtual CPPMakeProperty *as_make_property();
   virtual CPPMakeSeq *as_make_seq();
   virtual CPPMakeSeq *as_make_seq();
+  virtual CPPClosureType *as_closure_type();
 
 
   inline const CPPInstance *as_instance() const {
   inline const CPPInstance *as_instance() const {
     return ((CPPDeclaration *)this)->as_instance();
     return ((CPPDeclaration *)this)->as_instance();
@@ -207,6 +210,9 @@ public:
   inline const CPPMakeSeq *as_make_seq() const {
   inline const CPPMakeSeq *as_make_seq() const {
     return ((CPPDeclaration *)this)->as_make_seq();
     return ((CPPDeclaration *)this)->as_make_seq();
   }
   }
+  inline const CPPClosureType *as_closure_type() const {
+    return ((CPPDeclaration *)this)->as_closure_type();
+  }
 
 
   CPPVisibility _vis;
   CPPVisibility _vis;
   CPPTemplateScope *_template_scope;
   CPPTemplateScope *_template_scope;

+ 97 - 3
dtool/src/cppparser/cppExpression.cxx

@@ -24,6 +24,7 @@
 #include "cppInstance.h"
 #include "cppInstance.h"
 #include "cppFunctionGroup.h"
 #include "cppFunctionGroup.h"
 #include "cppFunctionType.h"
 #include "cppFunctionType.h"
+#include "cppClosureType.h"
 #include "cppStructType.h"
 #include "cppStructType.h"
 #include "cppBison.h"
 #include "cppBison.h"
 #include "pdtoa.h"
 #include "pdtoa.h"
@@ -256,13 +257,12 @@ CPPExpression(CPPIdentifier *ident, CPPScope *current_scope,
       _u._variable = inst;
       _u._variable = inst;
       return;
       return;
     }
     }
-    // Actually, we can't scope function groups.
-    /*CPPFunctionGroup *fgroup = decl->as_function_group();
+    CPPFunctionGroup *fgroup = decl->as_function_group();
     if (fgroup != NULL) {
     if (fgroup != NULL) {
       _type = T_function;
       _type = T_function;
       _u._fgroup = fgroup;
       _u._fgroup = fgroup;
       return;
       return;
-    }*/
+    }
   }
   }
 
 
   _type = T_unknown_ident;
   _type = T_unknown_ident;
@@ -346,6 +346,22 @@ construct_op(CPPType *type, CPPExpression *op1) {
   return expr;
   return expr;
 }
 }
 
 
+/**
+ * Creates an expression that represents an aggregate initialization.
+ */
+CPPExpression CPPExpression::
+aggregate_init_op(CPPType *type, CPPExpression *op1) {
+  CPPExpression expr(0);
+  if (op1 == NULL) {
+    expr._type = T_empty_aggregate_init;
+  } else {
+    expr._type = T_aggregate_init;
+  }
+  expr._u._typecast._to = type;
+  expr._u._typecast._op1 = op1;
+  return expr;
+}
+
 /**
 /**
  * Creates an expression that represents a use of the new operator.
  * Creates an expression that represents a use of the new operator.
  */
  */
@@ -438,6 +454,17 @@ alignof_func(CPPType *type) {
   return expr;
   return expr;
 }
 }
 
 
+/**
+ *
+ */
+CPPExpression CPPExpression::
+lambda(CPPClosureType *type) {
+  CPPExpression expr(0);
+  expr._type = T_lambda;
+  expr._u._closure_type = type;
+  return expr;
+}
+
 /**
 /**
  *
  *
  */
  */
@@ -594,6 +621,8 @@ evaluate() const {
 
 
   case T_construct:
   case T_construct:
   case T_default_construct:
   case T_default_construct:
+  case T_aggregate_init:
+  case T_empty_aggregate_init:
   case T_new:
   case T_new:
   case T_default_new:
   case T_default_new:
   case T_sizeof:
   case T_sizeof:
@@ -1017,6 +1046,8 @@ determine_type() const {
   case T_reinterpret_cast:
   case T_reinterpret_cast:
   case T_construct:
   case T_construct:
   case T_default_construct:
   case T_default_construct:
+  case T_aggregate_init:
+  case T_empty_aggregate_init:
     return _u._typecast._to;
     return _u._typecast._to;
 
 
   case T_new:
   case T_new:
@@ -1135,10 +1166,28 @@ determine_type() const {
 
 
     case 'f': // Function evaluation
     case 'f': // Function evaluation
       if (t1 != NULL) {
       if (t1 != NULL) {
+        // Easy case, function with only a single overload.
         CPPFunctionType *ftype = t1->as_function_type();
         CPPFunctionType *ftype = t1->as_function_type();
         if (ftype != (CPPFunctionType *)NULL) {
         if (ftype != (CPPFunctionType *)NULL) {
           return ftype->_return_type;
           return ftype->_return_type;
         }
         }
+      } else if (_u._op._op1->_type == T_function) {
+        CPPFunctionGroup *fgroup = _u._op._op1->_u._fgroup;
+        if (_u._op._op2 == NULL) {
+          // If we are passing no args, look for an overload that has takes no
+          // args.
+          for (auto it = fgroup->_instances.begin(); it != fgroup->_instances.end(); ++it) {
+            CPPInstance *inst = *it;
+            if (inst != NULL && inst->_type != NULL) {
+              CPPFunctionType *type = inst->_type->as_function_type();
+              if (type != NULL && type->accepts_num_parameters(0)) {
+                return type->_return_type;
+              }
+            }
+          }
+        } else {
+          //TODO
+        }
       }
       }
       return NULL;
       return NULL;
 
 
@@ -1169,6 +1218,9 @@ determine_type() const {
   case T_type_trait:
   case T_type_trait:
     return bool_type;
     return bool_type;
 
 
+  case T_lambda:
+    return _u._closure_type;
+
   default:
   default:
     cerr << "**invalid operand**\n";
     cerr << "**invalid operand**\n";
     abort();
     abort();
@@ -1215,11 +1267,13 @@ is_fully_specified() const {
   case T_const_cast:
   case T_const_cast:
   case T_reinterpret_cast:
   case T_reinterpret_cast:
   case T_construct:
   case T_construct:
+  case T_aggregate_init:
   case T_new:
   case T_new:
     return (_u._typecast._to->is_fully_specified() &&
     return (_u._typecast._to->is_fully_specified() &&
             _u._typecast._op1->is_fully_specified());
             _u._typecast._op1->is_fully_specified());
 
 
   case T_default_construct:
   case T_default_construct:
+  case T_empty_aggregate_init:
   case T_default_new:
   case T_default_new:
   case T_sizeof:
   case T_sizeof:
   case T_alignof:
   case T_alignof:
@@ -1259,6 +1313,9 @@ is_fully_specified() const {
   case T_type_trait:
   case T_type_trait:
     return _u._type_trait._type->is_fully_specified();
     return _u._type_trait._type->is_fully_specified();
 
 
+  case T_lambda:
+    return _u._closure_type->is_fully_specified();
+
   default:
   default:
     return true;
     return true;
   }
   }
@@ -1342,6 +1399,7 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
   case T_const_cast:
   case T_const_cast:
   case T_reinterpret_cast:
   case T_reinterpret_cast:
   case T_construct:
   case T_construct:
+  case T_aggregate_init:
   case T_new:
   case T_new:
     rep->_u._typecast._op1 =
     rep->_u._typecast._op1 =
       _u._typecast._op1->substitute_decl(subst, current_scope, global_scope)
       _u._typecast._op1->substitute_decl(subst, current_scope, global_scope)
@@ -1350,6 +1408,7 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
     // fall through
     // fall through
 
 
   case T_default_construct:
   case T_default_construct:
+  case T_empty_aggregate_init:
   case T_default_new:
   case T_default_new:
   case T_sizeof:
   case T_sizeof:
   case T_alignof:
   case T_alignof:
@@ -1444,6 +1503,8 @@ is_tbd() const {
   case T_const_cast:
   case T_const_cast:
   case T_reinterpret_cast:
   case T_reinterpret_cast:
   case T_construct:
   case T_construct:
+  case T_aggregate_init:
+  case T_empty_aggregate_init:
   case T_new:
   case T_new:
   case T_default_construct:
   case T_default_construct:
   case T_default_new:
   case T_default_new:
@@ -1478,6 +1539,9 @@ is_tbd() const {
   case T_type_trait:
   case T_type_trait:
     return _u._type_trait._type->is_tbd();
     return _u._type_trait._type->is_tbd();
 
 
+  case T_lambda:
+    return _u._closure_type->is_tbd();
+
   default:
   default:
     return false;
     return false;
   }
   }
@@ -1558,6 +1622,10 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
           out << "\\\"";
           out << "\\\"";
           break;
           break;
 
 
+        case '\\':
+          out << "\\\\";
+          break;
+
         default:
         default:
           if (isprint(*si)) {
           if (isprint(*si)) {
             out << *si;
             out << *si;
@@ -1649,6 +1717,18 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
     out << "()";
     out << "()";
     break;
     break;
 
 
+  case T_aggregate_init:
+    _u._typecast._to->output(out, indent_level, scope, false);
+    out << "{";
+    _u._typecast._op1->output(out, indent_level, scope, false);
+    out << "}";
+    break;
+
+  case T_empty_aggregate_init:
+    _u._typecast._to->output(out, indent_level, scope, false);
+    out << "{}";
+    break;
+
   case T_new:
   case T_new:
     out << "(new ";
     out << "(new ";
     _u._typecast._to->output(out, indent_level, scope, false);
     _u._typecast._to->output(out, indent_level, scope, false);
@@ -1946,6 +2026,10 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
     out << ')';
     out << ')';
     break;
     break;
 
 
+  case T_lambda:
+    _u._closure_type->output(out, indent_level, scope, false);
+    break;
+
   default:
   default:
     out << "(** invalid operand type " << (int)_type << " **)";
     out << "(** invalid operand type " << (int)_type << " **)";
   }
   }
@@ -2066,11 +2150,13 @@ is_equal(const CPPDeclaration *other) const {
   case T_const_cast:
   case T_const_cast:
   case T_reinterpret_cast:
   case T_reinterpret_cast:
   case T_construct:
   case T_construct:
+  case T_aggregate_init:
   case T_new:
   case T_new:
     return _u._typecast._to == ot->_u._typecast._to &&
     return _u._typecast._to == ot->_u._typecast._to &&
       *_u._typecast._op1 == *ot->_u._typecast._op1;
       *_u._typecast._op1 == *ot->_u._typecast._op1;
 
 
   case T_default_construct:
   case T_default_construct:
+  case T_empty_aggregate_init:
   case T_default_new:
   case T_default_new:
   case T_sizeof:
   case T_sizeof:
   case T_alignof:
   case T_alignof:
@@ -2105,6 +2191,9 @@ is_equal(const CPPDeclaration *other) const {
     return _u._type_trait._trait == ot->_u._type_trait._trait &&
     return _u._type_trait._trait == ot->_u._type_trait._trait &&
            _u._type_trait._type == ot->_u._type_trait._type;
            _u._type_trait._type == ot->_u._type_trait._type;
 
 
+  case T_lambda:
+    return _u._closure_type == ot->_u._closure_type;
+
   default:
   default:
     cerr << "(** invalid operand type " << (int)_type << " **)";
     cerr << "(** invalid operand type " << (int)_type << " **)";
   }
   }
@@ -2161,6 +2250,7 @@ is_less(const CPPDeclaration *other) const {
   case T_const_cast:
   case T_const_cast:
   case T_reinterpret_cast:
   case T_reinterpret_cast:
   case T_construct:
   case T_construct:
+  case T_aggregate_init:
   case T_new:
   case T_new:
     if (_u._typecast._to != ot->_u._typecast._to) {
     if (_u._typecast._to != ot->_u._typecast._to) {
       return _u._typecast._to < ot->_u._typecast._to;
       return _u._typecast._to < ot->_u._typecast._to;
@@ -2168,6 +2258,7 @@ is_less(const CPPDeclaration *other) const {
     return *_u._typecast._op1 < *ot->_u._typecast._op1;
     return *_u._typecast._op1 < *ot->_u._typecast._op1;
 
 
   case T_default_construct:
   case T_default_construct:
+  case T_empty_aggregate_init:
   case T_default_new:
   case T_default_new:
   case T_sizeof:
   case T_sizeof:
   case T_alignof:
   case T_alignof:
@@ -2212,6 +2303,9 @@ is_less(const CPPDeclaration *other) const {
     }
     }
     return *_u._type_trait._type < *ot->_u._type_trait._type;
     return *_u._type_trait._type < *ot->_u._type_trait._type;
 
 
+  case T_lambda:
+    return _u._closure_type < ot->_u._closure_type;
+
   default:
   default:
     cerr << "(** invalid operand type " << (int)_type << " **)";
     cerr << "(** invalid operand type " << (int)_type << " **)";
   }
   }

+ 6 - 0
dtool/src/cppparser/cppExpression.h

@@ -48,6 +48,8 @@ public:
     T_reinterpret_cast,
     T_reinterpret_cast,
     T_construct,
     T_construct,
     T_default_construct,
     T_default_construct,
+    T_aggregate_init,
+    T_empty_aggregate_init,
     T_new,
     T_new,
     T_default_new,
     T_default_new,
     T_sizeof,
     T_sizeof,
@@ -61,6 +63,7 @@ public:
     T_typeid_type,
     T_typeid_type,
     T_typeid_expr,
     T_typeid_expr,
     T_type_trait,
     T_type_trait,
+    T_lambda,
 
 
     // These are used when parsing =default and =delete methods.
     // These are used when parsing =default and =delete methods.
     T_default,
     T_default,
@@ -80,6 +83,7 @@ public:
 
 
   static CPPExpression typecast_op(CPPType *type, CPPExpression *op1, Type cast_type = T_typecast);
   static CPPExpression typecast_op(CPPType *type, CPPExpression *op1, Type cast_type = T_typecast);
   static CPPExpression construct_op(CPPType *type, CPPExpression *op1);
   static CPPExpression construct_op(CPPType *type, CPPExpression *op1);
+  static CPPExpression aggregate_init_op(CPPType *type, CPPExpression *op1);
   static CPPExpression new_op(CPPType *type, CPPExpression *op1 = NULL);
   static CPPExpression new_op(CPPType *type, CPPExpression *op1 = NULL);
   static CPPExpression typeid_op(CPPType *type, CPPType *std_type_info);
   static CPPExpression typeid_op(CPPType *type, CPPType *std_type_info);
   static CPPExpression typeid_op(CPPExpression *op1, CPPType *std_type_info);
   static CPPExpression typeid_op(CPPExpression *op1, CPPType *std_type_info);
@@ -87,6 +91,7 @@ public:
   static CPPExpression sizeof_func(CPPType *type);
   static CPPExpression sizeof_func(CPPType *type);
   static CPPExpression sizeof_ellipsis_func(CPPIdentifier *ident);
   static CPPExpression sizeof_ellipsis_func(CPPIdentifier *ident);
   static CPPExpression alignof_func(CPPType *type);
   static CPPExpression alignof_func(CPPType *type);
+  static CPPExpression lambda(CPPClosureType *type);
 
 
   static CPPExpression literal(unsigned long long value, CPPInstance *lit_op);
   static CPPExpression literal(unsigned long long value, CPPInstance *lit_op);
   static CPPExpression literal(long double value, CPPInstance *lit_op);
   static CPPExpression literal(long double value, CPPInstance *lit_op);
@@ -150,6 +155,7 @@ public:
     CPPInstance *_variable;
     CPPInstance *_variable;
     CPPFunctionGroup *_fgroup;
     CPPFunctionGroup *_fgroup;
     CPPIdentifier *_ident;
     CPPIdentifier *_ident;
+    CPPClosureType *_closure_type;
     struct {
     struct {
       union {
       union {
         CPPType *_type;
         CPPType *_type;

+ 53 - 8
dtool/src/cppparser/cppFunctionType.cxx

@@ -31,7 +31,8 @@ CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
 
 
   // If the parameter list contains just the token "void", it means no
   // If the parameter list contains just the token "void", it means no
   // parameters.
   // parameters.
-  if (_parameters->_parameters.size() == 1 &&
+  if (_parameters != NULL &&
+      _parameters->_parameters.size() == 1 &&
       _parameters->_parameters.front()->_type->as_simple_type() != NULL &&
       _parameters->_parameters.front()->_type->as_simple_type() != NULL &&
       _parameters->_parameters.front()->_type->as_simple_type()->_type ==
       _parameters->_parameters.front()->_type->as_simple_type()->_type ==
       CPPSimpleType::T_void &&
       CPPSimpleType::T_void &&
@@ -65,6 +66,31 @@ operator = (const CPPFunctionType &copy) {
   _class_owner = copy._class_owner;
   _class_owner = copy._class_owner;
 }
 }
 
 
+/**
+ * Returns true if the function accepts the given number of parameters.
+ */
+bool CPPFunctionType::
+accepts_num_parameters(int num_parameters) {
+  if (_parameters == NULL) {
+    return (num_parameters == 0);
+  }
+  size_t actual_num_parameters = _parameters->_parameters.size();
+  // If we passed too many parameters, it must have an ellipsis.
+  if (num_parameters > actual_num_parameters) {
+    return _parameters->_includes_ellipsis;
+  }
+
+  // Make sure all superfluous parameters have a default value.
+  for (size_t i = num_parameters; i < actual_num_parameters; ++i) {
+    CPPInstance *param = _parameters->_parameters[i];
+    if (param->_initializer == NULL) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 /**
 /**
  * Returns true if this declaration is an actual, factual declaration, or
  * Returns true if this declaration is an actual, factual declaration, or
  * false if some part of the declaration depends on a template parameter which
  * false if some part of the declaration depends on a template parameter which
@@ -95,8 +121,10 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
       ->as_type();
       ->as_type();
   }
   }
 
 
-  rep->_parameters =
-    _parameters->substitute_decl(subst, current_scope, global_scope);
+  if (_parameters != NULL) {
+    rep->_parameters =
+      _parameters->substitute_decl(subst, current_scope, global_scope);
+  }
 
 
   if (rep->_return_type == _return_type &&
   if (rep->_return_type == _return_type &&
       rep->_parameters == _parameters) {
       rep->_parameters == _parameters) {
@@ -117,8 +145,12 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
 CPPType *CPPFunctionType::
 CPPType *CPPFunctionType::
 resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
 resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
   CPPType *rtype = _return_type->resolve_type(current_scope, global_scope);
   CPPType *rtype = _return_type->resolve_type(current_scope, global_scope);
-  CPPParameterList *params =
-    _parameters->resolve_type(current_scope, global_scope);
+  CPPParameterList *params;
+  if (_parameters == NULL) {
+    params = NULL;
+  } else {
+    params = _parameters->resolve_type(current_scope, global_scope);
+  }
 
 
   if (rtype != _return_type || params != _parameters) {
   if (rtype != _return_type || params != _parameters) {
     CPPFunctionType *rep = new CPPFunctionType(*this);
     CPPFunctionType *rep = new CPPFunctionType(*this);
@@ -139,7 +171,7 @@ is_tbd() const {
   if (_return_type->is_tbd()) {
   if (_return_type->is_tbd()) {
     return true;
     return true;
   }
   }
-  return _parameters->is_tbd();
+  return _parameters == NULL || _parameters->is_tbd();
 }
 }
 
 
 /**
 /**
@@ -294,6 +326,10 @@ get_num_default_parameters() const {
   // The trick is just to count, beginning from the end and working towards
   // The trick is just to count, beginning from the end and working towards
   // the front, the number of parameters that have some initializer.
   // the front, the number of parameters that have some initializer.
 
 
+  if (_parameters == NULL) {
+    return 0;
+  }
+
   const CPPParameterList::Parameters &params = _parameters->_parameters;
   const CPPParameterList::Parameters &params = _parameters->_parameters;
   CPPParameterList::Parameters::const_reverse_iterator pi;
   CPPParameterList::Parameters::const_reverse_iterator pi;
   int count = 0;
   int count = 0;
@@ -362,7 +398,11 @@ is_equal(const CPPDeclaration *other) const {
   if (_flags != ot->_flags) {
   if (_flags != ot->_flags) {
     return false;
     return false;
   }
   }
-  if (*_parameters != *ot->_parameters) {
+  if (_parameters == ot->_parameters) {
+    return true;
+  }
+  if (_parameters == NULL || ot->_parameters == NULL ||
+      *_parameters != *ot->_parameters) {
     return false;
     return false;
   }
   }
   return true;
   return true;
@@ -384,6 +424,11 @@ is_less(const CPPDeclaration *other) const {
   if (_flags != ot->_flags) {
   if (_flags != ot->_flags) {
     return _flags < ot->_flags;
     return _flags < ot->_flags;
   }
   }
-
+  if (_parameters == ot->_parameters) {
+    return 0;
+  }
+  if (_parameters == NULL || ot->_parameters == NULL) {
+    return _parameters < ot->_parameters;
+  }
   return *_parameters < *ot->_parameters;
   return *_parameters < *ot->_parameters;
 }
 }

+ 2 - 0
dtool/src/cppparser/cppFunctionType.h

@@ -50,6 +50,8 @@ public:
   CPPFunctionType(const CPPFunctionType &copy);
   CPPFunctionType(const CPPFunctionType &copy);
   void operator = (const CPPFunctionType &copy);
   void operator = (const CPPFunctionType &copy);
 
 
+  bool accepts_num_parameters(int num_parameters);
+
   CPPType *_return_type;
   CPPType *_return_type;
   CPPParameterList *_parameters;
   CPPParameterList *_parameters;
   int _flags;
   int _flags;

+ 70 - 5
dtool/src/cppparser/cppPreprocessor.cxx

@@ -209,6 +209,7 @@ CPPPreprocessor() {
   _state = S_eof;
   _state = S_eof;
   _paren_nesting = 0;
   _paren_nesting = 0;
   _parsing_template_params = false;
   _parsing_template_params = false;
+  _parsing_attribute = false;
   _unget = '\0';
   _unget = '\0';
   _last_c = '\0';
   _last_c = '\0';
   _start_of_line = true;
   _start_of_line = true;
@@ -986,6 +987,13 @@ internal_get_next_token() {
         return CPPToken(0, loc);
         return CPPToken(0, loc);
       }
       }
     }
     }
+  } else if (_parsing_attribute) {
+    // If we're parsing an attribute, also keep track of the paren nesting.
+    if (c == '[' || c == '(') {
+      ++_paren_nesting;
+    } else if (c == ']' || c == ')') {
+      --_paren_nesting;
+    }
   }
   }
 
 
   // Look for an end-of-line comment, and parse it before we finish this
   // Look for an end-of-line comment, and parse it before we finish this
@@ -1090,6 +1098,20 @@ check_digraph(int c) {
     if (next_c == '=') return MODEQUAL;
     if (next_c == '=') return MODEQUAL;
     if (next_c == '>') return '}';
     if (next_c == '>') return '}';
     break;
     break;
+
+  case '[':
+    if (next_c == '[' && !_parsing_attribute) {
+      _parsing_attribute = true;
+      return ATTR_LEFT;
+    }
+    break;
+
+  case ']':
+    if (next_c == ']' && _parsing_attribute && _paren_nesting == 0) {
+      _parsing_attribute = false;
+      return ATTR_RIGHT;
+    }
+    break;
   }
   }
 
 
   return 0;
   return 0;
@@ -1870,11 +1892,19 @@ get_identifier(int c) {
   loc.last_column = get_col_number();
   loc.last_column = get_col_number();
 
 
   if ((c == '\'' || c == '"') &&
   if ((c == '\'' || c == '"') &&
-      (name == "L" || name == "u8" ||
-       name == "u" || name == "U")) {
+      (name == "L" || name == "u8" || name == "u" || name == "U" ||
+       name == "R" || name == "LR" || name == "u8R" || name == "uR" || name == "UR")) {
     // This is actually a wide-character or wide-string literal or some such.
     // This is actually a wide-character or wide-string literal or some such.
-    // Figure out the correct character type to use.
+    get();
+    string str;
+    if (name[name.size() - 1] == 'R') {
+      name.resize(name.size() - 1);
+      str = scan_raw(c);
+    } else {
+      str = scan_quoted(c);
+    }
 
 
+    // Figure out the correct character type to use.
     CPPExpression::Type type;
     CPPExpression::Type type;
     if (name == "L") {
     if (name == "L") {
       type = CPPExpression::T_wstring;
       type = CPPExpression::T_wstring;
@@ -1887,8 +1917,6 @@ get_identifier(int c) {
     } else {
     } else {
       type = CPPExpression::T_string;
       type = CPPExpression::T_string;
     }
     }
-    get();
-    string str = scan_quoted(c);
 
 
     loc.last_line = get_line_number();
     loc.last_line = get_line_number();
     loc.last_column = get_col_number();
     loc.last_column = get_col_number();
@@ -2772,6 +2800,43 @@ scan_quoted(int c) {
   return str;
   return str;
 }
 }
 
 
+/**
+ * Parses a C++11 raw string.
+ */
+string CPPPreprocessor::
+scan_raw(int c) {
+  int quote_mark = c;
+
+  string delimiter = ")";
+
+  string str;
+  c = get();
+  while (c != EOF && c != '(') {
+    delimiter += c;
+    c = get();
+  }
+
+  // OK, now start parsing the string, until we see the delimiter again.
+  c = get();
+  while (c != EOF) {
+    if (c == quote_mark) {
+      // We encountered a quote mark - did the last part of the string end
+      // with the given delimiter?  If so, we've reached the end.
+      if (str.compare(str.size() - delimiter.size(), delimiter.size(), delimiter) == 0) {
+        str.resize(str.size() - delimiter.size());
+        break;
+      }
+    }
+    str += c;
+    c = get();
+  }
+
+  if (c != quote_mark) {
+    warning("Unclosed string");
+  }
+  return str;
+}
+
 /**
 /**
  * Returns true if the manifest is one that is being ignored right now
  * Returns true if the manifest is one that is being ignored right now
  * (presumably because we are presently expanding it).
  * (presumably because we are presently expanding it).

+ 2 - 0
dtool/src/cppparser/cppPreprocessor.h

@@ -166,6 +166,7 @@ private:
   static int check_keyword(const string &name);
   static int check_keyword(const string &name);
   int scan_escape_sequence(int c);
   int scan_escape_sequence(int c);
   string scan_quoted(int c);
   string scan_quoted(int c);
+  string scan_raw(int c);
 
 
   bool should_ignore_manifest(const CPPManifest *manifest) const;
   bool should_ignore_manifest(const CPPManifest *manifest) const;
   bool should_ignore_preprocessor() const;
   bool should_ignore_preprocessor() const;
@@ -212,6 +213,7 @@ private:
   State _state;
   State _state;
   int _paren_nesting;
   int _paren_nesting;
   bool _parsing_template_params;
   bool _parsing_template_params;
+  bool _parsing_attribute;
 
 
   bool _start_of_line;
   bool _start_of_line;
   int _unget;
   int _unget;

+ 8 - 0
dtool/src/cppparser/cppToken.cxx

@@ -252,6 +252,14 @@ output(ostream &out) const {
     out << "RSHIFTEQUAL";
     out << "RSHIFTEQUAL";
     break;
     break;
 
 
+  case ATTR_LEFT:
+    out << "ATTR_LEFT";
+    break;
+
+  case ATTR_RIGHT:
+    out << "ATTR_RIGHT";
+    break;
+
   case KW_BOOL:
   case KW_BOOL:
     out << "KW_BOOL";
     out << "KW_BOOL";
     break;
     break;

+ 1 - 0
dtool/src/cppparser/p3cppParser_composite1.cxx

@@ -2,6 +2,7 @@
 #include "cppFunctionType.cxx"
 #include "cppFunctionType.cxx"
 #include "cppGlobals.cxx"
 #include "cppGlobals.cxx"
 #include "cppCommentBlock.cxx"
 #include "cppCommentBlock.cxx"
+#include "cppClosureType.cxx"
 #include "cppConstType.cxx"
 #include "cppConstType.cxx"
 #include "cppDeclaration.cxx"
 #include "cppDeclaration.cxx"
 #include "cppMakeProperty.cxx"
 #include "cppMakeProperty.cxx"

+ 4 - 4
dtool/src/dtoolbase/deletedBufferChain.cxx

@@ -39,7 +39,7 @@ allocate(size_t size, TypeHandle type_handle) {
   assert(size <= _buffer_size);
   assert(size <= _buffer_size);
 
 
   // Determine how much space to allocate.
   // Determine how much space to allocate.
-  const size_t alloc_size = _buffer_size + flag_reserved_bytes + MemoryHook::get_memory_alignment() - 1;
+  const size_t alloc_size = _buffer_size + flag_reserved_bytes + MEMORY_HOOK_ALIGNMENT - 1;
 
 
   ObjectNode *obj;
   ObjectNode *obj;
 
 
@@ -71,8 +71,8 @@ allocate(size_t size, TypeHandle type_handle) {
 
 
   // Allocate memory, and make sure the object starts at the proper alignment.
   // Allocate memory, and make sure the object starts at the proper alignment.
   void *mem = NeverFreeMemory::alloc(alloc_size);
   void *mem = NeverFreeMemory::alloc(alloc_size);
-  intptr_t pad = (-(intptr_t)flag_reserved_bytes - (intptr_t)mem) % MemoryHook::get_memory_alignment();
-  obj = (ObjectNode *)((uintptr_t)mem + pad);
+  uintptr_t aligned = ((uintptr_t)mem + flag_reserved_bytes + MEMORY_HOOK_ALIGNMENT - 1) & ~(MEMORY_HOOK_ALIGNMENT - 1);
+  obj = (ObjectNode *)(aligned - flag_reserved_bytes);
 
 
 #ifdef USE_DELETEDCHAINFLAG
 #ifdef USE_DELETEDCHAINFLAG
   obj->_flag = DCF_alive;
   obj->_flag = DCF_alive;
@@ -81,7 +81,7 @@ allocate(size_t size, TypeHandle type_handle) {
   void *ptr = node_to_buffer(obj);
   void *ptr = node_to_buffer(obj);
 
 
 #ifndef NDEBUG
 #ifndef NDEBUG
-  assert(((uintptr_t)ptr % MemoryHook::get_memory_alignment()) == 0);
+  assert(((uintptr_t)ptr % MEMORY_HOOK_ALIGNMENT) == 0);
 #endif
 #endif
 
 
 #ifdef DO_MEMORY_USAGE
 #ifdef DO_MEMORY_USAGE

+ 60 - 85
dtool/src/dtoolbase/deletedChain.T

@@ -1,25 +1,22 @@
-// Filename: deletedChain.T
-// Created by:  drose (01Apr06)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) Carnegie Mellon University.  All rights reserved.
-//
-// All use of this software is subject to the terms of the revised BSD
-// license.  You should have received a copy of this license along
-// with this source code in a file named "LICENSE."
-//
-////////////////////////////////////////////////////////////////////
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file deletedChain.T
+ * @author drose
+ * @date 2006-04-01
+ */
 
 
 template<class Type>
 template<class Type>
 DeletedChain<Type> StaticDeletedChain<Type>::_chain;
 DeletedChain<Type> StaticDeletedChain<Type>::_chain;
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::allocate
-//       Access: Public
-//  Description: Allocates the memory for a new object of Type.
-////////////////////////////////////////////////////////////////////
+/**
+ * Allocates the memory for a new object of Type.
+ */
 template<class Type>
 template<class Type>
 INLINE Type *DeletedChain<Type>::
 INLINE Type *DeletedChain<Type>::
 allocate(size_t size, TypeHandle type_handle) {
 allocate(size_t size, TypeHandle type_handle) {
@@ -31,14 +28,12 @@ allocate(size_t size, TypeHandle type_handle) {
   memory_hook->mark_pointer(ptr, _chain->get_buffer_size(), make_ref_ptr(ptr));
   memory_hook->mark_pointer(ptr, _chain->get_buffer_size(), make_ref_ptr(ptr));
 #endif  // DO_MEMORY_USAGE
 #endif  // DO_MEMORY_USAGE
 
 
-  return (Type *)ptr;
+  return (Type *)ASSUME_ALIGNED(ptr, MEMORY_HOOK_ALIGNMENT);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::deallocate
-//       Access: Public
-//  Description: Frees the memory for an object of Type.
-////////////////////////////////////////////////////////////////////
+/**
+ * Frees the memory for an object of Type.
+ */
 template<class Type>
 template<class Type>
 INLINE void DeletedChain<Type>::
 INLINE void DeletedChain<Type>::
 deallocate(Type *ptr, TypeHandle type_handle) {
 deallocate(Type *ptr, TypeHandle type_handle) {
@@ -57,16 +52,13 @@ deallocate(Type *ptr, TypeHandle type_handle) {
   _chain->deallocate(ptr, type_handle);
   _chain->deallocate(ptr, type_handle);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::validate
-//       Access: Public
-//  Description: Returns true if the pointer is valid, false if it has
-//               been deleted or if it was never a valid pointer.
-//
-//               This is only meaningful in debug mode, where
-//               USE_DELETEDCHAINFLAG is defined.  If not, this
-//               trivially returns true.
-////////////////////////////////////////////////////////////////////
+/**
+ * Returns true if the pointer is valid, false if it has been deleted or if it
+ * was never a valid pointer.
+ *
+ * This is only meaningful in debug mode, where USE_DELETEDCHAINFLAG is
+ * defined.  If not, this trivially returns true.
+ */
 template<class Type>
 template<class Type>
 INLINE bool DeletedChain<Type>::
 INLINE bool DeletedChain<Type>::
 validate(const Type *ptr) {
 validate(const Type *ptr) {
@@ -80,48 +72,37 @@ validate(const Type *ptr) {
 #endif  // USE_DELETEDCHAINFLAG
 #endif  // USE_DELETEDCHAINFLAG
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::make_ref_ptr
-//       Access: Public, Static
-//  Description: This method has two overloads: one that accepts a
-//               void *, and one that accepts a ReferenceCount *.  We
-//               rely on the C++ compiler to select the most
-//               appropriate one for a given type to return the
-//               ReferenceCount pointer that corresponds to a
-//               particular type, or NULL if the type does not inherit
-//               from ReferenceCount.
-////////////////////////////////////////////////////////////////////
+/**
+ * This method has two overloads: one that accepts a void *, and one that
+ * accepts a ReferenceCount *.  We rely on the C++ compiler to select the most
+ * appropriate one for a given type to return the ReferenceCount pointer that
+ * corresponds to a particular type, or NULL if the type does not inherit from
+ * ReferenceCount.
+ */
 template<class Type>
 template<class Type>
 INLINE ReferenceCount *DeletedChain<Type>::
 INLINE ReferenceCount *DeletedChain<Type>::
 make_ref_ptr(void *) {
 make_ref_ptr(void *) {
   return NULL;
   return NULL;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::make_ref_ptr
-//       Access: Public, Static
-//  Description: This method has two overloads: one that accepts a
-//               void *, and one that accepts a ReferenceCount *.  We
-//               rely on the C++ compiler to select the most
-//               appropriate one for a given type to return the
-//               ReferenceCount pointer that corresponds to a
-//               particular type, or NULL if the type does not inherit
-//               from ReferenceCount.
-////////////////////////////////////////////////////////////////////
+/**
+ * This method has two overloads: one that accepts a void *, and one that
+ * accepts a ReferenceCount *.  We rely on the C++ compiler to select the most
+ * appropriate one for a given type to return the ReferenceCount pointer that
+ * corresponds to a particular type, or NULL if the type does not inherit from
+ * ReferenceCount.
+ */
 template<class Type>
 template<class Type>
 INLINE ReferenceCount *DeletedChain<Type>::
 INLINE ReferenceCount *DeletedChain<Type>::
 make_ref_ptr(ReferenceCount *ptr) {
 make_ref_ptr(ReferenceCount *ptr) {
   return ptr;
   return ptr;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::init_deleted_chain
-//       Access: Private
-//  Description: Assigns the _chain pointer if it is not already
-//               assigned.  This can't be done by a constructor, since
-//               often the DeletedChain instance is used before its
-//               static construct has had a chance to be called.
-////////////////////////////////////////////////////////////////////
+/**
+ * Assigns the _chain pointer if it is not already assigned.  This can't be
+ * done by a constructor, since often the DeletedChain instance is used before
+ * its static construct has had a chance to be called.
+ */
 template<class Type>
 template<class Type>
 void DeletedChain<Type>::
 void DeletedChain<Type>::
 init_deleted_chain() {
 init_deleted_chain() {
@@ -131,38 +112,32 @@ init_deleted_chain() {
   }
   }
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: StaticDeletedChain::allocate
-//       Access: Public, Static
-//  Description: Allocates the memory for a new object of Type.
-////////////////////////////////////////////////////////////////////
+/**
+ * Allocates the memory for a new object of Type.
+ */
 template<class Type>
 template<class Type>
 INLINE Type *StaticDeletedChain<Type>::
 INLINE Type *StaticDeletedChain<Type>::
 allocate(size_t size, TypeHandle type_handle) {
 allocate(size_t size, TypeHandle type_handle) {
-  return _chain.allocate(size, type_handle);
+  Type *ptr = _chain.allocate(size, type_handle);
+  return (Type *)ASSUME_ALIGNED(ptr, MEMORY_HOOK_ALIGNMENT);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: StaticDeletedChain::deallocate
-//       Access: Public
-//  Description: Frees the memory for an object of Type.
-////////////////////////////////////////////////////////////////////
+/**
+ * Frees the memory for an object of Type.
+ */
 template<class Type>
 template<class Type>
 INLINE void StaticDeletedChain<Type>::
 INLINE void StaticDeletedChain<Type>::
 deallocate(Type *ptr, TypeHandle type_handle) {
 deallocate(Type *ptr, TypeHandle type_handle) {
   _chain.deallocate(ptr, type_handle);
   _chain.deallocate(ptr, type_handle);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: StaticDeletedChain::validate
-//       Access: Public
-//  Description: Returns true if the pointer is valid, false if it has
-//               been deleted or if it was never a valid pointer.
-//
-//               This is only meaningful in debug mode, where
-//               USE_DELETEDCHAINFLAG is defined.  If not, this
-//               trivially returns true.
-////////////////////////////////////////////////////////////////////
+/**
+ * Returns true if the pointer is valid, false if it has been deleted or if it
+ * was never a valid pointer.
+ *
+ * This is only meaningful in debug mode, where USE_DELETEDCHAINFLAG is
+ * defined.  If not, this trivially returns true.
+ */
 template<class Type>
 template<class Type>
 INLINE bool StaticDeletedChain<Type>::
 INLINE bool StaticDeletedChain<Type>::
 validate(const Type *ptr) {
 validate(const Type *ptr) {

+ 6 - 0
dtool/src/dtoolbase/dtoolbase.h

@@ -89,6 +89,12 @@
 #define NODEFAULT
 #define NODEFAULT
 #endif
 #endif
 
 
+// Use this to hint the compiler that a memory address is aligned.
+#if __has_builtin(__builtin_assume_aligned) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
+#define ASSUME_ALIGNED(x, y) (__builtin_assume_aligned(x, y))
+#else
+#define ASSUME_ALIGNED(x, y) (x)
+#endif
 
 
 /*
 /*
   include win32 defns for everything up to WinServer2003, and assume
   include win32 defns for everything up to WinServer2003, and assume

+ 34 - 4
dtool/src/dtoolbase/dtoolbase_cc.h

@@ -39,6 +39,10 @@ using namespace std;
 #define OVERRIDE override
 #define OVERRIDE override
 #define MOVE(x) x
 #define MOVE(x) x
 #define DEFAULT_CTOR = default
 #define DEFAULT_CTOR = default
+#define DEFAULT_DTOR = default
+#define DEFAULT_ASSIGN = default
+#define DELETED = delete
+#define DELETED_ASSIGN = delete
 
 
 #define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname)
 #define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname)
 
 
@@ -166,6 +170,11 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
 #  endif
 #  endif
 #  if __has_extension(cxx_defaulted_functions)
 #  if __has_extension(cxx_defaulted_functions)
 #     define DEFAULT_CTOR = default
 #     define DEFAULT_CTOR = default
+#     define DEFAULT_DTOR = default
+#     define DEFAULT_ASSIGN = default
+#  endif
+#  if __has_extension(cxx_deleted_functions)
+#     define DELETED = delete
 #  endif
 #  endif
 #elif defined(__GNUC__) && (__cplusplus >= 201103L) // GCC
 #elif defined(__GNUC__) && (__cplusplus >= 201103L) // GCC
 
 
@@ -178,6 +187,9 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
 // Starting at GCC 4.4
 // Starting at GCC 4.4
 #  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
 #  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
 #  define DEFAULT_CTOR = default
 #  define DEFAULT_CTOR = default
+#  define DEFAULT_DTOR = default
+#  define DEFAULT_ASSIGN = default
+#  define DELETED = delete
 #  endif
 #  endif
 
 
 // Starting at GCC 4.6
 // Starting at GCC 4.6
@@ -200,7 +212,6 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
 #  define FINAL final
 #  define FINAL final
 #  define OVERRIDE override
 #  define OVERRIDE override
 #  define MOVE(x) move(x)
 #  define MOVE(x) move(x)
-#  define DEFAULT_CTOR = default
 #elif defined(_MSC_VER) && _MSC_VER >= 1600 // Visual Studio 2010
 #elif defined(_MSC_VER) && _MSC_VER >= 1600 // Visual Studio 2010
 #  define NOEXCEPT throw()
 #  define NOEXCEPT throw()
 #  define OVERRIDE override
 #  define OVERRIDE override
@@ -209,6 +220,13 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
 #  define MOVE(x) move(x)
 #  define MOVE(x) move(x)
 #endif
 #endif
 
 
+#if defined(_MSC_VER) && _MSC_VER >= 1800 // Visual Studio 2013
+#  define DEFAULT_CTOR = default
+#  define DEFAULT_DTOR = default
+#  define DEFAULT_ASSIGN = default
+#  define DELETED = delete
+#endif
+
 // Fallbacks if features are not supported
 // Fallbacks if features are not supported
 #ifndef CONSTEXPR
 #ifndef CONSTEXPR
 #  define CONSTEXPR INLINE
 #  define CONSTEXPR INLINE
@@ -228,6 +246,18 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
 #ifndef DEFAULT_CTOR
 #ifndef DEFAULT_CTOR
 #  define DEFAULT_CTOR {}
 #  define DEFAULT_CTOR {}
 #endif
 #endif
+#ifndef DEFAULT_DTOR
+#  define DEFAULT_DTOR {}
+#endif
+#ifndef DEFAULT_ASSIGN
+#  define DEFAULT_ASSIGN {return *this;}
+#endif
+#ifndef DELETED
+#  define DELETED {assert(false);}
+#  define DELETED_ASSIGN {assert(false);return *this;}
+#else
+#  define DELETED_ASSIGN DELETED
+#endif
 
 
 
 
 #if !defined(LINK_ALL_STATIC) && defined(EXPORT_TEMPLATES)
 #if !defined(LINK_ALL_STATIC) && defined(EXPORT_TEMPLATES)
@@ -260,10 +290,10 @@ EXPCL_DTOOL void init_memory_hook();
 
 
 // Now redefine some handy macros to hook into the above MemoryHook object.
 // Now redefine some handy macros to hook into the above MemoryHook object.
 #ifndef USE_MEMORY_NOWRAPPERS
 #ifndef USE_MEMORY_NOWRAPPERS
-#define PANDA_MALLOC_SINGLE(size) (memory_hook->heap_alloc_single(size))
+#define PANDA_MALLOC_SINGLE(size) (ASSUME_ALIGNED(memory_hook->heap_alloc_single(size), MEMORY_HOOK_ALIGNMENT))
 #define PANDA_FREE_SINGLE(ptr) memory_hook->heap_free_single(ptr)
 #define PANDA_FREE_SINGLE(ptr) memory_hook->heap_free_single(ptr)
-#define PANDA_MALLOC_ARRAY(size) (memory_hook->heap_alloc_array(size))
-#define PANDA_REALLOC_ARRAY(ptr, size) (memory_hook->heap_realloc_array(ptr, size))
+#define PANDA_MALLOC_ARRAY(size) (ASSUME_ALIGNED(memory_hook->heap_alloc_array(size), MEMORY_HOOK_ALIGNMENT))
+#define PANDA_REALLOC_ARRAY(ptr, size) (ASSUME_ALIGNED(memory_hook->heap_realloc_array(ptr, size), MEMORY_HOOK_ALIGNMENT))
 #define PANDA_FREE_ARRAY(ptr) memory_hook->heap_free_array(ptr)
 #define PANDA_FREE_ARRAY(ptr) memory_hook->heap_free_array(ptr)
 #else
 #else
 #define PANDA_MALLOC_SINGLE(size) ::malloc(size)
 #define PANDA_MALLOC_SINGLE(size) ::malloc(size)

+ 36 - 67
dtool/src/dtoolbase/memoryHook.I

@@ -38,57 +38,9 @@ dec_heap(size_t size) {
  * Returns the global memory alignment.  This is the number of bytes at which
  * Returns the global memory alignment.  This is the number of bytes at which
  * each allocated memory pointer will be aligned.
  * each allocated memory pointer will be aligned.
  */
  */
-INLINE size_t MemoryHook::
+CONSTEXPR size_t MemoryHook::
 get_memory_alignment() {
 get_memory_alignment() {
-#ifdef LINMATH_ALIGN
-  // We require 16-byte alignment of certain structures, to support SSE2.  We
-  // don't strictly have to align *everything*, but it's just easier to do so.
-#ifdef __AVX__
-  // Eigen requires 32-byte alignment when using AVX instructions.
-  const size_t alignment_size = 32;
-#else
-  const size_t alignment_size = 16;
-#endif
-#else
-  // Otherwise, align to two words.  This seems to be pretty standard to the
-  // point where some code may rely on this being the case.
-  const size_t alignment_size = sizeof(void *) * 2;
-#endif
-  return alignment_size;
-}
-
-/**
- * Returns the number of additional bytes that are reserved at the beginning
- * of every allocated block to store a size_t.
- */
-INLINE size_t MemoryHook::
-get_header_reserved_bytes() {
-  // We need to figure out the minimum amount of additional space we need in
-  // order to place a single word at the start of each allocated block, to
-  // store the size of the block.
-
-#ifdef LINMATH_ALIGN
-  // If we're doing SSE2 alignment, we must reserve a full 16-byte block,
-  // since anything less than that will spoil the alignment.
-#ifdef __AVX__
-  // Eigen requires 32-byte alignment when using AVX instructions.
-  static const size_t header_reserved_bytes = 32;
-#else
-  static const size_t header_reserved_bytes = 16;
-#endif
-
-#elif defined(MEMORY_HOOK_DO_ALIGN)
-  // If we're just aligning to words, we reserve a block as big as two words,
-  // to allow us wiggle room to align the word precisely within that block.
-  static const size_t header_reserved_bytes = sizeof(size_t) + sizeof(size_t);
-
-#else
-  // Virtually all allocators align to two words, so we make sure we preserve
-  // that alignment for the benefit of anyone who relies upon that.
-  static const size_t header_reserved_bytes = sizeof(void *) * 2;
-#endif
-
-  return header_reserved_bytes;
+  return MEMORY_HOOK_ALIGNMENT;
 }
 }
 
 
 /**
 /**
@@ -109,6 +61,24 @@ round_up_to_page_size(size_t size) const {
   return  ((size + _page_size - 1) / _page_size) * _page_size;
   return  ((size + _page_size - 1) / _page_size) * _page_size;
 }
 }
 
 
+/**
+ * Given a pointer that was returned by a MemoryHook allocation, returns the
+ * number of bytes that were allocated for it.  Returns 0 if not compiling
+ * with DO_MEMORY_USAGE.
+ */
+INLINE size_t MemoryHook::
+get_ptr_size(void *ptr) {
+#if defined(MEMORY_HOOK_DO_ALIGN)
+  uintptr_t *root = (uintptr_t *)ptr;
+  return (size_t)root[-2];
+#elif defined(DO_MEMORY_USAGE)
+  size_t *root = (size_t *)((char *)ptr - MEMORY_HOOK_ALIGNMENT);
+  return *root;
+#else
+  return 0;
+#endif  // DO_MEMORY_USAGE
+}
+
 /**
 /**
  * Increments the amount of requested size as necessary to accommodate the
  * Increments the amount of requested size as necessary to accommodate the
  * extra data we might piggyback on each allocated block.
  * extra data we might piggyback on each allocated block.
@@ -118,12 +88,13 @@ inflate_size(size_t size) {
 #if defined(MEMORY_HOOK_DO_ALIGN)
 #if defined(MEMORY_HOOK_DO_ALIGN)
   // If we're aligning, we need to request the header size, plus extra bytes
   // If we're aligning, we need to request the header size, plus extra bytes
   // to give us wiggle room to adjust the pointer.
   // to give us wiggle room to adjust the pointer.
-  return size + get_header_reserved_bytes() + get_memory_alignment() - 1;
+  return size + sizeof(uintptr_t) * 2 + MEMORY_HOOK_ALIGNMENT - 1;
 #elif defined(DO_MEMORY_USAGE)
 #elif defined(DO_MEMORY_USAGE)
   // If we're not aligning, but we're tracking memory allocations, we just
   // If we're not aligning, but we're tracking memory allocations, we just
   // need the header size extra (this gives us a place to store the size of
   // need the header size extra (this gives us a place to store the size of
-  // the allocated block).
-  return size + get_header_reserved_bytes();
+  // the allocated block).  However, we do need to make sure that any
+  // alignment guarantee is kept.
+  return size + MEMORY_HOOK_ALIGNMENT;
 #else
 #else
   // If we're not doing any of that, we can just allocate the precise
   // If we're not doing any of that, we can just allocate the precise
   // requested amount.
   // requested amount.
@@ -138,17 +109,17 @@ inflate_size(size_t size) {
 INLINE void *MemoryHook::
 INLINE void *MemoryHook::
 alloc_to_ptr(void *alloc, size_t size) {
 alloc_to_ptr(void *alloc, size_t size) {
 #if defined(MEMORY_HOOK_DO_ALIGN)
 #if defined(MEMORY_HOOK_DO_ALIGN)
-  size_t alignment = get_memory_alignment();
-  // Move the allocated pointer up to the next even alignment.
-  size_t *root = (size_t *)((((size_t)alloc + alignment - 1) / alignment) * alignment);
-  assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < alignment);
-  root[0] = size;
-  root[1] = (size_t)alloc;  // Save the pointer we originally allocated.
-  return (void *)((char *)root + get_header_reserved_bytes());
+  // Add room for two uintptr_t values.
+  uintptr_t *root = (uintptr_t *)((char *)alloc + sizeof(uintptr_t) * 2);
+  // Align this to the requested boundary.
+  root = (uintptr_t *)(((uintptr_t)root + MEMORY_HOOK_ALIGNMENT - 1) & ~(MEMORY_HOOK_ALIGNMENT - 1));
+  root[-2] = size;
+  root[-1] = (uintptr_t)alloc;  // Save the pointer we originally allocated.
+  return (void *)root;
 #elif defined(DO_MEMORY_USAGE)
 #elif defined(DO_MEMORY_USAGE)
   size_t *root = (size_t *)alloc;
   size_t *root = (size_t *)alloc;
   root[0] = size;
   root[0] = size;
-  return (void *)((char *)root + get_header_reserved_bytes());
+  return (void *)((char *)root + MEMORY_HOOK_ALIGNMENT);
 #else
 #else
   return alloc;
   return alloc;
 #endif  // DO_MEMORY_USAGE
 #endif  // DO_MEMORY_USAGE
@@ -161,13 +132,11 @@ alloc_to_ptr(void *alloc, size_t size) {
 INLINE void *MemoryHook::
 INLINE void *MemoryHook::
 ptr_to_alloc(void *ptr, size_t &size) {
 ptr_to_alloc(void *ptr, size_t &size) {
 #if defined(MEMORY_HOOK_DO_ALIGN)
 #if defined(MEMORY_HOOK_DO_ALIGN)
-  size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes());
-  size = root[0];
-  void *alloc = (void *)root[1]; // Get the pointer we originally allocated.
-  assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < get_memory_alignment());
-  return alloc;
+  uintptr_t *root = (uintptr_t *)ptr;
+  size = root[-2];
+  return (void *)root[-1]; // Get the pointer we originally allocated.
 #elif defined(DO_MEMORY_USAGE)
 #elif defined(DO_MEMORY_USAGE)
-  size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes());
+  size_t *root = (size_t *)((char *)ptr - MEMORY_HOOK_ALIGNMENT);
   size = root[0];
   size = root[0];
   return (void *)root;
   return (void *)root;
 #else
 #else

+ 29 - 17
dtool/src/dtoolbase/memoryHook.cxx

@@ -36,6 +36,15 @@
 
 
 #endif  // WIN32
 #endif  // WIN32
 
 
+// Ensure we made the right decisions about the alignment size.
+static_assert(MEMORY_HOOK_ALIGNMENT >= sizeof(size_t),
+              "MEMORY_HOOK_ALIGNMENT should at least be sizeof(size_t)");
+static_assert(MEMORY_HOOK_ALIGNMENT >= sizeof(void *),
+              "MEMORY_HOOK_ALIGNMENT should at least be sizeof(void *)");
+static_assert(MEMORY_HOOK_ALIGNMENT * 8 >= NATIVE_WORDSIZE,
+              "MEMORY_HOOK_ALIGNMENT * 8 should at least be NATIVE_WORDSIZE");
+static_assert((MEMORY_HOOK_ALIGNMENT & (MEMORY_HOOK_ALIGNMENT - 1)) == 0,
+              "MEMORY_HOOK_ALIGNMENT should be a power of two");
 
 
 #if defined(USE_MEMORY_DLMALLOC)
 #if defined(USE_MEMORY_DLMALLOC)
 
 
@@ -49,17 +58,8 @@
 #ifdef _DEBUG
 #ifdef _DEBUG
   #define DEBUG 1
   #define DEBUG 1
 #endif
 #endif
-#ifdef LINMATH_ALIGN
-// drose: We require 16-byte alignment of certain structures, to
-// support SSE2.  We don't strictly have to align *everything*, but
-// it's just easier to do so.
-#ifdef __AVX__
-// Eigen requires 32-byte alignment when using AVX instructions.
-#define MALLOC_ALIGNMENT ((size_t)32U)
-#else
-#define MALLOC_ALIGNMENT ((size_t)16U)
-#endif
-#endif
+// dlmalloc can do the alignment we ask for.
+#define MALLOC_ALIGNMENT MEMORY_HOOK_ALIGNMENT
 
 
 #include "dlmalloc_src.cxx"
 #include "dlmalloc_src.cxx"
 
 
@@ -204,6 +204,7 @@ heap_alloc_single(size_t size) {
 #endif  // DO_MEMORY_USAGE
 #endif  // DO_MEMORY_USAGE
 
 
   void *ptr = alloc_to_ptr(alloc, size);
   void *ptr = alloc_to_ptr(alloc, size);
+  assert(((uintptr_t)ptr % MEMORY_HOOK_ALIGNMENT) == 0);
   assert(ptr >= alloc && (char *)ptr + size <= (char *)alloc + inflated_size);
   assert(ptr >= alloc && (char *)ptr + size <= (char *)alloc + inflated_size);
   return ptr;
   return ptr;
 }
 }
@@ -273,6 +274,7 @@ heap_alloc_array(size_t size) {
 #endif  // DO_MEMORY_USAGE
 #endif  // DO_MEMORY_USAGE
 
 
   void *ptr = alloc_to_ptr(alloc, size);
   void *ptr = alloc_to_ptr(alloc, size);
+  assert(((uintptr_t)ptr % MEMORY_HOOK_ALIGNMENT) == 0);
   assert(ptr >= alloc && (char *)ptr + size <= (char *)alloc + inflated_size);
   assert(ptr >= alloc && (char *)ptr + size <= (char *)alloc + inflated_size);
   return ptr;
   return ptr;
 }
 }
@@ -316,17 +318,27 @@ heap_realloc_array(void *ptr, size_t size) {
 #endif
 #endif
   }
   }
 
 
-  void *ptr1 = alloc_to_ptr(alloc1, size);
-  assert(ptr1 >= alloc1 && (char *)ptr1 + size <= (char *)alloc1 + inflated_size);
-#if defined(MEMORY_HOOK_DO_ALIGN)
-  // We might have to shift the memory to account for the new offset due to
-  // the alignment.
+  // Align this to the requested boundary.
+#ifdef MEMORY_HOOK_DO_ALIGN
+  // This copies the code from alloc_to_ptr, since we can't write the size and
+  // pointer until after we have done the memmove.
+  uintptr_t *root = (uintptr_t *)((char *)alloc1 + sizeof(uintptr_t) * 2);
+  root = (uintptr_t *)(((uintptr_t)root + MEMORY_HOOK_ALIGNMENT - 1) & ~(MEMORY_HOOK_ALIGNMENT - 1));
+  void *ptr1 = (void *)root;
+
   size_t orig_delta = (char *)ptr - (char *)alloc;
   size_t orig_delta = (char *)ptr - (char *)alloc;
   size_t new_delta = (char *)ptr1 - (char *)alloc1;
   size_t new_delta = (char *)ptr1 - (char *)alloc1;
   if (orig_delta != new_delta) {
   if (orig_delta != new_delta) {
     memmove((char *)alloc1 + new_delta, (char *)alloc1 + orig_delta, min(size, orig_size));
     memmove((char *)alloc1 + new_delta, (char *)alloc1 + orig_delta, min(size, orig_size));
   }
   }
-#endif  // MEMORY_HOOK_DO_ALIGN
+
+  root[-2] = size;
+  root[-1] = (uintptr_t)alloc1;  // Save the pointer we originally allocated.
+#else
+  void *ptr1 = alloc_to_ptr(alloc1, size);
+#endif
+  assert(ptr1 >= alloc1 && (char *)ptr1 + size <= (char *)alloc1 + inflated_size);
+  assert(((uintptr_t)ptr1 % MEMORY_HOOK_ALIGNMENT) == 0);
   return ptr1;
   return ptr1;
 }
 }
 
 

+ 19 - 2
dtool/src/dtoolbase/memoryHook.h

@@ -20,6 +20,22 @@
 #include "mutexImpl.h"
 #include "mutexImpl.h"
 #include <map>
 #include <map>
 
 
+#ifdef LINMATH_ALIGN
+// We require 16-byte alignment of certain structures, to support SSE2.  We
+// don't strictly have to align *everything*, but it's just easier to do so.
+#ifdef __AVX__
+#define MEMORY_HOOK_ALIGNMENT 32
+#else
+#define MEMORY_HOOK_ALIGNMENT 16
+#endif
+// Otherwise, align to two words.  This seems to be pretty standard to the
+// point where some code may rely on this being the case.
+#elif defined(IS_OSX) || NATIVE_WORDSIZE >= 64
+#define MEMORY_HOOK_ALIGNMENT 16
+#else
+#define MEMORY_HOOK_ALIGNMENT 8
+#endif
+
 class DeletedBufferChain;
 class DeletedBufferChain;
 
 
 /**
 /**
@@ -52,8 +68,7 @@ public:
 
 
   bool heap_trim(size_t pad);
   bool heap_trim(size_t pad);
 
 
-  INLINE static size_t get_memory_alignment();
-  INLINE static size_t get_header_reserved_bytes();
+  CONSTEXPR static size_t get_memory_alignment();
 
 
   virtual void *mmap_alloc(size_t size, bool allow_exec);
   virtual void *mmap_alloc(size_t size, bool allow_exec);
   virtual void mmap_free(void *ptr, size_t size);
   virtual void mmap_free(void *ptr, size_t size);
@@ -66,6 +81,8 @@ public:
 
 
   virtual void alloc_fail(size_t attempted_size);
   virtual void alloc_fail(size_t attempted_size);
 
 
+  INLINE static size_t get_ptr_size(void *ptr);
+
 private:
 private:
   INLINE static size_t inflate_size(size_t size);
   INLINE static size_t inflate_size(size_t size);
   INLINE static void *alloc_to_ptr(void *alloc, size_t size);
   INLINE static void *alloc_to_ptr(void *alloc, size_t size);

+ 3 - 17
dtool/src/dtoolbase/mutexDummyImpl.I

@@ -14,28 +14,14 @@
 /**
 /**
  *
  *
  */
  */
-INLINE MutexDummyImpl::
-MutexDummyImpl() {
-}
-
-/**
- *
- */
-INLINE MutexDummyImpl::
-~MutexDummyImpl() {
-}
-
-/**
- *
- */
-INLINE void MutexDummyImpl::
+ALWAYS_INLINE void MutexDummyImpl::
 acquire() {
 acquire() {
 }
 }
 
 
 /**
 /**
  *
  *
  */
  */
-INLINE bool MutexDummyImpl::
+ALWAYS_INLINE bool MutexDummyImpl::
 try_acquire() {
 try_acquire() {
   return true;
   return true;
 }
 }
@@ -43,6 +29,6 @@ try_acquire() {
 /**
 /**
  *
  *
  */
  */
-INLINE void MutexDummyImpl::
+ALWAYS_INLINE void MutexDummyImpl::
 release() {
 release() {
 }
 }

+ 9 - 5
dtool/src/dtoolbase/mutexDummyImpl.h

@@ -23,12 +23,16 @@
  */
  */
 class EXPCL_DTOOL MutexDummyImpl {
 class EXPCL_DTOOL MutexDummyImpl {
 public:
 public:
-  INLINE MutexDummyImpl();
-  INLINE ~MutexDummyImpl();
+  CONSTEXPR MutexDummyImpl() DEFAULT_CTOR;
 
 
-  INLINE void acquire();
-  INLINE bool try_acquire();
-  INLINE void release();
+private:
+  MutexDummyImpl(const MutexDummyImpl &copy) DELETED;
+  MutexDummyImpl &operator = (const MutexDummyImpl &copy) DELETED_ASSIGN;
+
+public:
+  ALWAYS_INLINE void acquire();
+  ALWAYS_INLINE bool try_acquire();
+  ALWAYS_INLINE void release();
 };
 };
 
 
 #include "mutexDummyImpl.I"
 #include "mutexDummyImpl.I"

+ 8 - 10
dtool/src/dtoolbase/mutexPosixImpl.I

@@ -14,16 +14,8 @@
 /**
 /**
  *
  *
  */
  */
-INLINE MutexPosixImpl::
-MutexPosixImpl() {
-  TAU_PROFILE("MutexPosixImpl::MutexPosixImpl", " ", TAU_USER);
-  pthread_mutexattr_t attr;
-  pthread_mutexattr_init(&attr);
-  // The symbol PTHREAD_MUTEX_DEFAULT isn't always available?
-  // pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
-  int result = pthread_mutex_init(&_lock, &attr);
-  pthread_mutexattr_destroy(&attr);
-  assert(result == 0);
+CONSTEXPR MutexPosixImpl::
+MutexPosixImpl() NOEXCEPT : _lock(PTHREAD_MUTEX_INITIALIZER) {
 }
 }
 
 
 /**
 /**
@@ -78,6 +70,11 @@ get_posix_lock() {
 /**
 /**
  *
  *
  */
  */
+#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+CONSTEXPR ReMutexPosixImpl::
+ReMutexPosixImpl() NOEXCEPT : _lock(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) {
+}
+#else
 INLINE ReMutexPosixImpl::
 INLINE ReMutexPosixImpl::
 ReMutexPosixImpl() {
 ReMutexPosixImpl() {
   TAU_PROFILE("ReMutexPosixImpl::ReMutexPosixImpl", " ", TAU_USER);
   TAU_PROFILE("ReMutexPosixImpl::ReMutexPosixImpl", " ", TAU_USER);
@@ -88,6 +85,7 @@ ReMutexPosixImpl() {
   pthread_mutexattr_destroy(&attr);
   pthread_mutexattr_destroy(&attr);
   assert(result == 0);
   assert(result == 0);
 }
 }
+#endif
 
 
 /**
 /**
  *
  *

+ 15 - 1
dtool/src/dtoolbase/mutexPosixImpl.h

@@ -28,9 +28,14 @@
  */
  */
 class EXPCL_DTOOL MutexPosixImpl {
 class EXPCL_DTOOL MutexPosixImpl {
 public:
 public:
-  INLINE MutexPosixImpl();
+  CONSTEXPR MutexPosixImpl() NOEXCEPT;
   INLINE ~MutexPosixImpl();
   INLINE ~MutexPosixImpl();
 
 
+private:
+  MutexPosixImpl(const MutexPosixImpl &copy) DELETED;
+  MutexPosixImpl &operator = (const MutexPosixImpl &copy) DELETED_ASSIGN;
+
+public:
   INLINE void acquire();
   INLINE void acquire();
   INLINE bool try_acquire();
   INLINE bool try_acquire();
   INLINE void release();
   INLINE void release();
@@ -47,9 +52,18 @@ private:
  */
  */
 class EXPCL_DTOOL ReMutexPosixImpl {
 class EXPCL_DTOOL ReMutexPosixImpl {
 public:
 public:
+#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+  CONSTEXPR ReMutexPosixImpl() NOEXCEPT;
+#else
   INLINE ReMutexPosixImpl();
   INLINE ReMutexPosixImpl();
+#endif
   INLINE ~ReMutexPosixImpl();
   INLINE ~ReMutexPosixImpl();
 
 
+private:
+  ReMutexPosixImpl(const ReMutexPosixImpl &copy) DELETED;
+  ReMutexPosixImpl &operator = (const ReMutexPosixImpl &copy) DELETED;
+
+public:
   INLINE void acquire();
   INLINE void acquire();
   INLINE bool try_acquire();
   INLINE bool try_acquire();
   INLINE void release();
   INLINE void release();

+ 2 - 10
dtool/src/dtoolbase/mutexSpinlockImpl.I

@@ -14,16 +14,8 @@
 /**
 /**
  *
  *
  */
  */
-INLINE MutexSpinlockImpl::
-MutexSpinlockImpl() {
-  _lock = 0;
-}
-
-/**
- *
- */
-INLINE MutexSpinlockImpl::
-~MutexSpinlockImpl() {
+CONSTEXPR MutexSpinlockImpl::
+MutexSpinlockImpl() : _lock(0) {
 }
 }
 
 
 /**
 /**

+ 6 - 2
dtool/src/dtoolbase/mutexSpinlockImpl.h

@@ -29,9 +29,13 @@
  */
  */
 class EXPCL_DTOOL MutexSpinlockImpl {
 class EXPCL_DTOOL MutexSpinlockImpl {
 public:
 public:
-  INLINE MutexSpinlockImpl();
-  INLINE ~MutexSpinlockImpl();
+  CONSTEXPR MutexSpinlockImpl();
 
 
+private:
+  MutexSpinlockImpl(const MutexSpinlockImpl &copy) DELETED;
+  MutexSpinlockImpl &operator = (const MutexSpinlockImpl &copy) DELETED_ASSIGN;
+
+public:
   INLINE void acquire();
   INLINE void acquire();
   INLINE bool try_acquire();
   INLINE bool try_acquire();
   INLINE void release();
   INLINE void release();

+ 5 - 0
dtool/src/dtoolbase/mutexWin32Impl.h

@@ -31,6 +31,11 @@ public:
   MutexWin32Impl();
   MutexWin32Impl();
   INLINE ~MutexWin32Impl();
   INLINE ~MutexWin32Impl();
 
 
+private:
+  MutexWin32Impl(const MutexWin32Impl &copy) DELETED;
+  MutexWin32Impl &operator = (const MutexWin32Impl &copy) DELETED_ASSIGN;
+
+public:
   INLINE void acquire();
   INLINE void acquire();
   INLINE bool try_acquire();
   INLINE bool try_acquire();
   INLINE void release();
   INLINE void release();

+ 25 - 26
dtool/src/dtoolbase/pallocator.T

@@ -1,20 +1,19 @@
-// Filename: pallocator.T
-// Created by:  drose (05Jun01)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) Carnegie Mellon University.  All rights reserved.
-//
-// All use of this software is subject to the terms of the revised BSD
-// license.  You should have received a copy of this license along
-// with this source code in a file named "LICENSE."
-//
-////////////////////////////////////////////////////////////////////
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file pallocator.T
+ * @author drose
+ * @date 2001-06-05
+ */
 
 
 template<class Type>
 template<class Type>
 INLINE pallocator_single<Type>::
 INLINE pallocator_single<Type>::
-pallocator_single(TypeHandle type_handle) throw() :
+pallocator_single(TypeHandle type_handle) NOEXCEPT :
   _type_handle(type_handle)
   _type_handle(type_handle)
 {
 {
 }
 }
@@ -25,7 +24,8 @@ allocate(TYPENAME pallocator_single<Type>::size_type n, TYPENAME allocator<void>
   TAU_PROFILE("pallocator_single:allocate()", " ", TAU_USER);
   TAU_PROFILE("pallocator_single:allocate()", " ", TAU_USER);
   // This doesn't support allocating arrays.
   // This doesn't support allocating arrays.
   assert(n == 1);
   assert(n == 1);
-  return StaticDeletedChain<Type>::allocate(sizeof(Type), _type_handle);
+  return (Type *)ASSUME_ALIGNED(StaticDeletedChain<Type>::allocate(sizeof(Type), _type_handle),
+                                MEMORY_HOOK_ALIGNMENT);
 }
 }
 
 
 template<class Type>
 template<class Type>
@@ -37,7 +37,7 @@ deallocate(TYPENAME pallocator_single<Type>::pointer p, TYPENAME pallocator_sing
 
 
 template<class Type>
 template<class Type>
 INLINE pallocator_array<Type>::
 INLINE pallocator_array<Type>::
-pallocator_array(TypeHandle type_handle) throw() :
+pallocator_array(TypeHandle type_handle) NOEXCEPT :
   _type_handle(type_handle)
   _type_handle(type_handle)
 {
 {
 }
 }
@@ -47,14 +47,13 @@ INLINE TYPENAME pallocator_array<Type>::pointer pallocator_array<Type>::
 allocate(TYPENAME pallocator_array<Type>::size_type n, TYPENAME allocator<void>::const_pointer) {
 allocate(TYPENAME pallocator_array<Type>::size_type n, TYPENAME allocator<void>::const_pointer) {
   TAU_PROFILE("pallocator_array:allocate()", " ", TAU_USER);
   TAU_PROFILE("pallocator_array:allocate()", " ", TAU_USER);
 #ifdef DO_MEMORY_USAGE
 #ifdef DO_MEMORY_USAGE
-  const size_t header_reserved_bytes = MemoryHook::get_header_reserved_bytes();
   size_t alloc_size = n * sizeof(Type);
   size_t alloc_size = n * sizeof(Type);
-  // We also need to store the total number of bytes we allocated.
-  alloc_size += header_reserved_bytes;
-  _type_handle.inc_memory_usage(TypeHandle::MC_array, alloc_size);
   void *ptr = (TYPENAME pallocator_array<Type>::pointer)PANDA_MALLOC_ARRAY(alloc_size);
   void *ptr = (TYPENAME pallocator_array<Type>::pointer)PANDA_MALLOC_ARRAY(alloc_size);
-  *((size_t *)ptr) = alloc_size;
-  return (TYPENAME pallocator_array<Type>::pointer)(((char *)ptr) + header_reserved_bytes);
+#ifdef _DEBUG
+  assert(alloc_size == MemoryHook::get_ptr_size(ptr));
+#endif
+  _type_handle.inc_memory_usage(TypeHandle::MC_array, alloc_size);
+  return (TYPENAME pallocator_array<Type>::pointer)ASSUME_ALIGNED(ptr, MEMORY_HOOK_ALIGNMENT);
 #else
 #else
   return (TYPENAME pallocator_array<Type>::pointer)PANDA_MALLOC_ARRAY(n * sizeof(Type));
   return (TYPENAME pallocator_array<Type>::pointer)PANDA_MALLOC_ARRAY(n * sizeof(Type));
 #endif  // DO_MEMORY_USAGE
 #endif  // DO_MEMORY_USAGE
@@ -65,10 +64,10 @@ INLINE void pallocator_array<Type>::
 deallocate(TYPENAME pallocator_array<Type>::pointer p, TYPENAME pallocator_array<Type>::size_type) {
 deallocate(TYPENAME pallocator_array<Type>::pointer p, TYPENAME pallocator_array<Type>::size_type) {
   TAU_PROFILE("pallocator_array:deallocate()", " ", TAU_USER);
   TAU_PROFILE("pallocator_array:deallocate()", " ", TAU_USER);
 #ifdef DO_MEMORY_USAGE
 #ifdef DO_MEMORY_USAGE
-  // Now we need to recover the total number of bytes.
-  const size_t header_reserved_bytes = MemoryHook::get_header_reserved_bytes();
-  void *ptr = (void *)((char *)p - header_reserved_bytes);
-  size_t alloc_size = *((size_t *)ptr);
+  // Now we need to recover the total number of bytes.  Fortunately, in the
+  // case of DO_MEMORY_USAGE, MemoryHook already keeps track of this.
+  void *ptr = (void *)p;
+  size_t alloc_size = MemoryHook::get_ptr_size(ptr);
   _type_handle.dec_memory_usage(TypeHandle::MC_array, alloc_size);
   _type_handle.dec_memory_usage(TypeHandle::MC_array, alloc_size);
   PANDA_FREE_ARRAY(ptr);
   PANDA_FREE_ARRAY(ptr);
 #else
 #else

+ 4 - 4
dtool/src/dtoolbase/pallocator.h

@@ -52,11 +52,11 @@ public:
   typedef TYPENAME allocator<Type>::const_reference const_reference;
   typedef TYPENAME allocator<Type>::const_reference const_reference;
   typedef TYPENAME allocator<Type>::size_type size_type;
   typedef TYPENAME allocator<Type>::size_type size_type;
 
 
-  INLINE pallocator_single(TypeHandle type_handle) throw();
+  INLINE pallocator_single(TypeHandle type_handle) NOEXCEPT;
 
 
   // template member functions in VC++ can only be defined in-class.
   // template member functions in VC++ can only be defined in-class.
   template<class U>
   template<class U>
-  INLINE pallocator_single(const pallocator_single<U> &copy) throw() :
+  INLINE pallocator_single(const pallocator_single<U> &copy) NOEXCEPT :
     _type_handle(copy._type_handle) { }
     _type_handle(copy._type_handle) { }
 
 
   INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
   INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
@@ -80,11 +80,11 @@ public:
   typedef TYPENAME allocator<Type>::const_reference const_reference;
   typedef TYPENAME allocator<Type>::const_reference const_reference;
   typedef TYPENAME allocator<Type>::size_type size_type;
   typedef TYPENAME allocator<Type>::size_type size_type;
 
 
-  INLINE pallocator_array(TypeHandle type_handle = TypeHandle::none()) throw();
+  INLINE pallocator_array(TypeHandle type_handle = TypeHandle::none()) NOEXCEPT;
 
 
   // template member functions in VC++ can only be defined in-class.
   // template member functions in VC++ can only be defined in-class.
   template<class U>
   template<class U>
-  INLINE pallocator_array(const pallocator_array<U> &copy) throw() :
+  INLINE pallocator_array(const pallocator_array<U> &copy) NOEXCEPT :
     _type_handle(copy._type_handle) { }
     _type_handle(copy._type_handle) { }
 
 
   INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
   INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);

+ 0 - 1
dtool/src/dtoolbase/pdeque.h

@@ -37,7 +37,6 @@ public:
   typedef pallocator_array<Type> allocator;
   typedef pallocator_array<Type> allocator;
   typedef TYPENAME deque<Type, allocator>::size_type size_type;
   typedef TYPENAME deque<Type, allocator>::size_type size_type;
   pdeque(TypeHandle type_handle = pdeque_type_handle) : deque<Type, pallocator_array<Type> >(allocator(type_handle)) { }
   pdeque(TypeHandle type_handle = pdeque_type_handle) : deque<Type, pallocator_array<Type> >(allocator(type_handle)) { }
-  pdeque(const pdeque<Type> &copy) : deque<Type, pallocator_array<Type> >(copy) { }
   pdeque(size_type n, TypeHandle type_handle = pdeque_type_handle) : deque<Type, pallocator_array<Type> >(n, Type(), allocator(type_handle)) { }
   pdeque(size_type n, TypeHandle type_handle = pdeque_type_handle) : deque<Type, pallocator_array<Type> >(n, Type(), allocator(type_handle)) { }
   pdeque(size_type n, const Type &value, TypeHandle type_handle = pdeque_type_handle) : deque<Type, pallocator_array<Type> >(n, value, allocator(type_handle)) { }
   pdeque(size_type n, const Type &value, TypeHandle type_handle = pdeque_type_handle) : deque<Type, pallocator_array<Type> >(n, value, allocator(type_handle)) { }
 };
 };

+ 0 - 1
dtool/src/dtoolbase/plist.h

@@ -38,7 +38,6 @@ public:
   typedef list<Type, allocator> base_class;
   typedef list<Type, allocator> base_class;
   typedef TYPENAME base_class::size_type size_type;
   typedef TYPENAME base_class::size_type size_type;
   plist(TypeHandle type_handle = plist_type_handle) : base_class(allocator(type_handle)) { }
   plist(TypeHandle type_handle = plist_type_handle) : base_class(allocator(type_handle)) { }
-  plist(const plist<Type> &copy) : base_class(copy) { }
   plist(size_type n, TypeHandle type_handle = plist_type_handle) : base_class(n, Type(), allocator(type_handle)) { }
   plist(size_type n, TypeHandle type_handle = plist_type_handle) : base_class(n, Type(), allocator(type_handle)) { }
   plist(size_type n, const Type &value, TypeHandle type_handle = plist_type_handle) : base_class(n, value, allocator(type_handle)) { }
   plist(size_type n, const Type &value, TypeHandle type_handle = plist_type_handle) : base_class(n, value, allocator(type_handle)) { }
 
 

+ 0 - 4
dtool/src/dtoolbase/pmap.h

@@ -52,7 +52,6 @@ public:
   typedef map<Key, Value, Compare, allocator> base_class;
   typedef map<Key, Value, Compare, allocator> base_class;
 
 
   pmap(TypeHandle type_handle = pmap_type_handle) : base_class(Compare(), allocator(type_handle)) { }
   pmap(TypeHandle type_handle = pmap_type_handle) : base_class(Compare(), allocator(type_handle)) { }
-  pmap(const pmap<Key, Value, Compare> &copy) : base_class(copy) { }
   pmap(const Compare &comp, TypeHandle type_handle = pmap_type_handle) : base_class(comp, allocator(type_handle)) { }
   pmap(const Compare &comp, TypeHandle type_handle = pmap_type_handle) : base_class(comp, allocator(type_handle)) { }
 
 
 #ifdef USE_TAU
 #ifdef USE_TAU
@@ -118,7 +117,6 @@ class pmultimap : public multimap<Key, Value, Compare, pallocator_single<pair<co
 public:
 public:
   typedef pallocator_single<pair<const Key, Value> > allocator;
   typedef pallocator_single<pair<const Key, Value> > allocator;
   pmultimap(TypeHandle type_handle = pmap_type_handle) : multimap<Key, Value, Compare, allocator>(Compare(), allocator(type_handle)) { }
   pmultimap(TypeHandle type_handle = pmap_type_handle) : multimap<Key, Value, Compare, allocator>(Compare(), allocator(type_handle)) { }
-  pmultimap(const pmultimap<Key, Value, Compare> &copy) : multimap<Key, Value, Compare, allocator>(copy) { }
   pmultimap(const Compare &comp, TypeHandle type_handle = pmap_type_handle) : multimap<Key, Value, Compare, allocator>(comp, allocator(type_handle)) { }
   pmultimap(const Compare &comp, TypeHandle type_handle = pmap_type_handle) : multimap<Key, Value, Compare, allocator>(comp, allocator(type_handle)) { }
 };
 };
 
 
@@ -132,7 +130,6 @@ template<class Key, class Value, class Compare = method_hash<Key, less<Key> > >
 class phash_map : public stdext::hash_map<Key, Value, Compare, pallocator_array<pair<const Key, Value> > > {
 class phash_map : public stdext::hash_map<Key, Value, Compare, pallocator_array<pair<const Key, Value> > > {
 public:
 public:
   phash_map() : stdext::hash_map<Key, Value, Compare, pallocator_array<pair<const Key, Value> > >() { }
   phash_map() : stdext::hash_map<Key, Value, Compare, pallocator_array<pair<const Key, Value> > >() { }
-  phash_map(const phash_map<Key, Value, Compare> &copy) : stdext::hash_map<Key, Value, Compare, pallocator_array<pair<const Key, Value> > >(copy) { }
   phash_map(const Compare &comp) : stdext::hash_map<Key, Value, Compare, pallocator_array<pair<const Key, Value> > >(comp) { }
   phash_map(const Compare &comp) : stdext::hash_map<Key, Value, Compare, pallocator_array<pair<const Key, Value> > >(comp) { }
 };
 };
 
 
@@ -145,7 +142,6 @@ template<class Key, class Value, class Compare = method_hash<Key, less<Key> > >
 class phash_multimap : public stdext::hash_multimap<Key, Value, Compare, pallocator_array<pair<const Key, Value> > > {
 class phash_multimap : public stdext::hash_multimap<Key, Value, Compare, pallocator_array<pair<const Key, Value> > > {
 public:
 public:
   phash_multimap() : stdext::hash_multimap<Key, Value, Compare, pallocator_array<pair<const Key, Value> > >() { }
   phash_multimap() : stdext::hash_multimap<Key, Value, Compare, pallocator_array<pair<const Key, Value> > >() { }
-  phash_multimap(const phash_multimap<Key, Value, Compare> &copy) : stdext::hash_multimap<Key, Value, Compare, pallocator_array<pair<const Key, Value> > >(copy) { }
   phash_multimap(const Compare &comp) : stdext::hash_multimap<Key, Value, Compare, pallocator_array<pair<const Key, Value> > >(comp) { }
   phash_multimap(const Compare &comp) : stdext::hash_multimap<Key, Value, Compare, pallocator_array<pair<const Key, Value> > >(comp) { }
 };
 };
 
 

+ 0 - 4
dtool/src/dtoolbase/pset.h

@@ -51,7 +51,6 @@ public:
   typedef pallocator_single<Key> allocator;
   typedef pallocator_single<Key> allocator;
   typedef set<Key, Compare, allocator> base_class;
   typedef set<Key, Compare, allocator> base_class;
   pset(TypeHandle type_handle = pset_type_handle) : base_class(Compare(), allocator(type_handle)) { }
   pset(TypeHandle type_handle = pset_type_handle) : base_class(Compare(), allocator(type_handle)) { }
-  pset(const pset<Key, Compare> &copy) : base_class(copy) { }
   pset(const Compare &comp, TypeHandle type_handle = pset_type_handle) : base_class(comp, type_handle) { }
   pset(const Compare &comp, TypeHandle type_handle = pset_type_handle) : base_class(comp, type_handle) { }
 
 
 #ifdef USE_TAU
 #ifdef USE_TAU
@@ -110,7 +109,6 @@ class pmultiset : public multiset<Key, Compare, pallocator_single<Key> > {
 public:
 public:
   typedef pallocator_single<Key> allocator;
   typedef pallocator_single<Key> allocator;
   pmultiset(TypeHandle type_handle = pset_type_handle) : multiset<Key, Compare, allocator>(Compare(), allocator(type_handle)) { }
   pmultiset(TypeHandle type_handle = pset_type_handle) : multiset<Key, Compare, allocator>(Compare(), allocator(type_handle)) { }
-  pmultiset(const pmultiset<Key, Compare> &copy) : multiset<Key, Compare, allocator>(copy) { }
   pmultiset(const Compare &comp, TypeHandle type_handle = pset_type_handle) : multiset<Key, Compare, allocator>(comp, type_handle) { }
   pmultiset(const Compare &comp, TypeHandle type_handle = pset_type_handle) : multiset<Key, Compare, allocator>(comp, type_handle) { }
 };
 };
 
 
@@ -124,7 +122,6 @@ template<class Key, class Compare = method_hash<Key, less<Key> > >
 class phash_set : public stdext::hash_set<Key, Compare, pallocator_array<Key> > {
 class phash_set : public stdext::hash_set<Key, Compare, pallocator_array<Key> > {
 public:
 public:
   phash_set() : stdext::hash_set<Key, Compare, pallocator_array<Key> >() { }
   phash_set() : stdext::hash_set<Key, Compare, pallocator_array<Key> >() { }
-  phash_set(const phash_set<Key, Compare> &copy) : stdext::hash_set<Key, Compare, pallocator_array<Key> >(copy) { }
   phash_set(const Compare &comp) : stdext::hash_set<Key, Compare, pallocator_array<Key> >(comp) { }
   phash_set(const Compare &comp) : stdext::hash_set<Key, Compare, pallocator_array<Key> >(comp) { }
 };
 };
 
 
@@ -137,7 +134,6 @@ template<class Key, class Compare = method_hash<Key, less<Key> > >
 class phash_multiset : public stdext::hash_multiset<Key, Compare, pallocator_array<Key> > {
 class phash_multiset : public stdext::hash_multiset<Key, Compare, pallocator_array<Key> > {
 public:
 public:
   phash_multiset() : stdext::hash_multiset<Key, Compare, pallocator_array<Key> >() { }
   phash_multiset() : stdext::hash_multiset<Key, Compare, pallocator_array<Key> >() { }
-  phash_multiset(const phash_multiset<Key, Compare> &copy) : stdext::hash_multiset<Key, Compare, pallocator_array<Key> >(copy) { }
   phash_multiset(const Compare &comp) : stdext::hash_multiset<Key, Compare, pallocator_array<Key> >(comp) { }
   phash_multiset(const Compare &comp) : stdext::hash_multiset<Key, Compare, pallocator_array<Key> >(comp) { }
 };
 };
 
 

+ 0 - 15
dtool/src/dtoolbase/pvector.h

@@ -46,24 +46,9 @@ public:
   typedef TYPENAME base_class::size_type size_type;
   typedef TYPENAME base_class::size_type size_type;
 
 
   explicit pvector(TypeHandle type_handle = pvector_type_handle) : base_class(allocator(type_handle)) { }
   explicit pvector(TypeHandle type_handle = pvector_type_handle) : base_class(allocator(type_handle)) { }
-  pvector(const pvector<Type> &copy) : base_class(copy) { }
   explicit pvector(size_type n, TypeHandle type_handle = pvector_type_handle) : base_class(n, Type(), allocator(type_handle)) { }
   explicit pvector(size_type n, TypeHandle type_handle = pvector_type_handle) : base_class(n, Type(), allocator(type_handle)) { }
   explicit pvector(size_type n, const Type &value, TypeHandle type_handle = pvector_type_handle) : base_class(n, value, allocator(type_handle)) { }
   explicit pvector(size_type n, const Type &value, TypeHandle type_handle = pvector_type_handle) : base_class(n, value, allocator(type_handle)) { }
   pvector(const Type *begin, const Type *end, TypeHandle type_handle = pvector_type_handle) : base_class(begin, end, allocator(type_handle)) { }
   pvector(const Type *begin, const Type *end, TypeHandle type_handle = pvector_type_handle) : base_class(begin, end, allocator(type_handle)) { }
-
-#ifdef USE_MOVE_SEMANTICS
-  pvector(pvector<Type> &&from) NOEXCEPT : base_class(move(from)) {};
-
-  pvector<Type> &operator =(pvector<Type> &&from) NOEXCEPT {
-    base_class::operator =(move(from));
-    return *this;
-  }
-#endif
-
-  pvector<Type> &operator =(const pvector<Type> &copy) {
-    base_class::operator =(copy);
-    return *this;
-  }
 };
 };
 
 
 #endif  // USE_STL_ALLOCATOR
 #endif  // USE_STL_ALLOCATOR

+ 0 - 21
dtool/src/dtoolbase/typedObject.I

@@ -11,27 +11,6 @@
  * @date 2001-05-11
  * @date 2001-05-11
  */
  */
 
 
-/**
- *
- */
-INLINE TypedObject::
-TypedObject() {
-}
-
-/**
- *
- */
-INLINE TypedObject::
-TypedObject(const TypedObject &) {
-}
-
-/**
- *
- */
-INLINE void TypedObject::
-operator = (const TypedObject &) {
-}
-
 /**
 /**
  * Returns the internal index number associated with this object's TypeHandle,
  * Returns the internal index number associated with this object's TypeHandle,
  * a unique number for each different type.  This is equivalent to
  * a unique number for each different type.  This is equivalent to

+ 37 - 17
dtool/src/dtoolbase/typedObject.h

@@ -47,29 +47,49 @@
  * What follows are some examples that can be used in new classes that you
  * What follows are some examples that can be used in new classes that you
  * create.
  * create.
  *
  *
- * @par In the class definition (.h file): @code public: static TypeHandle
- * get_class_type() { return _type_handle; } static void init_type() {
- * <<<BaseClassOne>>>::init_type(); <<<BaseClassTwo>>>::init_type();
- * <<<BaseClassN>>>::init_type(); register_type(_type_handle,
- * "<<<ThisClassStringName>>>", <<<BaseClassOne>>>::get_class_type(),
- * <<<BaseClassTwo>>>::get_class_type(), <<<BaseClassN>>>::get_class_type());
- * } virtual TypeHandle get_type() const { return get_class_type(); } virtual
- * TypeHandle force_init_type() {init_type(); return get_class_type();}
+ * @par In the class definition (.h file):
+ * @code
+ * public:
+ *   static TypeHandle get_class_type() {
+ *     return _type_handle;
+ *   }
+ *   static void init_type() {
+ *     <<<BaseClassOne>>>::init_type();
+ *     <<<BaseClassTwo>>>::init_type();
+ *     <<<BaseClassN>>>::init_type();
+ *     register_type(_type_handle, "<<<ThisClassStringName>>>",
+ *                   <<<BaseClassOne>>>::get_class_type(),
+ *                   <<<BaseClassTwo>>>::get_class_type(),
+ *                   <<<BaseClassN>>>::get_class_type());
+ *   }
+ *   virtual TypeHandle get_type() const {
+ *     return get_class_type();
+ *   }
+ *   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
  *
  *
- * private: static TypeHandle _type_handle; @endcode
+ * private:
+ *   static TypeHandle _type_handle;
+ * @endcode
  *
  *
- * @par In the class .cxx file: @code TypeHandle
- * <<<ThisClassStringName>>>::_type_handle; @endcode
+ * @par In the class .cxx file:
+ * @code
+ * TypeHandle <<<ThisClassStringName>>>::_type_handle;
+ * @endcode
  *
  *
- * @par In the class config_<<<PackageName>>>.cxx file: @code
- * ConfigureFn(config_<<<PackageName>>>) { <<<ClassOne>>>::init_type();
- * <<<ClassTwo>>>::init_type(); <<<ClassN>>>::init_type(); } @endcode
+ * @par In the class config_<<<PackageName>>>.cxx file:
+ * @code
+ * ConfigureFn(config_<<<PackageName>>>) {
+ *   <<<ClassOne>>>::init_type();
+ *   <<<ClassTwo>>>::init_type();
+ *   <<<ClassN>>>::init_type();
+ * }
+ * @endcode
  */
  */
 class EXPCL_DTOOL TypedObject : public MemoryBase {
 class EXPCL_DTOOL TypedObject : public MemoryBase {
 public:
 public:
-  INLINE TypedObject();
-  INLINE TypedObject(const TypedObject &copy);
-  INLINE void operator = (const TypedObject &copy);
+  INLINE TypedObject() DEFAULT_CTOR;
+  INLINE TypedObject(const TypedObject &copy) DEFAULT_CTOR;
+  INLINE TypedObject &operator = (const TypedObject &copy) DEFAULT_ASSIGN;
 
 
 PUBLISHED:
 PUBLISHED:
   // A virtual destructor is just a good idea.
   // A virtual destructor is just a good idea.

+ 10 - 1
dtool/src/interrogate/functionRemap.cxx

@@ -791,6 +791,15 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
     _args_type = InterfaceMaker::AT_single_arg;
     _args_type = InterfaceMaker::AT_single_arg;
   } else {
   } else {
     _args_type = InterfaceMaker::AT_varargs;
     _args_type = InterfaceMaker::AT_varargs;
+
+    // If the arguments are named "args" and "kwargs", we will be directly
+    // passing the argument tuples to the function.
+    if (_parameters.size() == first_param + 2 &&
+        _parameters[first_param]._name == "args" &&
+        (_parameters[first_param + 1]._name == "kwargs" ||
+          _parameters[first_param + 1]._name == "kwds")) {
+      _flags |= F_explicit_args;
+    }
   }
   }
 
 
   switch (_type) {
   switch (_type) {
@@ -890,7 +899,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
       if (_args_type == InterfaceMaker::AT_varargs) {
       if (_args_type == InterfaceMaker::AT_varargs) {
         // Every other method can take keyword arguments, if they take more
         // Every other method can take keyword arguments, if they take more
         // than one argument.
         // than one argument.
-        _args_type = InterfaceMaker::AT_keyword_args;
+        _args_type |= InterfaceMaker::AT_keyword_args;
       }
       }
     }
     }
     break;
     break;

+ 1 - 0
dtool/src/interrogate/functionRemap.h

@@ -100,6 +100,7 @@ public:
     F_coerce_constructor = 0x1000,
     F_coerce_constructor = 0x1000,
     F_divide_float       = 0x2000,
     F_divide_float       = 0x2000,
     F_hash               = 0x4000,
     F_hash               = 0x4000,
+    F_explicit_args      = 0x8000,
   };
   };
 
 
   typedef vector<Parameter> Parameters;
   typedef vector<Parameter> Parameters;

+ 32 - 11
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -3453,7 +3453,13 @@ write_function_for_name(ostream &out, Object *obj,
     max_required_args = collapse_default_remaps(map_sets, max_required_args);
     max_required_args = collapse_default_remaps(map_sets, max_required_args);
   }
   }
 
 
-  if (map_sets.size() > 1 && (args_type == AT_varargs || args_type == AT_keyword_args)) {
+  if (remap->_flags & FunctionRemap::F_explicit_args) {
+    // We have a remap that wants to handle the wrapper itself.
+    string expected_params;
+    write_function_instance(out, remap, 0, 0, expected_params, 2, true, true,
+                            args_type, return_flags);
+
+  } else if (map_sets.size() > 1 && (args_type == AT_varargs || args_type == AT_keyword_args)) {
     switch (args_type) {
     switch (args_type) {
     case AT_keyword_args:
     case AT_keyword_args:
       indent(out, 2) << "int parameter_count = (int)PyTuple_Size(args);\n";
       indent(out, 2) << "int parameter_count = (int)PyTuple_Size(args);\n";
@@ -4536,19 +4542,23 @@ write_function_instance(ostream &out, FunctionRemap *remap,
   expected_params += methodNameFromCppName(remap, "", false);
   expected_params += methodNameFromCppName(remap, "", false);
   expected_params += "(";
   expected_params += "(";
 
 
-  int num_params = max_num_args;
-  if (remap->_has_this) {
-    num_params += 1;
-  }
-  if (num_params > (int)remap->_parameters.size()) {
-    // Limit to how many parameters this remap actually has.
-    num_params = (int)remap->_parameters.size();
-    max_num_args = num_params;
+  int num_params = 0;
+
+  if ((remap->_flags & FunctionRemap::F_explicit_args) == 0) {
+    num_params = max_num_args;
     if (remap->_has_this) {
     if (remap->_has_this) {
-      --max_num_args;
+      num_params += 1;
     }
     }
+    if (num_params > (int)remap->_parameters.size()) {
+      // Limit to how many parameters this remap actually has.
+      num_params = (int)remap->_parameters.size();
+      max_num_args = num_params;
+      if (remap->_has_this) {
+        --max_num_args;
+      }
+    }
+    nassertv(num_params <= (int)remap->_parameters.size());
   }
   }
-  nassertv(num_params <= (int)remap->_parameters.size());
 
 
   bool only_pyobjects = true;
   bool only_pyobjects = true;
 
 
@@ -4584,6 +4594,17 @@ write_function_instance(ostream &out, FunctionRemap *remap,
     }
     }
   }
   }
 
 
+  if (remap->_flags & FunctionRemap::F_explicit_args) {
+    // The function handles the arguments by itself.
+    expected_params += "*args";
+    pexprs.push_back("args");
+    if (args_type == AT_keyword_args) {
+      expected_params += ", **kwargs";
+      pexprs.push_back("kwds");
+    }
+    num_params = 0;
+  }
+
   // Now convert (the rest of the) actual arguments, one by one.
   // Now convert (the rest of the) actual arguments, one by one.
   for (; pn < num_params; ++pn) {
   for (; pn < num_params; ++pn) {
     ParameterRemap *param = remap->_parameters[pn]._remap;
     ParameterRemap *param = remap->_parameters[pn]._remap;

+ 3 - 0
dtool/src/prc/streamWrapper.h

@@ -25,6 +25,9 @@ class EXPCL_DTOOLCONFIG StreamWrapperBase {
 protected:
 protected:
   INLINE StreamWrapperBase();
   INLINE StreamWrapperBase();
 
 
+private:
+  INLINE StreamWrapperBase(const StreamWrapperBase &copy) DELETED;
+
 PUBLISHED:
 PUBLISHED:
   INLINE void acquire();
   INLINE void acquire();
   INLINE void release();
   INLINE void release();

+ 1 - 1
dtool/src/prckeys/makePrcKey.cxx

@@ -161,7 +161,7 @@ write_public_keys(Filename outfile) {
       }
       }
 
 
       output_c_string(out, "prc_pubkey", i, mbio);
       output_c_string(out, "prc_pubkey", i, mbio);
-      BIO_reset(mbio);
+      (void)BIO_reset(mbio);
       out << "\n";
       out << "\n";
     }
     }
   }
   }

+ 14 - 0
dtool/src/pystub/pystub.cxx

@@ -90,6 +90,7 @@ extern "C" {
   EXPCL_PYSTUB int PyModule_AddObject(...);
   EXPCL_PYSTUB int PyModule_AddObject(...);
   EXPCL_PYSTUB int PyModule_AddStringConstant(...);
   EXPCL_PYSTUB int PyModule_AddStringConstant(...);
   EXPCL_PYSTUB int PyModule_Create2(...);
   EXPCL_PYSTUB int PyModule_Create2(...);
+  EXPCL_PYSTUB int PyModule_Create2TraceRefs(...);
   EXPCL_PYSTUB int PyNumber_Check(...);
   EXPCL_PYSTUB int PyNumber_Check(...);
   EXPCL_PYSTUB int PyNumber_Float(...);
   EXPCL_PYSTUB int PyNumber_Float(...);
   EXPCL_PYSTUB int PyNumber_Int(...);
   EXPCL_PYSTUB int PyNumber_Int(...);
@@ -175,6 +176,7 @@ extern "C" {
   EXPCL_PYSTUB int Py_InitModule4(...);
   EXPCL_PYSTUB int Py_InitModule4(...);
   EXPCL_PYSTUB int Py_InitModule4_64(...);
   EXPCL_PYSTUB int Py_InitModule4_64(...);
   EXPCL_PYSTUB int Py_InitModule4TraceRefs(...);
   EXPCL_PYSTUB int Py_InitModule4TraceRefs(...);
+  EXPCL_PYSTUB int Py_InitModule4TraceRefs_64(...);
   EXPCL_PYSTUB int _PyArg_ParseTuple_SizeT(...);
   EXPCL_PYSTUB int _PyArg_ParseTuple_SizeT(...);
   EXPCL_PYSTUB int _PyArg_ParseTupleAndKeywords_SizeT(...);
   EXPCL_PYSTUB int _PyArg_ParseTupleAndKeywords_SizeT(...);
   EXPCL_PYSTUB int _PyArg_Parse_SizeT(...);
   EXPCL_PYSTUB int _PyArg_Parse_SizeT(...);
@@ -184,9 +186,14 @@ extern "C" {
   EXPCL_PYSTUB int _PyObject_Del(...);
   EXPCL_PYSTUB int _PyObject_Del(...);
   EXPCL_PYSTUB int _PyUnicode_AsString(...);
   EXPCL_PYSTUB int _PyUnicode_AsString(...);
   EXPCL_PYSTUB int _PyUnicode_AsStringAndSize(...);
   EXPCL_PYSTUB int _PyUnicode_AsStringAndSize(...);
+  EXPCL_PYSTUB int _Py_AddToAllObjects(...);
   EXPCL_PYSTUB int _Py_BuildValue_SizeT(...);
   EXPCL_PYSTUB int _Py_BuildValue_SizeT(...);
   EXPCL_PYSTUB int _Py_Dealloc(...);
   EXPCL_PYSTUB int _Py_Dealloc(...);
+  EXPCL_PYSTUB int _Py_ForgetReference(...);
   EXPCL_PYSTUB int _Py_NegativeRefcount(...);
   EXPCL_PYSTUB int _Py_NegativeRefcount(...);
+  EXPCL_PYSTUB int _Py_NewReference(...);
+  EXPCL_PYSTUB int _Py_PrintReferenceAddresses(...);
+  EXPCL_PYSTUB int _Py_PrintReferences(...);
   EXPCL_PYSTUB int _Py_RefTotal(...);
   EXPCL_PYSTUB int _Py_RefTotal(...);
 
 
   EXPCL_PYSTUB void Py_Initialize();
   EXPCL_PYSTUB void Py_Initialize();
@@ -292,6 +299,7 @@ int PyModule_AddIntConstant(...) { return 0; };
 int PyModule_AddObject(...) { return 0; };
 int PyModule_AddObject(...) { return 0; };
 int PyModule_AddStringConstant(...) { return 0; };
 int PyModule_AddStringConstant(...) { return 0; };
 int PyModule_Create2(...) { return 0; };
 int PyModule_Create2(...) { return 0; };
+int PyModule_Create2TraceRefs(...) { return 0; };
 int PyNumber_Check(...) { return 0; }
 int PyNumber_Check(...) { return 0; }
 int PyNumber_Float(...) { return 0; }
 int PyNumber_Float(...) { return 0; }
 int PyNumber_Int(...) { return 0; }
 int PyNumber_Int(...) { return 0; }
@@ -377,6 +385,7 @@ int Py_BuildValue(...) { return 0; }
 int Py_InitModule4(...) { return 0; }
 int Py_InitModule4(...) { return 0; }
 int Py_InitModule4_64(...) { return 0; }
 int Py_InitModule4_64(...) { return 0; }
 int Py_InitModule4TraceRefs(...) { return 0; };
 int Py_InitModule4TraceRefs(...) { return 0; };
+int Py_InitModule4TraceRefs_64(...) { return 0; };
 int _PyArg_ParseTuple_SizeT(...) { return 0; };
 int _PyArg_ParseTuple_SizeT(...) { return 0; };
 int _PyArg_ParseTupleAndKeywords_SizeT(...) { return 0; };
 int _PyArg_ParseTupleAndKeywords_SizeT(...) { return 0; };
 int _PyArg_Parse_SizeT(...) { return 0; };
 int _PyArg_Parse_SizeT(...) { return 0; };
@@ -386,9 +395,14 @@ int _PyObject_DebugFree(...) { return 0; };
 int _PyObject_Del(...) { return 0; };
 int _PyObject_Del(...) { return 0; };
 int _PyUnicode_AsString(...) { return 0; };
 int _PyUnicode_AsString(...) { return 0; };
 int _PyUnicode_AsStringAndSize(...) { return 0; };
 int _PyUnicode_AsStringAndSize(...) { return 0; };
+int _Py_AddToAllObjects(...) { return 0; };
 int _Py_BuildValue_SizeT(...) { return 0; };
 int _Py_BuildValue_SizeT(...) { return 0; };
 int _Py_Dealloc(...) { return 0; };
 int _Py_Dealloc(...) { return 0; };
+int _Py_ForgetReference(...) { return 0; };
 int _Py_NegativeRefcount(...) { return 0; };
 int _Py_NegativeRefcount(...) { return 0; };
+int _Py_NewReference(...) { return 0; };
+int _Py_PrintReferenceAddresses(...) { return 0; };
+int _Py_PrintReferences(...) { return 0; };
 int _Py_RefTotal(...) { return 0; };
 int _Py_RefTotal(...) { return 0; };
 
 
 // We actually might call this one.
 // We actually might call this one.

+ 145 - 128
makepanda/makepanda.py

@@ -81,7 +81,7 @@ PkgListSet(["PYTHON", "DIRECT",                        # Python support
   "ODE", "PHYSX", "BULLET", "PANDAPHYSICS",            # Physics
   "ODE", "PHYSX", "BULLET", "PANDAPHYSICS",            # Physics
   "SPEEDTREE",                                         # SpeedTree
   "SPEEDTREE",                                         # SpeedTree
   "ZLIB", "PNG", "JPEG", "TIFF", "OPENEXR", "SQUISH", "FREETYPE", # 2D Formats support
   "ZLIB", "PNG", "JPEG", "TIFF", "OPENEXR", "SQUISH", "FREETYPE", # 2D Formats support
-  ] + MAYAVERSIONS + MAXVERSIONS + [ "FCOLLADA", "ASSIMP", # 3D Formats support
+  ] + MAYAVERSIONS + MAXVERSIONS + [ "FCOLLADA", "ASSIMP", "EGG", # 3D Formats support
   "VRPN", "OPENSSL",                                   # Transport
   "VRPN", "OPENSSL",                                   # Transport
   "FFTW",                                              # Algorithm helpers
   "FFTW",                                              # Algorithm helpers
   "ARTOOLKIT", "OPENCV", "DIRECTCAM", "VISION",        # Augmented Reality
   "ARTOOLKIT", "OPENCV", "DIRECTCAM", "VISION",        # Augmented Reality
@@ -840,7 +840,7 @@ if (COMPILER=="GCC"):
             if not RTDIST:
             if not RTDIST:
                 # We don't link anything in the SDK with libpython.
                 # We don't link anything in the SDK with libpython.
                 python_lib = ""
                 python_lib = ""
-            SmartPkgEnable("PYTHON", "", python_lib, (SDK["PYTHONVERSION"], SDK["PYTHONVERSION"] + "/Python.h"), tool = SDK["PYTHONVERSION"] + "-config")
+            SmartPkgEnable("PYTHON", "", python_lib, (SDK["PYTHONVERSION"], SDK["PYTHONVERSION"] + "/Python.h"))
 
 
     SmartPkgEnable("OPENSSL",   "openssl",   ("ssl", "crypto"), ("openssl/ssl.h", "openssl/crypto.h"))
     SmartPkgEnable("OPENSSL",   "openssl",   ("ssl", "crypto"), ("openssl/ssl.h", "openssl/crypto.h"))
     SmartPkgEnable("ZLIB",      "zlib",      ("z"), "zlib.h")
     SmartPkgEnable("ZLIB",      "zlib",      ("z"), "zlib.h")
@@ -2235,7 +2235,6 @@ DTOOL_CONFIG=[
     ("HAVE_NET",                       'UNDEF',                  'UNDEF'),
     ("HAVE_NET",                       'UNDEF',                  'UNDEF'),
     ("WANT_NATIVE_NET",                '1',                      '1'),
     ("WANT_NATIVE_NET",                '1',                      '1'),
     ("SIMULATE_NETWORK_DELAY",         'UNDEF',                  'UNDEF'),
     ("SIMULATE_NETWORK_DELAY",         'UNDEF',                  'UNDEF'),
-    ("HAVE_EGG",                       '1',                      '1'),
     ("HAVE_CG",                        'UNDEF',                  'UNDEF'),
     ("HAVE_CG",                        'UNDEF',                  'UNDEF'),
     ("HAVE_CGGL",                      'UNDEF',                  'UNDEF'),
     ("HAVE_CGGL",                      'UNDEF',                  'UNDEF'),
     ("HAVE_CGDX9",                     'UNDEF',                  'UNDEF'),
     ("HAVE_CGDX9",                     'UNDEF',                  'UNDEF'),
@@ -2711,7 +2710,8 @@ if not PkgSkip("VISION"):
     panda_modules.append('vision')
     panda_modules.append('vision')
 if not PkgSkip("SKEL"):
 if not PkgSkip("SKEL"):
     panda_modules.append('skel')
     panda_modules.append('skel')
-panda_modules.append('egg')
+if not PkgSkip("EGG"):
+    panda_modules.append('egg')
 if not PkgSkip("AWESOMIUM"):
 if not PkgSkip("AWESOMIUM"):
     panda_modules.append('awesomium')
     panda_modules.append('awesomium')
 if not PkgSkip("ODE"):
 if not PkgSkip("ODE"):
@@ -3065,15 +3065,17 @@ CopyAllHeaders('panda/src/downloadertools')
 CopyAllHeaders('panda/src/windisplay')
 CopyAllHeaders('panda/src/windisplay')
 CopyAllHeaders('panda/src/dxgsg9')
 CopyAllHeaders('panda/src/dxgsg9')
 CopyAllHeaders('panda/metalibs/pandadx9')
 CopyAllHeaders('panda/metalibs/pandadx9')
-CopyAllHeaders('panda/src/egg')
-CopyAllHeaders('panda/src/egg2pg')
+if not PkgSkip("EGG"):
+    CopyAllHeaders('panda/src/egg')
+    CopyAllHeaders('panda/src/egg2pg')
 CopyAllHeaders('panda/src/framework')
 CopyAllHeaders('panda/src/framework')
 CopyAllHeaders('panda/metalibs/pandafx')
 CopyAllHeaders('panda/metalibs/pandafx')
 CopyAllHeaders('panda/src/glstuff')
 CopyAllHeaders('panda/src/glstuff')
 CopyAllHeaders('panda/src/glgsg')
 CopyAllHeaders('panda/src/glgsg')
 CopyAllHeaders('panda/src/glesgsg')
 CopyAllHeaders('panda/src/glesgsg')
 CopyAllHeaders('panda/src/gles2gsg')
 CopyAllHeaders('panda/src/gles2gsg')
-CopyAllHeaders('panda/metalibs/pandaegg')
+if not PkgSkip("EGG"):
+    CopyAllHeaders('panda/metalibs/pandaegg')
 if GetTarget() == 'windows':
 if GetTarget() == 'windows':
     CopyAllHeaders('panda/src/wgldisplay')
     CopyAllHeaders('panda/src/wgldisplay')
 elif GetTarget() == 'darwin':
 elif GetTarget() == 'darwin':
@@ -4462,7 +4464,7 @@ if GetTarget() == 'windows' and PkgSkip("DX9")==0 and not RUNTIME:
 # DIRECTORY: panda/src/egg/
 # DIRECTORY: panda/src/egg/
 #
 #
 
 
-if (not RUNTIME):
+if not RUNTIME and not PkgSkip("EGG"):
   OPTS=['DIR:panda/src/egg', 'BUILDING:PANDAEGG', 'ZLIB', 'BISONPREFIX_eggyy', 'FLEXDASHI']
   OPTS=['DIR:panda/src/egg', 'BUILDING:PANDAEGG', 'ZLIB', 'BISONPREFIX_eggyy', 'FLEXDASHI']
   CreateFile(GetOutputDir()+"/include/parser.h")
   CreateFile(GetOutputDir()+"/include/parser.h")
   TargetAdd('p3egg_parser.obj', opts=OPTS, input='parser.yxx')
   TargetAdd('p3egg_parser.obj', opts=OPTS, input='parser.yxx')
@@ -4483,7 +4485,7 @@ if (not RUNTIME):
 # DIRECTORY: panda/src/egg2pg/
 # DIRECTORY: panda/src/egg2pg/
 #
 #
 
 
-if (not RUNTIME):
+if not RUNTIME and not PkgSkip("EGG"):
   OPTS=['DIR:panda/src/egg2pg', 'BUILDING:PANDAEGG']
   OPTS=['DIR:panda/src/egg2pg', 'BUILDING:PANDAEGG']
   TargetAdd('p3egg2pg_composite1.obj', opts=OPTS, input='p3egg2pg_composite1.cxx')
   TargetAdd('p3egg2pg_composite1.obj', opts=OPTS, input='p3egg2pg_composite1.cxx')
   TargetAdd('p3egg2pg_composite2.obj', opts=OPTS, input='p3egg2pg_composite2.cxx')
   TargetAdd('p3egg2pg_composite2.obj', opts=OPTS, input='p3egg2pg_composite2.cxx')
@@ -4502,11 +4504,13 @@ if (not RUNTIME):
   deps = []
   deps = []
   # Framework wants to link in a renderer when building statically, so tell it what is available.
   # Framework wants to link in a renderer when building statically, so tell it what is available.
   if GetLinkAllStatic():
   if GetLinkAllStatic():
-    deps = ['dtool_have_gl.dat', 'dtool_have_tinydisplay.dat']
+    deps = ['dtool_have_gl.dat', 'dtool_have_tinydisplay.dat', 'dtool_have_egg.dat']
     if not PkgSkip("GL"):
     if not PkgSkip("GL"):
       DefSymbol("FRAMEWORK", "HAVE_GL")
       DefSymbol("FRAMEWORK", "HAVE_GL")
     if not PkgSkip("TINYDISPLAY"):
     if not PkgSkip("TINYDISPLAY"):
       DefSymbol("FRAMEWORK", "HAVE_TINYDISPLAY")
       DefSymbol("FRAMEWORK", "HAVE_TINYDISPLAY")
+    if not PkgSkip("EGG"):
+      DefSymbol("FRAMEWORK", "HAVE_EGG")
 
 
   OPTS=['DIR:panda/src/framework', 'BUILDING:FRAMEWORK', 'FRAMEWORK']
   OPTS=['DIR:panda/src/framework', 'BUILDING:FRAMEWORK', 'FRAMEWORK']
   TargetAdd('p3framework_composite1.obj', opts=OPTS, input='p3framework_composite1.cxx', dep=deps)
   TargetAdd('p3framework_composite1.obj', opts=OPTS, input='p3framework_composite1.cxx', dep=deps)
@@ -4545,7 +4549,7 @@ if (not RUNTIME and PkgSkip("GLES2")==0):
 # DIRECTORY: panda/metalibs/pandaegg/
 # DIRECTORY: panda/metalibs/pandaegg/
 #
 #
 
 
-if (not RUNTIME):
+if not RUNTIME and not PkgSkip("EGG"):
   OPTS=['DIR:panda/metalibs/pandaegg', 'DIR:panda/src/egg', 'BUILDING:PANDAEGG']
   OPTS=['DIR:panda/metalibs/pandaegg', 'DIR:panda/src/egg', 'BUILDING:PANDAEGG']
   TargetAdd('pandaegg_pandaegg.obj', opts=OPTS, input='pandaegg.cxx')
   TargetAdd('pandaegg_pandaegg.obj', opts=OPTS, input='pandaegg.cxx')
 
 
@@ -4915,7 +4919,8 @@ if (not RTDIST and not RUNTIME and PkgSkip("PVIEW")==0 and GetTarget() != 'andro
   TargetAdd('pview_pview.obj', opts=OPTS, input='pview.cxx')
   TargetAdd('pview_pview.obj', opts=OPTS, input='pview.cxx')
   TargetAdd('pview.exe', input='pview_pview.obj')
   TargetAdd('pview.exe', input='pview_pview.obj')
   TargetAdd('pview.exe', input='libp3framework.dll')
   TargetAdd('pview.exe', input='libp3framework.dll')
-  TargetAdd('pview.exe', input='libpandaegg.dll')
+  if not PkgSkip("EGG"):
+    TargetAdd('pview.exe', input='libpandaegg.dll')
   TargetAdd('pview.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('pview.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('pview.exe', opts=['ADVAPI', 'WINSOCK2', 'WINSHELL'])
   TargetAdd('pview.exe', opts=['ADVAPI', 'WINSOCK2', 'WINSHELL'])
 
 
@@ -4941,7 +4946,8 @@ if (not RUNTIME and GetTarget() == 'android'):
     TargetAdd('pview.exe', input='android_main.obj')
     TargetAdd('pview.exe', input='android_main.obj')
     TargetAdd('pview.exe', input='pview_pview.obj')
     TargetAdd('pview.exe', input='pview_pview.obj')
     TargetAdd('pview.exe', input='libp3framework.dll')
     TargetAdd('pview.exe', input='libp3framework.dll')
-    TargetAdd('pview.exe', input='libpandaegg.dll')
+    if not PkgSkip("EGG"):
+      TargetAdd('pview.exe', input='libpandaegg.dll')
     TargetAdd('pview.exe', input='libp3android.dll')
     TargetAdd('pview.exe', input='libp3android.dll')
     TargetAdd('pview.exe', input=COMMON_PANDA_LIBS)
     TargetAdd('pview.exe', input=COMMON_PANDA_LIBS)
     TargetAdd('AndroidManifest.xml', opts=OPTS, input='pview_manifest.xml')
     TargetAdd('AndroidManifest.xml', opts=OPTS, input='pview_manifest.xml')
@@ -5495,7 +5501,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/converter/
 # DIRECTORY: pandatool/src/converter/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/converter']
   OPTS=['DIR:pandatool/src/converter']
   TargetAdd('p3converter_somethingToEggConverter.obj', opts=OPTS, input='somethingToEggConverter.cxx')
   TargetAdd('p3converter_somethingToEggConverter.obj', opts=OPTS, input='somethingToEggConverter.cxx')
   TargetAdd('p3converter_eggToSomethingConverter.obj', opts=OPTS, input='eggToSomethingConverter.cxx')
   TargetAdd('p3converter_eggToSomethingConverter.obj', opts=OPTS, input='eggToSomethingConverter.cxx')
@@ -5506,7 +5512,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/progbase/
 # DIRECTORY: pandatool/src/progbase/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/progbase', 'ZLIB']
   OPTS=['DIR:pandatool/src/progbase', 'ZLIB']
   TargetAdd('p3progbase_composite1.obj', opts=OPTS, input='p3progbase_composite1.cxx')
   TargetAdd('p3progbase_composite1.obj', opts=OPTS, input='p3progbase_composite1.cxx')
   TargetAdd('libp3progbase.lib', input='p3progbase_composite1.obj')
   TargetAdd('libp3progbase.lib', input='p3progbase_composite1.obj')
@@ -5515,7 +5521,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/eggbase/
 # DIRECTORY: pandatool/src/eggbase/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/eggbase']
   OPTS=['DIR:pandatool/src/eggbase']
   TargetAdd('p3eggbase_composite1.obj', opts=OPTS, input='p3eggbase_composite1.cxx')
   TargetAdd('p3eggbase_composite1.obj', opts=OPTS, input='p3eggbase_composite1.cxx')
   TargetAdd('libp3eggbase.lib', input='p3eggbase_composite1.obj')
   TargetAdd('libp3eggbase.lib', input='p3eggbase_composite1.obj')
@@ -5524,31 +5530,31 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/bam/
 # DIRECTORY: pandatool/src/bam/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/bam']
   OPTS=['DIR:pandatool/src/bam']
   TargetAdd('bam-info_bamInfo.obj', opts=OPTS, input='bamInfo.cxx')
   TargetAdd('bam-info_bamInfo.obj', opts=OPTS, input='bamInfo.cxx')
   TargetAdd('bam-info.exe', input='bam-info_bamInfo.obj')
   TargetAdd('bam-info.exe', input='bam-info_bamInfo.obj')
   TargetAdd('bam-info.exe', input='libp3progbase.lib')
   TargetAdd('bam-info.exe', input='libp3progbase.lib')
   TargetAdd('bam-info.exe', input='libp3pandatoolbase.lib')
   TargetAdd('bam-info.exe', input='libp3pandatoolbase.lib')
-  TargetAdd('bam-info.exe', input='libpandaegg.dll')
   TargetAdd('bam-info.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('bam-info.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('bam-info.exe', opts=['ADVAPI', 'FFTW'])
   TargetAdd('bam-info.exe', opts=['ADVAPI', 'FFTW'])
 
 
-  TargetAdd('bam2egg_bamToEgg.obj', opts=OPTS, input='bamToEgg.cxx')
-  TargetAdd('bam2egg.exe', input='bam2egg_bamToEgg.obj')
-  TargetAdd('bam2egg.exe', input=COMMON_EGG2X_LIBS)
-  TargetAdd('bam2egg.exe', opts=['ADVAPI',  'FFTW'])
+  if not PkgSkip("EGG"):
+    TargetAdd('bam2egg_bamToEgg.obj', opts=OPTS, input='bamToEgg.cxx')
+    TargetAdd('bam2egg.exe', input='bam2egg_bamToEgg.obj')
+    TargetAdd('bam2egg.exe', input=COMMON_EGG2X_LIBS)
+    TargetAdd('bam2egg.exe', opts=['ADVAPI',  'FFTW'])
 
 
-  TargetAdd('egg2bam_eggToBam.obj', opts=OPTS, input='eggToBam.cxx')
-  TargetAdd('egg2bam.exe', input='egg2bam_eggToBam.obj')
-  TargetAdd('egg2bam.exe', input=COMMON_EGG2X_LIBS)
-  TargetAdd('egg2bam.exe', opts=['ADVAPI',  'FFTW'])
+    TargetAdd('egg2bam_eggToBam.obj', opts=OPTS, input='eggToBam.cxx')
+    TargetAdd('egg2bam.exe', input='egg2bam_eggToBam.obj')
+    TargetAdd('egg2bam.exe', input=COMMON_EGG2X_LIBS)
+    TargetAdd('egg2bam.exe', opts=['ADVAPI',  'FFTW'])
 
 
 #
 #
 # DIRECTORY: pandatool/src/cvscopy/
 # DIRECTORY: pandatool/src/cvscopy/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/cvscopy']
   OPTS=['DIR:pandatool/src/cvscopy']
   TargetAdd('p3cvscopy_composite1.obj', opts=OPTS, input='p3cvscopy_composite1.cxx')
   TargetAdd('p3cvscopy_composite1.obj', opts=OPTS, input='p3cvscopy_composite1.cxx')
   TargetAdd('libp3cvscopy.lib', input='p3cvscopy_composite1.obj')
   TargetAdd('libp3cvscopy.lib', input='p3cvscopy_composite1.obj')
@@ -5556,7 +5562,7 @@ if (PkgSkip("PANDATOOL")==0):
 #
 #
 # DIRECTORY: pandatool/src/daeegg/
 # DIRECTORY: pandatool/src/daeegg/
 #
 #
-if (PkgSkip("PANDATOOL")==0 and PkgSkip("FCOLLADA")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("FCOLLADA") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/daeegg', 'FCOLLADA']
   OPTS=['DIR:pandatool/src/daeegg', 'FCOLLADA']
   TargetAdd('p3daeegg_composite1.obj', opts=OPTS, input='p3daeegg_composite1.cxx')
   TargetAdd('p3daeegg_composite1.obj', opts=OPTS, input='p3daeegg_composite1.cxx')
   TargetAdd('libp3daeegg.lib', input='p3daeegg_composite1.obj')
   TargetAdd('libp3daeegg.lib', input='p3daeegg_composite1.obj')
@@ -5565,7 +5571,7 @@ if (PkgSkip("PANDATOOL")==0 and PkgSkip("FCOLLADA")==0):
 #
 #
 # DIRECTORY: pandatool/src/assimp
 # DIRECTORY: pandatool/src/assimp
 #
 #
-if (PkgSkip("PANDATOOL") == 0 and PkgSkip("ASSIMP")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("ASSIMP"):
   OPTS=['DIR:pandatool/src/assimp', 'BUILDING:ASSIMP', 'ASSIMP', 'MODULE']
   OPTS=['DIR:pandatool/src/assimp', 'BUILDING:ASSIMP', 'ASSIMP', 'MODULE']
   TargetAdd('p3assimp_composite1.obj', opts=OPTS, input='p3assimp_composite1.cxx')
   TargetAdd('p3assimp_composite1.obj', opts=OPTS, input='p3assimp_composite1.cxx')
   TargetAdd('libp3assimp.dll', input='p3assimp_composite1.obj')
   TargetAdd('libp3assimp.dll', input='p3assimp_composite1.obj')
@@ -5575,7 +5581,7 @@ if (PkgSkip("PANDATOOL") == 0 and PkgSkip("ASSIMP")==0):
 #
 #
 # DIRECTORY: pandatool/src/daeprogs/
 # DIRECTORY: pandatool/src/daeprogs/
 #
 #
-if (PkgSkip("PANDATOOL")==0 and PkgSkip("FCOLLADA")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("FCOLLADA") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/daeprogs', 'FCOLLADA']
   OPTS=['DIR:pandatool/src/daeprogs', 'FCOLLADA']
   TargetAdd('dae2egg_daeToEgg.obj', opts=OPTS, input='daeToEgg.cxx')
   TargetAdd('dae2egg_daeToEgg.obj', opts=OPTS, input='daeToEgg.cxx')
   TargetAdd('dae2egg.exe', input='dae2egg_daeToEgg.obj')
   TargetAdd('dae2egg.exe', input='dae2egg_daeToEgg.obj')
@@ -5587,7 +5593,7 @@ if (PkgSkip("PANDATOOL")==0 and PkgSkip("FCOLLADA")==0):
 # DIRECTORY: pandatool/src/dxf/
 # DIRECTORY: pandatool/src/dxf/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/dxf']
   OPTS=['DIR:pandatool/src/dxf']
   TargetAdd('p3dxf_composite1.obj', opts=OPTS, input='p3dxf_composite1.cxx')
   TargetAdd('p3dxf_composite1.obj', opts=OPTS, input='p3dxf_composite1.cxx')
   TargetAdd('libp3dxf.lib', input='p3dxf_composite1.obj')
   TargetAdd('libp3dxf.lib', input='p3dxf_composite1.obj')
@@ -5596,7 +5602,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/dxfegg/
 # DIRECTORY: pandatool/src/dxfegg/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/dxfegg']
   OPTS=['DIR:pandatool/src/dxfegg']
   TargetAdd('p3dxfegg_dxfToEggConverter.obj', opts=OPTS, input='dxfToEggConverter.cxx')
   TargetAdd('p3dxfegg_dxfToEggConverter.obj', opts=OPTS, input='dxfToEggConverter.cxx')
   TargetAdd('p3dxfegg_dxfToEggLayer.obj', opts=OPTS, input='dxfToEggLayer.cxx')
   TargetAdd('p3dxfegg_dxfToEggLayer.obj', opts=OPTS, input='dxfToEggLayer.cxx')
@@ -5607,7 +5613,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/dxfprogs/
 # DIRECTORY: pandatool/src/dxfprogs/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/dxfprogs']
   OPTS=['DIR:pandatool/src/dxfprogs']
   TargetAdd('dxf-points_dxfPoints.obj', opts=OPTS, input='dxfPoints.cxx')
   TargetAdd('dxf-points_dxfPoints.obj', opts=OPTS, input='dxfPoints.cxx')
   TargetAdd('dxf-points.exe', input='dxf-points_dxfPoints.obj')
   TargetAdd('dxf-points.exe', input='dxf-points_dxfPoints.obj')
@@ -5617,26 +5623,27 @@ if (PkgSkip("PANDATOOL")==0):
   TargetAdd('dxf-points.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('dxf-points.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('dxf-points.exe', opts=['ADVAPI',  'FFTW'])
   TargetAdd('dxf-points.exe', opts=['ADVAPI',  'FFTW'])
 
 
-  TargetAdd('dxf2egg_dxfToEgg.obj', opts=OPTS, input='dxfToEgg.cxx')
-  TargetAdd('dxf2egg.exe', input='dxf2egg_dxfToEgg.obj')
-  TargetAdd('dxf2egg.exe', input='libp3dxfegg.lib')
-  TargetAdd('dxf2egg.exe', input='libp3dxf.lib')
-  TargetAdd('dxf2egg.exe', input=COMMON_EGG2X_LIBS)
-  TargetAdd('dxf2egg.exe', opts=['ADVAPI',  'FFTW'])
+  if not PkgSkip("EGG"):
+    TargetAdd('dxf2egg_dxfToEgg.obj', opts=OPTS, input='dxfToEgg.cxx')
+    TargetAdd('dxf2egg.exe', input='dxf2egg_dxfToEgg.obj')
+    TargetAdd('dxf2egg.exe', input='libp3dxfegg.lib')
+    TargetAdd('dxf2egg.exe', input='libp3dxf.lib')
+    TargetAdd('dxf2egg.exe', input=COMMON_EGG2X_LIBS)
+    TargetAdd('dxf2egg.exe', opts=['ADVAPI',  'FFTW'])
 
 
-  TargetAdd('egg2dxf_eggToDXF.obj', opts=OPTS, input='eggToDXF.cxx')
-  TargetAdd('egg2dxf_eggToDXFLayer.obj', opts=OPTS, input='eggToDXFLayer.cxx')
-  TargetAdd('egg2dxf.exe', input='egg2dxf_eggToDXF.obj')
-  TargetAdd('egg2dxf.exe', input='egg2dxf_eggToDXFLayer.obj')
-  TargetAdd('egg2dxf.exe', input='libp3dxf.lib')
-  TargetAdd('egg2dxf.exe', input=COMMON_EGG2X_LIBS)
-  TargetAdd('egg2dxf.exe', opts=['ADVAPI',  'FFTW'])
+    TargetAdd('egg2dxf_eggToDXF.obj', opts=OPTS, input='eggToDXF.cxx')
+    TargetAdd('egg2dxf_eggToDXFLayer.obj', opts=OPTS, input='eggToDXFLayer.cxx')
+    TargetAdd('egg2dxf.exe', input='egg2dxf_eggToDXF.obj')
+    TargetAdd('egg2dxf.exe', input='egg2dxf_eggToDXFLayer.obj')
+    TargetAdd('egg2dxf.exe', input='libp3dxf.lib')
+    TargetAdd('egg2dxf.exe', input=COMMON_EGG2X_LIBS)
+    TargetAdd('egg2dxf.exe', opts=['ADVAPI',  'FFTW'])
 
 
 #
 #
 # DIRECTORY: pandatool/src/objegg/
 # DIRECTORY: pandatool/src/objegg/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/objegg']
   OPTS=['DIR:pandatool/src/objegg']
   TargetAdd('p3objegg_objToEggConverter.obj', opts=OPTS, input='objToEggConverter.cxx')
   TargetAdd('p3objegg_objToEggConverter.obj', opts=OPTS, input='objToEggConverter.cxx')
   TargetAdd('p3objegg_eggToObjConverter.obj', opts=OPTS, input='eggToObjConverter.cxx')
   TargetAdd('p3objegg_eggToObjConverter.obj', opts=OPTS, input='eggToObjConverter.cxx')
@@ -5649,7 +5656,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/objprogs/
 # DIRECTORY: pandatool/src/objprogs/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/objprogs']
   OPTS=['DIR:pandatool/src/objprogs']
   TargetAdd('obj2egg_objToEgg.obj', opts=OPTS, input='objToEgg.cxx')
   TargetAdd('obj2egg_objToEgg.obj', opts=OPTS, input='objToEgg.cxx')
   TargetAdd('obj2egg.exe', input='obj2egg_objToEgg.obj')
   TargetAdd('obj2egg.exe', input='obj2egg_objToEgg.obj')
@@ -5665,7 +5672,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/palettizer/
 # DIRECTORY: pandatool/src/palettizer/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/palettizer']
   OPTS=['DIR:pandatool/src/palettizer']
   TargetAdd('p3palettizer_composite1.obj', opts=OPTS, input='p3palettizer_composite1.cxx')
   TargetAdd('p3palettizer_composite1.obj', opts=OPTS, input='p3palettizer_composite1.cxx')
   TargetAdd('libp3palettizer.lib', input='p3palettizer_composite1.obj')
   TargetAdd('libp3palettizer.lib', input='p3palettizer_composite1.obj')
@@ -5674,7 +5681,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/egg-mkfont/
 # DIRECTORY: pandatool/src/egg-mkfont/
 #
 #
 
 
-if (PkgSkip("FREETYPE")==0) and (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("FREETYPE") and not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/egg-mkfont', 'DIR:pandatool/src/palettizer', 'FREETYPE']
   OPTS=['DIR:pandatool/src/egg-mkfont', 'DIR:pandatool/src/palettizer', 'FREETYPE']
   TargetAdd('egg-mkfont_eggMakeFont.obj', opts=OPTS, input='eggMakeFont.cxx')
   TargetAdd('egg-mkfont_eggMakeFont.obj', opts=OPTS, input='eggMakeFont.cxx')
   TargetAdd('egg-mkfont_rangeDescription.obj', opts=OPTS, input='rangeDescription.cxx')
   TargetAdd('egg-mkfont_rangeDescription.obj', opts=OPTS, input='rangeDescription.cxx')
@@ -5690,7 +5697,7 @@ if (PkgSkip("FREETYPE")==0) and (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/eggcharbase/
 # DIRECTORY: pandatool/src/eggcharbase/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/eggcharbase', 'ZLIB']
   OPTS=['DIR:pandatool/src/eggcharbase', 'ZLIB']
   TargetAdd('p3eggcharbase_composite1.obj', opts=OPTS, input='p3eggcharbase_composite1.cxx')
   TargetAdd('p3eggcharbase_composite1.obj', opts=OPTS, input='p3eggcharbase_composite1.cxx')
   TargetAdd('libp3eggcharbase.lib', input='p3eggcharbase_composite1.obj')
   TargetAdd('libp3eggcharbase.lib', input='p3eggcharbase_composite1.obj')
@@ -5699,7 +5706,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/egg-optchar/
 # DIRECTORY: pandatool/src/egg-optchar/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/egg-optchar']
   OPTS=['DIR:pandatool/src/egg-optchar']
   TargetAdd('egg-optchar_config_egg_optchar.obj', opts=OPTS, input='config_egg_optchar.cxx')
   TargetAdd('egg-optchar_config_egg_optchar.obj', opts=OPTS, input='config_egg_optchar.cxx')
   TargetAdd('egg-optchar_eggOptchar.obj', opts=OPTS, input='eggOptchar.cxx')
   TargetAdd('egg-optchar_eggOptchar.obj', opts=OPTS, input='eggOptchar.cxx')
@@ -5717,7 +5724,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/egg-palettize/
 # DIRECTORY: pandatool/src/egg-palettize/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/egg-palettize', 'DIR:pandatool/src/palettizer']
   OPTS=['DIR:pandatool/src/egg-palettize', 'DIR:pandatool/src/palettizer']
   TargetAdd('egg-palettize_eggPalettize.obj', opts=OPTS, input='eggPalettize.cxx')
   TargetAdd('egg-palettize_eggPalettize.obj', opts=OPTS, input='eggPalettize.cxx')
   TargetAdd('egg-palettize.exe', input='egg-palettize_eggPalettize.obj')
   TargetAdd('egg-palettize.exe', input='egg-palettize_eggPalettize.obj')
@@ -5729,7 +5736,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/egg-qtess/
 # DIRECTORY: pandatool/src/egg-qtess/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/egg-qtess']
   OPTS=['DIR:pandatool/src/egg-qtess']
   TargetAdd('egg-qtess_composite1.obj', opts=OPTS, input='egg-qtess_composite1.cxx')
   TargetAdd('egg-qtess_composite1.obj', opts=OPTS, input='egg-qtess_composite1.cxx')
   TargetAdd('egg-qtess.exe', input='egg-qtess_composite1.obj')
   TargetAdd('egg-qtess.exe', input='egg-qtess_composite1.obj')
@@ -5743,7 +5750,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/eggprogs/
 # DIRECTORY: pandatool/src/eggprogs/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/eggprogs']
   OPTS=['DIR:pandatool/src/eggprogs']
   TargetAdd('egg-crop_eggCrop.obj', opts=OPTS, input='eggCrop.cxx')
   TargetAdd('egg-crop_eggCrop.obj', opts=OPTS, input='eggCrop.cxx')
   TargetAdd('egg-crop.exe', input='egg-crop_eggCrop.obj')
   TargetAdd('egg-crop.exe', input='egg-crop_eggCrop.obj')
@@ -5796,7 +5803,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/flt/
 # DIRECTORY: pandatool/src/flt/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/flt', 'ZLIB']
   OPTS=['DIR:pandatool/src/flt', 'ZLIB']
   TargetAdd('p3flt_composite1.obj', opts=OPTS, input='p3flt_composite1.cxx')
   TargetAdd('p3flt_composite1.obj', opts=OPTS, input='p3flt_composite1.cxx')
   TargetAdd('libp3flt.lib', input=['p3flt_composite1.obj'])
   TargetAdd('libp3flt.lib', input=['p3flt_composite1.obj'])
@@ -5805,7 +5812,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/fltegg/
 # DIRECTORY: pandatool/src/fltegg/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/fltegg']
   OPTS=['DIR:pandatool/src/fltegg']
   TargetAdd('p3fltegg_fltToEggConverter.obj', opts=OPTS, input='fltToEggConverter.cxx')
   TargetAdd('p3fltegg_fltToEggConverter.obj', opts=OPTS, input='fltToEggConverter.cxx')
   TargetAdd('p3fltegg_fltToEggLevelState.obj', opts=OPTS, input='fltToEggLevelState.cxx')
   TargetAdd('p3fltegg_fltToEggLevelState.obj', opts=OPTS, input='fltToEggLevelState.cxx')
@@ -5815,46 +5822,52 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/fltprogs/
 # DIRECTORY: pandatool/src/fltprogs/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/fltprogs', 'DIR:pandatool/src/flt', 'DIR:pandatool/src/cvscopy']
   OPTS=['DIR:pandatool/src/fltprogs', 'DIR:pandatool/src/flt', 'DIR:pandatool/src/cvscopy']
-  TargetAdd('egg2flt_eggToFlt.obj', opts=OPTS, input='eggToFlt.cxx')
-  TargetAdd('egg2flt.exe', input='egg2flt_eggToFlt.obj')
-  TargetAdd('egg2flt.exe', input='libp3flt.lib')
-  TargetAdd('egg2flt.exe', input=COMMON_EGG2X_LIBS)
-  TargetAdd('egg2flt.exe', opts=['ADVAPI'])
-
   TargetAdd('flt-info_fltInfo.obj', opts=OPTS, input='fltInfo.cxx')
   TargetAdd('flt-info_fltInfo.obj', opts=OPTS, input='fltInfo.cxx')
   TargetAdd('flt-info.exe', input='flt-info_fltInfo.obj')
   TargetAdd('flt-info.exe', input='flt-info_fltInfo.obj')
   TargetAdd('flt-info.exe', input='libp3flt.lib')
   TargetAdd('flt-info.exe', input='libp3flt.lib')
-  TargetAdd('flt-info.exe', input=COMMON_EGG2X_LIBS)
+  TargetAdd('flt-info.exe', input='libp3progbase.lib')
+  TargetAdd('flt-info.exe', input='libp3pandatoolbase.lib')
+  TargetAdd('flt-info.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('flt-info.exe', opts=['ADVAPI'])
   TargetAdd('flt-info.exe', opts=['ADVAPI'])
 
 
   TargetAdd('flt-trans_fltTrans.obj', opts=OPTS, input='fltTrans.cxx')
   TargetAdd('flt-trans_fltTrans.obj', opts=OPTS, input='fltTrans.cxx')
   TargetAdd('flt-trans.exe', input='flt-trans_fltTrans.obj')
   TargetAdd('flt-trans.exe', input='flt-trans_fltTrans.obj')
   TargetAdd('flt-trans.exe', input='libp3flt.lib')
   TargetAdd('flt-trans.exe', input='libp3flt.lib')
-  TargetAdd('flt-trans.exe', input=COMMON_EGG2X_LIBS)
+  TargetAdd('flt-trans.exe', input='libp3progbase.lib')
+  TargetAdd('flt-trans.exe', input='libp3pandatoolbase.lib')
+  TargetAdd('flt-trans.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('flt-trans.exe', opts=['ADVAPI'])
   TargetAdd('flt-trans.exe', opts=['ADVAPI'])
 
 
-  TargetAdd('flt2egg_fltToEgg.obj', opts=OPTS, input='fltToEgg.cxx')
-  TargetAdd('flt2egg.exe', input='flt2egg_fltToEgg.obj')
-  TargetAdd('flt2egg.exe', input='libp3flt.lib')
-  TargetAdd('flt2egg.exe', input='libp3fltegg.lib')
-  TargetAdd('flt2egg.exe', input=COMMON_EGG2X_LIBS)
-  TargetAdd('flt2egg.exe', opts=['ADVAPI'])
-
   TargetAdd('fltcopy_fltCopy.obj', opts=OPTS, input='fltCopy.cxx')
   TargetAdd('fltcopy_fltCopy.obj', opts=OPTS, input='fltCopy.cxx')
   TargetAdd('fltcopy.exe', input='fltcopy_fltCopy.obj')
   TargetAdd('fltcopy.exe', input='fltcopy_fltCopy.obj')
   TargetAdd('fltcopy.exe', input='libp3cvscopy.lib')
   TargetAdd('fltcopy.exe', input='libp3cvscopy.lib')
   TargetAdd('fltcopy.exe', input='libp3flt.lib')
   TargetAdd('fltcopy.exe', input='libp3flt.lib')
-  TargetAdd('fltcopy.exe', input=COMMON_EGG2X_LIBS)
+  TargetAdd('fltcopy.exe', input='libp3progbase.lib')
+  TargetAdd('fltcopy.exe', input='libp3pandatoolbase.lib')
+  TargetAdd('fltcopy.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('fltcopy.exe', opts=['ADVAPI'])
   TargetAdd('fltcopy.exe', opts=['ADVAPI'])
 
 
+  if not PkgSkip("EGG"):
+    TargetAdd('egg2flt_eggToFlt.obj', opts=OPTS, input='eggToFlt.cxx')
+    TargetAdd('egg2flt.exe', input='egg2flt_eggToFlt.obj')
+    TargetAdd('egg2flt.exe', input='libp3flt.lib')
+    TargetAdd('egg2flt.exe', input=COMMON_EGG2X_LIBS)
+    TargetAdd('egg2flt.exe', opts=['ADVAPI'])
+
+    TargetAdd('flt2egg_fltToEgg.obj', opts=OPTS, input='fltToEgg.cxx')
+    TargetAdd('flt2egg.exe', input='flt2egg_fltToEgg.obj')
+    TargetAdd('flt2egg.exe', input='libp3flt.lib')
+    TargetAdd('flt2egg.exe', input='libp3fltegg.lib')
+    TargetAdd('flt2egg.exe', input=COMMON_EGG2X_LIBS)
+    TargetAdd('flt2egg.exe', opts=['ADVAPI'])
 
 
 #
 #
 # DIRECTORY: pandatool/src/imagebase/
 # DIRECTORY: pandatool/src/imagebase/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/imagebase']
   OPTS=['DIR:pandatool/src/imagebase']
   TargetAdd('p3imagebase_composite1.obj', opts=OPTS, input='p3imagebase_composite1.cxx')
   TargetAdd('p3imagebase_composite1.obj', opts=OPTS, input='p3imagebase_composite1.cxx')
   TargetAdd('libp3imagebase.lib', input='p3imagebase_composite1.obj')
   TargetAdd('libp3imagebase.lib', input='p3imagebase_composite1.obj')
@@ -5863,14 +5876,13 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/imageprogs/
 # DIRECTORY: pandatool/src/imageprogs/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/imageprogs']
   OPTS=['DIR:pandatool/src/imageprogs']
   TargetAdd('image-info_imageInfo.obj', opts=OPTS, input='imageInfo.cxx')
   TargetAdd('image-info_imageInfo.obj', opts=OPTS, input='imageInfo.cxx')
   TargetAdd('image-info.exe', input='image-info_imageInfo.obj')
   TargetAdd('image-info.exe', input='image-info_imageInfo.obj')
   TargetAdd('image-info.exe', input='libp3imagebase.lib')
   TargetAdd('image-info.exe', input='libp3imagebase.lib')
   TargetAdd('image-info.exe', input='libp3progbase.lib')
   TargetAdd('image-info.exe', input='libp3progbase.lib')
   TargetAdd('image-info.exe', input='libp3pandatoolbase.lib')
   TargetAdd('image-info.exe', input='libp3pandatoolbase.lib')
-  TargetAdd('image-info.exe', input='libpandaegg.dll')
   TargetAdd('image-info.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('image-info.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('image-info.exe', opts=['ADVAPI'])
   TargetAdd('image-info.exe', opts=['ADVAPI'])
 
 
@@ -5879,7 +5891,6 @@ if (PkgSkip("PANDATOOL")==0):
   TargetAdd('image-resize.exe', input='libp3imagebase.lib')
   TargetAdd('image-resize.exe', input='libp3imagebase.lib')
   TargetAdd('image-resize.exe', input='libp3progbase.lib')
   TargetAdd('image-resize.exe', input='libp3progbase.lib')
   TargetAdd('image-resize.exe', input='libp3pandatoolbase.lib')
   TargetAdd('image-resize.exe', input='libp3pandatoolbase.lib')
-  TargetAdd('image-resize.exe', input='libpandaegg.dll')
   TargetAdd('image-resize.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('image-resize.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('image-resize.exe', opts=['ADVAPI'])
   TargetAdd('image-resize.exe', opts=['ADVAPI'])
 
 
@@ -5888,7 +5899,6 @@ if (PkgSkip("PANDATOOL")==0):
   TargetAdd('image-trans.exe', input='libp3imagebase.lib')
   TargetAdd('image-trans.exe', input='libp3imagebase.lib')
   TargetAdd('image-trans.exe', input='libp3progbase.lib')
   TargetAdd('image-trans.exe', input='libp3progbase.lib')
   TargetAdd('image-trans.exe', input='libp3pandatoolbase.lib')
   TargetAdd('image-trans.exe', input='libp3pandatoolbase.lib')
-  TargetAdd('image-trans.exe', input='libpandaegg.dll')
   TargetAdd('image-trans.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('image-trans.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('image-trans.exe', opts=['ADVAPI'])
   TargetAdd('image-trans.exe', opts=['ADVAPI'])
 
 
@@ -5896,7 +5906,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/pfmprogs/
 # DIRECTORY: pandatool/src/pfmprogs/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/pfmprogs']
   OPTS=['DIR:pandatool/src/pfmprogs']
   TargetAdd('pfm-trans_pfmTrans.obj', opts=OPTS, input='pfmTrans.cxx')
   TargetAdd('pfm-trans_pfmTrans.obj', opts=OPTS, input='pfmTrans.cxx')
   TargetAdd('pfm-trans.exe', input='pfm-trans_pfmTrans.obj')
   TargetAdd('pfm-trans.exe', input='pfm-trans_pfmTrans.obj')
@@ -5918,7 +5928,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/lwo/
 # DIRECTORY: pandatool/src/lwo/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/lwo']
   OPTS=['DIR:pandatool/src/lwo']
   TargetAdd('p3lwo_composite1.obj', opts=OPTS, input='p3lwo_composite1.cxx')
   TargetAdd('p3lwo_composite1.obj', opts=OPTS, input='p3lwo_composite1.cxx')
   TargetAdd('libp3lwo.lib', input='p3lwo_composite1.obj')
   TargetAdd('libp3lwo.lib', input='p3lwo_composite1.obj')
@@ -5927,7 +5937,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/lwoegg/
 # DIRECTORY: pandatool/src/lwoegg/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/lwoegg']
   OPTS=['DIR:pandatool/src/lwoegg']
   TargetAdd('p3lwoegg_composite1.obj', opts=OPTS, input='p3lwoegg_composite1.cxx')
   TargetAdd('p3lwoegg_composite1.obj', opts=OPTS, input='p3lwoegg_composite1.cxx')
   TargetAdd('libp3lwoegg.lib', input='p3lwoegg_composite1.obj')
   TargetAdd('libp3lwoegg.lib', input='p3lwoegg_composite1.obj')
@@ -5936,23 +5946,23 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/lwoprogs/
 # DIRECTORY: pandatool/src/lwoprogs/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/lwoprogs', 'DIR:pandatool/src/lwo']
   OPTS=['DIR:pandatool/src/lwoprogs', 'DIR:pandatool/src/lwo']
   TargetAdd('lwo-scan_lwoScan.obj', opts=OPTS, input='lwoScan.cxx')
   TargetAdd('lwo-scan_lwoScan.obj', opts=OPTS, input='lwoScan.cxx')
   TargetAdd('lwo-scan.exe', input='lwo-scan_lwoScan.obj')
   TargetAdd('lwo-scan.exe', input='lwo-scan_lwoScan.obj')
   TargetAdd('lwo-scan.exe', input='libp3lwo.lib')
   TargetAdd('lwo-scan.exe', input='libp3lwo.lib')
   TargetAdd('lwo-scan.exe', input='libp3progbase.lib')
   TargetAdd('lwo-scan.exe', input='libp3progbase.lib')
   TargetAdd('lwo-scan.exe', input='libp3pandatoolbase.lib')
   TargetAdd('lwo-scan.exe', input='libp3pandatoolbase.lib')
-  TargetAdd('lwo-scan.exe', input='libpandaegg.dll')
   TargetAdd('lwo-scan.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('lwo-scan.exe', input=COMMON_PANDA_LIBS)
   TargetAdd('lwo-scan.exe', opts=['ADVAPI'])
   TargetAdd('lwo-scan.exe', opts=['ADVAPI'])
 
 
-  TargetAdd('lwo2egg_lwoToEgg.obj', opts=OPTS, input='lwoToEgg.cxx')
-  TargetAdd('lwo2egg.exe', input='lwo2egg_lwoToEgg.obj')
-  TargetAdd('lwo2egg.exe', input='libp3lwo.lib')
-  TargetAdd('lwo2egg.exe', input='libp3lwoegg.lib')
-  TargetAdd('lwo2egg.exe', input=COMMON_EGG2X_LIBS)
-  TargetAdd('lwo2egg.exe', opts=['ADVAPI'])
+  if not PkgSkip("EGG"):
+    TargetAdd('lwo2egg_lwoToEgg.obj', opts=OPTS, input='lwoToEgg.cxx')
+    TargetAdd('lwo2egg.exe', input='lwo2egg_lwoToEgg.obj')
+    TargetAdd('lwo2egg.exe', input='libp3lwo.lib')
+    TargetAdd('lwo2egg.exe', input='libp3lwoegg.lib')
+    TargetAdd('lwo2egg.exe', input=COMMON_EGG2X_LIBS)
+    TargetAdd('lwo2egg.exe', opts=['ADVAPI'])
 
 
 #
 #
 # DIRECTORY: pandatool/src/maya/
 # DIRECTORY: pandatool/src/maya/
@@ -5960,7 +5970,7 @@ if (PkgSkip("PANDATOOL")==0):
 
 
 for VER in MAYAVERSIONS:
 for VER in MAYAVERSIONS:
   VNUM=VER[4:]
   VNUM=VER[4:]
-  if (PkgSkip(VER)==0) and (PkgSkip("PANDATOOL")==0):
+  if not PkgSkip(VER) and not PkgSkip("PANDATOOL"):
     OPTS=['DIR:pandatool/src/maya', VER]
     OPTS=['DIR:pandatool/src/maya', VER]
     TargetAdd('maya'+VNUM+'_composite1.obj', opts=OPTS, input='p3maya_composite1.cxx')
     TargetAdd('maya'+VNUM+'_composite1.obj', opts=OPTS, input='p3maya_composite1.cxx')
     TargetAdd('libmaya'+VNUM+'.lib', input='maya'+VNUM+'_composite1.obj')
     TargetAdd('libmaya'+VNUM+'.lib', input='maya'+VNUM+'_composite1.obj')
@@ -5971,7 +5981,7 @@ for VER in MAYAVERSIONS:
 
 
 for VER in MAYAVERSIONS:
 for VER in MAYAVERSIONS:
   VNUM=VER[4:]
   VNUM=VER[4:]
-  if (PkgSkip(VER)==0) and (PkgSkip("PANDATOOL")==0):
+  if not PkgSkip(VER) and not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
     OPTS=['DIR:pandatool/src/mayaegg', 'DIR:pandatool/src/maya', VER]
     OPTS=['DIR:pandatool/src/mayaegg', 'DIR:pandatool/src/maya', VER]
     TargetAdd('mayaegg'+VNUM+'_loader.obj', opts=OPTS, input='mayaEggLoader.cxx')
     TargetAdd('mayaegg'+VNUM+'_loader.obj', opts=OPTS, input='mayaEggLoader.cxx')
     TargetAdd('mayaegg'+VNUM+'_composite1.obj', opts=OPTS, input='p3mayaegg_composite1.cxx')
     TargetAdd('mayaegg'+VNUM+'_composite1.obj', opts=OPTS, input='p3mayaegg_composite1.cxx')
@@ -5984,7 +5994,7 @@ for VER in MAYAVERSIONS:
 
 
 for VER in MAXVERSIONS:
 for VER in MAXVERSIONS:
   VNUM=VER[3:]
   VNUM=VER[3:]
-  if (PkgSkip(VER)==0) and (PkgSkip("PANDATOOL")==0):
+  if not PkgSkip(VER) and not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
     OPTS=['DIR:pandatool/src/maxegg', VER,  "WINCOMCTL", "WINCOMDLG", "WINUSER", "MSFORSCOPE", "RTTI"]
     OPTS=['DIR:pandatool/src/maxegg', VER,  "WINCOMCTL", "WINCOMDLG", "WINUSER", "MSFORSCOPE", "RTTI"]
     TargetAdd('maxEgg'+VNUM+'.res', opts=OPTS, input='maxEgg.rc')
     TargetAdd('maxEgg'+VNUM+'.res', opts=OPTS, input='maxEgg.rc')
     TargetAdd('maxegg'+VNUM+'_loader.obj', opts=OPTS, input='maxEggLoader.cxx')
     TargetAdd('maxegg'+VNUM+'_loader.obj', opts=OPTS, input='maxEggLoader.cxx')
@@ -6001,7 +6011,7 @@ for VER in MAXVERSIONS:
 
 
 for VER in MAXVERSIONS:
 for VER in MAXVERSIONS:
   VNUM=VER[3:]
   VNUM=VER[3:]
-  if (PkgSkip(VER)==0) and (PkgSkip("PANDATOOL")==0):
+  if not PkgSkip(VER) and not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
     OPTS=['DIR:pandatool/src/maxprogs', VER,  "WINCOMCTL", "WINCOMDLG", "WINUSER", "MSFORSCOPE", "RTTI"]
     OPTS=['DIR:pandatool/src/maxprogs', VER,  "WINCOMCTL", "WINCOMDLG", "WINUSER", "MSFORSCOPE", "RTTI"]
     TargetAdd('maxImportRes.res', opts=OPTS, input='maxImportRes.rc')
     TargetAdd('maxImportRes.res', opts=OPTS, input='maxImportRes.rc')
     TargetAdd('maxprogs'+VNUM+'_maxeggimport.obj', opts=OPTS, input='maxEggImport.cxx')
     TargetAdd('maxprogs'+VNUM+'_maxeggimport.obj', opts=OPTS, input='maxEggImport.cxx')
@@ -6019,7 +6029,7 @@ for VER in MAXVERSIONS:
 # DIRECTORY: pandatool/src/vrml/
 # DIRECTORY: pandatool/src/vrml/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
   OPTS=['DIR:pandatool/src/vrml', 'ZLIB', 'BISONPREFIX_vrmlyy']
   OPTS=['DIR:pandatool/src/vrml', 'ZLIB', 'BISONPREFIX_vrmlyy']
   CreateFile(GetOutputDir()+"/include/vrmlParser.h")
   CreateFile(GetOutputDir()+"/include/vrmlParser.h")
   TargetAdd('p3vrml_vrmlParser.obj', opts=OPTS, input='vrmlParser.yxx')
   TargetAdd('p3vrml_vrmlParser.obj', opts=OPTS, input='vrmlParser.yxx')
@@ -6040,7 +6050,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/vrmlegg/
 # DIRECTORY: pandatool/src/vrmlegg/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
   OPTS=['DIR:pandatool/src/vrmlegg', 'DIR:pandatool/src/vrml']
   OPTS=['DIR:pandatool/src/vrmlegg', 'DIR:pandatool/src/vrml']
   TargetAdd('p3vrmlegg_indexedFaceSet.obj', opts=OPTS, input='indexedFaceSet.cxx')
   TargetAdd('p3vrmlegg_indexedFaceSet.obj', opts=OPTS, input='indexedFaceSet.cxx')
   TargetAdd('p3vrmlegg_vrmlAppearance.obj', opts=OPTS, input='vrmlAppearance.cxx')
   TargetAdd('p3vrmlegg_vrmlAppearance.obj', opts=OPTS, input='vrmlAppearance.cxx')
@@ -6053,7 +6063,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/xfile/
 # DIRECTORY: pandatool/src/xfile/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
     OPTS=['DIR:pandatool/src/xfile', 'ZLIB', 'BISONPREFIX_xyy', 'FLEXDASHI']
     OPTS=['DIR:pandatool/src/xfile', 'ZLIB', 'BISONPREFIX_xyy', 'FLEXDASHI']
     CreateFile(GetOutputDir()+"/include/xParser.h")
     CreateFile(GetOutputDir()+"/include/xParser.h")
     TargetAdd('p3xfile_xParser.obj', opts=OPTS, input='xParser.yxx')
     TargetAdd('p3xfile_xParser.obj', opts=OPTS, input='xParser.yxx')
@@ -6068,7 +6078,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/xfileegg/
 # DIRECTORY: pandatool/src/xfileegg/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
     OPTS=['DIR:pandatool/src/xfileegg', 'DIR:pandatool/src/xfile']
     OPTS=['DIR:pandatool/src/xfileegg', 'DIR:pandatool/src/xfile']
     TargetAdd('p3xfileegg_composite1.obj', opts=OPTS, input='p3xfileegg_composite1.cxx')
     TargetAdd('p3xfileegg_composite1.obj', opts=OPTS, input='p3xfileegg_composite1.cxx')
     TargetAdd('libp3xfileegg.lib', input='p3xfileegg_composite1.obj')
     TargetAdd('libp3xfileegg.lib', input='p3xfileegg_composite1.obj')
@@ -6077,7 +6087,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/ptloader/
 # DIRECTORY: pandatool/src/ptloader/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
     if not PkgSkip("FCOLLADA"):
     if not PkgSkip("FCOLLADA"):
         DefSymbol("FCOLLADA", "HAVE_FCOLLADA")
         DefSymbol("FCOLLADA", "HAVE_FCOLLADA")
 
 
@@ -6143,7 +6153,6 @@ if (PkgSkip("PANDATOOL")==0):
     TargetAdd('softcvs.exe', input='softcvs_softFilename.obj')
     TargetAdd('softcvs.exe', input='softcvs_softFilename.obj')
     TargetAdd('softcvs.exe', input='libp3progbase.lib')
     TargetAdd('softcvs.exe', input='libp3progbase.lib')
     TargetAdd('softcvs.exe', input='libp3pandatoolbase.lib')
     TargetAdd('softcvs.exe', input='libp3pandatoolbase.lib')
-    TargetAdd('softcvs.exe', input='libpandaegg.dll')
     TargetAdd('softcvs.exe', input=COMMON_PANDA_LIBS)
     TargetAdd('softcvs.exe', input=COMMON_PANDA_LIBS)
     TargetAdd('softcvs.exe', opts=['ADVAPI'])
     TargetAdd('softcvs.exe', opts=['ADVAPI'])
 
 
@@ -6160,7 +6169,6 @@ if (PkgSkip("PANDATOOL")==0):
     TargetAdd('text-stats.exe', input='libp3progbase.lib')
     TargetAdd('text-stats.exe', input='libp3progbase.lib')
     TargetAdd('text-stats.exe', input='libp3pstatserver.lib')
     TargetAdd('text-stats.exe', input='libp3pstatserver.lib')
     TargetAdd('text-stats.exe', input='libp3pandatoolbase.lib')
     TargetAdd('text-stats.exe', input='libp3pandatoolbase.lib')
-    TargetAdd('text-stats.exe', input='libpandaegg.dll')
     TargetAdd('text-stats.exe', input=COMMON_PANDA_LIBS)
     TargetAdd('text-stats.exe', input=COMMON_PANDA_LIBS)
     TargetAdd('text-stats.exe', opts=['ADVAPI'])
     TargetAdd('text-stats.exe', opts=['ADVAPI'])
 
 
@@ -6168,7 +6176,7 @@ if (PkgSkip("PANDATOOL")==0):
 # DIRECTORY: pandatool/src/vrmlprogs/
 # DIRECTORY: pandatool/src/vrmlprogs/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
     OPTS=['DIR:pandatool/src/vrmlprogs', 'DIR:pandatool/src/vrml', 'DIR:pandatool/src/vrmlegg']
     OPTS=['DIR:pandatool/src/vrmlprogs', 'DIR:pandatool/src/vrml', 'DIR:pandatool/src/vrmlegg']
     TargetAdd('vrml-trans_vrmlTrans.obj', opts=OPTS, input='vrmlTrans.cxx')
     TargetAdd('vrml-trans_vrmlTrans.obj', opts=OPTS, input='vrmlTrans.cxx')
     TargetAdd('vrml-trans.exe', input='vrml-trans_vrmlTrans.obj')
     TargetAdd('vrml-trans.exe', input='vrml-trans_vrmlTrans.obj')
@@ -6178,12 +6186,13 @@ if (PkgSkip("PANDATOOL")==0):
     TargetAdd('vrml-trans.exe', input=COMMON_PANDA_LIBS)
     TargetAdd('vrml-trans.exe', input=COMMON_PANDA_LIBS)
     TargetAdd('vrml-trans.exe', opts=['ADVAPI'])
     TargetAdd('vrml-trans.exe', opts=['ADVAPI'])
 
 
-    TargetAdd('vrml2egg_vrmlToEgg.obj', opts=OPTS, input='vrmlToEgg.cxx')
-    TargetAdd('vrml2egg.exe', input='vrml2egg_vrmlToEgg.obj')
-    TargetAdd('vrml2egg.exe', input='libp3vrmlegg.lib')
-    TargetAdd('vrml2egg.exe', input='libp3vrml.lib')
-    TargetAdd('vrml2egg.exe', input=COMMON_EGG2X_LIBS)
-    TargetAdd('vrml2egg.exe', opts=['ADVAPI'])
+    if not PkgSkip("EGG"):
+        TargetAdd('vrml2egg_vrmlToEgg.obj', opts=OPTS, input='vrmlToEgg.cxx')
+        TargetAdd('vrml2egg.exe', input='vrml2egg_vrmlToEgg.obj')
+        TargetAdd('vrml2egg.exe', input='libp3vrmlegg.lib')
+        TargetAdd('vrml2egg.exe', input='libp3vrml.lib')
+        TargetAdd('vrml2egg.exe', input=COMMON_EGG2X_LIBS)
+        TargetAdd('vrml2egg.exe', opts=['ADVAPI'])
 
 
 #
 #
 # DIRECTORY: pandatool/src/win-stats/
 # DIRECTORY: pandatool/src/win-stats/
@@ -6208,15 +6217,8 @@ if (PkgSkip("PANDATOOL")==0 and (GetTarget() == 'windows' or PkgSkip("GTK2")==0)
 # DIRECTORY: pandatool/src/xfileprogs/
 # DIRECTORY: pandatool/src/xfileprogs/
 #
 #
 
 
-if (PkgSkip("PANDATOOL")==0):
+if not PkgSkip("PANDATOOL"):
     OPTS=['DIR:pandatool/src/xfileprogs', 'DIR:pandatool/src/xfile', 'DIR:pandatool/src/xfileegg']
     OPTS=['DIR:pandatool/src/xfileprogs', 'DIR:pandatool/src/xfile', 'DIR:pandatool/src/xfileegg']
-    TargetAdd('egg2x_eggToX.obj', opts=OPTS, input='eggToX.cxx')
-    TargetAdd('egg2x.exe', input='egg2x_eggToX.obj')
-    TargetAdd('egg2x.exe', input='libp3xfileegg.lib')
-    TargetAdd('egg2x.exe', input='libp3xfile.lib')
-    TargetAdd('egg2x.exe', input=COMMON_EGG2X_LIBS)
-    TargetAdd('egg2x.exe', opts=['ADVAPI'])
-
     TargetAdd('x-trans_xFileTrans.obj', opts=OPTS, input='xFileTrans.cxx')
     TargetAdd('x-trans_xFileTrans.obj', opts=OPTS, input='xFileTrans.cxx')
     TargetAdd('x-trans.exe', input='x-trans_xFileTrans.obj')
     TargetAdd('x-trans.exe', input='x-trans_xFileTrans.obj')
     TargetAdd('x-trans.exe', input='libp3progbase.lib')
     TargetAdd('x-trans.exe', input='libp3progbase.lib')
@@ -6225,12 +6227,20 @@ if (PkgSkip("PANDATOOL")==0):
     TargetAdd('x-trans.exe', input=COMMON_PANDA_LIBS)
     TargetAdd('x-trans.exe', input=COMMON_PANDA_LIBS)
     TargetAdd('x-trans.exe', opts=['ADVAPI'])
     TargetAdd('x-trans.exe', opts=['ADVAPI'])
 
 
-    TargetAdd('x2egg_xFileToEgg.obj', opts=OPTS, input='xFileToEgg.cxx')
-    TargetAdd('x2egg.exe', input='x2egg_xFileToEgg.obj')
-    TargetAdd('x2egg.exe', input='libp3xfileegg.lib')
-    TargetAdd('x2egg.exe', input='libp3xfile.lib')
-    TargetAdd('x2egg.exe', input=COMMON_EGG2X_LIBS)
-    TargetAdd('x2egg.exe', opts=['ADVAPI'])
+    if not PkgSkip("EGG"):
+        TargetAdd('egg2x_eggToX.obj', opts=OPTS, input='eggToX.cxx')
+        TargetAdd('egg2x.exe', input='egg2x_eggToX.obj')
+        TargetAdd('egg2x.exe', input='libp3xfileegg.lib')
+        TargetAdd('egg2x.exe', input='libp3xfile.lib')
+        TargetAdd('egg2x.exe', input=COMMON_EGG2X_LIBS)
+        TargetAdd('egg2x.exe', opts=['ADVAPI'])
+
+        TargetAdd('x2egg_xFileToEgg.obj', opts=OPTS, input='xFileToEgg.cxx')
+        TargetAdd('x2egg.exe', input='x2egg_xFileToEgg.obj')
+        TargetAdd('x2egg.exe', input='libp3xfileegg.lib')
+        TargetAdd('x2egg.exe', input='libp3xfile.lib')
+        TargetAdd('x2egg.exe', input=COMMON_EGG2X_LIBS)
+        TargetAdd('x2egg.exe', opts=['ADVAPI'])
 
 
 #
 #
 # DIRECTORY: pandatool/src/mayaprogs/
 # DIRECTORY: pandatool/src/mayaprogs/
@@ -6238,7 +6248,7 @@ if (PkgSkip("PANDATOOL")==0):
 
 
 for VER in MAYAVERSIONS:
 for VER in MAYAVERSIONS:
   VNUM = VER[4:]
   VNUM = VER[4:]
-  if not PkgSkip(VER) and not PkgSkip("PANDATOOL"):
+  if not PkgSkip(VER) and not PkgSkip("PANDATOOL") and not PkgSkip("EGG"):
     if GetTarget() == 'darwin' and int(VNUM) >= 2012:
     if GetTarget() == 'darwin' and int(VNUM) >= 2012:
       ARCH_OPTS = ['NOARCH:PPC', 'NOARCH:I386']
       ARCH_OPTS = ['NOARCH:PPC', 'NOARCH:I386']
       if len(OSX_ARCHS) != 0 and 'x86_64' not in OSX_ARCHS:
       if len(OSX_ARCHS) != 0 and 'x86_64' not in OSX_ARCHS:
@@ -6374,8 +6384,9 @@ if (PkgSkip("CONTRIB")==0 and not RUNTIME):
 # Generate the models directory and samples directory
 # Generate the models directory and samples directory
 #
 #
 
 
-if (PkgSkip("DIRECT")==0 and not RUNTIME):
+if not PkgSkip("DIRECT") and not RUNTIME and not PkgSkip("EGG"):
   model_extensions = ["*.egg"]
   model_extensions = ["*.egg"]
+
   # Check if we have access to an flt2egg utility, either self-compiled or on the system.
   # Check if we have access to an flt2egg utility, either self-compiled or on the system.
   if ((PkgSkip("PANDATOOL")==0 and GetHost()==GetTarget()) or LocateBinary('flt2egg')):
   if ((PkgSkip("PANDATOOL")==0 and GetHost()==GetTarget()) or LocateBinary('flt2egg')):
       model_extensions.append("*.flt")
       model_extensions.append("*.flt")
@@ -6401,6 +6412,7 @@ if (PkgSkip("DIRECT")==0 and not RUNTIME):
           newname = model[:-4] + ".egg"
           newname = model[:-4] + ".egg"
       TargetAdd(GetOutputDir()+"/models/"+newname, input="models/"+model)
       TargetAdd(GetOutputDir()+"/models/"+newname, input="models/"+model)
 
 
+if not PkgSkip("DIRECT") and not RUNTIME:
   CopyAllFiles(GetOutputDir()+"/models/audio/sfx/",  "dmodels/src/audio/sfx/", ".wav")
   CopyAllFiles(GetOutputDir()+"/models/audio/sfx/",  "dmodels/src/audio/sfx/", ".wav")
   CopyAllFiles(GetOutputDir()+"/models/icons/",      "dmodels/src/icons/",     ".gif")
   CopyAllFiles(GetOutputDir()+"/models/icons/",      "dmodels/src/icons/",     ".gif")
 
 
@@ -6813,7 +6825,7 @@ deps: {DEPENDS}
 
 
 def MakeInstallerLinux():
 def MakeInstallerLinux():
     if not RUNTIME and not PkgSkip("PYTHON"):
     if not RUNTIME and not PkgSkip("PYTHON"):
-        PYTHONV = SDK["PYTHONVERSION"]
+        PYTHONV = SDK["PYTHONVERSION"].rstrip('dmu')
     else:
     else:
         PYTHONV = "python"
         PYTHONV = "python"
     PV = PYTHONV.replace("python", "")
     PV = PYTHONV.replace("python", "")
@@ -6968,8 +6980,13 @@ def MakeInstallerOSX():
         oscmd(cmdstr)
         oscmd(cmdstr)
         return
         return
 
 
+    dmg_name = "Panda3D-" + VERSION
+    if not SDK["PYTHONVERSION"].startswith("python2."):
+        dmg_name += '-py' + SDK["PYTHONVERSION"][6:9]
+    dmg_name += ".dmg"
+
     import compileall
     import compileall
-    if (os.path.isfile("Panda3D-%s.dmg" % VERSION)): oscmd("rm -f Panda3D-%s.dmg" % VERSION)
+    if (os.path.isfile(dmg_name)): oscmd("rm -f %s" % dmg_name)
     if (os.path.exists("dstroot")): oscmd("rm -rf dstroot")
     if (os.path.exists("dstroot")): oscmd("rm -rf dstroot")
     if (os.path.exists("Panda3D-rw.dmg")): oscmd('rm -f Panda3D-rw.dmg')
     if (os.path.exists("Panda3D-rw.dmg")): oscmd('rm -f Panda3D-rw.dmg')
 
 
@@ -7010,7 +7027,7 @@ def MakeInstallerOSX():
         oscmd("cp -R " + GetOutputDir() + "/bin/" + base + " " + binname)
         oscmd("cp -R " + GetOutputDir() + "/bin/" + base + " " + binname)
 
 
     if PkgSkip("PYTHON")==0:
     if PkgSkip("PYTHON")==0:
-        PV = SDK["PYTHONVERSION"].replace("python", "")
+        PV = SDK["PYTHONVERSION"][6:9]
         oscmd("mkdir -p dstroot/pythoncode/usr/local/bin")
         oscmd("mkdir -p dstroot/pythoncode/usr/local/bin")
         oscmd("mkdir -p dstroot/pythoncode/Developer/Panda3D/panda3d")
         oscmd("mkdir -p dstroot/pythoncode/Developer/Panda3D/panda3d")
         oscmd("mkdir -p dstroot/pythoncode/Library/Python/%s/site-packages" % PV)
         oscmd("mkdir -p dstroot/pythoncode/Library/Python/%s/site-packages" % PV)
@@ -7165,7 +7182,7 @@ def MakeInstallerOSX():
     dist.close()
     dist.close()
 
 
     oscmd('hdiutil create Panda3D-rw.dmg -volname "Panda3D SDK %s" -srcfolder dstroot/Panda3D' % (VERSION))
     oscmd('hdiutil create Panda3D-rw.dmg -volname "Panda3D SDK %s" -srcfolder dstroot/Panda3D' % (VERSION))
-    oscmd('hdiutil convert Panda3D-rw.dmg -format UDBZ -o Panda3D-%s.dmg' % (VERSION))
+    oscmd('hdiutil convert Panda3D-rw.dmg -format UDBZ -o %s' % (dmg_name))
     oscmd('rm -f Panda3D-rw.dmg')
     oscmd('rm -f Panda3D-rw.dmg')
 
 
 def MakeInstallerFreeBSD():
 def MakeInstallerFreeBSD():

+ 21 - 17
makepanda/makepandacore.py

@@ -1928,6 +1928,8 @@ def SdkLocatePython(prefer_thirdparty_python=False):
         SDK["PYTHONEXEC"] = os.path.realpath(sys.executable)
         SDK["PYTHONEXEC"] = os.path.realpath(sys.executable)
         return
         return
 
 
+    abiflags = getattr(sys, 'abiflags', '')
+
     if GetTarget() == 'windows':
     if GetTarget() == 'windows':
         sdkdir = GetThirdpartyBase() + "/win-python"
         sdkdir = GetThirdpartyBase() + "/win-python"
 
 
@@ -1992,26 +1994,28 @@ def SdkLocatePython(prefer_thirdparty_python=False):
         SDK["PYTHON"] = tp_python + "/include/" + SDK["PYTHONVERSION"]
         SDK["PYTHON"] = tp_python + "/include/" + SDK["PYTHONVERSION"]
 
 
     elif GetTarget() == 'darwin':
     elif GetTarget() == 'darwin':
-         # On Mac OS X, use the system Python framework.
-         py_fwx = SDK.get("MACOSX", "") + "/System/Library/Frameworks/Python.framework/Versions/Current"
+        # On macOS, search for the Python framework directory matching the
+        # version number of our current Python version.
+        sysroot = SDK.get("MACOSX", "")
+        version = sysconfig.get_python_version()
 
 
-         if not os.path.islink(py_fwx):
-             exit("Could not locate Python installation at %s" % (py_fwx))
+        py_fwx = "{0}/System/Library/Frameworks/Python.framework/Versions/{1}".format(sysroot, version)
 
 
-         ver = os.path.basename(os.readlink(py_fwx))
-         py_fwx = SDK.get("MACOSX", "") + "/System/Library/Frameworks/Python.framework/Versions/%s" % ver
+        if not os.path.exists(py_fwx):
+            # Fall back to looking on the system.
+            py_fwx = "/Library/Frameworks/Python.framework/Versions/" + version
 
 
-         SDK["PYTHON"] = py_fwx + "/Headers"
-         SDK["PYTHONVERSION"] = "python" + ver
-         SDK["PYTHONEXEC"] = "/System/Library/Frameworks/Python.framework/Versions/" + ver + "/bin/python" + ver
+        if not os.path.exists(py_fwx):
+            exit("Could not locate Python installation at %s" % (py_fwx))
 
 
-         # Avoid choosing the one in the thirdparty package dir.
-         PkgSetCustomLocation("PYTHON")
-         IncDirectory("PYTHON", py_fwx + "/include")
-         LibDirectory("PYTHON", "%s/usr/lib" % (SDK.get("MACOSX", "")))
+        SDK["PYTHON"] = py_fwx + "/Headers"
+        SDK["PYTHONVERSION"] = "python" + version + abiflags
+        SDK["PYTHONEXEC"] = py_fwx + "/bin/python" + version
 
 
-         if sys.version[:3] != ver:
-             print("Warning: building with Python %s instead of %s since you targeted a specific Mac OS X version." % (ver, sys.version[:3]))
+        # Avoid choosing the one in the thirdparty package dir.
+        PkgSetCustomLocation("PYTHON")
+        IncDirectory("PYTHON", py_fwx + "/include")
+        LibDirectory("PYTHON", py_fwx + "/lib")
 
 
     #elif GetTarget() == 'windows':
     #elif GetTarget() == 'windows':
     #    SDK["PYTHON"] = os.path.dirname(sysconfig.get_python_inc())
     #    SDK["PYTHON"] = os.path.dirname(sysconfig.get_python_inc())
@@ -2020,13 +2024,13 @@ def SdkLocatePython(prefer_thirdparty_python=False):
 
 
     else:
     else:
         SDK["PYTHON"] = sysconfig.get_python_inc()
         SDK["PYTHON"] = sysconfig.get_python_inc()
-        SDK["PYTHONVERSION"] = "python" + sysconfig.get_python_version()
+        SDK["PYTHONVERSION"] = "python" + sysconfig.get_python_version() + abiflags
         SDK["PYTHONEXEC"] = os.path.realpath(sys.executable)
         SDK["PYTHONEXEC"] = os.path.realpath(sys.executable)
 
 
     if CrossCompiling():
     if CrossCompiling():
         # We need a version of Python we can run.
         # We need a version of Python we can run.
         SDK["PYTHONEXEC"] = sys.executable
         SDK["PYTHONEXEC"] = sys.executable
-        host_version = "python" + sysconfig.get_python_version()
+        host_version = "python" + sysconfig.get_python_version() + abiflags
         if SDK["PYTHONVERSION"] != host_version:
         if SDK["PYTHONVERSION"] != host_version:
             exit("Host Python version (%s) must be the same as target Python version (%s)!" % (host_version, SDK["PYTHONVERSION"]))
             exit("Host Python version (%s) must be the same as target Python version (%s)!" % (host_version, SDK["PYTHONVERSION"]))
 
 

+ 21 - 73
panda/src/display/displayInformation.cxx

@@ -14,6 +14,13 @@
 #include "graphicsStateGuardian.h"
 #include "graphicsStateGuardian.h"
 #include "displayInformation.h"
 #include "displayInformation.h"
 
 
+// For __rdtsc
+#ifdef _MSC_VER
+#include <intrin.h>
+#elif defined(__GNUC__) && !defined(__clang__)
+#include <x86intrin.h>
+#endif
+
 /**
 /**
  * Returns true if these two DisplayModes are identical.
  * Returns true if these two DisplayModes are identical.
  */
  */
@@ -58,12 +65,6 @@ DisplayInformation::
   if (_display_mode_array != NULL) {
   if (_display_mode_array != NULL) {
     delete[] _display_mode_array;
     delete[] _display_mode_array;
   }
   }
-  if (_cpu_id_data != NULL) {
-    delete _cpu_id_data;
-  }
-  if (_cpu_brand_string != NULL) {
-    delete _cpu_brand_string;
-  }
 }
 }
 
 
 /**
 /**
@@ -134,12 +135,6 @@ DisplayInformation() {
   _driver_date_day = 0;
   _driver_date_day = 0;
   _driver_date_year = 0;
   _driver_date_year = 0;
 
 
-  _cpu_id_version = 1;
-  _cpu_id_size = 0;
-  _cpu_id_data = 0;
-
-  _cpu_vendor_string = 0;
-  _cpu_brand_string = 0;
   _cpu_version_information = 0;
   _cpu_version_information = 0;
   _cpu_brand_index = 0;
   _cpu_brand_index = 0;
 
 
@@ -152,7 +147,6 @@ DisplayInformation() {
   _num_logical_cpus = 0;
   _num_logical_cpus = 0;
 
 
   _get_memory_information_function = 0;
   _get_memory_information_function = 0;
-  _cpu_time_function = 0;
   _update_cpu_frequency_function = 0;
   _update_cpu_frequency_function = 0;
 
 
   _os_version_major = -1;
   _os_version_major = -1;
@@ -493,62 +487,17 @@ get_driver_date_year() {
 /**
 /**
  *
  *
  */
  */
-int DisplayInformation::
-get_cpu_id_version() {
-  return _cpu_id_version;
-}
-
-/**
- * Returns the number of 32-bit values for cpu id binary data.
- */
-int DisplayInformation::
-get_cpu_id_size() {
-  return _cpu_id_size;
-}
-
-/**
- * Returns part of cpu id binary data based on the index.
- */
-unsigned int DisplayInformation::
-get_cpu_id_data(int index) {
-  unsigned int data;
-
-  data = 0;
-  if (index >= 0 && index < _cpu_id_size) {
-    data = _cpu_id_data [index];
-  }
-
-  return data;
+const string &DisplayInformation::
+get_cpu_vendor_string() const {
+  return _cpu_vendor_string;
 }
 }
 
 
 /**
 /**
  *
  *
  */
  */
-const char *DisplayInformation::
-get_cpu_vendor_string() {
-  const char *string;
-
-  string = _cpu_vendor_string;
-  if (string == 0) {
-    string = "";
-  }
-
-  return string;
-}
-
-/**
- *
- */
-const char *DisplayInformation::
-get_cpu_brand_string() {
-  const char *string;
-
-  string = _cpu_brand_string;
-  if (string == 0) {
-    string = "";
-  }
-
-  return string;
+const string &DisplayInformation::
+get_cpu_brand_string() const {
+  return _cpu_brand_string;
 }
 }
 
 
 /**
 /**
@@ -576,18 +525,17 @@ get_cpu_frequency() {
 }
 }
 
 
 /**
 /**
- *
+ * Equivalent to the rdtsc processor instruction.
  */
  */
 uint64_t DisplayInformation::
 uint64_t DisplayInformation::
 get_cpu_time() {
 get_cpu_time() {
-  uint64_t cpu_time;
-
-  cpu_time = 0;
-  if (_cpu_time_function) {
-    cpu_time = _cpu_time_function();
-  }
-
-  return cpu_time;
+#if defined(_MSC_VER) || (defined(__GNUC__) && !defined(__clang__))
+  return __rdtsc();
+#else
+  unsigned int lo, hi = 0;
+  __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+  return ((uint64_t)hi << 32) | lo;
+#endif
 }
 }
 
 
 /**
 /**

+ 5 - 13
panda/src/display/displayInformation.h

@@ -94,17 +94,13 @@ PUBLISHED:
   int get_driver_date_day();
   int get_driver_date_day();
   int get_driver_date_year();
   int get_driver_date_year();
 
 
-  int get_cpu_id_version();
-  int get_cpu_id_size();
-  unsigned int get_cpu_id_data(int index);
-
-  const char *get_cpu_vendor_string();
-  const char *get_cpu_brand_string();
+  const string &get_cpu_vendor_string() const;
+  const string &get_cpu_brand_string() const;
   unsigned int get_cpu_version_information();
   unsigned int get_cpu_version_information();
   unsigned int get_cpu_brand_index();
   unsigned int get_cpu_brand_index();
 
 
   uint64_t get_cpu_frequency();
   uint64_t get_cpu_frequency();
-  uint64_t get_cpu_time();
+  static uint64_t get_cpu_time();
 
 
   uint64_t get_maximum_cpu_frequency();
   uint64_t get_maximum_cpu_frequency();
   uint64_t get_current_cpu_frequency();
   uint64_t get_current_cpu_frequency();
@@ -158,12 +154,9 @@ public:
   int _driver_date_day;
   int _driver_date_day;
   int _driver_date_year;
   int _driver_date_year;
 
 
-  int _cpu_id_version;
-  int _cpu_id_size;
-  unsigned int *_cpu_id_data;
 
 
-  char *_cpu_vendor_string;
-  char *_cpu_brand_string;
+  string _cpu_vendor_string;
+  string _cpu_brand_string;
   unsigned int _cpu_version_information;
   unsigned int _cpu_version_information;
   unsigned int _cpu_brand_index;
   unsigned int _cpu_brand_index;
 
 
@@ -176,7 +169,6 @@ public:
   int _num_logical_cpus;
   int _num_logical_cpus;
 
 
   void (*_get_memory_information_function) (DisplayInformation *display_information);
   void (*_get_memory_information_function) (DisplayInformation *display_information);
-  uint64_t (*_cpu_time_function) (void);
   int (*_update_cpu_frequency_function) (int processor_number, DisplayInformation *display_information);
   int (*_update_cpu_frequency_function) (int processor_number, DisplayInformation *display_information);
 
 
   int _os_version_major;
   int _os_version_major;

+ 157 - 16
panda/src/display/graphicsPipe.cxx

@@ -18,6 +18,92 @@
 #include "mutexHolder.h"
 #include "mutexHolder.h"
 #include "displayInformation.h"
 #include "displayInformation.h"
 
 
+#ifdef IS_LINUX
+#include <sys/sysinfo.h>
+#include <unistd.h>
+#endif
+
+#ifdef IS_OSX
+#include <sys/sysctl.h>
+#endif
+
+#ifdef IS_FREEBSD
+#include <unistd.h>
+#endif
+
+#if defined(__GNUC__) && !defined(__APPLE__)
+// GCC and Clang offer a useful cpuid.h header.
+#include <cpuid.h>
+#endif
+
+#ifdef _MSC_VER
+// MSVC has a __cpuid intrinsic.
+#include <intrin.h>
+#endif
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#include <windows.h>
+#endif
+
+union cpuid_info {
+  char str[16];
+  struct {
+    uint32_t eax, ebx, ecx, edx;
+  };
+};
+
+/**
+ * Returns the highest cpuid leaf that is supported by the CPU.
+ */
+static inline uint32_t get_cpuid_max(uint32_t leaf) {
+#if defined(__GNUC__) && !defined(__APPLE__)
+  return __get_cpuid_max(leaf, 0);
+#elif defined(_MSC_VER)
+  uint32_t p[4] = {0};
+  __cpuid((int *)p, leaf);
+  return p[0];
+#else
+  unsigned int eax = 0;
+  __asm__ ("cpuid\n\t"
+           : "=a" (eax)
+           : "0" (leaf));
+  return eax;
+#endif
+}
+
+/**
+ * Gets cpuid info for the given leaf.
+ */
+static inline void get_cpuid(uint32_t leaf, cpuid_info &info) {
+#if defined(__GNUC__) && !defined(__APPLE__)
+  __cpuid(leaf, info.eax, info.ebx, info.ecx, info.edx);
+#elif defined(_MSC_VER)
+  __cpuid((int *)info.str, leaf);
+#else
+  __asm__ ("cpuid\n\t"
+           : "=a" (info.eax), "=b" (info.ebx), "=c" (info.ecx), "=d" (info.edx)
+           : "0" (leaf));
+#endif
+}
+
+#ifdef IS_LINUX
+/**
+ * Updates the current memory usage statistics in the DisplayInformation.
+ */
+static void update_memory_info(DisplayInformation *info) {
+  struct sysinfo meminfo;
+  if (sysinfo(&meminfo) == 0) {
+    info->_physical_memory = meminfo.totalram;
+    info->_available_physical_memory = meminfo.freeram;
+    info->_page_file_size = meminfo.totalswap;
+    info->_available_page_file_size = meminfo.freeswap;
+  }
+}
+#endif
+
 TypeHandle GraphicsPipe::_type_handle;
 TypeHandle GraphicsPipe::_type_handle;
 
 
 /**
 /**
@@ -38,24 +124,79 @@ GraphicsPipe() :
   _display_width = 0;
   _display_width = 0;
   _display_height = 0;
   _display_height = 0;
 
 
-  _display_information = new DisplayInformation ( );
-}
+  _display_information = new DisplayInformation();
 
 
-/**
- * Don't try to copy GraphicsPipes.
- */
-GraphicsPipe::
-GraphicsPipe(const GraphicsPipe &) {
-  _is_valid = false;
-  nassertv(false);
-}
+  cpuid_info info;
+  const uint32_t max_cpuid = get_cpuid_max(0);
+  const uint32_t max_extended = get_cpuid_max(0x80000000);
 
 
-/**
- * Don't try to copy GraphicsPipes.
- */
-void GraphicsPipe::
-operator = (const GraphicsPipe &) {
-  nassertv(false);
+  if (max_cpuid >= 1) {
+    get_cpuid(0, info);
+    swap(info.ecx, info.edx);
+    _display_information->_cpu_vendor_string = string(info.str + 4, 12);
+
+    get_cpuid(1, info);
+    _display_information->_cpu_version_information = info.eax;
+    _display_information->_cpu_brand_index = info.ebx & 0xff;
+  }
+
+  if (max_extended >= 0x80000004) {
+    char brand[49];
+    get_cpuid(0x80000002, info);
+    memcpy(brand, info.str, 16);
+    get_cpuid(0x80000003, info);
+    memcpy(brand + 16, info.str, 16);
+    get_cpuid(0x80000004, info);
+    memcpy(brand + 32, info.str, 16);
+    brand[48] = 0;
+    _display_information->_cpu_brand_string = brand;
+  }
+
+#if defined(IS_OSX)
+  // macOS exposes a lot of useful information through sysctl.
+  size_t len = sizeof(uint64_t);
+  sysctlbyname("hw.memsize", &_display_information->_physical_memory, &len, NULL, 0);
+  len = sizeof(uint64_t);
+  sysctlbyname("hw.cpufrequency", &_display_information->_cpu_frequency, &len, NULL, 0);
+  len = sizeof(uint64_t);
+  sysctlbyname("hw.cpufrequency", &_display_information->_current_cpu_frequency, &len, NULL, 0);
+  len = sizeof(uint64_t);
+  sysctlbyname("hw.cpufrequency_max", &_display_information->_maximum_cpu_frequency, &len, NULL, 0);
+  len = sizeof(int);
+  sysctlbyname("hw.physicalcpu", &_display_information->_num_cpu_cores, &len, NULL, 0);
+  len = sizeof(int);
+  sysctlbyname("hw.logicalcpu", &_display_information->_num_logical_cpus, &len, NULL, 0);
+
+#elif defined(IS_LINUX)
+  _display_information->_get_memory_information_function = &update_memory_info;
+  update_memory_info(_display_information);
+
+#elif defined(IS_FREEBSD)
+  size_t len = sizeof(uint64_t);
+  sysctlbyname("hw.physmem", &_display_information->_physical_memory, &len, NULL, 0);
+  len = sizeof(uint64_t);
+  sysctlbyname("vm.swap_total", &_display_information->_page_file_size, &len, NULL, 0);
+
+#elif defined(_WIN32)
+  MEMORYSTATUSEX status;
+  status.dwLength = sizeof(MEMORYSTATUSEX);
+  if (GlobalMemoryStatusEx(&status)) {
+    _display_information->_physical_memory = status.ullTotalPhys;
+    _display_information->_available_physical_memory = status.ullAvailPhys;
+    _display_information->_page_file_size = status.ullTotalPageFile;
+    _display_information->_available_page_file_size = status.ullAvailPageFile;
+    _display_information->_process_virtual_memory = status.ullTotalVirtual;
+    _display_information->_available_process_virtual_memory = status.ullAvailVirtual;
+    _display_information->_memory_load = status.dwMemoryLoad;
+  }
+#endif
+
+#if defined(IS_LINUX) || defined(IS_FREEBSD)
+  long nproc = sysconf(_SC_NPROCESSORS_CONF);
+  if (nproc > 0) {
+    _display_information->_num_logical_cpus = nproc;
+  }
+#endif
 }
 }
 
 
 /**
 /**

+ 2 - 2
panda/src/display/graphicsPipe.h

@@ -53,8 +53,8 @@ class EXPCL_PANDA_DISPLAY GraphicsPipe : public TypedReferenceCount {
 protected:
 protected:
   GraphicsPipe();
   GraphicsPipe();
 private:
 private:
-  GraphicsPipe(const GraphicsPipe &copy);
-  void operator = (const GraphicsPipe &copy);
+  GraphicsPipe(const GraphicsPipe &copy) DELETED;
+  GraphicsPipe &operator = (const GraphicsPipe &copy) DELETED_ASSIGN;
 
 
 PUBLISHED:
 PUBLISHED:
   virtual ~GraphicsPipe();
   virtual ~GraphicsPipe();

+ 5 - 2
panda/src/display/graphicsStateGuardian.cxx

@@ -1684,8 +1684,11 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     t = get_external_transform()->get_mat() *
     t = get_external_transform()->get_mat() *
       get_scene()->get_camera_transform()->get_mat() *
       get_scene()->get_camera_transform()->get_mat() *
       np.get_net_transform()->get_inverse()->get_mat() *
       np.get_net_transform()->get_inverse()->get_mat() *
-      LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()) *
-      lens->get_projection_mat() * biasmat;
+      LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system());
+
+    if (!node->is_of_type(PointLight::get_class_type())) {
+      t *= lens->get_projection_mat() * biasmat;
+    }
     return &t;
     return &t;
 
 
   } else {
   } else {

+ 8 - 0
panda/src/downloader/httpChannel.cxx

@@ -1474,6 +1474,14 @@ run_setup_ssl() {
     return false;
     return false;
   }
   }
 
 
+  string hostname = _request.get_url().get_server();
+  result = SSL_set_tlsext_host_name(ssl, hostname.c_str());
+  if (result == 0) {
+    downloader_cat.error()
+      << _NOTIFY_HTTP_CHANNEL_ID
+      << "Could not set TLS SNI hostname to '" << hostname << "'\n";
+  }
+
 /*
 /*
  * It would be nice to use something like SSL_set_client_cert_cb() here to set
  * It would be nice to use something like SSL_set_client_cert_cb() here to set
  * a callback to provide the certificate should it be requested, or even to
  * a callback to provide the certificate should it be requested, or even to

+ 4 - 27
panda/src/express/datagramIterator.I

@@ -30,36 +30,13 @@ DatagramIterator(const Datagram &datagram, size_t offset) :
   nassertv(_current_index <= _datagram->get_length());
   nassertv(_current_index <= _datagram->get_length());
 }
 }
 
 
-/**
- *
- */
-INLINE DatagramIterator::
-DatagramIterator(const DatagramIterator &copy) :
-    _datagram(copy._datagram),
-  _current_index(copy._current_index) {
-}
-
-/**
- *
- */
-INLINE void DatagramIterator::
-operator = (const DatagramIterator &copy) {
-  _datagram = copy._datagram;
-  _current_index = copy._current_index;
-}
 /**
 /**
  * direct Assignment to a Datagram
  * direct Assignment to a Datagram
  */
  */
-INLINE void DatagramIterator::assign(Datagram &datagram, size_t offset)
-{
-    _datagram =&datagram;
-    _current_index = offset;
-}
-/**
- *
- */
-INLINE DatagramIterator::
-~DatagramIterator() {
+INLINE void DatagramIterator::
+assign(Datagram &datagram, size_t offset) {
+  _datagram = &datagram;
+  _current_index = offset;
 }
 }
 
 
 // Various ways to get data and increment the iterator... Cut-and-paste-orama
 // Various ways to get data and increment the iterator... Cut-and-paste-orama

+ 0 - 3
panda/src/express/datagramIterator.h

@@ -31,9 +31,6 @@ public:
 PUBLISHED:
 PUBLISHED:
   INLINE DatagramIterator();
   INLINE DatagramIterator();
   INLINE DatagramIterator(const Datagram &datagram, size_t offset = 0);
   INLINE DatagramIterator(const Datagram &datagram, size_t offset = 0);
-  INLINE DatagramIterator(const DatagramIterator &copy);
-  INLINE void operator = (const DatagramIterator &copy);
-  INLINE ~DatagramIterator();
 
 
   INLINE bool get_bool();
   INLINE bool get_bool();
   INLINE int8_t get_int8();
   INLINE int8_t get_int8();

+ 0 - 7
panda/src/express/hashGeneratorBase.I

@@ -19,13 +19,6 @@ HashGeneratorBase() {
   _hash = 0;
   _hash = 0;
 }
 }
 
 
-/**
- *
- */
-INLINE HashGeneratorBase::
-~HashGeneratorBase() {
-}
-
 /**
 /**
  * Returns the hash number generated.
  * Returns the hash number generated.
  */
  */

+ 0 - 1
panda/src/express/hashGeneratorBase.h

@@ -30,7 +30,6 @@
 class EXPCL_PANDAEXPRESS HashGeneratorBase {
 class EXPCL_PANDAEXPRESS HashGeneratorBase {
 public:
 public:
   INLINE HashGeneratorBase();
   INLINE HashGeneratorBase();
-  INLINE ~HashGeneratorBase();
 
 
   INLINE size_t get_hash() const;
   INLINE size_t get_hash() const;
 
 

+ 0 - 29
panda/src/express/namable.I

@@ -20,35 +20,6 @@ Namable(const string &initial_name) :
 {
 {
 }
 }
 
 
-/**
- *
- */
-INLINE Namable::
-Namable(const Namable &copy) :
-  _name(copy._name)
-{
-}
-
-/**
- *
- */
-INLINE Namable &Namable::
-operator = (const Namable &other) {
-  _name = other._name;
-  return *this;
-}
-
-#ifdef USE_MOVE_SEMANTICS
-/**
- *
- */
-INLINE Namable &Namable::
-operator = (Namable &&other) NOEXCEPT {
-  _name = MOVE(other._name);
-  return *this;
-}
-#endif
-
 /**
 /**
  *
  *
  */
  */

+ 0 - 6
panda/src/express/namable.h

@@ -26,12 +26,6 @@
 class EXPCL_PANDAEXPRESS Namable : public MemoryBase {
 class EXPCL_PANDAEXPRESS Namable : public MemoryBase {
 PUBLISHED:
 PUBLISHED:
   INLINE explicit Namable(const string &initial_name = "");
   INLINE explicit Namable(const string &initial_name = "");
-  INLINE Namable(const Namable &copy);
-  INLINE Namable &operator = (const Namable &other);
-
-#ifdef USE_MOVE_SEMANTICS
-  INLINE Namable &operator = (Namable &&other) NOEXCEPT;
-#endif
 
 
   INLINE void set_name(const string &name);
   INLINE void set_name(const string &name);
   INLINE void clear_name();
   INLINE void clear_name();

+ 0 - 20
panda/src/express/nodePointerTo.I

@@ -33,16 +33,6 @@ NodePointerTo(const NodePointerTo<T> &copy) :
 }
 }
 #endif  // CPPPARSER
 #endif  // CPPPARSER
 
 
-#ifndef CPPPARSER
-/**
- *
- */
-template<class T>
-INLINE NodePointerTo<T>::
-~NodePointerTo() {
-}
-#endif  // CPPPARSER
-
 #ifdef USE_MOVE_SEMANTICS
 #ifdef USE_MOVE_SEMANTICS
 #ifndef CPPPARSER
 #ifndef CPPPARSER
 /**
 /**
@@ -177,16 +167,6 @@ NodeConstPointerTo(const NodeConstPointerTo<T> &copy) :
 }
 }
 #endif  // CPPPARSER
 #endif  // CPPPARSER
 
 
-#ifndef CPPPARSER
-/**
- *
- */
-template<class T>
-INLINE NodeConstPointerTo<T>::
-~NodeConstPointerTo() {
-}
-#endif  // CPPPARSER
-
 #ifdef USE_MOVE_SEMANTICS
 #ifdef USE_MOVE_SEMANTICS
 #ifndef CPPPARSER
 #ifndef CPPPARSER
 /**
 /**

+ 0 - 2
panda/src/express/nodePointerTo.h

@@ -31,7 +31,6 @@ public:
   typedef TYPENAME NodePointerToBase<T>::To To;
   typedef TYPENAME NodePointerToBase<T>::To To;
   INLINE NodePointerTo(To *ptr = (To *)NULL);
   INLINE NodePointerTo(To *ptr = (To *)NULL);
   INLINE NodePointerTo(const NodePointerTo<T> &copy);
   INLINE NodePointerTo(const NodePointerTo<T> &copy);
-  INLINE ~NodePointerTo();
 
 
 #ifdef USE_MOVE_SEMANTICS
 #ifdef USE_MOVE_SEMANTICS
   INLINE NodePointerTo(NodePointerTo<T> &&from) NOEXCEPT;
   INLINE NodePointerTo(NodePointerTo<T> &&from) NOEXCEPT;
@@ -66,7 +65,6 @@ public:
   INLINE NodeConstPointerTo(const To *ptr = (const To *)NULL);
   INLINE NodeConstPointerTo(const To *ptr = (const To *)NULL);
   INLINE NodeConstPointerTo(const NodePointerTo<T> &copy);
   INLINE NodeConstPointerTo(const NodePointerTo<T> &copy);
   INLINE NodeConstPointerTo(const NodeConstPointerTo<T> &copy);
   INLINE NodeConstPointerTo(const NodeConstPointerTo<T> &copy);
-  INLINE ~NodeConstPointerTo();
 
 
 #ifdef USE_MOVE_SEMANTICS
 #ifdef USE_MOVE_SEMANTICS
   INLINE NodeConstPointerTo(NodePointerTo<T> &&from) NOEXCEPT;
   INLINE NodeConstPointerTo(NodePointerTo<T> &&from) NOEXCEPT;

+ 0 - 70
panda/src/express/ordered_vector.I

@@ -33,36 +33,6 @@ ordered_vector(const Compare &compare, TypeHandle type_handle) :
 {
 {
 }
 }
 
 
-/**
- *
- */
-template<class Key, class Compare, class Vector>
-INLINE ordered_vector<Key, Compare, Vector>::
-ordered_vector(const ordered_vector<Key, Compare, Vector> &copy) :
-  _compare(copy._compare),
-  _vector(copy._vector)
-{
-}
-
-/**
- *
- */
-template<class Key, class Compare, class Vector>
-INLINE ordered_vector<Key, Compare, Vector> &ordered_vector<Key, Compare, Vector>::
-operator = (const ordered_vector<Key, Compare, Vector> &copy) {
-  _compare = copy._compare;
-  _vector = copy._vector;
-  return *this;
-}
-
-/**
- *
- */
-template<class Key, class Compare, class Vector>
-INLINE ordered_vector<Key, Compare, Vector>::
-~ordered_vector() {
-}
-
 /**
 /**
  * Returns the iterator that marks the first element in the ordered vector.
  * Returns the iterator that marks the first element in the ordered vector.
  */
  */
@@ -636,26 +606,6 @@ ov_set(const Compare &compare, TypeHandle type_handle) :
 {
 {
 }
 }
 
 
-/**
- *
- */
-template<class Key, class Compare, class Vector>
-INLINE ov_set<Key, Compare, Vector>::
-ov_set(const ov_set<Key, Compare, Vector> &copy) :
-  ordered_vector<Key, Compare, Vector>(copy)
-{
-}
-
-/**
- *
- */
-template<class Key, class Compare, class Vector>
-INLINE ov_set<Key, Compare, Vector> &ov_set<Key, Compare, Vector>::
-operator = (const ov_set<Key, Compare, Vector> &copy) {
-  ordered_vector<Key, Compare, Vector>::operator = (copy);
-  return *this;
-}
-
 /**
 /**
  * Maps to insert_unique().
  * Maps to insert_unique().
  */
  */
@@ -713,26 +663,6 @@ ov_multiset(const Compare &compare, TypeHandle type_handle) :
 {
 {
 }
 }
 
 
-/**
- *
- */
-template<class Key, class Compare, class Vector>
-INLINE ov_multiset<Key, Compare, Vector>::
-ov_multiset(const ov_multiset<Key, Compare, Vector> &copy) :
-  ordered_vector<Key, Compare, Vector>(copy)
-{
-}
-
-/**
- *
- */
-template<class Key, class Compare, class Vector>
-INLINE ov_multiset<Key, Compare, Vector> &ov_multiset<Key, Compare, Vector>::
-operator = (const ov_multiset<Key, Compare, Vector> &copy) {
-  ordered_vector<Key, Compare, Vector>::operator = (copy);
-  return *this;
-}
-
 /**
 /**
  * Maps to insert_nonunique().
  * Maps to insert_nonunique().
  */
  */

+ 0 - 7
panda/src/express/ordered_vector.h

@@ -135,9 +135,6 @@ public:
   INLINE ordered_vector(TypeHandle type_handle = ov_set_type_handle);
   INLINE ordered_vector(TypeHandle type_handle = ov_set_type_handle);
   INLINE ordered_vector(const Compare &compare,
   INLINE ordered_vector(const Compare &compare,
                         TypeHandle type_handle = ov_set_type_handle);
                         TypeHandle type_handle = ov_set_type_handle);
-  INLINE ordered_vector(const ordered_vector<Key, Compare, Vector> &copy);
-  INLINE ordered_vector<Key, Compare, Vector> &operator = (const ordered_vector<Key, Compare, Vector> &copy);
-  INLINE ~ordered_vector();
 
 
   // Iterator access.
   // Iterator access.
   INLINE ITERATOR begin();
   INLINE ITERATOR begin();
@@ -265,8 +262,6 @@ public:
   INLINE ov_set(TypeHandle type_handle = ov_set_type_handle);
   INLINE ov_set(TypeHandle type_handle = ov_set_type_handle);
   INLINE ov_set(const Compare &compare,
   INLINE ov_set(const Compare &compare,
                 TypeHandle type_handle = ov_set_type_handle);
                 TypeHandle type_handle = ov_set_type_handle);
-  INLINE ov_set(const ov_set<Key, Compare, Vector> &copy);
-  INLINE ov_set<Key, Compare, Vector> &operator = (const ov_set<Key, Compare, Vector> &copy);
 
 
   INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key0);
   INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key0);
   INLINE pair<ITERATOR, bool> insert(const VALUE_TYPE &key0);
   INLINE pair<ITERATOR, bool> insert(const VALUE_TYPE &key0);
@@ -288,8 +283,6 @@ public:
   INLINE ov_multiset(TypeHandle type_handle = ov_set_type_handle);
   INLINE ov_multiset(TypeHandle type_handle = ov_set_type_handle);
   INLINE ov_multiset(const Compare &compare,
   INLINE ov_multiset(const Compare &compare,
                      TypeHandle type_handle = ov_set_type_handle);
                      TypeHandle type_handle = ov_set_type_handle);
-  INLINE ov_multiset(const ov_multiset<Key, Compare, Vector> &copy);
-  INLINE ov_multiset<Key, Compare, Vector> &operator = (const ov_multiset<Key, Compare, Vector> &copy);
 
 
   INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key);
   INLINE ITERATOR insert(ITERATOR position, const VALUE_TYPE &key);
   INLINE ITERATOR insert(const VALUE_TYPE &key);
   INLINE ITERATOR insert(const VALUE_TYPE &key);

+ 18 - 34
panda/src/express/pointerTo.I

@@ -16,7 +16,7 @@
  */
  */
 template<class T>
 template<class T>
 ALWAYS_INLINE PointerTo<T>::
 ALWAYS_INLINE PointerTo<T>::
-PointerTo(To *ptr) : PointerToBase<T>(ptr) {
+PointerTo(To *ptr) NOEXCEPT : PointerToBase<T>(ptr) {
 }
 }
 
 
 /**
 /**
@@ -55,16 +55,8 @@ operator = (PointerTo<T> &&from) NOEXCEPT {
  *
  *
  */
  */
 template<class T>
 template<class T>
-INLINE PointerTo<T>::
-~PointerTo() {
-}
-
-/**
- *
- */
-template<class T>
-INLINE TYPENAME PointerTo<T>::To &PointerTo<T>::
-operator *() const {
+CONSTEXPR TYPENAME PointerTo<T>::To &PointerTo<T>::
+operator *() const NOEXCEPT {
   return *((To *)(this->_void_ptr));
   return *((To *)(this->_void_ptr));
 }
 }
 
 
@@ -72,8 +64,8 @@ operator *() const {
  *
  *
  */
  */
 template<class T>
 template<class T>
-INLINE TYPENAME PointerTo<T>::To *PointerTo<T>::
-operator -> () const {
+CONSTEXPR TYPENAME PointerTo<T>::To *PointerTo<T>::
+operator -> () const NOEXCEPT {
   return (To *)(this->_void_ptr);
   return (To *)(this->_void_ptr);
 }
 }
 
 
@@ -84,8 +76,8 @@ operator -> () const {
  * goes because either will be correct.
  * goes because either will be correct.
  */
  */
 template<class T>
 template<class T>
-INLINE PointerTo<T>::
-operator T * () const {
+CONSTEXPR PointerTo<T>::
+operator T * () const NOEXCEPT {
   return (To *)(this->_void_ptr);
   return (To *)(this->_void_ptr);
 }
 }
 
 
@@ -107,8 +99,8 @@ cheat() {
  * compiler problems, particularly for implicit upcasts.
  * compiler problems, particularly for implicit upcasts.
  */
  */
 template<class T>
 template<class T>
-INLINE TYPENAME PointerTo<T>::To *PointerTo<T>::
-p() const {
+CONSTEXPR TYPENAME PointerTo<T>::To *PointerTo<T>::
+p() const NOEXCEPT {
   return (To *)(this->_void_ptr);
   return (To *)(this->_void_ptr);
 }
 }
 
 
@@ -137,7 +129,7 @@ operator = (const PointerTo<T> &copy) {
  */
  */
 template<class T>
 template<class T>
 ALWAYS_INLINE ConstPointerTo<T>::
 ALWAYS_INLINE ConstPointerTo<T>::
-ConstPointerTo(const TYPENAME ConstPointerTo<T>::To *ptr) :
+ConstPointerTo(const TYPENAME ConstPointerTo<T>::To *ptr) NOEXCEPT :
   PointerToBase<T>((TYPENAME ConstPointerTo<T>::To *)ptr)
   PointerToBase<T>((TYPENAME ConstPointerTo<T>::To *)ptr)
 {
 {
 }
 }
@@ -152,14 +144,6 @@ ConstPointerTo(const PointerTo<T> &copy) :
 {
 {
 }
 }
 
 
-/**
- *
- */
-template<class T>
-INLINE ConstPointerTo<T>::
-~ConstPointerTo() {
-}
-
 /**
 /**
  *
  *
  */
  */
@@ -216,8 +200,8 @@ operator = (ConstPointerTo<T> &&from) NOEXCEPT {
  *
  *
  */
  */
 template<class T>
 template<class T>
-INLINE const TYPENAME ConstPointerTo<T>::To &ConstPointerTo<T>::
-operator *() const {
+CONSTEXPR const TYPENAME ConstPointerTo<T>::To &ConstPointerTo<T>::
+operator *() const NOEXCEPT {
   return *((To *)(this->_void_ptr));
   return *((To *)(this->_void_ptr));
 }
 }
 
 
@@ -225,8 +209,8 @@ operator *() const {
  *
  *
  */
  */
 template<class T>
 template<class T>
-INLINE const TYPENAME ConstPointerTo<T>::To *ConstPointerTo<T>::
-operator -> () const {
+CONSTEXPR const TYPENAME ConstPointerTo<T>::To *ConstPointerTo<T>::
+operator -> () const NOEXCEPT {
   return (To *)(this->_void_ptr);
   return (To *)(this->_void_ptr);
 }
 }
 
 
@@ -237,8 +221,8 @@ operator -> () const {
  * don't care which way it goes because either will be correct.
  * don't care which way it goes because either will be correct.
  */
  */
 template<class T>
 template<class T>
-INLINE ConstPointerTo<T>::
-operator const T * () const {
+CONSTEXPR ConstPointerTo<T>::
+operator const T * () const NOEXCEPT {
 return (To *)(this->_void_ptr);
 return (To *)(this->_void_ptr);
 }
 }
 
 
@@ -260,8 +244,8 @@ cheat() {
  * around compiler problems, particularly for implicit upcasts.
  * around compiler problems, particularly for implicit upcasts.
  */
  */
 template<class T>
 template<class T>
-INLINE const TYPENAME ConstPointerTo<T>::To *ConstPointerTo<T>::
-p() const {
+CONSTEXPR const TYPENAME ConstPointerTo<T>::To *ConstPointerTo<T>::
+p() const NOEXCEPT {
   return (To *)(this->_void_ptr);
   return (To *)(this->_void_ptr);
 }
 }
 
 

+ 55 - 41
panda/src/express/pointerTo.h

@@ -14,35 +14,47 @@
 #ifndef POINTERTO_H
 #ifndef POINTERTO_H
 #define POINTERTO_H
 #define POINTERTO_H
 
 
-/*
+/**
  * This file defines the classes PointerTo and ConstPointerTo (and their
  * This file defines the classes PointerTo and ConstPointerTo (and their
  * abbreviations, PT and CPT).  These should be used in place of traditional
  * abbreviations, PT and CPT).  These should be used in place of traditional
- * C-style pointers wherever implicit reference counting is desired.  The
- * syntax is:                     instead of: PointerTo<MyClass> p;
- * MyClass *p; PT(MyClass) p; ConstPointerTo<MyClass> p;       const MyClass
- * *p; CPT(MyClass) p; PointerTo and ConstPointerTo will automatically
- * increment the object's reference count while the pointer is kept.  When the
- * PointerTo object is reassigned or goes out of scope, the reference count is
- * automatically decremented.  If the reference count reaches zero, the object
- * is freed.  Note that const PointerTo<MyClass> is different from
+ * C-style pointers wherever implicit reference counting is desired.
+ *
+ * The syntax is:                     instead of:
+ *
+ *    PointerTo<MyClass> p;            MyClass *p;
+ *    PT(MyClass) p;
+ *
+ *    ConstPointerTo<MyClass> p;       const MyClass *p;
+ *    CPT(MyClass) p;
+ *
+ * PointerTo and ConstPointerTo will automatically increment the object's
+ * reference count while the pointer is kept.  When the PointerTo object is
+ * reassigned or goes out of scope, the reference count is automatically
+ * decremented.  If the reference count reaches zero, the object is freed.
+ *
+ * Note that const PointerTo<MyClass> is different from
  * ConstPointerTo<MyClass>.  A const PointerTo may not reassign its pointer,
  * ConstPointerTo<MyClass>.  A const PointerTo may not reassign its pointer,
  * but it may still modify the contents at that address.  On the other hand, a
  * but it may still modify the contents at that address.  On the other hand, a
  * ConstPointerTo may reassign its pointer at will, but may not modify the
  * ConstPointerTo may reassign its pointer at will, but may not modify the
- * contents.  It is like the difference between (MyClass * const) and (const
- * MyClass *). In order to use PointerTo, it is necessary that the thing
- * pointed to--MyClass in the above example--either inherits from
- * ReferenceCount, or is a proxy built with RefCountProxy or RefCountObj (see
- * referenceCount.h).  However, also see PointerToArray, which does not have
- * this restriction.  It is crucial that the PointerTo object is only used to
- * refer to objects allocated from the free store, for which delete is a
- * sensible thing to do.  If you assign a PointerTo to an automatic variable
- * (allocated from the stack, for instance), bad things will certainly happen
- * when the reference count reaches zero and it tries to delete it.  It's also
- * important to remember that, as always, a virtual destructor is required if
- * you plan to support polymorphism.  That is, if you define a PointerTo to
- * some base type, and assign to it instances of a class derived from that
- * base class, the base class must have a virtual destructor in order to
- * properly destruct the derived object when it is deleted.
+ * contents.  It is like the difference between (MyClass * const) and
+ * (const MyClass *).
+ *
+ * In order to use PointerTo, it is necessary that the thing pointed to
+ * --MyClass in the above example--either inherits from ReferenceCount, or is
+ * a proxy built with RefCountProxy or RefCountObj (see referenceCount.h).
+ * However, also see PointerToArray, which does not have this restriction.
+ *
+ * It is crucial that the PointerTo object is only used to refer to objects
+ * allocated from the free store, for which delete is a sensible thing to do.
+ * If you assign a PointerTo to an automatic variable (allocated from the
+ * stack, for instance), bad things will certainly happen when the reference
+ * count reaches zero and it tries to delete it.
+ *
+ * It's also important to remember that, as always, a virtual destructor is
+ * required if you plan to support polymorphism.  That is, if you define a
+ * PointerTo to some base type, and assign to it instances of a class derived
+ * from that base class, the base class must have a virtual destructor in
+ * order to properly destruct the derived object when it is deleted.
  */
  */
 
 
 #include "pandabase.h"
 #include "pandabase.h"
@@ -58,10 +70,9 @@ class PointerTo : public PointerToBase<T> {
 public:
 public:
   typedef TYPENAME PointerToBase<T>::To To;
   typedef TYPENAME PointerToBase<T>::To To;
 PUBLISHED:
 PUBLISHED:
-  ALWAYS_INLINE PointerTo() DEFAULT_CTOR;
-  ALWAYS_INLINE PointerTo(To *ptr);
+  CONSTEXPR PointerTo() NOEXCEPT DEFAULT_CTOR;
+  ALWAYS_INLINE PointerTo(To *ptr) NOEXCEPT;
   INLINE PointerTo(const PointerTo<T> &copy);
   INLINE PointerTo(const PointerTo<T> &copy);
-  INLINE ~PointerTo();
 
 
 public:
 public:
 #ifdef USE_MOVE_SEMANTICS
 #ifdef USE_MOVE_SEMANTICS
@@ -69,10 +80,10 @@ public:
   INLINE PointerTo<T> &operator = (PointerTo<T> &&from) NOEXCEPT;
   INLINE PointerTo<T> &operator = (PointerTo<T> &&from) NOEXCEPT;
 #endif
 #endif
 
 
-  INLINE To &operator *() const;
-  INLINE To *operator -> () const;
+  CONSTEXPR To &operator *() const NOEXCEPT;
+  CONSTEXPR To *operator -> () const NOEXCEPT;
   // MSVC.NET 2005 insists that we use T *, and not To *, here.
   // MSVC.NET 2005 insists that we use T *, and not To *, here.
-  INLINE operator T *() const;
+  CONSTEXPR operator T *() const NOEXCEPT;
 
 
   INLINE T *&cheat();
   INLINE T *&cheat();
 
 
@@ -89,7 +100,7 @@ PUBLISHED:
   // the DCAST macro defined in typedObject.h instead, e.g.  DCAST(MyType,
   // the DCAST macro defined in typedObject.h instead, e.g.  DCAST(MyType,
   // ptr).  This provides a clean downcast that doesn't require .p() or any
   // ptr).  This provides a clean downcast that doesn't require .p() or any
   // double-casting, and it can be run-time checked for correctness.
   // double-casting, and it can be run-time checked for correctness.
-  INLINE To *p() const;
+  CONSTEXPR To *p() const NOEXCEPT;
 
 
   INLINE PointerTo<T> &operator = (To *ptr);
   INLINE PointerTo<T> &operator = (To *ptr);
   INLINE PointerTo<T> &operator = (const PointerTo<T> &copy);
   INLINE PointerTo<T> &operator = (const PointerTo<T> &copy);
@@ -98,8 +109,10 @@ PUBLISHED:
   // anyway just to help out interrogate (which doesn't seem to want to
   // anyway just to help out interrogate (which doesn't seem to want to
   // automatically export the PointerToBase class).  When this works again in
   // automatically export the PointerToBase class).  When this works again in
   // interrogate, we can remove these.
   // interrogate, we can remove these.
-  INLINE bool is_null() const { return PointerToBase<T>::is_null(); }
-  INLINE void clear() { PointerToBase<T>::clear(); }
+#ifdef CPPPARSER
+  INLINE bool is_null() const;
+  INLINE void clear();
+#endif
 };
 };
 
 
 
 
@@ -120,11 +133,10 @@ class ConstPointerTo : public PointerToBase<T> {
 public:
 public:
   typedef TYPENAME PointerToBase<T>::To To;
   typedef TYPENAME PointerToBase<T>::To To;
 PUBLISHED:
 PUBLISHED:
-  ALWAYS_INLINE ConstPointerTo() DEFAULT_CTOR;
-  ALWAYS_INLINE ConstPointerTo(const To *ptr);
+  CONSTEXPR ConstPointerTo() NOEXCEPT DEFAULT_CTOR;
+  ALWAYS_INLINE ConstPointerTo(const To *ptr) NOEXCEPT;
   INLINE ConstPointerTo(const PointerTo<T> &copy);
   INLINE ConstPointerTo(const PointerTo<T> &copy);
   INLINE ConstPointerTo(const ConstPointerTo<T> &copy);
   INLINE ConstPointerTo(const ConstPointerTo<T> &copy);
-  INLINE ~ConstPointerTo();
 
 
 public:
 public:
 #ifdef USE_MOVE_SEMANTICS
 #ifdef USE_MOVE_SEMANTICS
@@ -134,14 +146,14 @@ public:
   INLINE ConstPointerTo<T> &operator = (ConstPointerTo<T> &&from) NOEXCEPT;
   INLINE ConstPointerTo<T> &operator = (ConstPointerTo<T> &&from) NOEXCEPT;
 #endif
 #endif
 
 
-  INLINE const To &operator *() const;
-  INLINE const To *operator -> () const;
-  INLINE operator const T *() const;
+  CONSTEXPR const To &operator *() const NOEXCEPT;
+  CONSTEXPR const To *operator -> () const NOEXCEPT;
+  CONSTEXPR operator const T *() const NOEXCEPT;
 
 
   INLINE const T *&cheat();
   INLINE const T *&cheat();
 
 
 PUBLISHED:
 PUBLISHED:
-  INLINE const To *p() const;
+  CONSTEXPR const To *p() const NOEXCEPT;
 
 
   INLINE ConstPointerTo<T> &operator = (const To *ptr);
   INLINE ConstPointerTo<T> &operator = (const To *ptr);
   INLINE ConstPointerTo<T> &operator = (const PointerTo<T> &copy);
   INLINE ConstPointerTo<T> &operator = (const PointerTo<T> &copy);
@@ -151,7 +163,9 @@ PUBLISHED:
   // anyway just to help out interrogate (which doesn't seem to want to
   // anyway just to help out interrogate (which doesn't seem to want to
   // automatically export the PointerToBase class).  When this works again in
   // automatically export the PointerToBase class).  When this works again in
   // interrogate, we can remove this.
   // interrogate, we can remove this.
-  INLINE void clear() { PointerToBase<T>::clear(); }
+#ifdef CPPPARSER
+  INLINE void clear();
+#endif
 };
 };
 
 
 
 

+ 22 - 0
panda/src/express/pointerToArray.I

@@ -68,6 +68,17 @@ PointerToArray(const PointerToArray<Element> &copy) :
 {
 {
 }
 }
 
 
+/**
+ * Initializes a PointerToArray by copying existing elements.
+ */
+template<class Element>
+INLINE PointerToArray<Element>::
+PointerToArray(const Element *begin, const Element *end, TypeHandle type_handle) :
+  PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(begin, end, type_handle)),
+  _type_handle(type_handle)
+{
+}
+
 #ifdef USE_MOVE_SEMANTICS
 #ifdef USE_MOVE_SEMANTICS
 /**
 /**
  *
  *
@@ -627,6 +638,17 @@ ConstPointerToArray(TypeHandle type_handle) :
 {
 {
 }
 }
 
 
+/**
+ * Initializes a ConstPointerToArray by copying existing elements.
+ */
+template<class Element>
+INLINE ConstPointerToArray<Element>::
+ConstPointerToArray(const Element *begin, const Element *end, TypeHandle type_handle) :
+  PointerToArrayBase<Element>(new ReferenceCountedVector<Element>(begin, end, type_handle)),
+  _type_handle(type_handle)
+{
+}
+
 /**
 /**
  *
  *
  */
  */

+ 2 - 0
panda/src/express/pointerToArray.h

@@ -134,6 +134,7 @@ public:
   INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element));
   INLINE PointerToArray(TypeHandle type_handle = get_type_handle(Element));
   INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element));
   INLINE static PointerToArray<Element> empty_array(size_type n, TypeHandle type_handle = get_type_handle(Element));
   INLINE PointerToArray(size_type n, const Element &value, TypeHandle type_handle = get_type_handle(Element));
   INLINE PointerToArray(size_type n, const Element &value, TypeHandle type_handle = get_type_handle(Element));
+  INLINE PointerToArray(const Element *begin, const Element *end, TypeHandle type_handle = get_type_handle(Element));
   INLINE PointerToArray(const PointerToArray<Element> &copy);
   INLINE PointerToArray(const PointerToArray<Element> &copy);
 
 
 #ifdef USE_MOVE_SEMANTICS
 #ifdef USE_MOVE_SEMANTICS
@@ -289,6 +290,7 @@ PUBLISHED:
   typedef TYPENAME pvector<Element>::size_type size_type;
   typedef TYPENAME pvector<Element>::size_type size_type;
 
 
   INLINE ConstPointerToArray(TypeHandle type_handle = get_type_handle(Element));
   INLINE ConstPointerToArray(TypeHandle type_handle = get_type_handle(Element));
+  INLINE ConstPointerToArray(const Element *begin, const Element *end, TypeHandle type_handle = get_type_handle(Element));
   INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
   INLINE ConstPointerToArray(const PointerToArray<Element> &copy);
   INLINE ConstPointerToArray(const ConstPointerToArray<Element> &copy);
   INLINE ConstPointerToArray(const ConstPointerToArray<Element> &copy);
 
 

+ 4 - 13
panda/src/express/pointerToArrayBase.I

@@ -19,17 +19,6 @@ INLINE ReferenceCountedVector<Element>::
 ReferenceCountedVector(TypeHandle type_handle) : pvector<Element>(type_handle) {
 ReferenceCountedVector(TypeHandle type_handle) : pvector<Element>(type_handle) {
 }
 }
 
 
-/**
- *
- */
-template<class Element>
-INLINE ReferenceCountedVector<Element>::
-ReferenceCountedVector(const ReferenceCountedVector<Element> &copy) :
-  NodeReferenceCount(copy),
-  pvector<Element>(copy)
-{
-}
-
 /**
 /**
  * Creates an array of initial_size elements.
  * Creates an array of initial_size elements.
  */
  */
@@ -41,11 +30,13 @@ ReferenceCountedVector(TYPENAME ReferenceCountedVector<Element>::size_type initi
 }
 }
 
 
 /**
 /**
- *
+ * Creates an array with all elements from begin up to but not including end.
  */
  */
 template<class Element>
 template<class Element>
 INLINE ReferenceCountedVector<Element>::
 INLINE ReferenceCountedVector<Element>::
-~ReferenceCountedVector() {
+ReferenceCountedVector(const Element *begin, const Element *end, TypeHandle type_handle) :
+  pvector<Element>(begin, end, type_handle)
+{
 }
 }
 
 
 /**
 /**

+ 1 - 2
panda/src/express/pointerToArrayBase.h

@@ -41,9 +41,8 @@ public:
   typedef TYPENAME pvector<Element>::size_type size_type;
   typedef TYPENAME pvector<Element>::size_type size_type;
 
 
   INLINE ReferenceCountedVector(TypeHandle type_handle);
   INLINE ReferenceCountedVector(TypeHandle type_handle);
-  INLINE ReferenceCountedVector(const ReferenceCountedVector<Element> &copy);
   INLINE ReferenceCountedVector(size_type initial_size, TypeHandle type_handle);
   INLINE ReferenceCountedVector(size_type initial_size, TypeHandle type_handle);
-  INLINE ~ReferenceCountedVector();
+  INLINE ReferenceCountedVector(const Element *begin, const Element *end, TypeHandle type_handle);
   ALLOC_DELETED_CHAIN(ReferenceCountedVector<Element>);
   ALLOC_DELETED_CHAIN(ReferenceCountedVector<Element>);
 
 
   INLINE size_type size() const;
   INLINE size_type size() const;

+ 1 - 1
panda/src/express/pointerToBase.h

@@ -31,7 +31,7 @@ public:
   typedef T To;
   typedef T To;
 
 
 protected:
 protected:
-  ALWAYS_INLINE PointerToBase() DEFAULT_CTOR;
+  CONSTEXPR PointerToBase() NOEXCEPT DEFAULT_CTOR;
   INLINE PointerToBase(To *ptr);
   INLINE PointerToBase(To *ptr);
   INLINE PointerToBase(const PointerToBase<T> &copy);
   INLINE PointerToBase(const PointerToBase<T> &copy);
   INLINE ~PointerToBase();
   INLINE ~PointerToBase();

+ 8 - 17
panda/src/express/pointerToVoid.I

@@ -14,34 +14,25 @@
 /**
 /**
  *
  *
  */
  */
-INLINE PointerToVoid::
-PointerToVoid() {
-  _void_ptr = (void *)NULL;
+CONSTEXPR PointerToVoid::
+PointerToVoid() NOEXCEPT : _void_ptr(nullptr) {
 }
 }
 
 
 /**
 /**
  *
  *
  */
  */
-INLINE PointerToVoid::
-~PointerToVoid() {
-  nassertv(_void_ptr == (void *)NULL);
-}
-
-/**
- * Don't use this constructor.
- */
-INLINE PointerToVoid::
-PointerToVoid(const PointerToVoid &) {
-  nassertv(false);
-}
+//INLINE PointerToVoid::
+//~PointerToVoid() {
+//  nassertv(_void_ptr == nullptr);
+//}
 
 
 /**
 /**
  * Returns true if the PointerTo is a NULL pointer, false otherwise.  (Direct
  * Returns true if the PointerTo is a NULL pointer, false otherwise.  (Direct
  * comparison to a NULL pointer also works.)
  * comparison to a NULL pointer also works.)
  */
  */
-ALWAYS_INLINE bool PointerToVoid::
+CONSTEXPR bool PointerToVoid::
 is_null() const {
 is_null() const {
-  return (_void_ptr == (void *)NULL);
+  return _void_ptr == nullptr;
 }
 }
 
 
 /**
 /**

+ 4 - 4
panda/src/express/pointerToVoid.h

@@ -32,14 +32,14 @@
  */
  */
 class EXPCL_PANDAEXPRESS PointerToVoid : public MemoryBase {
 class EXPCL_PANDAEXPRESS PointerToVoid : public MemoryBase {
 protected:
 protected:
-  INLINE PointerToVoid();
-  INLINE ~PointerToVoid();
+  CONSTEXPR PointerToVoid() NOEXCEPT;
+  //INLINE ~PointerToVoid();
 
 
 private:
 private:
-  INLINE PointerToVoid(const PointerToVoid &copy);
+  PointerToVoid(const PointerToVoid &copy) DELETED;
 
 
 PUBLISHED:
 PUBLISHED:
-  ALWAYS_INLINE bool is_null() const;
+  CONSTEXPR bool is_null() const;
   INLINE size_t get_hash() const;
   INLINE size_t get_hash() const;
 
 
 public:
 public:

+ 3 - 10
panda/src/express/weakPointerToVoid.I

@@ -15,16 +15,9 @@
  *
  *
  */
  */
 INLINE WeakPointerToVoid::
 INLINE WeakPointerToVoid::
-WeakPointerToVoid() {
-  _ptr_was_deleted = false;
-  _callback = NULL;
-}
-
-/**
- *
- */
-INLINE WeakPointerToVoid::
-~WeakPointerToVoid() {
+WeakPointerToVoid() :
+  _ptr_was_deleted(false),
+  _callback(NULL) {
 }
 }
 
 
 /**
 /**

+ 0 - 1
panda/src/express/weakPointerToVoid.h

@@ -25,7 +25,6 @@
 class EXPCL_PANDAEXPRESS WeakPointerToVoid : public PointerToVoid {
 class EXPCL_PANDAEXPRESS WeakPointerToVoid : public PointerToVoid {
 protected:
 protected:
   INLINE WeakPointerToVoid();
   INLINE WeakPointerToVoid();
-  INLINE ~WeakPointerToVoid();
 
 
 public:
 public:
   INLINE void mark_deleted();
   INLINE void mark_deleted();

+ 18 - 10
panda/src/gobj/vertexDataBuffer.I

@@ -67,17 +67,22 @@ INLINE const unsigned char *VertexDataBuffer::
 get_read_pointer(bool force) const {
 get_read_pointer(bool force) const {
   LightMutexHolder holder(_lock);
   LightMutexHolder holder(_lock);
 
 
+  const unsigned char *ptr;
   if (_resident_data != (unsigned char *)NULL || _size == 0) {
   if (_resident_data != (unsigned char *)NULL || _size == 0) {
-    return _resident_data;
+    ptr = _resident_data;
+  } else {
+    nassertr(_block != (VertexDataBlock *)NULL, NULL);
+    nassertr(_reserved_size >= _size, NULL);
+
+    // We don't necessarily need to page the buffer all the way into independent
+    // status; it's sufficient just to return the block's pointer, which will
+    // force its page to resident status.
+    ptr = _block->get_pointer(force);
   }
   }
-
-  nassertr(_block != (VertexDataBlock *)NULL, NULL);
-  nassertr(_reserved_size >= _size, NULL);
-
-  // We don't necessarily need to page the buffer all the way into independent
-  // status; it's sufficient just to return the block's pointer, which will
-  // force its page to resident status.
-  return _block->get_pointer(force);
+#ifdef _DEBUG
+  assert(((uintptr_t)ptr % MEMORY_HOOK_ALIGNMENT) == 0);
+#endif
+  return (const unsigned char *)ASSUME_ALIGNED(ptr, MEMORY_HOOK_ALIGNMENT);
 }
 }
 
 
 /**
 /**
@@ -91,7 +96,10 @@ get_write_pointer() {
     do_page_in();
     do_page_in();
   }
   }
   nassertr(_reserved_size >= _size, NULL);
   nassertr(_reserved_size >= _size, NULL);
-  return _resident_data;
+#ifdef _DEBUG
+  assert(((uintptr_t)_resident_data % MEMORY_HOOK_ALIGNMENT) == 0);
+#endif
+  return (unsigned char *)ASSUME_ALIGNED(_resident_data, MEMORY_HOOK_ALIGNMENT);
 }
 }
 
 
 /**
 /**

+ 2 - 2
panda/src/parametrics/parametricCurveCollection.h

@@ -11,8 +11,8 @@
  * @date 2001-03-04
  * @date 2001-03-04
  */
  */
 
 
-#ifndef NODEPATHCOLLECTION_H
-#define NODEPATHCOLLECTION_H
+#ifndef PARAMETRICCURVECOLLECTION_H
+#define PARAMETRICCURVECOLLECTION_H
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 
 

+ 2 - 0
panda/src/pgraph/nodePath.h

@@ -659,6 +659,8 @@ PUBLISHED:
   INLINE void set_shader_input(CPT_InternalName id, PN_stdfloat n1, PN_stdfloat n2=0,
   INLINE void set_shader_input(CPT_InternalName id, PN_stdfloat n1, PN_stdfloat n2=0,
                                PN_stdfloat n3=0, PN_stdfloat n4=0, int priority=0);
                                PN_stdfloat n3=0, PN_stdfloat n4=0, int priority=0);
 
 
+  EXTENSION(void set_shader_inputs(PyObject *args, PyObject *kwargs));
+
   void clear_shader_input(CPT_InternalName id);
   void clear_shader_input(CPT_InternalName id);
   void set_instance_count(int instance_count);
   void set_instance_count(int instance_count);
 
 

+ 216 - 0
panda/src/pgraph/nodePath_ext.cxx

@@ -13,6 +13,7 @@
 
 
 #include "nodePath_ext.h"
 #include "nodePath_ext.h"
 #include "typedWritable_ext.h"
 #include "typedWritable_ext.h"
+#include "shaderAttrib.h"
 
 
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
 
 
@@ -24,6 +25,35 @@ extern struct Dtool_PyTypedObject Dtool_LPoint3d;
 #else
 #else
 extern struct Dtool_PyTypedObject Dtool_LPoint3f;
 extern struct Dtool_PyTypedObject Dtool_LPoint3f;
 #endif
 #endif
+extern struct Dtool_PyTypedObject Dtool_Texture;
+extern struct Dtool_PyTypedObject Dtool_NodePath;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_float;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_double;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_int;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4f;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3f;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2f;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLMatrix4f;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_LMatrix3f;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4d;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3d;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2d;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLMatrix4d;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_LMatrix3d;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4i;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3i;
+extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2i;
+extern struct Dtool_PyTypedObject Dtool_LVecBase4f;
+extern struct Dtool_PyTypedObject Dtool_LVecBase3f;
+extern struct Dtool_PyTypedObject Dtool_LVecBase2f;
+extern struct Dtool_PyTypedObject Dtool_LVecBase4d;
+extern struct Dtool_PyTypedObject Dtool_LVecBase3d;
+extern struct Dtool_PyTypedObject Dtool_LVecBase2d;
+extern struct Dtool_PyTypedObject Dtool_LVecBase4i;
+extern struct Dtool_PyTypedObject Dtool_LVecBase3i;
+extern struct Dtool_PyTypedObject Dtool_LVecBase2i;
+extern struct Dtool_PyTypedObject Dtool_ShaderBuffer;
+extern struct Dtool_PyTypedObject Dtool_ParamValueBase;
 #endif  // CPPPARSER
 #endif  // CPPPARSER
 
 
 /**
 /**
@@ -211,6 +241,192 @@ py_decode_NodePath_from_bam_stream_persist(PyObject *unpickler, const string &da
   return NodePath::decode_from_bam_stream(data, reader);
   return NodePath::decode_from_bam_stream(data, reader);
 }
 }
 
 
+/**
+ * Sets multiple shader inputs at the same time.  This can be significantly
+ * more efficient if many inputs need to be set at the same time.
+ */
+void Extension<NodePath>::
+set_shader_inputs(PyObject *args, PyObject *kwargs) {
+  if (PyObject_Size(args) > 0) {
+    Dtool_Raise_TypeError("NodePath.set_shader_inputs takes only keyword arguments");
+    return;
+  }
+
+  PT(PandaNode) node = _this->node();
+  CPT(RenderAttrib) prev_attrib = node->get_attrib(ShaderAttrib::get_class_slot());
+  PT(ShaderAttrib) attrib;
+  if (prev_attrib == nullptr) {
+    attrib = new ShaderAttrib();
+  } else {
+    attrib = new ShaderAttrib(*(const ShaderAttrib *)prev_attrib.p());
+  }
+
+  PyObject *key, *value;
+  Py_ssize_t pos = 0;
+
+  while (PyDict_Next(kwargs, &pos, &key, &value)) {
+    char *buffer;
+    Py_ssize_t length;
+#if PY_MAJOR_VERSION >= 3
+    buffer = (char *)PyUnicode_AsUTF8AndSize(key, &length);
+    if (buffer == nullptr) {
+#else
+    if (PyString_AsStringAndSize(key, &buffer, &length) == -1) {
+#endif
+      Dtool_Raise_TypeError("NodePath.set_shader_inputs accepts only string keywords");
+      return;
+    }
+
+    CPT_InternalName name(string(buffer, length));
+    ShaderInput *input = nullptr;
+
+    if (PyTuple_CheckExact(value)) {
+      // A tuple is interpreted as a vector.
+      Py_ssize_t size = PyTuple_GET_SIZE(value);
+      if (size > 4) {
+        Dtool_Raise_TypeError("NodePath.set_shader_inputs tuple input should not have more than 4 scalars");
+        return;
+      }
+      // If any of them is a float, we are storing it as a float vector.
+      bool is_float = false;
+      for (Py_ssize_t i = 0; i < size; ++i) {
+        if (PyFloat_CheckExact(PyTuple_GET_ITEM(value, i))) {
+          is_float = true;
+          break;
+        }
+      }
+      if (is_float) {
+        LVecBase4 vec(0);
+        for (Py_ssize_t i = 0; i < size; ++i) {
+          vec[i] = (PN_stdfloat)PyFloat_AsDouble(PyTuple_GET_ITEM(value, i));
+        }
+        input = new ShaderInput(name, vec);
+      } else {
+        LVecBase4i vec(0);
+        for (Py_ssize_t i = 0; i < size; ++i) {
+          vec[i] = (int)PyLong_AsLong(PyTuple_GET_ITEM(value, i));
+        }
+        input = new ShaderInput(name, vec);
+      }
+
+    } else if (DtoolCanThisBeAPandaInstance(value)) {
+      Dtool_PyInstDef *inst = (Dtool_PyInstDef *)value;
+      void *ptr;
+
+      if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_Texture))) {
+        input = new ShaderInput(name, (Texture *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_NodePath))) {
+        input = new ShaderInput(name, *(const NodePath *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_float))) {
+        input = new ShaderInput(name, *(const PTA_float *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_double))) {
+        input = new ShaderInput(name, *(const PTA_double *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_int))) {
+        input = new ShaderInput(name, *(const PTA_int *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4f))) {
+        input = new ShaderInput(name, *(const PTA_LVecBase4f *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3f))) {
+        input = new ShaderInput(name, *(const PTA_LVecBase3f *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2f))) {
+        input = new ShaderInput(name, *(const PTA_LVecBase2f *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLMatrix4f))) {
+        input = new ShaderInput(name, *(const PTA_LMatrix4f *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LMatrix3f))) {
+        input = new ShaderInput(name, *(const PTA_LMatrix3f *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4d))) {
+        input = new ShaderInput(name, *(const PTA_LVecBase4d *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3d))) {
+        input = new ShaderInput(name, *(const PTA_LVecBase3d *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2d))) {
+        input = new ShaderInput(name, *(const PTA_LVecBase2d *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLMatrix4d))) {
+        input = new ShaderInput(name, *(const PTA_LMatrix4d *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LMatrix3d))) {
+        input = new ShaderInput(name, *(const PTA_LMatrix3d *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4i))) {
+        input = new ShaderInput(name, *(const PTA_LVecBase4i *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3i))) {
+        input = new ShaderInput(name, *(const PTA_LVecBase3i *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2i))) {
+        input = new ShaderInput(name, *(const PTA_LVecBase2i *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4f))) {
+        input = new ShaderInput(name, *(const LVecBase4f *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3f))) {
+        input = new ShaderInput(name, *(const LVecBase3f *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2f))) {
+        input = new ShaderInput(name, *(const LVecBase2f *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4d))) {
+        input = new ShaderInput(name, *(const LVecBase4d *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3d))) {
+        input = new ShaderInput(name, *(const LVecBase3d *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2d))) {
+        input = new ShaderInput(name, *(const LVecBase2d *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4i))) {
+        input = new ShaderInput(name, *(const LVecBase4i *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3i))) {
+        input = new ShaderInput(name, *(const LVecBase3i *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2i))) {
+        input = new ShaderInput(name, *(const LVecBase2i *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_ShaderBuffer))) {
+        input = new ShaderInput(name, (ShaderBuffer *)ptr);
+
+      } else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_ParamValueBase))) {
+        input = new ShaderInput(name, (ParamValueBase *)ptr);
+
+      } else {
+        Dtool_Raise_TypeError("unknown type passed to NodePath.set_shader_inputs");
+        return;
+      }
+
+    } else if (PyFloat_Check(value)) {
+      input = new ShaderInput(name, LVecBase4(PyFloat_AS_DOUBLE(value), 0, 0, 0));
+
+#if PY_MAJOR_VERSION < 3
+    } else if (PyInt_Check(value)) {
+      input = new ShaderInput(name, LVecBase4i((int)PyInt_AS_LONG(value), 0, 0, 0));
+#endif
+
+    } else if (PyLong_Check(value)) {
+      input = new ShaderInput(name, LVecBase4i((int)PyLong_AsLong(value), 0, 0, 0));
+
+    } else {
+      Dtool_Raise_TypeError("unknown type passed to NodePath.set_shader_inputs");
+      return;
+    }
+
+    attrib->_inputs[move(name)] = input;
+  }
+
+  node->set_attrib(ShaderAttrib::return_new(attrib));
+}
+
 /**
 /**
  * Returns the tight bounds as a 2-tuple of LPoint3 objects.  This is a
  * Returns the tight bounds as a 2-tuple of LPoint3 objects.  This is a
  * convenience function for Python users, among which the use of
  * convenience function for Python users, among which the use of

+ 2 - 0
panda/src/pgraph/nodePath_ext.h

@@ -49,6 +49,8 @@ public:
   // This is defined to implement cycle detection in Python tags.
   // This is defined to implement cycle detection in Python tags.
   INLINE int __traverse__(visitproc visit, void *arg);
   INLINE int __traverse__(visitproc visit, void *arg);
 
 
+  void set_shader_inputs(PyObject *args, PyObject *kwargs);
+
   PyObject *get_tight_bounds(const NodePath &other = NodePath()) const;
   PyObject *get_tight_bounds(const NodePath &other = NodePath()) const;
 };
 };
 
 

+ 3 - 0
panda/src/pgraph/shaderAttrib.h

@@ -31,6 +31,7 @@
 #include "pta_LVecBase4.h"
 #include "pta_LVecBase4.h"
 #include "pta_LVecBase3.h"
 #include "pta_LVecBase3.h"
 #include "pta_LVecBase2.h"
 #include "pta_LVecBase2.h"
+#include "extension.h"
 
 
 /**
 /**
  *
  *
@@ -147,6 +148,8 @@ private:
   typedef pmap<CPT_InternalName, CPT(ShaderInput)> Inputs;
   typedef pmap<CPT_InternalName, CPT(ShaderInput)> Inputs;
   Inputs _inputs;
   Inputs _inputs;
 
 
+  friend class Extension<NodePath>;
+
 PUBLISHED:
 PUBLISHED:
   static int get_class_slot() {
   static int get_class_slot() {
     return _attrib_slot;
     return _attrib_slot;

+ 0 - 27
panda/src/putil/bitArray.I

@@ -30,26 +30,6 @@ BitArray(WordType init_value) {
   _highest_bits = 0;
   _highest_bits = 0;
 }
 }
 
 
-/**
- *
- */
-INLINE BitArray::
-BitArray(const BitArray &copy) :
-  _array(copy._array),
-  _highest_bits(copy._highest_bits)
-{
-}
-
-/**
- *
- */
-INLINE BitArray &BitArray::
-operator = (const BitArray &copy) {
-  _array = copy._array;
-  _highest_bits = copy._highest_bits;
-  return *this;
-}
-
 /**
 /**
  * Returns a BitArray with an infinite array of bits, all on.
  * Returns a BitArray with an infinite array of bits, all on.
  */
  */
@@ -98,13 +78,6 @@ range(int low_bit, int size) {
   return result;
   return result;
 }
 }
 
 
-/**
- *
- */
-INLINE BitArray::
-~BitArray() {
-}
-
 /**
 /**
  * Returns true if there is a maximum number of bits that may be stored in
  * Returns true if there is a maximum number of bits that may be stored in
  * this structure, false otherwise.  If this returns true, the number may be
  * this structure, false otherwise.  If this returns true, the number may be

+ 0 - 4
panda/src/putil/bitArray.h

@@ -46,8 +46,6 @@ PUBLISHED:
 
 
   INLINE BitArray();
   INLINE BitArray();
   INLINE BitArray(WordType init_value);
   INLINE BitArray(WordType init_value);
-  INLINE BitArray(const BitArray &copy);
-  INLINE BitArray &operator = (const BitArray &copy);
   BitArray(const SparseArray &from);
   BitArray(const SparseArray &from);
 
 
   INLINE static BitArray all_on();
   INLINE static BitArray all_on();
@@ -56,8 +54,6 @@ PUBLISHED:
   INLINE static BitArray bit(int index);
   INLINE static BitArray bit(int index);
   INLINE static BitArray range(int low_bit, int size);
   INLINE static BitArray range(int low_bit, int size);
 
 
-  INLINE ~BitArray();
-
   CONSTEXPR static bool has_max_num_bits();
   CONSTEXPR static bool has_max_num_bits();
   CONSTEXPR static int get_max_num_bits();
   CONSTEXPR static int get_max_num_bits();
 
 

+ 0 - 28
panda/src/putil/bitMask.I

@@ -34,26 +34,6 @@ BitMask(WordType init_value) :
 {
 {
 }
 }
 
 
-/**
- *
- */
-template<class WType, int nbits>
-INLINE BitMask<WType, nbits>::
-BitMask(const BitMask<WType, nbits> &copy) :
-  _word(copy._word)
-{
-}
-
-/**
- *
- */
-template<class WType, int nbits>
-INLINE BitMask<WType, nbits> &BitMask<WType, nbits>::
-operator = (const BitMask<WType, nbits> &copy) {
-  _word = copy._word;
-  return *this;
-}
-
 /**
 /**
  * Returns a BitMask whose bits are all on.
  * Returns a BitMask whose bits are all on.
  */
  */
@@ -121,14 +101,6 @@ range(int low_bit, int size) {
   return result;
   return result;
 }
 }
 
 
-/**
- *
- */
-template<class WType, int nbits>
-INLINE BitMask<WType, nbits>::
-~BitMask() {
-}
-
 /**
 /**
  * Returns true if there is a maximum number of bits that may be stored in
  * Returns true if there is a maximum number of bits that may be stored in
  * this structure, false otherwise.  If this returns true, the number may be
  * this structure, false otherwise.  If this returns true, the number may be

+ 0 - 4
panda/src/putil/bitMask.h

@@ -38,8 +38,6 @@ PUBLISHED:
 
 
   INLINE BitMask();
   INLINE BitMask();
   INLINE BitMask(WordType init_value);
   INLINE BitMask(WordType init_value);
-  INLINE BitMask(const BitMask<WType, nbits> &copy);
-  INLINE BitMask<WType, nbits> &operator = (const BitMask<WType, nbits> &copy);
 
 
   INLINE static BitMask<WType, nbits> all_on();
   INLINE static BitMask<WType, nbits> all_on();
   INLINE static BitMask<WType, nbits> all_off();
   INLINE static BitMask<WType, nbits> all_off();
@@ -47,8 +45,6 @@ PUBLISHED:
   INLINE static BitMask<WType, nbits> bit(int index);
   INLINE static BitMask<WType, nbits> bit(int index);
   INLINE static BitMask<WType, nbits> range(int low_bit, int size);
   INLINE static BitMask<WType, nbits> range(int low_bit, int size);
 
 
-  INLINE ~BitMask();
-
   CONSTEXPR static bool has_max_num_bits();
   CONSTEXPR static bool has_max_num_bits();
   CONSTEXPR static int get_max_num_bits();
   CONSTEXPR static int get_max_num_bits();
 
 

+ 0 - 7
panda/src/putil/buttonHandle.I

@@ -19,13 +19,6 @@ CONSTEXPR ButtonHandle::
 ButtonHandle(int index) : _index(index) {
 ButtonHandle(int index) : _index(index) {
 }
 }
 
 
-/**
- *
- */
-INLINE ButtonHandle::
-ButtonHandle(const ButtonHandle &copy) : _index(copy._index) {
-}
-
 /**
 /**
  *
  *
  */
  */

+ 0 - 1
panda/src/putil/buttonHandle.h

@@ -31,7 +31,6 @@ PUBLISHED:
   // previously by another static initializer!
   // previously by another static initializer!
   INLINE ButtonHandle() DEFAULT_CTOR;
   INLINE ButtonHandle() DEFAULT_CTOR;
   CONSTEXPR ButtonHandle(int index);
   CONSTEXPR ButtonHandle(int index);
-  INLINE ButtonHandle(const ButtonHandle &copy);
   ButtonHandle(const string &name);
   ButtonHandle(const string &name);
 
 
 PUBLISHED:
 PUBLISHED:

+ 4 - 6
panda/src/putil/iterator_types.h

@@ -14,6 +14,7 @@
 #ifndef ITERATOR_TYPES_H
 #ifndef ITERATOR_TYPES_H
 #define ITERATOR_TYPES_H
 #define ITERATOR_TYPES_H
 
 
+#include "dtoolbase.h"
 
 
 /**
 /**
  * This is an iterator adaptor that converts any iterator that returns a pair
  * This is an iterator adaptor that converts any iterator that returns a pair
@@ -25,9 +26,8 @@ class first_of_pair_iterator : public pair_iterator {
 public:
 public:
   typedef TYPENAME pair_iterator::value_type::first_type value_type;
   typedef TYPENAME pair_iterator::value_type::first_type value_type;
 
 
-  first_of_pair_iterator() { }
+  first_of_pair_iterator() DEFAULT_CTOR;
   first_of_pair_iterator(const pair_iterator &init) : pair_iterator(init) { }
   first_of_pair_iterator(const pair_iterator &init) : pair_iterator(init) { }
-  first_of_pair_iterator(const first_of_pair_iterator<pair_iterator> &copy) : pair_iterator(copy) { }
 
 
   value_type operator *() {
   value_type operator *() {
     return pair_iterator::operator *().first;
     return pair_iterator::operator *().first;
@@ -44,9 +44,8 @@ class second_of_pair_iterator : public pair_iterator {
 public:
 public:
   typedef TYPENAME pair_iterator::value_type::second_type value_type;
   typedef TYPENAME pair_iterator::value_type::second_type value_type;
 
 
-  second_of_pair_iterator() { }
+  second_of_pair_iterator() DEFAULT_CTOR;
   second_of_pair_iterator(const pair_iterator &init) : pair_iterator(init) { }
   second_of_pair_iterator(const pair_iterator &init) : pair_iterator(init) { }
-  second_of_pair_iterator(const second_of_pair_iterator<pair_iterator> &copy) : pair_iterator(copy) { }
 
 
   value_type operator *() {
   value_type operator *() {
     return pair_iterator::operator *().second;
     return pair_iterator::operator *().second;
@@ -62,9 +61,8 @@ class typecast_iterator : public base_iterator {
 public:
 public:
   typedef new_type value_type;
   typedef new_type value_type;
 
 
-  typecast_iterator() { }
+  typecast_iterator() DEFAULT_CTOR;
   typecast_iterator(const base_iterator &init) : base_iterator(init) { }
   typecast_iterator(const base_iterator &init) : base_iterator(init) { }
-  typecast_iterator(const typecast_iterator<base_iterator, new_type> &copy) : base_iterator(copy) { }
 
 
   value_type operator *() {
   value_type operator *() {
     return (new_type)base_iterator::operator *();
     return (new_type)base_iterator::operator *();

+ 3 - 28
panda/src/putil/sparseArray.I

@@ -18,26 +18,6 @@ INLINE SparseArray::
 SparseArray() : _inverse(false) {
 SparseArray() : _inverse(false) {
 }
 }
 
 
-/**
- *
- */
-INLINE SparseArray::
-SparseArray(const SparseArray &copy) :
-  _subranges(copy._subranges),
-  _inverse(copy._inverse)
-{
-}
-
-/**
- *
- */
-INLINE SparseArray &SparseArray::
-operator = (const SparseArray &copy) {
-  _subranges = copy._subranges;
-  _inverse = copy._inverse;
-  return *this;
-}
-
 /**
 /**
  * Returns a SparseArray with an infinite array of bits, all on.
  * Returns a SparseArray with an infinite array of bits, all on.
  */
  */
@@ -62,7 +42,9 @@ all_off() {
 INLINE SparseArray SparseArray::
 INLINE SparseArray SparseArray::
 lower_on(int on_bits) {
 lower_on(int on_bits) {
   SparseArray result;
   SparseArray result;
-  result.set_range(0, on_bits);
+  if (on_bits > 0) {
+    result._subranges.push_back(Subrange(0, on_bits));
+  }
   return result;
   return result;
 }
 }
 
 
@@ -86,13 +68,6 @@ range(int low_bit, int size) {
   return result;
   return result;
 }
 }
 
 
-/**
- *
- */
-INLINE SparseArray::
-~SparseArray() {
-}
-
 /**
 /**
  * Returns true if there is a maximum number of bits that may be stored in
  * Returns true if there is a maximum number of bits that may be stored in
  * this structure, false otherwise.  If this returns true, the number may be
  * this structure, false otherwise.  If this returns true, the number may be

+ 0 - 4
panda/src/putil/sparseArray.h

@@ -42,8 +42,6 @@ class DatagramIterator;
 class EXPCL_PANDA_PUTIL SparseArray {
 class EXPCL_PANDA_PUTIL SparseArray {
 PUBLISHED:
 PUBLISHED:
   INLINE SparseArray();
   INLINE SparseArray();
-  INLINE SparseArray(const SparseArray &copy);
-  INLINE SparseArray &operator = (const SparseArray &copy);
   SparseArray(const BitArray &from);
   SparseArray(const BitArray &from);
 
 
   INLINE static SparseArray all_on();
   INLINE static SparseArray all_on();
@@ -52,8 +50,6 @@ PUBLISHED:
   INLINE static SparseArray bit(int index);
   INLINE static SparseArray bit(int index);
   INLINE static SparseArray range(int low_bit, int size);
   INLINE static SparseArray range(int low_bit, int size);
 
 
-  INLINE ~SparseArray();
-
   INLINE static bool has_max_num_bits();
   INLINE static bool has_max_num_bits();
   INLINE static int get_max_num_bits();
   INLINE static int get_max_num_bits();
 
 

+ 0 - 16
panda/src/putil/writableParam.I

@@ -30,22 +30,6 @@ WritableParam(const WritableParam &copy) :
 {
 {
 }
 }
 
 
-/**
- *
- */
-INLINE WritableParam::
-~WritableParam() {
-}
-
-/**
- *
- */
-INLINE void WritableParam::
-operator = (const WritableParam &) {
-  // The assignment operator cannot be used for this class.
-  nassertv(false);
-}
-
 /**
 /**
  *
  *
  */
  */

+ 1 - 2
panda/src/putil/writableParam.h

@@ -36,11 +36,10 @@ private:
 public:
 public:
   INLINE WritableParam(const Datagram &datagram);
   INLINE WritableParam(const Datagram &datagram);
   INLINE WritableParam(const WritableParam &other);
   INLINE WritableParam(const WritableParam &other);
-  INLINE ~WritableParam();
 
 
 private:
 private:
   // The assignment operator cannot be used for this class.
   // The assignment operator cannot be used for this class.
-  INLINE void operator = (const WritableParam &other);
+  WritableParam &operator = (const WritableParam &other) DELETED_ASSIGN;
 
 
 public:
 public:
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {

+ 2 - 493
panda/src/windisplay/winGraphicsPipe.cxx

@@ -20,10 +20,7 @@
 
 
 #include "psapi.h"
 #include "psapi.h"
 #include "powrprof.h"
 #include "powrprof.h"
-
-#ifdef _WIN64
 #include <intrin.h>
 #include <intrin.h>
-#endif
 
 
 TypeHandle WinGraphicsPipe::_type_handle;
 TypeHandle WinGraphicsPipe::_type_handle;
 
 
@@ -99,443 +96,6 @@ void get_memory_information (DisplayInformation *display_information) {
   }
   }
 }
 }
 
 
-typedef union {
-  uint64_t long_integer;
-}
-LONG_INTEGER;
-
-uint64_t cpu_time_function (void) {
-#ifdef _WIN64
-  return __rdtsc();
-#else
-  LONG_INTEGER long_integer;
-  LONG_INTEGER *long_integer_pointer;
-
-  long_integer_pointer = &long_integer;
-
-  __asm {
-      mov   ebx,[long_integer_pointer]
-      rdtsc
-      mov   [ebx + 0], eax
-      mov   [ebx + 4], edx
-  }
-
-  return long_integer.long_integer;
-#endif
-}
-
-typedef union {
-  struct {
-    union {
-      struct {
-        unsigned char al;
-        unsigned char ah;
-      };
-      unsigned int eax;
-    };
-    unsigned int ebx;
-    unsigned int ecx;
-    unsigned int edx;
-  };
-} CPU_ID_REGISTERS;
-
-typedef struct {
-  union {
-    struct {
-      int maximum_cpu_id_input;
-      char cpu_vendor [16];
-    };
-
-    CPU_ID_REGISTERS cpu_id_registers_0;
-  };
-
-  union {
-    CPU_ID_REGISTERS cpu_id_registers_1;
-
-    struct {
-      // eax
-      union {
-        unsigned int eax;
-        unsigned int version_information;
-        struct {
-          unsigned int stepping_id : 4;
-          unsigned int model : 4;
-          unsigned int family : 4;
-          unsigned int processor_type : 2;
-          unsigned int reserved_0 : 2;
-          unsigned int extended_model_id : 4;
-          unsigned int extended_family_id : 8;
-          unsigned int reserved_1 : 4;
-        };
-      };
-
-      // ebx
-      union {
-        unsigned int ebx;
-        struct {
-          unsigned int brand_index : 8;
-          unsigned int clflush : 8;
-          unsigned int maximum_logical_processors : 8;
-          unsigned int initial_apic_id : 8;
-        };
-      };
-
-      // ecx
-      union {
-        unsigned int ecx;
-        struct {
-          unsigned int sse3 : 1;
-          unsigned int reserved_1_to_2 : 2;
-          unsigned int monitor : 1;
-          unsigned int ds_cpl : 1;
-          unsigned int vmx : 1;
-          unsigned int reserved_6 : 1;
-          unsigned int est : 1;
-          unsigned int tm2 : 1;
-          unsigned int reserved_9 : 1;
-          unsigned int cnxt_id : 1;
-          unsigned int reserved_11_to_12 : 2;
-          unsigned int cmpxchg16b : 1;
-          unsigned int xtpr_disable : 1;
-          unsigned int reserved_15_to_31 : 17;
-        };
-      };
-
-      // edx
-      union {
-        unsigned int edx;
-        struct {
-          unsigned int fpu : 1;
-          unsigned int vme : 1;
-          unsigned int de : 1;
-          unsigned int pse : 1;
-          unsigned int tsc : 1;
-          unsigned int msr : 1;
-          unsigned int pae : 1;
-          unsigned int mce : 1;
-          unsigned int cx8 : 1;
-          unsigned int apic : 1;
-          unsigned int reserved_10 : 1;
-          unsigned int sep : 1;
-          unsigned int mtrr : 1;
-          unsigned int pge : 1;
-          unsigned int mca : 1;
-          unsigned int cmov : 1;
-          unsigned int pat : 1;
-          unsigned int pse_36 : 1;
-          unsigned int psn : 1;
-          unsigned int cflush : 1;
-          unsigned int reserved_20 : 1;
-          unsigned int ds : 1;
-          unsigned int acpi : 1;
-          unsigned int mmx : 1;
-          unsigned int fxsr : 1;
-          unsigned int sse : 1;
-          unsigned int sse2 : 1;
-          unsigned int ss : 1;
-          unsigned int htt : 1;
-          unsigned int tm : 1;
-          unsigned int reserved_30 : 1;
-          unsigned int pbe : 1;
-        };
-      };
-    };
-  };
-
-  #define MAXIMUM_2 8
-  #define MAXIMUM_CHARACTERS (MAXIMUM_2 * sizeof(CPU_ID_REGISTERS))
-
-  union {
-    CPU_ID_REGISTERS cpu_id_registers_2;
-    unsigned char character_array_2 [MAXIMUM_CHARACTERS];
-    CPU_ID_REGISTERS cpu_id_registers_2_array [MAXIMUM_2];
-  };
-
-  union {
-    CPU_ID_REGISTERS cpu_id_registers_0x80000000;
-  };
-
-  union {
-    CPU_ID_REGISTERS cpu_id_registers_0x80000001;
-  };
-
-  union {
-    char cpu_brand_string [sizeof(CPU_ID_REGISTERS) * 3];
-    struct {
-      CPU_ID_REGISTERS cpu_id_registers_0x80000002;
-      CPU_ID_REGISTERS cpu_id_registers_0x80000003;
-      CPU_ID_REGISTERS cpu_id_registers_0x80000004;
-    };
-  };
-
-  union {
-    struct {
-      unsigned int eax;
-      unsigned int ebx;
-      union {
-        unsigned int ecx;
-        struct {
-          unsigned int l1_data_cache_line_size : 8;
-          unsigned int l1_data_reserved_8_to_15 : 8;
-          unsigned int l1_data_associativity : 8;
-          unsigned int l1_data_cache_size : 8;
-        };
-      };
-      union {
-        unsigned int edx;
-        struct {
-          unsigned int l1_code_cache_line_size : 8;
-          unsigned int l1_code_reserved_8_to_15 : 8;
-          unsigned int l1_code_associativity : 8;
-          unsigned int l1_code_cache_size : 8;
-        };
-      };
-    };
-    CPU_ID_REGISTERS cpu_id_registers_0x80000005;
-  };
-
-  union {
-    struct {
-      unsigned int eax;
-      unsigned int ebx;
-      union {
-        unsigned int ecx;
-        struct {
-          unsigned int l2_cache_line_size : 8;
-          unsigned int l2_reserved_8_to_11 : 4;
-          unsigned int l2_associativity : 4;
-          unsigned int l2_cache_size : 16;
-        };
-      };
-      unsigned int edx;
-    };
-    CPU_ID_REGISTERS cpu_id_registers_0x80000006;
-  };
-
-  CPU_ID_REGISTERS cpu_id_registers_0x80000008;
-
-  unsigned int cache_line_size;
-  unsigned int log_base_2_cache_line_size;
-} CPU_ID;
-
-typedef struct {
-  CPU_ID_REGISTERS cpu_id_registers_0;
-  CPU_ID_REGISTERS cpu_id_registers_1;
-
-  CPU_ID_REGISTERS cpu_id_registers_0x80000000;
-  CPU_ID_REGISTERS cpu_id_registers_0x80000001;
-  CPU_ID_REGISTERS cpu_id_registers_0x80000002;
-  CPU_ID_REGISTERS cpu_id_registers_0x80000003;
-  CPU_ID_REGISTERS cpu_id_registers_0x80000004;
-
-  CPU_ID_REGISTERS cpu_id_registers_0x80000006;
-
-  CPU_ID_REGISTERS cpu_id_registers_0x80000008;
-} CPU_ID_BINARY_DATA;
-
-void cpu_id_to_cpu_id_binary_data (CPU_ID *cpu_id, CPU_ID_BINARY_DATA *cpu_id_binary_data) {
-  cpu_id_binary_data->cpu_id_registers_0 = cpu_id->cpu_id_registers_0;
-  cpu_id_binary_data->cpu_id_registers_1 = cpu_id->cpu_id_registers_1;
-  cpu_id_binary_data->cpu_id_registers_0x80000000 = cpu_id->cpu_id_registers_0x80000000;
-  cpu_id_binary_data->cpu_id_registers_0x80000001 = cpu_id->cpu_id_registers_0x80000001;
-  cpu_id_binary_data->cpu_id_registers_0x80000002 = cpu_id->cpu_id_registers_0x80000002;
-  cpu_id_binary_data->cpu_id_registers_0x80000003 = cpu_id->cpu_id_registers_0x80000003;
-  cpu_id_binary_data->cpu_id_registers_0x80000004 = cpu_id->cpu_id_registers_0x80000004;
-  cpu_id_binary_data->cpu_id_registers_0x80000006 = cpu_id->cpu_id_registers_0x80000006;
-  cpu_id_binary_data->cpu_id_registers_0x80000008 = cpu_id->cpu_id_registers_0x80000008;
-}
-
-void cpu_id_binary_data_to_cpu_id (CPU_ID_BINARY_DATA *cpu_id_binary_data, CPU_ID *cpu_id) {
-  memset (cpu_id, 0, sizeof(CPU_ID));
-
-  cpu_id->cpu_id_registers_0 = cpu_id_binary_data->cpu_id_registers_0;
-  cpu_id->cpu_id_registers_1 = cpu_id_binary_data->cpu_id_registers_1;
-  cpu_id->cpu_id_registers_0x80000000 = cpu_id_binary_data->cpu_id_registers_0x80000000;
-  cpu_id->cpu_id_registers_0x80000001 = cpu_id_binary_data->cpu_id_registers_0x80000001;
-  cpu_id->cpu_id_registers_0x80000002 = cpu_id_binary_data->cpu_id_registers_0x80000002;
-  cpu_id->cpu_id_registers_0x80000003 = cpu_id_binary_data->cpu_id_registers_0x80000003;
-  cpu_id->cpu_id_registers_0x80000004 = cpu_id_binary_data->cpu_id_registers_0x80000004;
-  cpu_id->cpu_id_registers_0x80000006 = cpu_id_binary_data->cpu_id_registers_0x80000006;
-  cpu_id->cpu_id_registers_0x80000008 = cpu_id_binary_data->cpu_id_registers_0x80000008;
-}
-
-int cpuid(int input_eax, CPU_ID_REGISTERS *cpu_id_registers) {
-  int state;
-
-  state = false;
-  __try {
-    if (input_eax == 0) {
-      // the order of ecx and edx is swapped when saved to make a proper
-      // vendor string
-#ifdef _WIN64
-      __cpuid((int*)cpu_id_registers, input_eax);
-      unsigned int tmp = cpu_id_registers->edx;
-      cpu_id_registers->edx = cpu_id_registers->ecx;
-      cpu_id_registers->ecx = tmp;
-#else
-      __asm {
-          mov   eax, [input_eax]
-          mov   edi, [cpu_id_registers]
-
-          cpuid
-
-          mov   [edi + 0], eax
-          mov   [edi + 4], ebx
-          mov   [edi + 8], edx
-          mov   [edi + 12], ecx
-      }
-#endif
-    } else {
-#ifdef _WIN64
-      __cpuid((int*)cpu_id_registers, input_eax);
-#else
-      __asm {
-          mov   eax, [input_eax]
-          mov   edi, [cpu_id_registers]
-
-          cpuid
-
-          mov   [edi + 0], eax
-          mov   [edi + 4], ebx
-          mov   [edi + 8], ecx
-          mov   [edi + 12], edx
-      }
-#endif
-    }
-
-    state = true;
-  }
-  __except (1) {
-    state = false;
-  }
-
-  return state;
-}
-
-void parse_cpu_id(CPU_ID *cpu_id) {
-  printf("CPUID\n");
-  printf("  vendor = %s\n", cpu_id->cpu_vendor);
-  printf("  brand string %s\n", cpu_id->cpu_brand_string);
-  printf("  maximum_cpu_id_input = %u\n", cpu_id->maximum_cpu_id_input);
-  printf("  maximum extended information = 0x%X\n", cpu_id->cpu_id_registers_0x80000000.eax);
-
-  printf("  MMX  = %u\n", cpu_id->mmx);
-  printf("  SSE  = %u\n", cpu_id->sse);
-  printf("  SSE2 = %u\n", cpu_id->sse2);
-  printf("  SSE3 = %u\n", cpu_id->sse3);
-
-  printf("  EST  = %u\n", cpu_id->est);
-
-  if (cpu_id->maximum_cpu_id_input >= 1) {
-    printf("  version_information\n");
-    printf("    stepping_id %u\n", cpu_id->stepping_id);
-    printf("    model %u\n", cpu_id->model);
-    printf("    family %u\n", cpu_id->family);
-    printf("    processor_type %u\n", cpu_id->processor_type);
-    printf("    extended_model_id %u\n", cpu_id->extended_model_id);
-    printf("    extended_family_id %u\n", cpu_id->extended_family_id);
-
-    printf("    brand_index %u\n", cpu_id->brand_index);
-    printf("    clflush %u\n", cpu_id->clflush);
-    printf("    maximum_logical_processors %u\n", cpu_id->maximum_logical_processors);
-    printf("    initial_apic_id %u\n", cpu_id->initial_apic_id);
-
-// printf("  cache_line_size %u\n", cpu_id->cache_line_size); printf("
-// log_base_2_cache_line_size %u\n", cpu_id->log_base_2_cache_line_size);
-  }
-
-  if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000005) {
-    printf("  l1_data_cache_line_size %d\n", cpu_id->l1_data_cache_line_size);
-    printf("  l1_data_associativity %d\n", cpu_id->l1_data_associativity);
-    printf("  l1_data_cache_size %dK\n", cpu_id->l1_data_cache_size);
-
-    printf("  l1_code_cache_line_size %d\n", cpu_id->l1_code_cache_line_size);
-    printf("  l1_code_associativity %d\n", cpu_id->l1_code_associativity);
-    printf("  l1_code_cache_size %dK\n", cpu_id->l1_code_cache_size);
-  }
-
-  if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000006) {
-    printf("  l2_cache_line_size %d\n", cpu_id->l2_cache_line_size);
-    printf("  l2_associativity %d\n", cpu_id->l2_associativity);
-    printf("  l2_cache_size %dK\n", cpu_id->l2_cache_size);
-  }
-}
-
-int initialize_cpu_id(CPU_ID *cpu_id) {
-  int debug = false;
-  memset(cpu_id, 0, sizeof(CPU_ID));
-
-  if (cpuid(0, &cpu_id->cpu_id_registers_0)) {
-    if (cpu_id->maximum_cpu_id_input >= 1) {
-      cpuid(1, &cpu_id->cpu_id_registers_1);
-    }
-    if (cpu_id->maximum_cpu_id_input >= 2) {
-      unsigned int index;
-
-      cpuid(2, &cpu_id->cpu_id_registers_2);
-      if (debug) {
-        printf("  al = %u\n", cpu_id->cpu_id_registers_2.al);
-      }
-
-      for (index = 1; index < cpu_id->cpu_id_registers_2.al && index < MAXIMUM_2; index++) {
-        cpuid(2, &cpu_id->cpu_id_registers_2_array [index]);
-      }
-
-      for (index = 1; index < MAXIMUM_CHARACTERS; index++) {
-        if (cpu_id->character_array_2 [index]) {
-          if (debug) {
-            printf("  cache/TLB byte = %X\n", cpu_id->character_array_2 [index]);
-          }
-          switch (cpu_id->character_array_2 [index]) {
-          case 0x0A:
-          case 0x0C:
-            cpu_id->cache_line_size = 32;
-            cpu_id->log_base_2_cache_line_size = 5;
-            break;
-
-          case 0x2C:
-          case 0x60:
-          case 0x66:
-          case 0x67:
-          case 0x68:
-            cpu_id->cache_line_size = 64;
-            cpu_id->log_base_2_cache_line_size = 6;
-            break;
-          }
-        }
-      }
-    }
-
-    cpuid(0x80000000, &cpu_id->cpu_id_registers_0x80000000);
-
-    if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000001) {
-      cpuid(0x80000001, &cpu_id->cpu_id_registers_0x80000001);
-    }
-
-    if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000004) {
-      cpuid(0x80000002, &cpu_id->cpu_id_registers_0x80000002);
-      cpuid(0x80000003, &cpu_id->cpu_id_registers_0x80000003);
-      cpuid(0x80000004, &cpu_id->cpu_id_registers_0x80000004);
-    }
-
-    if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000005) {
-      cpuid(0x80000005, &cpu_id->cpu_id_registers_0x80000005);
-    }
-
-    if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000006) {
-      cpuid(0x80000006, &cpu_id->cpu_id_registers_0x80000006);
-    }
-
-    if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000008) {
-      cpuid(0x80000008, &cpu_id->cpu_id_registers_0x80000008);
-    }
-
-    return true;
-  }
-
-  return false;
-}
-
 int update_cpu_frequency_function(int processor_number, DisplayInformation *display_information) {
 int update_cpu_frequency_function(int processor_number, DisplayInformation *display_information) {
   int update;
   int update;
 
 
@@ -776,9 +336,6 @@ lookup_cpu_data() {
   // set callback for memory function
   // set callback for memory function
   _display_information->_get_memory_information_function = get_memory_information;
   _display_information->_get_memory_information_function = get_memory_information;
 
 
-  // set callback for cpu time function
-  _display_information->_cpu_time_function = cpu_time_function;
-
   // determine CPU frequency
   // determine CPU frequency
   uint64_t time;
   uint64_t time;
   uint64_t end_time;
   uint64_t end_time;
@@ -803,12 +360,12 @@ lookup_cpu_data() {
   if (QueryPerformanceFrequency(&frequency)) {
   if (QueryPerformanceFrequency(&frequency)) {
     if (frequency.QuadPart > 0) {
     if (frequency.QuadPart > 0) {
       if (QueryPerformanceCounter (&counter)) {
       if (QueryPerformanceCounter (&counter)) {
-        time = cpu_time_function();
+        time = __rdtsc();
         end.QuadPart = counter.QuadPart + frequency.QuadPart;
         end.QuadPart = counter.QuadPart + frequency.QuadPart;
         while (QueryPerformanceCounter (&counter) && counter.QuadPart < end.QuadPart) {
         while (QueryPerformanceCounter (&counter) && counter.QuadPart < end.QuadPart) {
 
 
         }
         }
-        end_time = cpu_time_function();
+        end_time = __rdtsc();
 
 
         _display_information->_cpu_frequency = end_time - time;
         _display_information->_cpu_frequency = end_time - time;
       }
       }
@@ -821,54 +378,6 @@ lookup_cpu_data() {
   sprintf(string, "CPU frequency: %I64d\n", _display_information->_cpu_frequency);
   sprintf(string, "CPU frequency: %I64d\n", _display_information->_cpu_frequency);
   windisplay_cat.info() << string;
   windisplay_cat.info() << string;
 
 
-
-  // CPUID
-  CPU_ID cpu_id;
-
-  windisplay_cat.info() << "start CPU ID\n";
-
-  if (initialize_cpu_id(&cpu_id)) {
-    CPU_ID_BINARY_DATA *cpu_id_binary_data;
-
-    cpu_id_binary_data = new (CPU_ID_BINARY_DATA);
-    if (cpu_id_binary_data) {
-      cpu_id_to_cpu_id_binary_data(&cpu_id, cpu_id_binary_data);
-      _display_information->_cpu_id_size = sizeof(CPU_ID_BINARY_DATA) / sizeof(unsigned int);
-      _display_information->_cpu_id_data = (unsigned int *) cpu_id_binary_data;
-
-      _display_information->_cpu_vendor_string = strdup(cpu_id.cpu_vendor);
-      _display_information->_cpu_brand_string = strdup(cpu_id.cpu_brand_string);
-      _display_information->_cpu_version_information = cpu_id.version_information;
-      _display_information->_cpu_brand_index = cpu_id.brand_index;
-
-      if (windisplay_cat.is_debug()) {
-        windisplay_cat.debug()
-          << hex << _display_information->_cpu_id_version << dec << "|";
-
-        int index;
-        for (index = 0; index < _display_information->_cpu_id_size; ++index) {
-          unsigned int data;
-          data = _display_information->_cpu_id_data[index];
-
-          windisplay_cat.debug(false)
-            << hex << data << dec;
-          if (index < _display_information->_cpu_id_size - 1) {
-            windisplay_cat.debug(false)
-              << "|";
-          }
-        }
-        windisplay_cat.debug(false)
-          << "\n";
-      }
-    }
-
-    if (windisplay_cat.is_debug()) {
-      parse_cpu_id(&cpu_id);
-    }
-  }
-
-  windisplay_cat.info() << "end CPU ID\n";
-
   // Number of CPU's
   // Number of CPU's
   count_number_of_cpus(_display_information);
   count_number_of_cpus(_display_information);
 }
 }

Some files were not shown because too many files changed in this diff