Browse Source

Merge branch 'master' into cmake

Sam Edwards 9 years ago
parent
commit
e3fcacb1f7
100 changed files with 1969 additions and 1074 deletions
  1. 52 4
      .gitignore
  2. 1 1
      .travis.yml
  3. 0 9
      contrib/.gitignore
  4. 0 4
      contrib/src/ai/aiBehaviors.h
  5. 0 5
      contrib/src/ai/aiCharacter.h
  6. 0 4
      contrib/src/ai/aiGlobals.h
  7. 0 5
      contrib/src/ai/aiWorld.h
  8. 3 3
      contrib/src/ai/obstacleAvoidance.cxx
  9. 0 2
      contrib/src/panda3dtoolsgui/.gitignore
  10. 0 9
      direct/.gitignore
  11. 0 1
      direct/src/configfiles/.gitignore
  12. 1 1
      direct/src/controls/BattleWalker.py
  13. 1 1
      direct/src/controls/NonPhysicsWalker.py
  14. 0 3
      direct/src/dcparser/.gitignore
  15. 1 1
      direct/src/dcparser/dcArrayParameter.h
  16. 1 1
      direct/src/dcparser/dcAtomicField.h
  17. 1 1
      direct/src/dcparser/dcClass.h
  18. 1 1
      direct/src/dcparser/dcClassParameter.h
  19. 1 1
      direct/src/dcparser/dcDeclaration.h
  20. 1 1
      direct/src/dcparser/dcField.h
  21. 1 1
      direct/src/dcparser/dcFile.h
  22. 1 1
      direct/src/dcparser/dcKeyword.h
  23. 1 1
      direct/src/dcparser/dcKeywordList.h
  24. 1 1
      direct/src/dcparser/dcMolecularField.h
  25. 1 1
      direct/src/dcparser/dcPackData.h
  26. 2 2
      direct/src/dcparser/dcPacker.h
  27. 1 1
      direct/src/dcparser/dcPackerCatalog.h
  28. 1 1
      direct/src/dcparser/dcPackerInterface.h
  29. 1 1
      direct/src/dcparser/dcParameter.h
  30. 1 1
      direct/src/dcparser/dcSimpleParameter.h
  31. 1 1
      direct/src/dcparser/dcSwitch.h
  32. 1 1
      direct/src/dcparser/dcSwitchParameter.h
  33. 1 1
      direct/src/dcparser/dcTypedef.h
  34. 1 1
      direct/src/distributed/CartesianGridBase.py
  35. 2 1
      direct/src/distributed/ClientRepositoryBase.py
  36. 2 1
      direct/src/distributed/ConnectionRepository.py
  37. 2 1
      direct/src/distributed/DistributedCamera.py
  38. 2 1
      direct/src/distributed/DistributedCameraOV.py
  39. 2 1
      direct/src/distributed/DistributedCartesianGrid.py
  40. 2 1
      direct/src/distributed/DistributedCartesianGridAI.py
  41. 1 1
      direct/src/distributed/DistributedNodeAI.py
  42. 3 7
      direct/src/distributed/DistributedObjectGlobalUD.py
  43. 2 1
      direct/src/distributed/DistributedObjectUD.py
  44. 2 1
      direct/src/distributed/DistributedSmoothNode.py
  45. 2 1
      direct/src/distributed/DoInterestManager.py
  46. 2 1
      direct/src/distributed/GridParent.py
  47. 2 1
      direct/src/distributed/ServerRepository.py
  48. 1 1
      direct/src/distributed/TimeManager.py
  49. 1 1
      direct/src/distributed/TimeManagerAI.py
  50. 22 2
      direct/src/distributed/cConnectionRepository.cxx
  51. 0 1
      direct/src/extensions_native/.gitignore
  52. 10 10
      direct/src/fsm/FSM.py
  53. 0 2
      direct/src/gui/.gitignore
  54. 3 3
      direct/src/gui/DirectScrolledList.py
  55. 0 8
      direct/src/p3d/.gitignore
  56. 4 4
      direct/src/p3d/FileSpec.py
  57. 11 1
      direct/src/p3d/Packager.py
  58. 7 0
      direct/src/p3d/panda3d.pdef
  59. 0 1
      direct/src/plugin/.gitignore
  60. 0 2
      direct/src/plugin/p3dCInstance.h
  61. 11 0
      direct/src/plugin/p3dInstanceManager.cxx
  62. 0 1
      direct/src/plugin_activex/.gitignore
  63. 0 1
      direct/src/plugin_npapi/.gitignore
  64. 0 2
      direct/src/plugin_standalone/.gitignore
  65. 12 3
      direct/src/showbase/BufferViewer.py
  66. 1 0
      direct/src/showbase/ExceptionVarDump.py
  67. 1 1
      direct/src/showbase/LeakDetectors.py
  68. 108 42
      direct/src/showbase/Loader.py
  69. 1 1
      direct/src/showbase/MirrorDemo.py
  70. 1 1
      direct/src/showbase/ShadowDemo.py
  71. 1 1
      direct/src/showbase/ShadowPlacer.py
  72. 0 4
      direct/src/showbase/ShowBase.py
  73. 0 1
      direct/src/showutil/.gitignore
  74. 4 1
      direct/src/showutil/FreezeTool.py
  75. 10 10
      direct/src/stdpy/thread.py
  76. 4 1
      direct/src/task/Task.py
  77. 0 7
      dmodels/.gitignore
  78. 0 6
      dmodels/src/.gitignore
  79. 33 0
      doc/ReleaseNotes
  80. 0 7
      dtool/.gitignore
  81. 0 2
      dtool/src/cppparser/.gitignore
  82. 10 1
      dtool/src/cppparser/cppArrayType.cxx
  83. 1 0
      dtool/src/cppparser/cppArrayType.h
  84. 555 491
      dtool/src/cppparser/cppBison.cxx.prebuilt
  85. 264 228
      dtool/src/cppparser/cppBison.h.prebuilt
  86. 370 106
      dtool/src/cppparser/cppBison.yxx
  87. 26 3
      dtool/src/cppparser/cppClassTemplateParameter.cxx
  88. 1 0
      dtool/src/cppparser/cppClassTemplateParameter.h
  89. 42 1
      dtool/src/cppparser/cppConstType.cxx
  90. 5 0
      dtool/src/cppparser/cppConstType.h
  91. 8 2
      dtool/src/cppparser/cppDeclaration.cxx
  92. 70 1
      dtool/src/cppparser/cppDeclaration.h
  93. 212 7
      dtool/src/cppparser/cppExpression.cxx
  94. 9 2
      dtool/src/cppparser/cppExpression.h
  95. 23 3
      dtool/src/cppparser/cppExtensionType.cxx
  96. 2 0
      dtool/src/cppparser/cppExtensionType.h
  97. 1 1
      dtool/src/cppparser/cppFile.h
  98. 8 3
      dtool/src/cppparser/cppFunctionType.cxx
  99. 3 0
      dtool/src/cppparser/cppFunctionType.h
  100. 8 5
      dtool/src/cppparser/cppInstance.cxx

+ 52 - 4
.gitignore

@@ -1,4 +1,52 @@
-/built_x64
-/built
-/thirdparty
-/targetroot
+# makepanda directories
+/built*/
+/thirdparty/
+/targetroot/
+/dstroot/
+
+# Core dumps
+core
+core.*
+vgcore.*
+
+# Editor files/directories
+*.save
+*.save.1
+*.sublime-workspace
+.vscode/
+
+# Temporary build files
+/_vfsimporter.*
+*.pdb
+*.obj
+*.o
+*.gch
+*.pch
+
+# Produced installer/executables
+/*.exe
+/*.deb
+/*.rpm
+/*.app
+/*.pkg
+/*.dmg
+/*.whl
+
+# CMake
+/build/
+CMakeCache.txt
+CMakeFiles/
+CMakeScripts/
+Makefile
+cmake_install.cmake
+install_manifest.txt
+CTestTestfile.cmake
+
+# Windows
+Thumbs.db
+ehthumbs.db
+
+# Python
+__pycache__
+*.pyc
+*.pyo

+ 1 - 1
.travis.yml

@@ -3,7 +3,7 @@ sudo: false
 matrix:
 matrix:
   include:
   include:
     - compiler: gcc
     - compiler: gcc
-      env: PYTHONV=python2.7 FLAGS=
+      env: PYTHONV=python2.7 FLAGS=--optimize=4
     - compiler: clang
     - compiler: clang
       env: PYTHONV=python3 FLAGS=--installer
       env: PYTHONV=python3 FLAGS=--installer
     - compiler: clang
     - compiler: clang

+ 0 - 9
contrib/.gitignore

@@ -1,9 +0,0 @@
-*.pyc
-*.pyo
-/__init__.py
-# These are files that are generated within the source tree by the
-# ppremake system.
-Makefile
-pp.dep
-/built/
-Opt?-*

+ 0 - 4
contrib/src/ai/aiBehaviors.h

@@ -11,10 +11,6 @@
  * @date 2009-09-08
  * @date 2009-09-08
  */
  */
 
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
 #ifndef _AIBEHAVIORS_H
 #ifndef _AIBEHAVIORS_H
 #define _AIBEHAVIORS_H
 #define _AIBEHAVIORS_H
 
 

+ 0 - 5
contrib/src/ai/aiCharacter.h

@@ -11,11 +11,6 @@
  * @date 2009-09-08
  * @date 2009-09-08
  */
  */
 
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
-
 #ifndef _AICHARACTER_H
 #ifndef _AICHARACTER_H
 #define _AICHARACTER_H
 #define _AICHARACTER_H
 
 

+ 0 - 4
contrib/src/ai/aiGlobals.h

@@ -11,10 +11,6 @@
  * @date 2009-09-08
  * @date 2009-09-08
  */
  */
 
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
 #ifndef _AI_GLOBALS_H
 #ifndef _AI_GLOBALS_H
 #define _AI_GLOBALS_H
 #define _AI_GLOBALS_H
 
 

+ 0 - 5
contrib/src/ai/aiWorld.h

@@ -11,11 +11,6 @@
  * @date 2009-09-08
  * @date 2009-09-08
  */
  */
 
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
-
 #ifndef _AIWORLD_H
 #ifndef _AIWORLD_H
 #define _AIWORLD_H
 #define _AIWORLD_H
 
 

+ 3 - 3
contrib/src/ai/obstacleAvoidance.cxx

@@ -34,7 +34,7 @@ obstacle_detection() {
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
   LVecBase3 avoidance(0.0, 0.0, 0.0);
   LVecBase3 avoidance(0.0, 0.0, 0.0);
   double distance = 0x7fff ;
   double distance = 0x7fff ;
-  double expanded_radius;
+  double expanded_radius = 0;
   LVecBase3 to_obstacle;
   LVecBase3 to_obstacle;
   LVecBase3 prev_avoidance;
   LVecBase3 prev_avoidance;
   for(unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) {
   for(unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) {
@@ -89,8 +89,8 @@ do_obstacle_avoidance() {
   CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();
   CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();
   PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
   PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
-  double distance_needed = offset.length() - bsphere->get_radius() - np_sphere->get_radius();
-  if((obstacle_detection())) {
+
+  if (obstacle_detection()) {
     LVecBase3 direction = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
     LVecBase3 direction = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
     direction.normalize();
     direction.normalize();
     float forward_component = offset.dot(direction);
     float forward_component = offset.dot(direction);

+ 0 - 2
contrib/src/panda3dtoolsgui/.gitignore

@@ -1,2 +0,0 @@
-/build
-/dist

+ 0 - 9
direct/.gitignore

@@ -1,9 +0,0 @@
-*.pyc
-*.pyo
-/__init__.py
-# These are files that are generated within the source tree by the
-# ppremake system.
-Makefile
-pp.dep
-/built/
-Opt?-*

+ 0 - 1
direct/src/configfiles/.gitignore

@@ -1 +0,0 @@
-/40_direct.prc

+ 1 - 1
direct/src/controls/BattleWalker.py

@@ -1,7 +1,7 @@
 
 
 from direct.showbase.InputStateGlobal import inputState
 from direct.showbase.InputStateGlobal import inputState
 from direct.task.Task import Task
 from direct.task.Task import Task
-from pandac.PandaModules import *
+from panda3d.core import *
 from . import GravityWalker
 from . import GravityWalker
 
 
 BattleStrafe = 0
 BattleStrafe = 0

+ 1 - 1
direct/src/controls/NonPhysicsWalker.py

@@ -19,7 +19,7 @@ from direct.showbase import DirectObject
 from direct.controls.ControlManager import CollisionHandlerRayStart
 from direct.controls.ControlManager import CollisionHandlerRayStart
 from direct.showbase.InputStateGlobal import inputState
 from direct.showbase.InputStateGlobal import inputState
 from direct.task.Task import Task
 from direct.task.Task import Task
-from pandac.PandaModules import *
+from panda3d.core import *
 
 
 class NonPhysicsWalker(DirectObject.DirectObject):
 class NonPhysicsWalker(DirectObject.DirectObject):
     notify = DirectNotifyGlobal.directNotify.newCategory("NonPhysicsWalker")
     notify = DirectNotifyGlobal.directNotify.newCategory("NonPhysicsWalker")

+ 0 - 3
direct/src/dcparser/.gitignore

@@ -1,3 +0,0 @@
-/dcLexer.cxx
-/dcParser.cxx
-/dcParser.h

+ 1 - 1
direct/src/dcparser/dcArrayParameter.h

@@ -23,7 +23,7 @@
  * parameter type accepts an arbitrary (or possibly fixed) number of nested
  * parameter type accepts an arbitrary (or possibly fixed) number of nested
  * fields, all of which are of the same type.
  * fields, all of which are of the same type.
  */
  */
-class EXPCL_DIRECT DCArrayParameter : public DCParameter {
+class DCArrayParameter : public DCParameter {
 public:
 public:
   DCArrayParameter(DCParameter *element_type,
   DCArrayParameter(DCParameter *element_type,
                    const DCUnsignedIntRange &size = DCUnsignedIntRange());
                    const DCUnsignedIntRange &size = DCUnsignedIntRange());

+ 1 - 1
direct/src/dcparser/dcAtomicField.h

@@ -27,7 +27,7 @@
  * This defines an interface to the Distributed Class, and is always
  * This defines an interface to the Distributed Class, and is always
  * implemented as a remote procedure method.
  * implemented as a remote procedure method.
  */
  */
-class EXPCL_DIRECT DCAtomicField : public DCField {
+class DCAtomicField : public DCField {
 public:
 public:
   DCAtomicField(const string &name, DCClass *dclass, bool bogus_field);
   DCAtomicField(const string &name, DCClass *dclass, bool bogus_field);
   virtual ~DCAtomicField();
   virtual ~DCAtomicField();

+ 1 - 1
direct/src/dcparser/dcClass.h

@@ -41,7 +41,7 @@ class DCParameter;
 /**
 /**
  * Defines a particular DistributedClass as read from an input .dc file.
  * Defines a particular DistributedClass as read from an input .dc file.
  */
  */
-class EXPCL_DIRECT DCClass : public DCDeclaration {
+class DCClass : public DCDeclaration {
 public:
 public:
   DCClass(DCFile *dc_file, const string &name,
   DCClass(DCFile *dc_file, const string &name,
           bool is_struct, bool bogus_class);
           bool is_struct, bool bogus_class);

+ 1 - 1
direct/src/dcparser/dcClassParameter.h

@@ -23,7 +23,7 @@ class DCClass;
  * This represents a class (or struct) object used as a parameter itself.
  * This represents a class (or struct) object used as a parameter itself.
  * This means that all the fields of the class get packed into the message.
  * This means that all the fields of the class get packed into the message.
  */
  */
-class EXPCL_DIRECT DCClassParameter : public DCParameter {
+class DCClassParameter : public DCParameter {
 public:
 public:
   DCClassParameter(const DCClass *dclass);
   DCClassParameter(const DCClass *dclass);
   DCClassParameter(const DCClassParameter &copy);
   DCClassParameter(const DCClassParameter &copy);

+ 1 - 1
direct/src/dcparser/dcDeclaration.h

@@ -26,7 +26,7 @@ class DCSwitch;
  * only purpose is so that classes and typedefs can be stored in one list
  * only purpose is so that classes and typedefs can be stored in one list
  * together so they can be ordered correctly on output.
  * together so they can be ordered correctly on output.
  */
  */
-class EXPCL_DIRECT DCDeclaration {
+class DCDeclaration {
 public:
 public:
   virtual ~DCDeclaration();
   virtual ~DCDeclaration();
 
 

+ 1 - 1
direct/src/dcparser/dcField.h

@@ -34,7 +34,7 @@ class HashGenerator;
 /**
 /**
  * A single field of a Distributed Class, either atomic or molecular.
  * A single field of a Distributed Class, either atomic or molecular.
  */
  */
-class EXPCL_DIRECT DCField : public DCPackerInterface, public DCKeywordList {
+class DCField : public DCPackerInterface, public DCKeywordList {
 public:
 public:
   DCField();
   DCField();
   DCField(const string &name, DCClass *dclass);
   DCField(const string &name, DCClass *dclass);

+ 1 - 1
direct/src/dcparser/dcFile.h

@@ -29,7 +29,7 @@ class DCDeclaration;
  * Represents the complete list of Distributed Class descriptions as read from
  * Represents the complete list of Distributed Class descriptions as read from
  * a .dc file.
  * a .dc file.
  */
  */
-class EXPCL_DIRECT DCFile {
+class DCFile {
 PUBLISHED:
 PUBLISHED:
   DCFile();
   DCFile();
   ~DCFile();
   ~DCFile();

+ 1 - 1
direct/src/dcparser/dcKeyword.h

@@ -25,7 +25,7 @@ class HashGenerator;
  * define a communication property associated with a field, for instance
  * define a communication property associated with a field, for instance
  * "broadcast" or "airecv".
  * "broadcast" or "airecv".
  */
  */
-class EXPCL_DIRECT DCKeyword : public DCDeclaration {
+class DCKeyword : public DCDeclaration {
 public:
 public:
   DCKeyword(const string &name, int historical_flag = ~0);
   DCKeyword(const string &name, int historical_flag = ~0);
   virtual ~DCKeyword();
   virtual ~DCKeyword();

+ 1 - 1
direct/src/dcparser/dcKeywordList.h

@@ -23,7 +23,7 @@ class HashGenerator;
  * This is a list of keywords (see DCKeyword) that may be set on a particular
  * This is a list of keywords (see DCKeyword) that may be set on a particular
  * field.
  * field.
  */
  */
-class EXPCL_DIRECT DCKeywordList {
+class DCKeywordList {
 public:
 public:
   DCKeywordList();
   DCKeywordList();
   DCKeywordList(const DCKeywordList &copy);
   DCKeywordList(const DCKeywordList &copy);

+ 1 - 1
direct/src/dcparser/dcMolecularField.h

@@ -25,7 +25,7 @@ class DCParameter;
  * This represents a combination of two or more related atomic fields, that
  * This represents a combination of two or more related atomic fields, that
  * will often be treated as a unit.
  * will often be treated as a unit.
  */
  */
-class EXPCL_DIRECT DCMolecularField : public DCField {
+class DCMolecularField : public DCField {
 public:
 public:
   DCMolecularField(const string &name, DCClass *dclass);
   DCMolecularField(const string &name, DCClass *dclass);
 
 

+ 1 - 1
direct/src/dcparser/dcPackData.h

@@ -19,7 +19,7 @@
 /**
 /**
  * This is a block of data that receives the results of DCPacker.
  * This is a block of data that receives the results of DCPacker.
  */
  */
-class EXPCL_DIRECT DCPackData {
+class DCPackData {
 PUBLISHED:
 PUBLISHED:
   INLINE DCPackData();
   INLINE DCPackData();
   INLINE ~DCPackData();
   INLINE ~DCPackData();

+ 2 - 2
direct/src/dcparser/dcPacker.h

@@ -31,7 +31,7 @@ class DCSwitchParameter;
  * See also direct/src/doc/dcPacker.txt for a more complete description and
  * See also direct/src/doc/dcPacker.txt for a more complete description and
  * examples of using this class.
  * examples of using this class.
  */
  */
-class EXPCL_DIRECT DCPacker {
+class DCPacker {
 PUBLISHED:
 PUBLISHED:
   DCPacker();
   DCPacker();
   ~DCPacker();
   ~DCPacker();
@@ -216,7 +216,7 @@ private:
   const DCPackerCatalog *_catalog;
   const DCPackerCatalog *_catalog;
   const DCPackerCatalog::LiveCatalog *_live_catalog;
   const DCPackerCatalog::LiveCatalog *_live_catalog;
 
 
-  class EXPCL_DIRECT StackElement {
+  class StackElement {
   public:
   public:
     // As an optimization, we implement operator new and delete here to
     // As an optimization, we implement operator new and delete here to
     // minimize allocation overhead during push() and pop().
     // minimize allocation overhead during push() and pop().

+ 1 - 1
direct/src/dcparser/dcPackerCatalog.h

@@ -26,7 +26,7 @@ class DCSwitchParameter;
  * requested from a particular field; its ownership is retained by the field
  * requested from a particular field; its ownership is retained by the field
  * so it must not be deleted.
  * so it must not be deleted.
  */
  */
-class EXPCL_DIRECT DCPackerCatalog {
+class DCPackerCatalog {
 private:
 private:
   DCPackerCatalog(const DCPackerInterface *root);
   DCPackerCatalog(const DCPackerInterface *root);
   DCPackerCatalog(const DCPackerCatalog &copy);
   DCPackerCatalog(const DCPackerCatalog &copy);

+ 1 - 1
direct/src/dcparser/dcPackerInterface.h

@@ -64,7 +64,7 @@ END_PUBLISH
  * Normally these methods are called only by the DCPacker object; the user
  * Normally these methods are called only by the DCPacker object; the user
  * wouldn't normally call these directly.
  * wouldn't normally call these directly.
  */
  */
-class EXPCL_DIRECT DCPackerInterface {
+class DCPackerInterface {
 public:
 public:
   DCPackerInterface(const string &name = string());
   DCPackerInterface(const string &name = string());
   DCPackerInterface(const DCPackerInterface &copy);
   DCPackerInterface(const DCPackerInterface &copy);

+ 1 - 1
direct/src/dcparser/dcParameter.h

@@ -32,7 +32,7 @@ class HashGenerator;
  * This may also be a typedef reference to another type, which has the same
  * This may also be a typedef reference to another type, which has the same
  * properties as the referenced type, but a different name.
  * properties as the referenced type, but a different name.
  */
  */
-class EXPCL_DIRECT DCParameter : public DCField {
+class DCParameter : public DCField {
 protected:
 protected:
   DCParameter();
   DCParameter();
   DCParameter(const DCParameter &copy);
   DCParameter(const DCParameter &copy);

+ 1 - 1
direct/src/dcparser/dcSimpleParameter.h

@@ -25,7 +25,7 @@
  * divisor, which is meaningful only for the numeric type elements (and
  * divisor, which is meaningful only for the numeric type elements (and
  * represents a fixed-point numeric convention).
  * represents a fixed-point numeric convention).
  */
  */
-class EXPCL_DIRECT DCSimpleParameter : public DCParameter {
+class DCSimpleParameter : public DCParameter {
 public:
 public:
   DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
   DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
   DCSimpleParameter(const DCSimpleParameter &copy);
   DCSimpleParameter(const DCSimpleParameter &copy);

+ 1 - 1
direct/src/dcparser/dcSwitch.h

@@ -27,7 +27,7 @@ class DCField;
  * and represents two or more alternative unpacking schemes based on the first
  * and represents two or more alternative unpacking schemes based on the first
  * field read.
  * field read.
  */
  */
-class EXPCL_DIRECT DCSwitch : public DCDeclaration {
+class DCSwitch : public DCDeclaration {
 public:
 public:
   DCSwitch(const string &name, DCField *key_parameter);
   DCSwitch(const string &name, DCField *key_parameter);
   virtual ~DCSwitch();
   virtual ~DCSwitch();

+ 1 - 1
direct/src/dcparser/dcSwitchParameter.h

@@ -23,7 +23,7 @@ class DCSwitch;
  * This represents a switch object used as a parameter itself, which packs the
  * This represents a switch object used as a parameter itself, which packs the
  * appropriate fields of the switch into the message.
  * appropriate fields of the switch into the message.
  */
  */
-class EXPCL_DIRECT DCSwitchParameter : public DCParameter {
+class DCSwitchParameter : public DCParameter {
 public:
 public:
   DCSwitchParameter(const DCSwitch *dswitch);
   DCSwitchParameter(const DCSwitch *dswitch);
   DCSwitchParameter(const DCSwitchParameter &copy);
   DCSwitchParameter(const DCSwitchParameter &copy);

+ 1 - 1
direct/src/dcparser/dcTypedef.h

@@ -23,7 +23,7 @@ class DCParameter;
  * This represents a single typedef declaration in the dc file.  It assigns a
  * This represents a single typedef declaration in the dc file.  It assigns a
  * particular type to a new name, just like a C typedef.
  * particular type to a new name, just like a C typedef.
  */
  */
-class EXPCL_DIRECT DCTypedef : public DCDeclaration {
+class DCTypedef : public DCDeclaration {
 public:
 public:
   DCTypedef(DCParameter *parameter, bool implicit = false);
   DCTypedef(DCParameter *parameter, bool implicit = false);
   DCTypedef(const string &name);
   DCTypedef(const string &name);

+ 1 - 1
direct/src/distributed/CartesianGridBase.py

@@ -1,4 +1,4 @@
-from pandac.PandaModules import Vec3
+from panda3d.core import Vec3
 # Utility functions that are useful to both AI and client CartesianGrid code
 # Utility functions that are useful to both AI and client CartesianGrid code
 
 
 class CartesianGridBase:
 class CartesianGridBase:

+ 2 - 1
direct/src/distributed/ClientRepositoryBase.py

@@ -1,4 +1,5 @@
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from .MsgTypes import *
 from .MsgTypes import *
 from direct.task import Task
 from direct.task import Task
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal

+ 2 - 1
direct/src/distributed/ConnectionRepository.py

@@ -1,4 +1,5 @@
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.task import Task
 from direct.task import Task
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.distributed.DoInterestManager import DoInterestManager
 from direct.distributed.DoInterestManager import DoInterestManager

+ 2 - 1
direct/src/distributed/DistributedCamera.py

@@ -1,4 +1,5 @@
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.fsm.FSM import FSM
 from direct.fsm.FSM import FSM
 from direct.interval.IntervalGlobal import *
 from direct.interval.IntervalGlobal import *
 from direct.distributed.DistributedObject import DistributedObject
 from direct.distributed.DistributedObject import DistributedObject

+ 2 - 1
direct/src/distributed/DistributedCameraOV.py

@@ -1,4 +1,5 @@
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.distributed.DistributedObjectOV import DistributedObjectOV
 from direct.distributed.DistributedObjectOV import DistributedObjectOV
 
 
 class DistributedCameraOV(DistributedObjectOV):
 class DistributedCameraOV(DistributedObjectOV):

+ 2 - 1
direct/src/distributed/DistributedCartesianGrid.py

@@ -1,5 +1,6 @@
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.interval.IntervalGlobal import *
 from direct.interval.IntervalGlobal import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 
 

+ 2 - 1
direct/src/distributed/DistributedCartesianGridAI.py

@@ -1,5 +1,6 @@
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.task import Task
 from direct.task import Task
 from .DistributedNodeAI import DistributedNodeAI
 from .DistributedNodeAI import DistributedNodeAI

+ 1 - 1
direct/src/distributed/DistributedNodeAI.py

@@ -1,4 +1,4 @@
-from pandac.PandaModules import NodePath
+from panda3d.core import NodePath
 from . import DistributedObjectAI
 from . import DistributedObjectAI
 from . import GridParent
 from . import GridParent
 
 

+ 3 - 7
direct/src/distributed/DistributedObjectGlobalUD.py

@@ -26,18 +26,14 @@ class DistributedObjectGlobalUD(DistributedObjectUD):
 
 
     def execCommand(self, command, mwMgrId, avId, zoneId):
     def execCommand(self, command, mwMgrId, avId, zoneId):
         text = str(self.__execMessage(command))[:config.GetInt("ai-debug-length",300)]
         text = str(self.__execMessage(command))[:config.GetInt("ai-debug-length",300)]
-
-        dclass = uber.air.dclassesByName.get("PiratesMagicWordManagerAI")
-        dg = dclass.aiFormatUpdate(
-            "setMagicWordResponse", mwMgrId, (1<<32)+avId, uber.air.ourChannel, [text])
-        uber.air.send(dg)
+        self.notify.info(text)
 
 
     def __execMessage(self, message):
     def __execMessage(self, message):
         if not self.ExecNamespace:
         if not self.ExecNamespace:
             # Import some useful variables into the ExecNamespace initially.
             # Import some useful variables into the ExecNamespace initially.
-            import pandac.PandaModules
+            import panda3d.core
 
 
-            for key, value in pandac.PandaModules.__dict__.items():
+            for key, value in panda3d.core.__dict__.items():
                 if not key.startswith('__'):
                 if not key.startswith('__'):
                     self.ExecNamespace[key] = value
                     self.ExecNamespace[key] = value
             #self.importExecNamespace()
             #self.importExecNamespace()

+ 2 - 1
direct/src/distributed/DistributedObjectUD.py

@@ -3,7 +3,8 @@
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.distributed.DistributedObjectBase import DistributedObjectBase
 from direct.distributed.DistributedObjectBase import DistributedObjectBase
 from direct.showbase import PythonUtil
 from direct.showbase import PythonUtil
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 #from PyDatagram import PyDatagram
 #from PyDatagram import PyDatagram
 #from PyDatagramIterator import PyDatagramIterator
 #from PyDatagramIterator import PyDatagramIterator
 
 

+ 2 - 1
direct/src/distributed/DistributedSmoothNode.py

@@ -1,6 +1,7 @@
 """DistributedSmoothNode module: contains the DistributedSmoothNode class"""
 """DistributedSmoothNode module: contains the DistributedSmoothNode class"""
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from .ClockDelta import *
 from .ClockDelta import *
 from . import DistributedNode
 from . import DistributedNode
 from . import DistributedSmoothNodeBase
 from . import DistributedSmoothNodeBase

+ 2 - 1
direct/src/distributed/DoInterestManager.py

@@ -7,7 +7,8 @@ zone, remove interest in that zone.
 p.s. A great deal of this code is just code moved from ClientRepository.py.
 p.s. A great deal of this code is just code moved from ClientRepository.py.
 """
 """
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from .MsgTypes import *
 from .MsgTypes import *
 from direct.showbase.PythonUtil import *
 from direct.showbase.PythonUtil import *
 from direct.showbase import DirectObject
 from direct.showbase import DirectObject

+ 2 - 1
direct/src/distributed/GridParent.py

@@ -1,5 +1,6 @@
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 
 
 #
 #
 # GridParent.py
 # GridParent.py

+ 2 - 1
direct/src/distributed/ServerRepository.py

@@ -1,6 +1,7 @@
 """ServerRepository module: contains the ServerRepository class"""
 """ServerRepository module: contains the ServerRepository class"""
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.distributed.MsgTypesCMU import *
 from direct.distributed.MsgTypesCMU import *
 from direct.task import Task
 from direct.task import Task
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal

+ 1 - 1
direct/src/distributed/TimeManager.py

@@ -1,5 +1,5 @@
 from direct.showbase.DirectObject import *
 from direct.showbase.DirectObject import *
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.task import Task
 from direct.task import Task
 from direct.distributed import DistributedObject
 from direct.distributed import DistributedObject
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal

+ 1 - 1
direct/src/distributed/TimeManagerAI.py

@@ -1,5 +1,5 @@
 from direct.distributed.ClockDelta import *
 from direct.distributed.ClockDelta import *
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.distributed import DistributedObjectAI
 from direct.distributed import DistributedObjectAI
 
 
 class TimeManagerAI(DistributedObjectAI.DistributedObjectAI):
 class TimeManagerAI(DistributedObjectAI.DistributedObjectAI):

+ 22 - 2
direct/src/distributed/cConnectionRepository.cxx

@@ -402,8 +402,28 @@ send_datagram(const Datagram &dg) {
   }
   }
 
 
 #ifdef WANT_NATIVE_NET
 #ifdef WANT_NATIVE_NET
-  if(_native)
-    return _bdc.SendMessage(dg);
+  if (_native) {
+    bool result = _bdc.SendMessage(dg);
+    if (!result && _bdc.IsConnected()) {
+#ifdef HAVE_PYTHON
+      ostringstream s;
+
+#if PY_VERSION_HEX >= 0x03030000
+      PyObject *exc_type = PyExc_ConnectionError;
+#else
+      PyObject *exc_type = PyExc_OSError;
+#endif
+
+      s << endl << "Error sending message: " << endl;
+      dg.dump_hex(s);
+      s << "Message data: " << dg.get_data() << endl;
+
+      string message = s.str();
+      PyErr_SetString(exc_type, message.c_str());
+#endif
+    }
+    return result;
+  }
 #endif
 #endif
 
 
 #ifdef HAVE_NET
 #ifdef HAVE_NET

+ 0 - 1
direct/src/extensions_native/.gitignore

@@ -1 +0,0 @@
-/extensions_darwin.py

+ 10 - 10
direct/src/fsm/FSM.py

@@ -149,7 +149,7 @@ class FSM(DirectObject):
 
 
     def __init__(self, name):
     def __init__(self, name):
         self.fsmLock = RLock()
         self.fsmLock = RLock()
-        self.name = name
+        self._name = name
         self.stateArray = []
         self.stateArray = []
         self._serialNum = FSM.SerialNum
         self._serialNum = FSM.SerialNum
         FSM.SerialNum += 1
         FSM.SerialNum += 1
@@ -185,7 +185,7 @@ class FSM(DirectObject):
         # the messenger on every state change. The new and old states are
         # the messenger on every state change. The new and old states are
         # accessible as self.oldState and self.newState, and the transition
         # accessible as self.oldState and self.newState, and the transition
         # functions will already have been called.
         # functions will already have been called.
-        return 'FSM-%s-%s-stateChange' % (self._serialNum, self.name)
+        return 'FSM-%s-%s-stateChange' % (self._serialNum, self._name)
 
 
     def getCurrentFilter(self):
     def getCurrentFilter(self):
         if not self.state:
         if not self.state:
@@ -240,7 +240,7 @@ class FSM(DirectObject):
         try:
         try:
             assert isinstance(request, str)
             assert isinstance(request, str)
             self.notify.debug("%s.forceTransition(%s, %s" % (
             self.notify.debug("%s.forceTransition(%s, %s" % (
-                self.name, request, str(args)[1:]))
+                self._name, request, str(args)[1:]))
 
 
             if not self.state:
             if not self.state:
                 # Queue up the request.
                 # Queue up the request.
@@ -268,7 +268,7 @@ class FSM(DirectObject):
         try:
         try:
             assert isinstance(request, str)
             assert isinstance(request, str)
             self.notify.debug("%s.demand(%s, %s" % (
             self.notify.debug("%s.demand(%s, %s" % (
-                self.name, request, str(args)[1:]))
+                self._name, request, str(args)[1:]))
             if not self.state:
             if not self.state:
                 # Queue up the request.
                 # Queue up the request.
                 self.__requestQueue.append(PythonUtil.Functor(
                 self.__requestQueue.append(PythonUtil.Functor(
@@ -307,7 +307,7 @@ class FSM(DirectObject):
         try:
         try:
             assert isinstance(request, str)
             assert isinstance(request, str)
             self.notify.debug("%s.request(%s, %s" % (
             self.notify.debug("%s.request(%s, %s" % (
-                self.name, request, str(args)[1:]))
+                self._name, request, str(args)[1:]))
 
 
             filter = self.getCurrentFilter()
             filter = self.getCurrentFilter()
             result = filter(request, args)
             result = filter(request, args)
@@ -385,7 +385,7 @@ class FSM(DirectObject):
 
 
         # In either case, we quietly ignore unhandled command
         # In either case, we quietly ignore unhandled command
         # (lowercase) requests.
         # (lowercase) requests.
-        assert self.notify.debug("%s ignoring request %s from state %s." % (self.name, request, self.state))
+        assert self.notify.debug("%s ignoring request %s from state %s." % (self._name, request, self.state))
         return None
         return None
 
 
     def filterOff(self, request, args):
     def filterOff(self, request, args):
@@ -444,7 +444,7 @@ class FSM(DirectObject):
         # Internal function to change unconditionally to the indicated
         # Internal function to change unconditionally to the indicated
         # state.
         # state.
         assert self.state
         assert self.state
-        assert self.notify.debug("%s to state %s." % (self.name, newState))
+        assert self.notify.debug("%s to state %s." % (self._name, newState))
 
 
         self.oldState = self.state
         self.oldState = self.state
         self.newState = newState
         self.newState = newState
@@ -476,7 +476,7 @@ class FSM(DirectObject):
 
 
         if self.__requestQueue:
         if self.__requestQueue:
             request = self.__requestQueue.pop(0)
             request = self.__requestQueue.pop(0)
-            assert self.notify.debug("%s continued queued request." % (self.name))
+            assert self.notify.debug("%s continued queued request." % (self._name))
             request()
             request()
 
 
     def __callEnterFunc(self, name, *args):
     def __callEnterFunc(self, name, *args):
@@ -525,9 +525,9 @@ class FSM(DirectObject):
         try:
         try:
             className = self.__class__.__name__
             className = self.__class__.__name__
             if self.state:
             if self.state:
-                str = ('%s FSM:%s in state "%s"' % (className, self.name, self.state))
+                str = ('%s FSM:%s in state "%s"' % (className, self._name, self.state))
             else:
             else:
-                str = ('%s FSM:%s in transition from \'%s\' to \'%s\'' % (className, self.name, self.oldState, self.newState))
+                str = ('%s FSM:%s in transition from \'%s\' to \'%s\'' % (className, self._name, self.oldState, self.newState))
             return str
             return str
         finally:
         finally:
             self.fsmLock.release()
             self.fsmLock.release()

+ 0 - 2
direct/src/gui/.gitignore

@@ -1,2 +0,0 @@
-/NL*
-/Nested*

+ 3 - 3
direct/src/gui/DirectScrolledList.py

@@ -20,7 +20,7 @@ class DirectScrolledListItem(DirectButton):
 
 
     def __init__(self, parent=None, **kw):
     def __init__(self, parent=None, **kw):
         assert self.notify.debugStateCall(self)
         assert self.notify.debugStateCall(self)
-        self.parent = parent
+        self._parent = parent
         if "command" in kw:
         if "command" in kw:
             self.nextCommand = kw.get("command")
             self.nextCommand = kw.get("command")
             del kw["command"]
             del kw["command"]
@@ -28,7 +28,7 @@ class DirectScrolledListItem(DirectButton):
             self.nextCommandExtraArgs = kw.get("extraArgs")
             self.nextCommandExtraArgs = kw.get("extraArgs")
             del kw["extraArgs"]
             del kw["extraArgs"]
         optiondefs = (
         optiondefs = (
-            ('parent', self.parent,    None),
+            ('parent', self._parent,    None),
             ('command', self.select, None),
             ('command', self.select, None),
             )
             )
         # Merge keyword options with default options
         # Merge keyword options with default options
@@ -39,7 +39,7 @@ class DirectScrolledListItem(DirectButton):
     def select(self):
     def select(self):
         assert self.notify.debugStateCall(self)
         assert self.notify.debugStateCall(self)
         self.nextCommand(*self.nextCommandExtraArgs)
         self.nextCommand(*self.nextCommandExtraArgs)
-        self.parent.selectListItem(self)
+        self._parent.selectListItem(self)
 
 
 
 
 class DirectScrolledList(DirectFrame):
 class DirectScrolledList(DirectFrame):

+ 0 - 8
direct/src/p3d/.gitignore

@@ -1,8 +0,0 @@
-/_vfsimporter.exp
-/_vfsimporter.lib
-/_vfsimporter.pyd
-/_vfsimporter.pyd.manifest
-/packp3d
-/ppackage
-/ppatcher
-/vc90.pdb

+ 4 - 4
direct/src/p3d/FileSpec.py

@@ -33,7 +33,7 @@ class FileSpec:
         if st is None:
         if st is None:
             st = os.stat(pathname.toOsSpecific())
             st = os.stat(pathname.toOsSpecific())
         self.size = st.st_size
         self.size = st.st_size
-        self.timestamp = st.st_mtime
+        self.timestamp = int(st.st_mtime)
 
 
         self.readHash(pathname)
         self.readHash(pathname)
 
 
@@ -124,7 +124,7 @@ class FileSpec:
                 self.__correctHash(packageDir, pathname, st, notify)
                 self.__correctHash(packageDir, pathname, st, notify)
             return False
             return False
 
 
-        if st.st_mtime == self.timestamp:
+        if int(st.st_mtime) == self.timestamp:
             # If the size is right and the timestamp is right, the
             # If the size is right and the timestamp is right, the
             # file passes.
             # file passes.
             if notify:
             if notify:
@@ -198,7 +198,7 @@ class FileSpec:
         # The hash is OK.  If the timestamp is wrong, change it back
         # The hash is OK.  If the timestamp is wrong, change it back
         # to what we expect it to be, so we can quick-verify it
         # to what we expect it to be, so we can quick-verify it
         # successfully next time.
         # successfully next time.
-        if st.st_mtime != self.timestamp:
+        if int(st.st_mtime) != self.timestamp:
             self.__updateTimestamp(pathname, st)
             self.__updateTimestamp(pathname, st)
 
 
         return True
         return True
@@ -219,7 +219,7 @@ class FileSpec:
         if notify:
         if notify:
             notify.info("Correcting timestamp of %s to %d (%s)" % (
             notify.info("Correcting timestamp of %s to %d (%s)" % (
                 self.filename, st.st_mtime, time.asctime(time.localtime(st.st_mtime))))
                 self.filename, st.st_mtime, time.asctime(time.localtime(st.st_mtime))))
-        self.timestamp = st.st_mtime
+        self.timestamp = int(st.st_mtime)
 
 
     def checkHash(self, packageDir, pathname, st):
     def checkHash(self, packageDir, pathname, st):
         """ Returns true if the file has the expected md5 hash, false
         """ Returns true if the file has the expected md5 hash, false

+ 11 - 1
direct/src/p3d/Packager.py

@@ -1848,7 +1848,7 @@ class Packager:
 
 
         def addEggFile(self, file):
         def addEggFile(self, file):
             # Precompile egg files to bam's.
             # Precompile egg files to bam's.
-            np = self.packager.loader.loadModel(file.filename)
+            np = self.packager.loader.loadModel(file.filename, self.packager.loaderOptions)
             if not np:
             if not np:
                 raise Exception('Could not read egg file %s' % (file.filename))
                 raise Exception('Could not read egg file %s' % (file.filename))
 
 
@@ -1862,6 +1862,8 @@ class Packager:
             if not bamFile.openRead(file.filename):
             if not bamFile.openRead(file.filename):
                 raise Exception('Could not read bam file %s' % (file.filename))
                 raise Exception('Could not read bam file %s' % (file.filename))
 
 
+            bamFile.getReader().setLoaderOptions(self.packager.loaderOptions)
+
             if not bamFile.resolve():
             if not bamFile.resolve():
                 raise Exception('Could not resolve bam file %s' % (file.filename))
                 raise Exception('Could not resolve bam file %s' % (file.filename))
 
 
@@ -2492,6 +2494,14 @@ class Packager:
         self.sfxManagerList = None
         self.sfxManagerList = None
         self.musicManager = None
         self.musicManager = None
 
 
+        # These options will be used when loading models and textures.  By
+        # default we don't load textures beyond the header and don't store
+        # models in the RAM cache in order to conserve on memory usage.
+        opts = LoaderOptions()
+        opts.setFlags(opts.getFlags() | LoaderOptions.LFNoRamCache)
+        opts.setTextureFlags(opts.getTextureFlags() & ~LoaderOptions.TFPreload)
+        self.loaderOptions = opts
+
         # This is filled in during readPackageDef().
         # This is filled in during readPackageDef().
         self.packageList = []
         self.packageList = []
 
 

+ 7 - 0
direct/src/p3d/panda3d.pdef

@@ -56,6 +56,9 @@ class panda3d(package):
            'direct.stdpy.*',
            'direct.stdpy.*',
            'direct.task.*')
            'direct.task.*')
 
 
+    # Keep these modules for backward compatibility.
+    module('pandac.PandaModules', 'pandac.extension_native_helpers')
+
     module('panda3d.core',
     module('panda3d.core',
            'panda3d.direct',
            'panda3d.direct',
            'panda3d.fx',
            'panda3d.fx',
@@ -462,6 +465,8 @@ class packp3d(p3d):
 
 
     mainModule('direct.p3d.packp3d')
     mainModule('direct.p3d.packp3d')
 
 
+    file('packp3d.prc', extract = True, text = "preload-textures false")
+
 
 
 class ppackage(p3d):
 class ppackage(p3d):
     # As above, a packaging utility.  This is the fully-general ppackage
     # As above, a packaging utility.  This is the fully-general ppackage
@@ -475,6 +480,8 @@ class ppackage(p3d):
 
 
     mainModule('direct.p3d.ppackage')
     mainModule('direct.p3d.ppackage')
 
 
+    file('ppackage.prc', extract = True, text = "preload-textures false")
+
 
 
 class ppatcher(p3d):
 class ppatcher(p3d):
     # A handy utility to go along with ppackage.  This builds
     # A handy utility to go along with ppackage.  This builds

+ 0 - 1
direct/src/plugin/.gitignore

@@ -1 +0,0 @@
-/p3d_plugin_config.h

+ 0 - 2
direct/src/plugin/p3dCInstance.h

@@ -21,8 +21,6 @@
 #include "get_tinyxml.h"
 #include "get_tinyxml.h"
 #include "windowHandle.h"
 #include "windowHandle.h"
 
 
-#include <Python.h>
-
 class P3DSession;
 class P3DSession;
 
 
 /**
 /**

+ 11 - 0
direct/src/plugin/p3dInstanceManager.cxx

@@ -1421,6 +1421,17 @@ create_runtime_environment() {
     }
     }
   }
   }
 
 
+#ifndef _WIN32
+  // If we're running from the console, make sure that terminating the parent
+  // process will cause the child process to terminate as well.
+  if (_console_environment) {
+    struct sigaction ignore;
+    memset(&ignore, 0, sizeof(ignore));
+    ignore.sa_handler = SIG_IGN;
+    sigaction(SIGINT, &ignore, NULL);
+  }
+#endif
+
   _created_runtime_environment = true;
   _created_runtime_environment = true;
 }
 }
 
 

+ 0 - 1
direct/src/plugin_activex/.gitignore

@@ -1 +0,0 @@
-/P3DActiveX.rc

+ 0 - 1
direct/src/plugin_npapi/.gitignore

@@ -1 +0,0 @@
-/nppanda3d.rc

+ 0 - 2
direct/src/plugin_standalone/.gitignore

@@ -1,2 +0,0 @@
-/p3d_plugin_config.h
-/panda3d.rc

+ 12 - 3
direct/src/showbase/BufferViewer.py

@@ -278,6 +278,15 @@ class BufferViewer(DirectObject):
         self.analyzeTextureSet(self.exclude, exclude)
         self.analyzeTextureSet(self.exclude, exclude)
         self.analyzeTextureSet(self.include, include)
         self.analyzeTextureSet(self.include, include)
 
 
+        # Use a custom sampler when applying the textures.  This fixes
+        # wrap issues and prevents depth compare on shadow maps.
+        sampler = SamplerState()
+        sampler.setWrapU(SamplerState.WM_clamp)
+        sampler.setWrapV(SamplerState.WM_clamp)
+        sampler.setWrapW(SamplerState.WM_clamp)
+        sampler.setMinfilter(SamplerState.FT_linear)
+        sampler.setMagfilter(SamplerState.FT_nearest)
+
         # Generate a list of cards and the corresponding windows.
         # Generate a list of cards and the corresponding windows.
         cards = []
         cards = []
         wins = []
         wins = []
@@ -290,7 +299,7 @@ class BufferViewer(DirectObject):
                         for face in range(6):
                         for face in range(6):
                             self.cardmaker.setUvRangeCube(face)
                             self.cardmaker.setUvRangeCube(face)
                             card = NodePath(self.cardmaker.generate())
                             card = NodePath(self.cardmaker.generate())
-                            card.setTexture(tex)
+                            card.setTexture(tex, sampler)
                             cards.append(card)
                             cards.append(card)
                     elif (tex.getTextureType() == Texture.TT2dTextureArray):
                     elif (tex.getTextureType() == Texture.TT2dTextureArray):
                         for layer in range(tex.getZSize()):
                         for layer in range(tex.getZSize()):
@@ -301,11 +310,11 @@ class BufferViewer(DirectObject):
                             # the fixed-function pipeline, so we need to
                             # the fixed-function pipeline, so we need to
                             # enable the shader generator to view them.
                             # enable the shader generator to view them.
                             card.setShaderAuto()
                             card.setShaderAuto()
-                            card.setTexture(tex)
+                            card.setTexture(tex, sampler)
                             cards.append(card)
                             cards.append(card)
                     else:
                     else:
                         card = win.getTextureCard()
                         card = win.getTextureCard()
-                        card.setTexture(tex)
+                        card.setTexture(tex, sampler)
                         cards.append(card)
                         cards.append(card)
                     wins.append(win)
                     wins.append(win)
                     exclude[tex] = 1
                     exclude[tex] = 1

+ 1 - 0
direct/src/showbase/ExceptionVarDump.py

@@ -1,5 +1,6 @@
 __all__ = ["install"]
 __all__ = ["install"]
 
 
+from panda3d.core import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.showbase.PythonUtil import fastRepr
 from direct.showbase.PythonUtil import fastRepr
 import sys
 import sys

+ 1 - 1
direct/src/showbase/LeakDetectors.py

@@ -1,6 +1,6 @@
 # objects that report different types of leaks to the ContainerLeakDetector
 # objects that report different types of leaks to the ContainerLeakDetector
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.Job import Job
 from direct.showbase.Job import Job
 import gc, sys
 import gc, sys

+ 108 - 42
direct/src/showbase/Loader.py

@@ -28,7 +28,7 @@ class Loader(DirectObject):
             self.extraArgs = extraArgs
             self.extraArgs = extraArgs
             self.numRemaining = numObjects
             self.numRemaining = numObjects
             self.cancelled = False
             self.cancelled = False
-            self.requests = {}
+            self.requests = set()
 
 
         def gotObject(self, index, object):
         def gotObject(self, index, object):
             self.objects[index] = object
             self.objects[index] = object
@@ -45,6 +45,8 @@ class Loader(DirectObject):
         self.base = base
         self.base = base
         self.loader = PandaLoader.getGlobalPtr()
         self.loader = PandaLoader.getGlobalPtr()
 
 
+        self.__requests = {}
+
         self.hook = "async_loader_%s" % (Loader.loaderIndex)
         self.hook = "async_loader_%s" % (Loader.loaderIndex)
         Loader.loaderIndex += 1
         Loader.loaderIndex += 1
         self.accept(self.hook, self.__gotAsyncObject)
         self.accept(self.hook, self.__gotAsyncObject)
@@ -116,7 +118,7 @@ class Loader(DirectObject):
         """
         """
 
 
         assert Loader.notify.debug("Loading model: %s" % (modelPath))
         assert Loader.notify.debug("Loading model: %s" % (modelPath))
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
             loaderOptions = LoaderOptions()
         else:
         else:
             loaderOptions = LoaderOptions(loaderOptions)
             loaderOptions = LoaderOptions(loaderOptions)
@@ -156,7 +158,7 @@ class Loader(DirectObject):
             result = []
             result = []
             for modelPath in modelList:
             for modelPath in modelList:
                 node = self.loader.loadSync(Filename(modelPath), loaderOptions)
                 node = self.loader.loadSync(Filename(modelPath), loaderOptions)
-                if (node != None):
+                if node is not None:
                     nodePath = NodePath(node)
                     nodePath = NodePath(node)
                 else:
                 else:
                     nodePath = None
                     nodePath = None
@@ -179,16 +181,16 @@ class Loader(DirectObject):
             # callback (passing it the models on the parameter list).
             # callback (passing it the models on the parameter list).
 
 
             cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
             cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
-            i=0
+            i = 0
             for modelPath in modelList:
             for modelPath in modelList:
                 request = self.loader.makeAsyncRequest(Filename(modelPath), loaderOptions)
                 request = self.loader.makeAsyncRequest(Filename(modelPath), loaderOptions)
                 if priority is not None:
                 if priority is not None:
                     request.setPriority(priority)
                     request.setPriority(priority)
                 request.setDoneEvent(self.hook)
                 request.setDoneEvent(self.hook)
-                request.setPythonObject((cb, i))
-                i+=1
                 self.loader.loadAsync(request)
                 self.loader.loadAsync(request)
-                cb.requests[request] = True
+                cb.requests.add(request)
+                self.__requests[request] = (cb, i)
+                i += 1
             return cb
             return cb
 
 
     def cancelRequest(self, cb):
     def cancelRequest(self, cb):
@@ -200,6 +202,7 @@ class Loader(DirectObject):
             cb.cancelled = True
             cb.cancelled = True
             for request in cb.requests:
             for request in cb.requests:
                 self.loader.remove(request)
                 self.loader.remove(request)
+                del self.__requests[request]
             cb.requests = None
             cb.requests = None
 
 
     def isRequestPending(self, cb):
     def isRequestPending(self, cb):
@@ -273,7 +276,7 @@ class Loader(DirectObject):
             # to resolve it for us.
             # to resolve it for us.
             options = LoaderOptions(LoaderOptions.LFSearch | LoaderOptions.LFNoDiskCache | LoaderOptions.LFCacheOnly)
             options = LoaderOptions(LoaderOptions.LFSearch | LoaderOptions.LFNoDiskCache | LoaderOptions.LFCacheOnly)
             modelNode = self.loader.loadSync(Filename(model), options)
             modelNode = self.loader.loadSync(Filename(model), options)
-            if modelNode == None:
+            if modelNode is None:
                 # Model not found.
                 # Model not found.
                 assert Loader.notify.debug("Unloading model not loaded: %s" % (model))
                 assert Loader.notify.debug("Unloading model not loaded: %s" % (model))
                 return
                 return
@@ -293,7 +296,7 @@ class Loader(DirectObject):
         a callback is used, the model is saved asynchronously, and the
         a callback is used, the model is saved asynchronously, and the
         true/false status is passed to the callback function. """
         true/false status is passed to the callback function. """
 
 
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
             loaderOptions = LoaderOptions()
         else:
         else:
             loaderOptions = LoaderOptions(loaderOptions)
             loaderOptions = LoaderOptions(loaderOptions)
@@ -342,16 +345,16 @@ class Loader(DirectObject):
             # callback (passing it the models on the parameter list).
             # callback (passing it the models on the parameter list).
 
 
             cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
             cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
-            i=0
+            i = 0
             for modelPath, node in modelList:
             for modelPath, node in modelList:
                 request = self.loader.makeAsyncSaveRequest(Filename(modelPath), loaderOptions, node)
                 request = self.loader.makeAsyncSaveRequest(Filename(modelPath), loaderOptions, node)
                 if priority is not None:
                 if priority is not None:
                     request.setPriority(priority)
                     request.setPriority(priority)
                 request.setDoneEvent(self.hook)
                 request.setDoneEvent(self.hook)
-                request.setPythonObject((cb, i))
-                i+=1
                 self.loader.saveAsync(request)
                 self.loader.saveAsync(request)
-                cb.requests[request] = True
+                cb.requests.add(request)
+                self.__requests[request] = (cb, i)
+                i += 1
             return cb
             return cb
 
 
 
 
@@ -496,7 +499,7 @@ class Loader(DirectObject):
             phaseChecker(modelPath, loaderOptions)
             phaseChecker(modelPath, loaderOptions)
 
 
         font = FontPool.loadFont(modelPath)
         font = FontPool.loadFont(modelPath)
-        if font == None:
+        if font is None:
             if not okMissing:
             if not okMissing:
                 message = 'Could not load font file: %s' % (modelPath)
                 message = 'Could not load font file: %s' % (modelPath)
                 raise IOError(message)
                 raise IOError(message)
@@ -506,21 +509,21 @@ class Loader(DirectObject):
 
 
         # The following properties may only be set for dynamic fonts.
         # The following properties may only be set for dynamic fonts.
         if hasattr(font, "setPointSize"):
         if hasattr(font, "setPointSize"):
-            if pointSize != None:
+            if pointSize is not None:
                 font.setPointSize(pointSize)
                 font.setPointSize(pointSize)
-            if pixelsPerUnit != None:
+            if pixelsPerUnit is not None:
                 font.setPixelsPerUnit(pixelsPerUnit)
                 font.setPixelsPerUnit(pixelsPerUnit)
-            if scaleFactor != None:
+            if scaleFactor is not None:
                 font.setScaleFactor(scaleFactor)
                 font.setScaleFactor(scaleFactor)
-            if textureMargin != None:
+            if textureMargin is not None:
                 font.setTextureMargin(textureMargin)
                 font.setTextureMargin(textureMargin)
-            if polyMargin != None:
+            if polyMargin is not None:
                 font.setPolyMargin(polyMargin)
                 font.setPolyMargin(polyMargin)
-            if minFilter != None:
+            if minFilter is not None:
                 font.setMinfilter(minFilter)
                 font.setMinfilter(minFilter)
-            if magFilter != None:
+            if magFilter is not None:
                 font.setMagfilter(magFilter)
                 font.setMagfilter(magFilter)
-            if anisotropicDegree != None:
+            if anisotropicDegree is not None:
                 font.setAnisotropicDegree(anisotropicDegree)
                 font.setAnisotropicDegree(anisotropicDegree)
             if color:
             if color:
                 font.setFg(color)
                 font.setFg(color)
@@ -577,10 +580,10 @@ class Loader(DirectObject):
         the texture and the number of expected mipmap images.
         the texture and the number of expected mipmap images.
 
 
         If minfilter or magfilter is not None, they should be a symbol
         If minfilter or magfilter is not None, they should be a symbol
-        like Texture.FTLinear or Texture.FTNearest.  (minfilter may be
-        further one of the Mipmap filter type symbols.)  These specify
-        the filter mode that will automatically be applied to the
-        texture when it is loaded.  Note that this setting may
+        like SamplerState.FTLinear or SamplerState.FTNearest.  (minfilter
+        may be further one of the Mipmap filter type symbols.)  These
+        specify the filter mode that will automatically be applied to
+        the texture when it is loaded.  Note that this setting may
         override the texture's existing settings, even if it has
         override the texture's existing settings, even if it has
         already been loaded.  See egg-texture-cards for a more robust
         already been loaded.  See egg-texture-cards for a more robust
         way to apply per-texture filter types and settings.
         way to apply per-texture filter types and settings.
@@ -596,7 +599,7 @@ class Loader(DirectObject):
         left image and '1' for the right image.  Larger numbers are
         left image and '1' for the right image.  Larger numbers are
         also allowed if you need more than two views.
         also allowed if you need more than two views.
         """
         """
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
             loaderOptions = LoaderOptions()
         else:
         else:
             loaderOptions = LoaderOptions(loaderOptions)
             loaderOptions = LoaderOptions(loaderOptions)
@@ -657,7 +660,7 @@ class Loader(DirectObject):
         numbered 8 - 15 will be part of the right eye view.
         numbered 8 - 15 will be part of the right eye view.
         """
         """
         assert Loader.notify.debug("Loading 3-D texture: %s" % (texturePattern))
         assert Loader.notify.debug("Loading 3-D texture: %s" % (texturePattern))
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
             loaderOptions = LoaderOptions()
         else:
         else:
             loaderOptions = LoaderOptions(loaderOptions)
             loaderOptions = LoaderOptions(loaderOptions)
@@ -684,6 +687,63 @@ class Loader(DirectObject):
 
 
         return texture
         return texture
 
 
+    def load2DTextureArray(self, texturePattern, readMipmaps = False, okMissing = False,
+                      minfilter = None, magfilter = None, anisotropicDegree = None,
+                      loaderOptions = None, multiview = None, numViews = 2):
+        """
+        texturePattern is a string that contains a sequence of one or
+        more hash characters ('#'), which will be filled in with the
+        z-height number.  Returns a 2-D Texture array object, suitable
+        for rendering array of textures.
+
+        okMissing should be True to indicate the method should return
+        None if the texture file is not found.  If it is False, the
+        method will raise an exception if the texture file is not
+        found or cannot be loaded.
+
+        If readMipmaps is True, then the filename string must contain
+        two sequences of hash characters; the first group is filled in
+        with the z-height number, and the second group with the mipmap
+        index number.
+
+        If multiview is true, it indicates to load a multiview or
+        stereo texture.  In this case, numViews should also be
+        specified (the default is 2), and the sequence of texture
+        images will be divided into numViews views.  The total
+        z-height will be (numImages / numViews).  For instance, if you
+        read 16 images with numViews = 2, then you have created a
+        stereo multiview image, with z = 8.  In this example, images
+        numbered 0 - 7 will be part of the left eye view, and images
+        numbered 8 - 15 will be part of the right eye view.
+        """
+        assert Loader.notify.debug("Loading 2-D texture array: %s" % (texturePattern))
+        if loaderOptions is None:
+            loaderOptions = LoaderOptions()
+        else:
+            loaderOptions = LoaderOptions(loaderOptions)
+        if multiview is not None:
+            flags = loaderOptions.getTextureFlags()
+            if multiview:
+                flags |= LoaderOptions.TFMultiview
+            else:
+                flags &= ~LoaderOptions.TFMultiview
+            loaderOptions.setTextureFlags(flags)
+            loaderOptions.setTextureNumViews(numViews)
+
+        texture = TexturePool.load2dTextureArray(texturePattern, readMipmaps, loaderOptions)
+        if not texture and not okMissing:
+            message = 'Could not load 2-D texture array: %s' % (texturePattern)
+            raise IOError(message)
+
+        if minfilter is not None:
+            texture.setMinfilter(minfilter)
+        if magfilter is not None:
+            texture.setMagfilter(magfilter)
+        if anisotropicDegree is not None:
+            texture.setAnisotropicDegree(anisotropicDegree)
+
+        return texture
+
     def loadCubeMap(self, texturePattern, readMipmaps = False, okMissing = False,
     def loadCubeMap(self, texturePattern, readMipmaps = False, okMissing = False,
                     minfilter = None, magfilter = None, anisotropicDegree = None,
                     minfilter = None, magfilter = None, anisotropicDegree = None,
                     loaderOptions = None, multiview = None):
                     loaderOptions = None, multiview = None):
@@ -711,7 +771,7 @@ class Loader(DirectObject):
         and each six images will define a new view.
         and each six images will define a new view.
         """
         """
         assert Loader.notify.debug("Loading cube map: %s" % (texturePattern))
         assert Loader.notify.debug("Loading cube map: %s" % (texturePattern))
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
             loaderOptions = LoaderOptions()
         else:
         else:
             loaderOptions = LoaderOptions(loaderOptions)
             loaderOptions = LoaderOptions(loaderOptions)
@@ -821,13 +881,12 @@ class Loader(DirectObject):
             # callback (passing it the sounds on the parameter list).
             # callback (passing it the sounds on the parameter list).
 
 
             cb = Loader.Callback(len(soundList), gotList, callback, extraArgs)
             cb = Loader.Callback(len(soundList), gotList, callback, extraArgs)
-            for i in range(len(soundList)):
-                soundPath = soundList[i]
+            for i, soundPath in enumerate(soundList):
                 request = AudioLoadRequest(manager, soundPath, positional)
                 request = AudioLoadRequest(manager, soundPath, positional)
                 request.setDoneEvent(self.hook)
                 request.setDoneEvent(self.hook)
-                request.setPythonObject((cb, i))
                 self.loader.loadAsync(request)
                 self.loader.loadAsync(request)
-                cb.requests[request] = True
+                cb.requests.add(request)
+                self.__requests[request] = (cb, i)
             return cb
             return cb
 
 
     def unloadSfx(self, sfx):
     def unloadSfx(self, sfx):
@@ -852,7 +911,7 @@ class Loader(DirectObject):
         return shader
         return shader
 
 
     def unloadShader(self, shaderPath):
     def unloadShader(self, shaderPath):
-        if (shaderPath != None):
+        if shaderPath is not None:
             ShaderPool.releaseShader(shaderPath)
             ShaderPool.releaseShader(shaderPath)
 
 
     def asyncFlattenStrong(self, model, inPlace = True,
     def asyncFlattenStrong(self, model, inPlace = True,
@@ -886,14 +945,14 @@ class Loader(DirectObject):
             gotList = True
             gotList = True
 
 
         cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
         cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
-        i=0
+        i = 0
         for model in modelList:
         for model in modelList:
             request = ModelFlattenRequest(model.node())
             request = ModelFlattenRequest(model.node())
             request.setDoneEvent(self.hook)
             request.setDoneEvent(self.hook)
-            request.setPythonObject((cb, i))
-            i+=1
             self.loader.loadAsync(request)
             self.loader.loadAsync(request)
-            cb.requests[request] = True
+            cb.requests.add(request)
+            self.__requests[request] = (cb, i)
+            i += 1
         return cb
         return cb
 
 
     def __asyncFlattenDone(self, models,
     def __asyncFlattenDone(self, models,
@@ -907,7 +966,7 @@ class Loader(DirectObject):
             orig = origModelList[i].node()
             orig = origModelList[i].node()
             flat = models[i].node()
             flat = models[i].node()
             orig.copyAllProperties(flat)
             orig.copyAllProperties(flat)
-            orig.replaceNode(flat)
+            flat.replaceNode(orig)
 
 
         if callback:
         if callback:
             if gotList:
             if gotList:
@@ -921,16 +980,23 @@ class Loader(DirectObject):
         of loaded objects, and call the appropriate callback when it's
         of loaded objects, and call the appropriate callback when it's
         time."""
         time."""
 
 
-        cb, i = request.getPythonObject()
+        if request not in self.__requests:
+            return
+
+        cb, i = self.__requests[request]
         if cb.cancelled:
         if cb.cancelled:
+            # Shouldn't be here.
+            del self.__requests[request]
             return
             return
 
 
-        del cb.requests[request]
+        cb.requests.discard(request)
+        if not cb.requests:
+            del self.__requests[request]
 
 
         object = None
         object = None
         if hasattr(request, "getModel"):
         if hasattr(request, "getModel"):
             node = request.getModel()
             node = request.getModel()
-            if (node != None):
+            if node is not None:
                 object = NodePath(node)
                 object = NodePath(node)
 
 
         elif hasattr(request, "getSound"):
         elif hasattr(request, "getSound"):

+ 1 - 1
direct/src/showbase/MirrorDemo.py

@@ -23,7 +23,7 @@ surface are possible, like a funhouse mirror.  However, the reflection
 itself is always basically planar; for more accurate convex
 itself is always basically planar; for more accurate convex
 reflections, you will need to use a sphere map or a cube map."""
 reflections, you will need to use a sphere map or a cube map."""
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.task import Task
 from direct.task import Task
 
 
 def setupMirror(name, width, height, rootCamera = None):
 def setupMirror(name, width, height, rootCamera = None):

+ 1 - 1
direct/src/showbase/ShadowDemo.py

@@ -14,7 +14,7 @@ multitexture rendering techniques.  It's not a particularly great
 way to do shadows.
 way to do shadows.
 """
 """
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.task import Task
 from direct.task import Task
 
 
 sc = None
 sc = None

+ 1 - 1
direct/src/showbase/ShadowPlacer.py

@@ -12,7 +12,7 @@ the its parent node.
 
 
 from direct.controls.ControlManager import CollisionHandlerRayStart
 from direct.controls.ControlManager import CollisionHandlerRayStart
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
-from pandac.PandaModules import *
+from panda3d.core import *
 from . import DirectObject
 from . import DirectObject
 
 
 class ShadowPlacer(DirectObject.DirectObject):
 class ShadowPlacer(DirectObject.DirectObject):

+ 0 - 4
direct/src/showbase/ShowBase.py

@@ -127,10 +127,6 @@ class ShowBase(DirectObject.DirectObject):
         ## just before Python is about to shut down.
         ## just before Python is about to shut down.
         self.finalExitCallbacks = []
         self.finalExitCallbacks = []
 
 
-        Task.TaskManager.taskTimerVerbose = self.config.GetBool('task-timer-verbose', 0)
-        Task.TaskManager.extendedExceptions = self.config.GetBool('extended-exceptions', 0)
-        Task.TaskManager.pStatsTasks = self.config.GetBool('pstats-tasks', 0)
-
         # Set up the TaskManager to reset the PStats clock back
         # Set up the TaskManager to reset the PStats clock back
         # whenever we resume from a pause.  This callback function is
         # whenever we resume from a pause.  This callback function is
         # a little hacky, but we can't call it directly from within
         # a little hacky, but we can't call it directly from within

+ 0 - 1
direct/src/showutil/.gitignore

@@ -1 +0,0 @@
-/runp3d

+ 4 - 1
direct/src/showutil/FreezeTool.py

@@ -984,7 +984,10 @@ class Freezer:
             try:
             try:
                 self.__loadModule(mdef)
                 self.__loadModule(mdef)
             except ImportError as ex:
             except ImportError as ex:
-                print("Unknown module: %s (%s)" % (mdef.moduleName, str(ex)))
+                message = "Unknown module: %s" % (mdef.moduleName)
+                if str(ex) != "No module named " + str(mdef.moduleName):
+                    message += " (%s)" % (ex)
+                print(message)
 
 
         # Also attempt to import any implicit modules.  If any of
         # Also attempt to import any implicit modules.  If any of
         # these fail to import, we don't really care.
         # these fail to import, we don't really care.

+ 10 - 10
direct/src/stdpy/thread.py

@@ -102,7 +102,7 @@ def start_new_thread(function, args, kwargs = {}, name = None):
             name = 'PythonThread-%s' % (threadId)
             name = 'PythonThread-%s' % (threadId)
 
 
         thread = core.PythonThread(threadFunc, [threadId], name, name)
         thread = core.PythonThread(threadFunc, [threadId], name, name)
-        thread.setPythonData(threadId)
+        thread.setPythonIndex(threadId)
         _threads[threadId] = (thread, {}, None)
         _threads[threadId] = (thread, {}, None)
 
 
         thread.start(core.TPNormal, False)
         thread.start(core.TPNormal, False)
@@ -121,7 +121,7 @@ def _add_thread(thread, wrapper):
         threadId = _nextThreadId
         threadId = _nextThreadId
         _nextThreadId += 1
         _nextThreadId += 1
 
 
-        thread.setPythonData(threadId)
+        thread.setPythonIndex(threadId)
         _threads[threadId] = (thread, {}, wrapper)
         _threads[threadId] = (thread, {}, wrapper)
         return threadId
         return threadId
 
 
@@ -133,8 +133,8 @@ def _get_thread_wrapper(thread, wrapperClass):
     is not one, creates an instance of the indicated wrapperClass
     is not one, creates an instance of the indicated wrapperClass
     instead. """
     instead. """
 
 
-    threadId = thread.getPythonData()
-    if threadId is None:
+    threadId = thread.getPythonIndex()
+    if threadId == -1:
         # The thread has never been assigned a threadId.  Go assign one.
         # The thread has never been assigned a threadId.  Go assign one.
 
 
         global _nextThreadId
         global _nextThreadId
@@ -143,7 +143,7 @@ def _get_thread_wrapper(thread, wrapperClass):
             threadId = _nextThreadId
             threadId = _nextThreadId
             _nextThreadId += 1
             _nextThreadId += 1
 
 
-            thread.setPythonData(threadId)
+            thread.setPythonIndex(threadId)
             wrapper = wrapperClass(thread, threadId)
             wrapper = wrapperClass(thread, threadId)
             _threads[threadId] = (thread, {}, wrapper)
             _threads[threadId] = (thread, {}, wrapper)
             return wrapper
             return wrapper
@@ -169,8 +169,8 @@ def _get_thread_locals(thread, i):
     """ Returns the locals dictionary for the indicated thread.  If
     """ Returns the locals dictionary for the indicated thread.  If
     there is not one, creates an empty dictionary. """
     there is not one, creates an empty dictionary. """
 
 
-    threadId = thread.getPythonData()
-    if threadId is None:
+    threadId = thread.getPythonIndex()
+    if threadId == -1:
         # The thread has never been assigned a threadId.  Go assign one.
         # The thread has never been assigned a threadId.  Go assign one.
 
 
         global _nextThreadId
         global _nextThreadId
@@ -179,7 +179,7 @@ def _get_thread_locals(thread, i):
             threadId = _nextThreadId
             threadId = _nextThreadId
             _nextThreadId += 1
             _nextThreadId += 1
 
 
-            thread.setPythonData(threadId)
+            thread.setPythonIndex(threadId)
             locals = {}
             locals = {}
             _threads[threadId] = (thread, locals, None)
             _threads[threadId] = (thread, locals, None)
             return locals.setdefault(i, {})
             return locals.setdefault(i, {})
@@ -205,9 +205,9 @@ def _remove_thread_id(threadId):
     _threadsLock.acquire()
     _threadsLock.acquire()
     try:
     try:
         thread, locals, wrapper = _threads[threadId]
         thread, locals, wrapper = _threads[threadId]
-        assert thread.getPythonData() == threadId
+        assert thread.getPythonIndex() == threadId
         del _threads[threadId]
         del _threads[threadId]
-        thread.setPythonData(None)
+        thread.setPythonIndex(-1)
 
 
     finally:
     finally:
         _threadsLock.release()
         _threadsLock.release()

+ 4 - 1
direct/src/task/Task.py

@@ -102,7 +102,10 @@ Task.DtoolClassDict['loop'] = staticmethod(loop)
 class TaskManager:
 class TaskManager:
     notify = directNotify.newCategory("TaskManager")
     notify = directNotify.newCategory("TaskManager")
 
 
-    extendedExceptions = False
+    taskTimerVerbose = ConfigVariableBool('task-timer-verbose', False)
+    extendedExceptions = ConfigVariableBool('extended-exceptions', False)
+    pStatsTasks = ConfigVariableBool('pstats-tasks', False)
+
     MaxEpochSpeed = 1.0/30.0
     MaxEpochSpeed = 1.0/30.0
 
 
     def __init__(self):
     def __init__(self):

+ 0 - 7
dmodels/.gitignore

@@ -1,7 +0,0 @@
-*.egg
-*.pt
-/built/
-Makefile
-bams/
-optchar/
-pal_egg/

+ 0 - 6
dmodels/src/.gitignore

@@ -1,6 +0,0 @@
-/*.buildings
-/game_options.txt
-/prefixstrip
-/retarget/
-/textures.boo
-/topstrip/

+ 33 - 0
doc/ReleaseNotes

@@ -6,15 +6,48 @@ This issue fixes several bugs that were still found in 1.9.2.
 * Fix crash using wx/tkinter on Mac as long as want-wx/tk is set
 * Fix crash using wx/tkinter on Mac as long as want-wx/tk is set
 * Fix loading models from 'models' package with models/ prefix
 * Fix loading models from 'models' package with models/ prefix
 * Fix random crashes in task system
 * Fix random crashes in task system
+* Fix various race conditions causing threading issues
 * Fix memory leaks in BulletTriangleMesh
 * Fix memory leaks in BulletTriangleMesh
 * Fix loading old models with MovingPart<LMatrix4f>
 * Fix loading old models with MovingPart<LMatrix4f>
 * Improve performance of CPU vertex animation somewhat
 * Improve performance of CPU vertex animation somewhat
 * Show framebuffer properties when fbprop request fails
 * Show framebuffer properties when fbprop request fails
+* Show error instead of crash on use of object before __init__
 * Fix hang on exit when using Python task on threaded task chain
 * Fix hang on exit when using Python task on threaded task chain
 * Fix inability to get RGBA renderbuffer in certain cases
 * Fix inability to get RGBA renderbuffer in certain cases
 * Work around GLSL issue with #pragma and certain Intel drivers
 * Work around GLSL issue with #pragma and certain Intel drivers
 * Improve performance of texture load and store operations
 * Improve performance of texture load and store operations
 * Fix crashes with pbuffers on Intel cards on Windows
 * Fix crashes with pbuffers on Intel cards on Windows
+* Support for Autodesk Maya 2016.5
+* Add shadow-depth-bits config var to control shadow map depth
+* Fix cull issue when rendering cube map (or any multi-lens setup)
+* Fix crash rendering with the same camera to different contexts
+* Fix compile error when making static build with DX9 renderer
+* Fix assertion when using aux render targets in DX9
+* Work around Cg bug generating invalid ASM for saturated tex loads
+* Fix issues with certain Cg shader inputs in DX9
+* Support uint8 index buffers in DX9
+* Fix occasional frame lag when loading a big model asynchronously
+* Fix interrogate parsing issue with "const static"
+* Add back missing libp3pystub.a to Mac OS X SDK
+* Fix RAM caching of 2D texture arrays
+* Fix Ctrl+C interrupt propagation to runtime applications
+* Support for InvSphere, Box and Tube solids in bam2egg
+* Preserve "intangible" and "level" collide flags in bam2egg
+* Add normalized() method to vectors
+* asyncFlattenStrong with inPlace=True caused node to disappear
+* Fix asyncFlattenStrong called on nodes without parent
+* Fix is_playing() check when playing an animation backwards
+* Windows installer no longer clears %PATH% if longer than 1024 chars
+* Fix inoperative -tbn/-tbnall/-tbnauto options in egg-optchar
+* Fix tinydisplay texture errors on shutdown
+* Fix mipmap filtering issues in tinydisplay renderer
+* Fix exception when creating intervals before ShowBase is started
+* Fix rare X11 .ico cursor bug; also now supports PNG-compressed icons
+* Add keyword argument support to make() methods such as Shader.make()
+* Fix compilation errors with Bullet 2.84
+* Fix exception when trying to pickle NodePathCollection objects
+* Fix error when trying to raise vectors to a power
+* GLSL: fix error when legacy matrix generator inputs are mat3
 
 
 ------------------------  RELEASE 1.9.2  ------------------------
 ------------------------  RELEASE 1.9.2  ------------------------
 
 

+ 0 - 7
dtool/.gitignore

@@ -1,7 +0,0 @@
-/dtool_config.h
-# These are files that are generated within the source tree by the
-# ppremake system.
-Makefile
-pp.dep
-/built/
-Opt?-*

+ 0 - 2
dtool/src/cppparser/.gitignore

@@ -1,2 +0,0 @@
-/cppBison.cxx
-/cppBison.h

+ 10 - 1
dtool/src/cppparser/cppArrayType.cxx

@@ -13,6 +13,7 @@
 
 
 #include "cppArrayType.h"
 #include "cppArrayType.h"
 #include "cppExpression.h"
 #include "cppExpression.h"
+#include "cppPointerType.h"
 
 
 /**
 /**
  *
  *
@@ -63,6 +64,14 @@ is_tbd() const {
   return _element_type->is_tbd();
   return _element_type->is_tbd();
 }
 }
 
 
+/**
+ * Returns true if the type is considered a standard layout type.
+ */
+bool CPPArrayType::
+is_standard_layout() const {
+  return _element_type->is_standard_layout();
+}
+
 /**
 /**
  * Returns true if the type is considered a Plain Old Data (POD) type.
  * Returns true if the type is considered a Plain Old Data (POD) type.
  */
  */
@@ -76,7 +85,7 @@ is_trivial() const {
  */
  */
 bool CPPArrayType::
 bool CPPArrayType::
 is_default_constructible() const {
 is_default_constructible() const {
-  return _element_type->is_default_constructible();
+  return _bounds != NULL && _element_type->is_default_constructible();
 }
 }
 
 
 /**
 /**

+ 1 - 0
dtool/src/cppparser/cppArrayType.h

@@ -38,6 +38,7 @@ public:
   virtual CPPType *resolve_type(CPPScope *current_scope,
   virtual CPPType *resolve_type(CPPScope *current_scope,
                                 CPPScope *global_scope);
                                 CPPScope *global_scope);
   virtual bool is_tbd() const;
   virtual bool is_tbd() const;
+  virtual bool is_standard_layout() const;
   virtual bool is_trivial() const;
   virtual bool is_trivial() const;
   virtual bool is_default_constructible() const;
   virtual bool is_default_constructible() const;
   virtual bool is_copy_constructible() const;
   virtual bool is_copy_constructible() const;

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


+ 264 - 228
dtool/src/cppparser/cppBison.h.prebuilt

@@ -54,120 +54,138 @@ extern int cppyydebug;
     CUSTOM_LITERAL = 264,
     CUSTOM_LITERAL = 264,
     IDENTIFIER = 265,
     IDENTIFIER = 265,
     TYPENAME_IDENTIFIER = 266,
     TYPENAME_IDENTIFIER = 266,
-    SCOPING = 267,
-    TYPEDEFNAME = 268,
-    ELLIPSIS = 269,
-    OROR = 270,
-    ANDAND = 271,
-    EQCOMPARE = 272,
-    NECOMPARE = 273,
-    LECOMPARE = 274,
-    GECOMPARE = 275,
-    LSHIFT = 276,
-    RSHIFT = 277,
-    POINTSAT_STAR = 278,
-    DOT_STAR = 279,
-    UNARY = 280,
-    UNARY_NOT = 281,
-    UNARY_NEGATE = 282,
-    UNARY_MINUS = 283,
-    UNARY_PLUS = 284,
-    UNARY_STAR = 285,
-    UNARY_REF = 286,
-    POINTSAT = 287,
-    SCOPE = 288,
-    PLUSPLUS = 289,
-    MINUSMINUS = 290,
-    TIMESEQUAL = 291,
-    DIVIDEEQUAL = 292,
-    MODEQUAL = 293,
-    PLUSEQUAL = 294,
-    MINUSEQUAL = 295,
-    OREQUAL = 296,
-    ANDEQUAL = 297,
-    XOREQUAL = 298,
-    LSHIFTEQUAL = 299,
-    RSHIFTEQUAL = 300,
-    KW_ALIGNAS = 301,
-    KW_ALIGNOF = 302,
-    KW_AUTO = 303,
-    KW_BEGIN_PUBLISH = 304,
-    KW_BLOCKING = 305,
-    KW_BOOL = 306,
-    KW_CATCH = 307,
-    KW_CHAR = 308,
-    KW_CHAR16_T = 309,
-    KW_CHAR32_T = 310,
-    KW_CLASS = 311,
-    KW_CONST = 312,
-    KW_CONSTEXPR = 313,
-    KW_CONST_CAST = 314,
-    KW_DECLTYPE = 315,
-    KW_DEFAULT = 316,
-    KW_DELETE = 317,
-    KW_DOUBLE = 318,
-    KW_DYNAMIC_CAST = 319,
-    KW_ELSE = 320,
-    KW_END_PUBLISH = 321,
-    KW_ENUM = 322,
-    KW_EXTENSION = 323,
-    KW_EXTERN = 324,
-    KW_EXPLICIT = 325,
-    KW_PUBLISHED = 326,
-    KW_FALSE = 327,
-    KW_FINAL = 328,
-    KW_FLOAT = 329,
-    KW_FRIEND = 330,
-    KW_FOR = 331,
-    KW_GOTO = 332,
-    KW_IF = 333,
-    KW_INLINE = 334,
-    KW_INT = 335,
-    KW_LONG = 336,
-    KW_MAKE_MAP_PROPERTY = 337,
-    KW_MAKE_PROPERTY = 338,
-    KW_MAKE_PROPERTY2 = 339,
-    KW_MAKE_SEQ = 340,
-    KW_MAKE_SEQ_PROPERTY = 341,
-    KW_MUTABLE = 342,
-    KW_NAMESPACE = 343,
-    KW_NEW = 344,
-    KW_NOEXCEPT = 345,
-    KW_NULLPTR = 346,
-    KW_OPERATOR = 347,
-    KW_OVERRIDE = 348,
-    KW_PRIVATE = 349,
-    KW_PROTECTED = 350,
-    KW_PUBLIC = 351,
-    KW_REGISTER = 352,
-    KW_REINTERPRET_CAST = 353,
-    KW_RETURN = 354,
-    KW_SHORT = 355,
-    KW_SIGNED = 356,
-    KW_SIZEOF = 357,
-    KW_STATIC = 358,
-    KW_STATIC_ASSERT = 359,
-    KW_STATIC_CAST = 360,
-    KW_STRUCT = 361,
-    KW_TEMPLATE = 362,
-    KW_THREAD_LOCAL = 363,
-    KW_THROW = 364,
-    KW_TRUE = 365,
-    KW_TRY = 366,
-    KW_TYPEDEF = 367,
-    KW_TYPEID = 368,
-    KW_TYPENAME = 369,
-    KW_UNION = 370,
-    KW_UNSIGNED = 371,
-    KW_USING = 372,
-    KW_VIRTUAL = 373,
-    KW_VOID = 374,
-    KW_VOLATILE = 375,
-    KW_WCHAR_T = 376,
-    KW_WHILE = 377,
-    START_CPP = 378,
-    START_CONST_EXPR = 379,
-    START_TYPE = 380
+    TYPEPACK_IDENTIFIER = 267,
+    SCOPING = 268,
+    TYPEDEFNAME = 269,
+    ELLIPSIS = 270,
+    OROR = 271,
+    ANDAND = 272,
+    EQCOMPARE = 273,
+    NECOMPARE = 274,
+    LECOMPARE = 275,
+    GECOMPARE = 276,
+    LSHIFT = 277,
+    RSHIFT = 278,
+    POINTSAT_STAR = 279,
+    DOT_STAR = 280,
+    UNARY = 281,
+    UNARY_NOT = 282,
+    UNARY_NEGATE = 283,
+    UNARY_MINUS = 284,
+    UNARY_PLUS = 285,
+    UNARY_STAR = 286,
+    UNARY_REF = 287,
+    POINTSAT = 288,
+    SCOPE = 289,
+    PLUSPLUS = 290,
+    MINUSMINUS = 291,
+    TIMESEQUAL = 292,
+    DIVIDEEQUAL = 293,
+    MODEQUAL = 294,
+    PLUSEQUAL = 295,
+    MINUSEQUAL = 296,
+    OREQUAL = 297,
+    ANDEQUAL = 298,
+    XOREQUAL = 299,
+    LSHIFTEQUAL = 300,
+    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
   };
   };
 #endif
 #endif
 /* Tokens.  */
 /* Tokens.  */
@@ -180,120 +198,138 @@ extern int cppyydebug;
 #define CUSTOM_LITERAL 264
 #define CUSTOM_LITERAL 264
 #define IDENTIFIER 265
 #define IDENTIFIER 265
 #define TYPENAME_IDENTIFIER 266
 #define TYPENAME_IDENTIFIER 266
-#define SCOPING 267
-#define TYPEDEFNAME 268
-#define ELLIPSIS 269
-#define OROR 270
-#define ANDAND 271
-#define EQCOMPARE 272
-#define NECOMPARE 273
-#define LECOMPARE 274
-#define GECOMPARE 275
-#define LSHIFT 276
-#define RSHIFT 277
-#define POINTSAT_STAR 278
-#define DOT_STAR 279
-#define UNARY 280
-#define UNARY_NOT 281
-#define UNARY_NEGATE 282
-#define UNARY_MINUS 283
-#define UNARY_PLUS 284
-#define UNARY_STAR 285
-#define UNARY_REF 286
-#define POINTSAT 287
-#define SCOPE 288
-#define PLUSPLUS 289
-#define MINUSMINUS 290
-#define TIMESEQUAL 291
-#define DIVIDEEQUAL 292
-#define MODEQUAL 293
-#define PLUSEQUAL 294
-#define MINUSEQUAL 295
-#define OREQUAL 296
-#define ANDEQUAL 297
-#define XOREQUAL 298
-#define LSHIFTEQUAL 299
-#define RSHIFTEQUAL 300
-#define KW_ALIGNAS 301
-#define KW_ALIGNOF 302
-#define KW_AUTO 303
-#define KW_BEGIN_PUBLISH 304
-#define KW_BLOCKING 305
-#define KW_BOOL 306
-#define KW_CATCH 307
-#define KW_CHAR 308
-#define KW_CHAR16_T 309
-#define KW_CHAR32_T 310
-#define KW_CLASS 311
-#define KW_CONST 312
-#define KW_CONSTEXPR 313
-#define KW_CONST_CAST 314
-#define KW_DECLTYPE 315
-#define KW_DEFAULT 316
-#define KW_DELETE 317
-#define KW_DOUBLE 318
-#define KW_DYNAMIC_CAST 319
-#define KW_ELSE 320
-#define KW_END_PUBLISH 321
-#define KW_ENUM 322
-#define KW_EXTENSION 323
-#define KW_EXTERN 324
-#define KW_EXPLICIT 325
-#define KW_PUBLISHED 326
-#define KW_FALSE 327
-#define KW_FINAL 328
-#define KW_FLOAT 329
-#define KW_FRIEND 330
-#define KW_FOR 331
-#define KW_GOTO 332
-#define KW_IF 333
-#define KW_INLINE 334
-#define KW_INT 335
-#define KW_LONG 336
-#define KW_MAKE_MAP_PROPERTY 337
-#define KW_MAKE_PROPERTY 338
-#define KW_MAKE_PROPERTY2 339
-#define KW_MAKE_SEQ 340
-#define KW_MAKE_SEQ_PROPERTY 341
-#define KW_MUTABLE 342
-#define KW_NAMESPACE 343
-#define KW_NEW 344
-#define KW_NOEXCEPT 345
-#define KW_NULLPTR 346
-#define KW_OPERATOR 347
-#define KW_OVERRIDE 348
-#define KW_PRIVATE 349
-#define KW_PROTECTED 350
-#define KW_PUBLIC 351
-#define KW_REGISTER 352
-#define KW_REINTERPRET_CAST 353
-#define KW_RETURN 354
-#define KW_SHORT 355
-#define KW_SIGNED 356
-#define KW_SIZEOF 357
-#define KW_STATIC 358
-#define KW_STATIC_ASSERT 359
-#define KW_STATIC_CAST 360
-#define KW_STRUCT 361
-#define KW_TEMPLATE 362
-#define KW_THREAD_LOCAL 363
-#define KW_THROW 364
-#define KW_TRUE 365
-#define KW_TRY 366
-#define KW_TYPEDEF 367
-#define KW_TYPEID 368
-#define KW_TYPENAME 369
-#define KW_UNION 370
-#define KW_UNSIGNED 371
-#define KW_USING 372
-#define KW_VIRTUAL 373
-#define KW_VOID 374
-#define KW_VOLATILE 375
-#define KW_WCHAR_T 376
-#define KW_WHILE 377
-#define START_CPP 378
-#define START_CONST_EXPR 379
-#define START_TYPE 380
+#define TYPEPACK_IDENTIFIER 267
+#define SCOPING 268
+#define TYPEDEFNAME 269
+#define ELLIPSIS 270
+#define OROR 271
+#define ANDAND 272
+#define EQCOMPARE 273
+#define NECOMPARE 274
+#define LECOMPARE 275
+#define GECOMPARE 276
+#define LSHIFT 277
+#define RSHIFT 278
+#define POINTSAT_STAR 279
+#define DOT_STAR 280
+#define UNARY 281
+#define UNARY_NOT 282
+#define UNARY_NEGATE 283
+#define UNARY_MINUS 284
+#define UNARY_PLUS 285
+#define UNARY_STAR 286
+#define UNARY_REF 287
+#define POINTSAT 288
+#define SCOPE 289
+#define PLUSPLUS 290
+#define MINUSMINUS 291
+#define TIMESEQUAL 292
+#define DIVIDEEQUAL 293
+#define MODEQUAL 294
+#define PLUSEQUAL 295
+#define MINUSEQUAL 296
+#define OREQUAL 297
+#define ANDEQUAL 298
+#define XOREQUAL 299
+#define LSHIFTEQUAL 300
+#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
 
 
 /* Value type.  */
 /* Value type.  */
 
 

+ 370 - 106
dtool/src/cppparser/cppBison.yxx

@@ -212,7 +212,7 @@ pop_struct() {
 %token <u.integer> CHAR_TOK
 %token <u.integer> CHAR_TOK
 %token <str> SIMPLE_STRING SIMPLE_IDENTIFIER
 %token <str> SIMPLE_STRING SIMPLE_IDENTIFIER
 %token <u.expr> STRING_LITERAL CUSTOM_LITERAL
 %token <u.expr> STRING_LITERAL CUSTOM_LITERAL
-%token <u.identifier> IDENTIFIER TYPENAME_IDENTIFIER SCOPING
+%token <u.identifier> IDENTIFIER TYPENAME_IDENTIFIER TYPEPACK_IDENTIFIER SCOPING
 %token <u.type> TYPEDEFNAME
 %token <u.type> TYPEDEFNAME
 
 
 %token ELLIPSIS
 %token ELLIPSIS
@@ -280,9 +280,25 @@ pop_struct() {
 %token KW_FRIEND
 %token KW_FRIEND
 %token KW_FOR
 %token KW_FOR
 %token KW_GOTO
 %token KW_GOTO
+%token KW_HAS_VIRTUAL_DESTRUCTOR
 %token KW_IF
 %token KW_IF
 %token KW_INLINE
 %token KW_INLINE
 %token KW_INT
 %token KW_INT
+%token KW_IS_ABSTRACT
+%token KW_IS_BASE_OF
+%token KW_IS_CLASS
+%token KW_IS_CONSTRUCTIBLE
+%token KW_IS_CONVERTIBLE_TO
+%token KW_IS_DESTRUCTIBLE
+%token KW_IS_EMPTY
+%token KW_IS_ENUM
+%token KW_IS_FINAL
+%token KW_IS_FUNDAMENTAL
+%token KW_IS_POD
+%token KW_IS_POLYMORPHIC
+%token KW_IS_STANDARD_LAYOUT
+%token KW_IS_TRIVIAL
+%token KW_IS_UNION
 %token KW_LONG
 %token KW_LONG
 %token KW_MAKE_MAP_PROPERTY
 %token KW_MAKE_MAP_PROPERTY
 %token KW_MAKE_PROPERTY
 %token KW_MAKE_PROPERTY
@@ -317,6 +333,7 @@ pop_struct() {
 %token KW_TYPEDEF
 %token KW_TYPEDEF
 %token KW_TYPEID
 %token KW_TYPEID
 %token KW_TYPENAME
 %token KW_TYPENAME
+%token KW_UNDERLYING_TYPE
 %token KW_UNION
 %token KW_UNION
 %token KW_UNSIGNED
 %token KW_UNSIGNED
 %token KW_USING
 %token KW_USING
@@ -354,9 +371,10 @@ pop_struct() {
 %type <u.instance> formal_parameter
 %type <u.instance> formal_parameter
 %type <u.inst_ident> not_paren_formal_parameter_identifier
 %type <u.inst_ident> not_paren_formal_parameter_identifier
 %type <u.inst_ident> formal_parameter_identifier
 %type <u.inst_ident> formal_parameter_identifier
+%type <u.inst_ident> parameter_pack_identifier
 %type <u.inst_ident> not_paren_empty_instance_identifier
 %type <u.inst_ident> not_paren_empty_instance_identifier
 %type <u.inst_ident> empty_instance_identifier
 %type <u.inst_ident> empty_instance_identifier
-%type <u.type> type
+%type <u.type> type type_pack
 %type <u.decl> type_decl
 %type <u.decl> type_decl
 %type <u.decl> var_type_decl
 %type <u.decl> var_type_decl
 %type <u.type> predefined_type
 %type <u.type> predefined_type
@@ -447,6 +465,10 @@ constructor_init:
         name '(' optional_const_expr_comma ')'
         name '(' optional_const_expr_comma ')'
 {
 {
   delete $3;
   delete $3;
+}
+        | name '(' optional_const_expr_comma ')' ELLIPSIS
+{
+  delete $3;
 }
 }
         | name '{' optional_const_expr_comma '}'
         | name '{' optional_const_expr_comma '}'
 {
 {
@@ -783,6 +805,11 @@ storage_class:
         empty
         empty
 {
 {
   $$ = 0;
   $$ = 0;
+}
+        | KW_CONST storage_class
+{
+  // This isn't really a storage class, but it helps with parsing.
+  $$ = $2 | (int)CPPInstance::SC_const;
 }
 }
         | KW_EXTERN storage_class
         | KW_EXTERN storage_class
 {
 {
@@ -861,10 +888,22 @@ attribute_specifier:
         ;
         ;
 
 
 type_like_declaration:
 type_like_declaration:
-        multiple_var_declaration
+        storage_class var_type_decl
+{
+  // We don't need to push/pop type, because we can't nest
+  // type_like_declaration.
+  if ($2->as_type_declaration()) {
+    current_type = $2->as_type_declaration()->_type;
+  } else {
+    current_type = $2->as_type();
+  }
+  push_storage_class($1);
+}
+        multiple_instance_identifiers
 {
 {
-  /* multiple_var_declaration adds itself to the scope. */
+  pop_storage_class();
 }
 }
+
         | storage_class type_decl ';'
         | storage_class type_decl ';'
 {
 {
   // We don't really care about the storage class here.  In fact, it's
   // We don't really care about the storage class here.  In fact, it's
@@ -891,39 +930,6 @@ type_like_declaration:
   }
   }
 }
 }
         | using_declaration
         | using_declaration
-        ;
-
-multiple_var_declaration:
-        storage_class var_type_decl
-{
-  // We don't need to push/pop type, because we can't nest
-  // multiple_var_declarations.
-  if ($2->as_type_declaration()) {
-    current_type = $2->as_type_declaration()->_type;
-  } else {
-    current_type = $2->as_type();
-  }
-  push_storage_class($1);
-}
-        multiple_instance_identifiers
-{
-  pop_storage_class();
-}
-        | storage_class KW_CONST var_type_decl
-{
-  // We don't need to push/pop type, because we can't nest
-  // multiple_var_declarations.
-  if ($3->as_type_declaration()) {
-    current_type = $3->as_type_declaration()->_type;
-  } else {
-    current_type = $3->as_type();
-  }
-  push_storage_class($1);
-}
-        multiple_const_instance_identifiers
-{
-  pop_storage_class();
-}
 
 
         /* We don't need to include a rule for variables that point to
         /* We don't need to include a rule for variables that point to
            functions, because we get those from the function_prototype
            functions, because we get those from the function_prototype
@@ -933,6 +939,9 @@ multiple_var_declaration:
 multiple_instance_identifiers:
 multiple_instance_identifiers:
         instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
         instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
 {
 {
+  if (current_storage_class & CPPInstance::SC_const) {
+    $1->add_modifier(IIT_const);
+  }
   CPPInstance *inst = new CPPInstance(current_type, $1,
   CPPInstance *inst = new CPPInstance(current_type, $1,
                                       current_storage_class,
                                       current_storage_class,
                                       @1.file);
                                       @1.file);
@@ -941,27 +950,9 @@ multiple_instance_identifiers:
 }
 }
         | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' multiple_instance_identifiers
         | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' multiple_instance_identifiers
 {
 {
-  CPPInstance *inst = new CPPInstance(current_type, $1,
-                                      current_storage_class,
-                                      @1.file);
-  inst->set_initializer($2);
-  current_scope->add_declaration(inst, global_scope, current_lexer, @1);
-}
-        ;
-
-multiple_const_instance_identifiers:
-        instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
-{
-  $1->add_modifier(IIT_const);
-  CPPInstance *inst = new CPPInstance(current_type, $1,
-                                      current_storage_class,
-                                      @1.file);
-  inst->set_initializer($2);
-  current_scope->add_declaration(inst, global_scope, current_lexer, @1);
-}
-        | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' multiple_const_instance_identifiers
-{
-  $1->add_modifier(IIT_const);
+  if (current_storage_class & CPPInstance::SC_const) {
+    $1->add_modifier(IIT_const);
+  }
   CPPInstance *inst = new CPPInstance(current_type, $1,
   CPPInstance *inst = new CPPInstance(current_type, $1,
                                       current_storage_class,
                                       current_storage_class,
                                       @1.file);
                                       @1.file);
@@ -986,21 +977,6 @@ typedef_declaration:
         typedef_instance_identifiers
         typedef_instance_identifiers
 {
 {
   pop_storage_class();
   pop_storage_class();
-}
-        | storage_class KW_CONST var_type_decl
-{
-  // We don't need to push/pop type, because we can't nest
-  // multiple_var_declarations.
-  if ($3->as_type_declaration()) {
-    current_type = $3->as_type_declaration()->_type;
-  } else {
-    current_type = $3->as_type();
-  }
-  push_storage_class($1);
-}
-        typedef_const_instance_identifiers
-{
-  pop_storage_class();
 }
 }
         | storage_class function_prototype maybe_initialize_or_function_body
         | storage_class function_prototype maybe_initialize_or_function_body
 {
 {
@@ -1019,29 +995,18 @@ typedef_declaration:
 typedef_instance_identifiers:
 typedef_instance_identifiers:
         instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
         instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
 {
 {
+  if (current_storage_class & CPPInstance::SC_const) {
+    $1->add_modifier(IIT_const);
+  }
   CPPType *target_type = current_type;
   CPPType *target_type = current_type;
   CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
   CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
   current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
   current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
 }
 }
         | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_instance_identifiers
         | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_instance_identifiers
 {
 {
-  CPPType *target_type = current_type;
-  CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
-  current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
-}
-        ;
-
-typedef_const_instance_identifiers:
-        instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
-{
-  $1->add_modifier(IIT_const);
-  CPPType *target_type = current_type;
-  CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
-  current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
-}
-        | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_const_instance_identifiers
-{
-  $1->add_modifier(IIT_const);
+  if (current_storage_class & CPPInstance::SC_const) {
+    $1->add_modifier(IIT_const);
+  }
   CPPType *target_type = current_type;
   CPPType *target_type = current_type;
   CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
   CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
   current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
   current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
@@ -1244,26 +1209,38 @@ function_post:
 {
 {
   $$ = 0;
   $$ = 0;
 }
 }
-        | KW_CONST
+        | function_post KW_CONST
+{
+  $$ = $1 | (int)CPPFunctionType::F_const_method;
+}
+        | function_post KW_VOLATILE
 {
 {
-  $$ = (int)CPPFunctionType::F_const_method;
+  $$ = $1 | (int)CPPFunctionType::F_volatile_method;
 }
 }
         | function_post KW_NOEXCEPT
         | function_post KW_NOEXCEPT
 {
 {
-  $$ = (int)CPPFunctionType::F_noexcept;
+  $$ = $1 | (int)CPPFunctionType::F_noexcept;
 }
 }
         | function_post KW_FINAL
         | function_post KW_FINAL
 {
 {
-  $$ = (int)CPPFunctionType::F_final;
+  $$ = $1 | (int)CPPFunctionType::F_final;
 }
 }
         | function_post KW_OVERRIDE
         | function_post KW_OVERRIDE
 {
 {
-  $$ = (int)CPPFunctionType::F_override;
+  $$ = $1 | (int)CPPFunctionType::F_override;
+}
+        | function_post '&'
+{
+  $$ = $1 | (int)CPPFunctionType::F_lvalue_method;
+}
+        | function_post ANDAND
+{
+  $$ = $1 | (int)CPPFunctionType::F_rvalue_method;
 }
 }
         | function_post KW_MUTABLE
         | function_post KW_MUTABLE
 {
 {
   // Used for lambdas, currently ignored.
   // Used for lambdas, currently ignored.
-  $$ = 0;
+  $$ = $1;
 }
 }
         | function_post KW_THROW '(' ')'
         | function_post KW_THROW '(' ')'
 {
 {
@@ -1272,6 +1249,10 @@ function_post:
         | function_post KW_THROW '(' name ')'
         | function_post KW_THROW '(' name ')'
 {
 {
   $$ = $1;
   $$ = $1;
+}
+        | function_post KW_THROW '(' name ELLIPSIS ')'
+{
+  $$ = $1;
 }
 }
 /*        | function_post '[' '[' attribute_specifiers ']' ']'
 /*        | function_post '[' '[' attribute_specifiers ']' ']'
 {
 {
@@ -1475,22 +1456,35 @@ template_nonempty_formal_parameters:
 }
 }
         ;
         ;
 
 
+typename_keyword:
+        KW_CLASS
+        | KW_TYPENAME
+        ;
+
 template_formal_parameter:
 template_formal_parameter:
-        KW_CLASS name
+        typename_keyword
+{
+  $$ = CPPType::new_type(new CPPClassTemplateParameter((CPPIdentifier *)NULL));
+}
+        | typename_keyword name
 {
 {
   $$ = CPPType::new_type(new CPPClassTemplateParameter($2));
   $$ = CPPType::new_type(new CPPClassTemplateParameter($2));
 }
 }
-        | KW_CLASS name '=' full_type
+        | typename_keyword name '=' full_type
 {
 {
   $$ = CPPType::new_type(new CPPClassTemplateParameter($2, $4));
   $$ = CPPType::new_type(new CPPClassTemplateParameter($2, $4));
 }
 }
-        | KW_TYPENAME name
+        | typename_keyword ELLIPSIS
 {
 {
-  $$ = CPPType::new_type(new CPPClassTemplateParameter($2));
+  CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter((CPPIdentifier *)NULL);
+  ctp->_packed = true;
+  $$ = CPPType::new_type(ctp);
 }
 }
-        | KW_TYPENAME name '=' full_type
+        | typename_keyword ELLIPSIS name
 {
 {
-  $$ = CPPType::new_type(new CPPClassTemplateParameter($2, $4));
+  CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter($3);
+  ctp->_packed = true;
+  $$ = CPPType::new_type(ctp);
 }
 }
         | template_formal_parameter_type formal_parameter_identifier template_parameter_maybe_initialize
         | template_formal_parameter_type formal_parameter_identifier template_parameter_maybe_initialize
 {
 {
@@ -1504,6 +1498,17 @@ template_formal_parameter:
   CPPInstance *inst = new CPPInstance($2, $3, 0, @3.file);
   CPPInstance *inst = new CPPInstance($2, $3, 0, @3.file);
   inst->set_initializer($4);
   inst->set_initializer($4);
   $$ = inst;
   $$ = inst;
+}
+        | template_formal_parameter_type parameter_pack_identifier
+{
+  CPPInstance *inst = new CPPInstance($1, $2, 0, @2.file);
+  $$ = inst;
+}
+        | KW_CONST template_formal_parameter_type parameter_pack_identifier
+{
+  $3->add_modifier(IIT_const);
+  CPPInstance *inst = new CPPInstance($2, $3, 0, @3.file);
+  $$ = inst;
 }
 }
         ;
         ;
 
 
@@ -1524,6 +1529,14 @@ template_formal_parameter_type:
     yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
     yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
   }
   }
   assert($$ != NULL);
   assert($$ != NULL);
+}
+        | TYPEPACK_IDENTIFIER
+{
+  $$ = $1->find_type(current_scope, global_scope, false, current_lexer);
+  if ($$ == NULL) {
+    yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
+  }
+  assert($$ != NULL);
 }
 }
         ;
         ;
 
 
@@ -1604,7 +1617,16 @@ instance_identifier:
 }
 }
         | instance_identifier '('
         | instance_identifier '('
 {
 {
-  push_scope($1->get_scope(current_scope, global_scope));
+  // Create a scope for this function (in case it is a function)
+  CPPScope *scope = new CPPScope($1->get_scope(current_scope, global_scope),
+                                 CPPNameComponent(""), V_private);
+
+  // It still needs to be able to pick up any template arguments, if this is
+  // a definition for a method template.  Add a fake "using" declaration to
+  // accomplish this.
+  scope->_using.insert(current_scope);
+
+  push_scope(scope);
 }
 }
         formal_parameter_list ')' function_post
         formal_parameter_list ')' function_post
 {
 {
@@ -1842,6 +1864,23 @@ function_parameter:
   $4->add_modifier(IIT_const);
   $4->add_modifier(IIT_const);
   $$ = new CPPInstance($3, $4, 0, @3.file);
   $$ = new CPPInstance($3, $4, 0, @3.file);
   $$->set_initializer($5);
   $$->set_initializer($5);
+}
+        | type_pack parameter_pack_identifier maybe_initialize
+{
+  $$ = new CPPInstance($1, $2, 0, @2.file);
+  $$->set_initializer($3);
+}
+        | KW_CONST type_pack parameter_pack_identifier maybe_initialize
+{
+  $3->add_modifier(IIT_const);
+  $$ = new CPPInstance($2, $3, 0, @3.file);
+  $$->set_initializer($4);
+}
+        | KW_CONST KW_REGISTER type_pack parameter_pack_identifier maybe_initialize
+{
+  $4->add_modifier(IIT_const);
+  $$ = new CPPInstance($3, $4, 0, @3.file);
+  $$->set_initializer($5);
 }
 }
         | KW_REGISTER function_parameter
         | KW_REGISTER function_parameter
 {
 {
@@ -1970,10 +2009,79 @@ formal_parameter_identifier:
 }
 }
         ;
         ;
 
 
+parameter_pack_identifier:
+        ELLIPSIS
+{
+  $$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
+  $$->_packed = true;
+}
+        | ELLIPSIS name
+{
+  $$ = new CPPInstanceIdentifier($2);
+  $$->_packed = true;
+}
+        | KW_CONST parameter_pack_identifier  %prec UNARY
+{
+  $$ = $2;
+  $$->add_modifier(IIT_const);
+}
+        | KW_VOLATILE parameter_pack_identifier  %prec UNARY
+{
+  $$ = $2;
+  $$->add_modifier(IIT_volatile);
+}
+        | '*' parameter_pack_identifier  %prec UNARY
+{
+  $$ = $2;
+  $$->add_modifier(IIT_pointer);
+}
+        | '&' parameter_pack_identifier  %prec UNARY
+{
+  $$ = $2;
+  $$->add_modifier(IIT_reference);
+}
+        | ANDAND parameter_pack_identifier  %prec UNARY
+{
+  $$ = $2;
+  $$->add_modifier(IIT_rvalue_reference);
+}
+        | SCOPING '*' parameter_pack_identifier  %prec UNARY
+{
+  $$ = $3;
+  $$->add_scoped_pointer_modifier($1);
+}
+        | parameter_pack_identifier '[' optional_const_expr ']'
+{
+  $$ = $1;
+  $$->add_array_modifier($3);
+}
+        | '(' parameter_pack_identifier ')' '(' function_parameter_list ')' function_post
+{
+  $$ = $2;
+  $$->add_modifier(IIT_paren);
+  $$->add_func_modifier($5, $7);
+}
+        | '(' parameter_pack_identifier ')'
+{
+  $$ = $2;
+  $$->add_modifier(IIT_paren);
+}
+        ;
+
 not_paren_empty_instance_identifier:
 not_paren_empty_instance_identifier:
         empty
         empty
 {
 {
   $$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
   $$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
+}
+        | ELLIPSIS
+{
+  $$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
+  $$->_packed = true;
+}
+        | ELLIPSIS name
+{
+  $$ = new CPPInstanceIdentifier($2);
+  $$->_packed = true;
 }
 }
         | KW_CONST not_paren_empty_instance_identifier  %prec UNARY
         | KW_CONST not_paren_empty_instance_identifier  %prec UNARY
 {
 {
@@ -2016,6 +2124,16 @@ empty_instance_identifier:
         empty
         empty
 {
 {
   $$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
   $$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
+}
+        | ELLIPSIS
+{
+  $$ = new CPPInstanceIdentifier((CPPIdentifier *)NULL);
+  $$->_packed = true;
+}
+        | ELLIPSIS name
+{
+  $$ = new CPPInstanceIdentifier($2);
+  $$->_packed = true;
 }
 }
         | KW_CONST empty_instance_identifier  %prec UNARY
         | KW_CONST empty_instance_identifier  %prec UNARY
 {
 {
@@ -2150,6 +2268,16 @@ type:
     str << *$3;
     str << *$3;
     yyerror("could not determine type of " + str.str(), @3);
     yyerror("could not determine type of " + str.str(), @3);
   }
   }
+}
+        | KW_UNDERLYING_TYPE '(' full_type ')'
+{
+  CPPEnumType *enum_type = $3->as_enum_type();
+  if (enum_type == NULL) {
+    yyerror("an enumeration type is required", @3);
+    $$ = $3;
+  } else {
+    $$ = enum_type->get_underlying_type();
+  }
 }
 }
         | KW_AUTO
         | KW_AUTO
 {
 {
@@ -2157,6 +2285,17 @@ type:
 }
 }
         ;
         ;
 
 
+type_pack:
+        TYPEPACK_IDENTIFIER
+{
+  $$ = $1->find_type(current_scope, global_scope, false, current_lexer);
+  if ($$ == NULL) {
+    yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
+  }
+  assert($$ != NULL);
+}
+        ;
+
 type_decl:
 type_decl:
         simple_type
         simple_type
 {
 {
@@ -2244,6 +2383,16 @@ 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_UNDERLYING_TYPE '(' full_type ')'
+{
+  CPPEnumType *enum_type = $3->as_enum_type();
+  if (enum_type == NULL) {
+    yyerror("an enumeration type is required", @3);
+    $$ = $3;
+  } else {
+    $$ = enum_type->get_underlying_type();
+  }
 }
 }
         | KW_AUTO
         | KW_AUTO
 {
 {
@@ -2308,6 +2457,16 @@ predefined_type:
     str << *$3;
     str << *$3;
     yyerror("could not determine type of " + str.str(), @3);
     yyerror("could not determine type of " + str.str(), @3);
   }
   }
+}
+        | KW_UNDERLYING_TYPE '(' full_type ')'
+{
+  CPPEnumType *enum_type = $3->as_enum_type();
+  if (enum_type == NULL) {
+    yyerror("an enumeration type is required", @3);
+    $$ = $3;
+  } else {
+    $$ = enum_type->get_underlying_type();
+  }
 }
 }
         | KW_AUTO
         | KW_AUTO
 {
 {
@@ -2336,6 +2495,15 @@ full_type:
 {
 {
   $3->add_modifier(IIT_const);
   $3->add_modifier(IIT_const);
   $$ = $3->unroll_type($2);
   $$ = $3->unroll_type($2);
+}
+        | type_pack empty_instance_identifier
+{
+  $$ = $2->unroll_type($1);
+}
+        | KW_CONST type_pack empty_instance_identifier
+{
+  $3->add_modifier(IIT_const);
+  $$ = $3->unroll_type($2);
 }
 }
         ;
         ;
 
 
@@ -2750,6 +2918,7 @@ element:
         | CHAR_TOK
         | CHAR_TOK
         | IDENTIFIER
         | IDENTIFIER
         | TYPENAME_IDENTIFIER
         | TYPENAME_IDENTIFIER
+        | TYPEPACK_IDENTIFIER
         | SCOPING
         | SCOPING
         | SIMPLE_IDENTIFIER
         | SIMPLE_IDENTIFIER
         | ELLIPSIS | OROR | ANDAND
         | ELLIPSIS | OROR | ANDAND
@@ -2768,10 +2937,11 @@ element:
         | KW_OPERATOR | KW_OVERRIDE | KW_PRIVATE | KW_PROTECTED
         | KW_OPERATOR | KW_OVERRIDE | KW_PRIVATE | KW_PROTECTED
         | KW_PUBLIC | KW_PUBLISHED | KW_REGISTER | KW_REINTERPRET_CAST
         | KW_PUBLIC | KW_PUBLISHED | KW_REGISTER | KW_REINTERPRET_CAST
         | KW_RETURN | KW_SHORT | KW_SIGNED | KW_SIZEOF | KW_STATIC
         | KW_RETURN | KW_SHORT | KW_SIGNED | KW_SIZEOF | KW_STATIC
-        | KW_STATIC_ASSERT | KW_STATIC_CAST | KW_STRUCT
+        | KW_STATIC_ASSERT | KW_STATIC_CAST | KW_STRUCT | KW_TEMPLATE
         | KW_THREAD_LOCAL | KW_THROW | KW_TRUE | KW_TRY | KW_TYPEDEF
         | KW_THREAD_LOCAL | KW_THROW | KW_TRUE | KW_TRY | KW_TYPEDEF
-        | KW_TYPEID | KW_TYPENAME | KW_UNION | KW_UNSIGNED | KW_USING
-        | KW_VIRTUAL | KW_VOID | KW_VOLATILE | KW_WCHAR_T | KW_WHILE
+        | KW_TYPEID | KW_TYPENAME | KW_UNDERLYING_TYPE | KW_UNION
+        | KW_UNSIGNED | KW_USING | KW_VIRTUAL | KW_VOID | KW_VOLATILE
+        | KW_WCHAR_T | KW_WHILE
 {
 {
 }
 }
         | '+' | '-' | '*' | '/' | '&' | '|' | '^' | '!' | '~' | '=' | '%'
         | '+' | '-' | '*' | '/' | '&' | '|' | '^' | '!' | '~' | '=' | '%'
@@ -2840,6 +3010,10 @@ 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 ELLIPSIS '(' name ')' %prec UNARY
+{
+  $$ = new CPPExpression(CPPExpression::sizeof_ellipsis_func($4));
 }
 }
         | KW_ALIGNOF '(' full_type ')' %prec UNARY
         | KW_ALIGNOF '(' full_type ')' %prec UNARY
 {
 {
@@ -3078,6 +3252,10 @@ 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 ELLIPSIS '(' name ')' %prec UNARY
+{
+  $$ = new CPPExpression(CPPExpression::sizeof_ellipsis_func($4));
 }
 }
         | KW_ALIGNOF '(' full_type ')' %prec UNARY
         | KW_ALIGNOF '(' full_type ')' %prec UNARY
 {
 {
@@ -3295,6 +3473,74 @@ const_operand:
         | '[' 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;
   $$ = NULL;
+}
+        | KW_HAS_VIRTUAL_DESTRUCTOR '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_HAS_VIRTUAL_DESTRUCTOR, $3));
+}
+        | KW_IS_ABSTRACT '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_ABSTRACT, $3));
+}
+        | KW_IS_BASE_OF '(' full_type ',' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_CLASS, $3, $5));
+}
+        | KW_IS_CLASS '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_CLASS, $3));
+}
+        | KW_IS_CONSTRUCTIBLE '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_CONSTRUCTIBLE, $3));
+}
+        | KW_IS_CONSTRUCTIBLE '(' full_type ',' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_CONSTRUCTIBLE, $3, $5));
+}
+        | KW_IS_CONVERTIBLE_TO '(' full_type ',' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_CONVERTIBLE_TO, $3, $5));
+}
+        | KW_IS_DESTRUCTIBLE '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_DESTRUCTIBLE, $3));
+}
+        | KW_IS_EMPTY '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_EMPTY, $3));
+}
+        | KW_IS_ENUM '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_ENUM, $3));
+}
+        | KW_IS_FINAL '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_FINAL, $3));
+}
+        | KW_IS_FUNDAMENTAL '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_FUNDAMENTAL, $3));
+}
+        | KW_IS_POD '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_POD, $3));
+}
+        | KW_IS_POLYMORPHIC '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_POLYMORPHIC, $3));
+}
+        | KW_IS_STANDARD_LAYOUT '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_STANDARD_LAYOUT, $3));
+}
+        | KW_IS_TRIVIAL '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_TRIVIAL, $3));
+}
+        | KW_IS_UNION '(' full_type ')'
+{
+  $$ = new CPPExpression(CPPExpression::type_trait(KW_IS_UNION, $3));
 }
 }
         ;
         ;
 
 
@@ -3333,6 +3579,10 @@ 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 ELLIPSIS '(' name ')' %prec UNARY
+{
+  $$ = new CPPExpression(CPPExpression::sizeof_ellipsis_func($4));
 }
 }
         | KW_ALIGNOF '(' full_type ')' %prec UNARY
         | KW_ALIGNOF '(' full_type ')' %prec UNARY
 {
 {
@@ -3575,6 +3825,12 @@ class_derivation_name:
         | KW_TYPENAME name
         | KW_TYPENAME name
 {
 {
   $$ = CPPType::new_type(new CPPTBDType($2));
   $$ = CPPType::new_type(new CPPTBDType($2));
+}
+        | name ELLIPSIS
+{
+  CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter($1);
+  ctp->_packed = true;
+  $$ = CPPType::new_type(ctp);
 }
 }
         ;
         ;
 
 
@@ -3607,6 +3863,10 @@ name:
         | TYPENAME_IDENTIFIER
         | TYPENAME_IDENTIFIER
 {
 {
   $$ = $1;
   $$ = $1;
+}
+        | TYPEPACK_IDENTIFIER
+{
+  $$ = $1;
 }
 }
         | KW_FINAL
         | KW_FINAL
 {
 {
@@ -3652,6 +3912,10 @@ name_no_final:
         | TYPENAME_IDENTIFIER
         | TYPENAME_IDENTIFIER
 {
 {
   $$ = $1;
   $$ = $1;
+}
+        | TYPEPACK_IDENTIFIER
+{
+  $$ = $1;
 }
 }
         | KW_OVERRIDE
         | KW_OVERRIDE
 {
 {

+ 26 - 3
dtool/src/cppparser/cppClassTemplateParameter.cxx

@@ -21,7 +21,8 @@ CPPClassTemplateParameter::
 CPPClassTemplateParameter(CPPIdentifier *ident, CPPType *default_type) :
 CPPClassTemplateParameter(CPPIdentifier *ident, CPPType *default_type) :
   CPPType(CPPFile()),
   CPPType(CPPFile()),
   _ident(ident),
   _ident(ident),
-  _default_type(default_type)
+  _default_type(default_type),
+  _packed(false)
 {
 {
 }
 }
 
 
@@ -41,8 +42,14 @@ is_fully_specified() const {
 void CPPClassTemplateParameter::
 void CPPClassTemplateParameter::
 output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
 output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
   if (complete) {
   if (complete) {
-    out << "class ";
-    _ident->output(out, scope);
+    out << "class";
+    if (_packed) {
+      out << "...";
+    }
+    if (_ident != NULL) {
+      out << " ";
+      _ident->output(out, scope);
+    }
     if (_default_type) {
     if (_default_type) {
       out << " = ";
       out << " = ";
       _default_type->output(out, indent_level, scope, false);
       _default_type->output(out, indent_level, scope, false);
@@ -82,6 +89,14 @@ is_equal(const CPPDeclaration *other) const {
     return false;
     return false;
   }
   }
 
 
+  if (_packed != ot->_packed) {
+    return false;
+  }
+
+  if (_ident == NULL || ot->_ident == NULL) {
+    return _ident == ot->_ident;
+  }
+
   return *_ident == *ot->_ident;
   return *_ident == *ot->_ident;
 }
 }
 
 
@@ -99,5 +114,13 @@ is_less(const CPPDeclaration *other) const {
     return _default_type < ot->_default_type;
     return _default_type < ot->_default_type;
   }
   }
 
 
+  if (_packed != ot->_packed) {
+    return _packed < ot->_packed;
+  }
+
+  if (_ident == NULL || ot->_ident == NULL) {
+    return _ident < ot->_ident;
+  }
+
   return *_ident < *ot->_ident;
   return *_ident < *ot->_ident;
 }
 }

+ 1 - 0
dtool/src/cppparser/cppClassTemplateParameter.h

@@ -37,6 +37,7 @@ public:
 
 
   CPPIdentifier *_ident;
   CPPIdentifier *_ident;
   CPPType *_default_type;
   CPPType *_default_type;
+  bool _packed;
 
 
 protected:
 protected:
   virtual bool is_equal(const CPPDeclaration *other) const;
   virtual bool is_equal(const CPPDeclaration *other) const;

+ 42 - 1
dtool/src/cppparser/cppConstType.cxx

@@ -86,6 +86,22 @@ is_tbd() const {
   return _wrapped_around->is_tbd();
   return _wrapped_around->is_tbd();
 }
 }
 
 
+/**
+ * Returns true if the type is considered a fundamental type.
+ */
+bool CPPConstType::
+is_fundamental() const {
+  return _wrapped_around->is_fundamental();
+}
+
+/**
+ * Returns true if the type is considered a standard layout type.
+ */
+bool CPPConstType::
+is_standard_layout() const {
+  return _wrapped_around->is_standard_layout();
+}
+
 /**
 /**
  * Returns true if the type is considered a Plain Old Data (POD) type.
  * Returns true if the type is considered a Plain Old Data (POD) type.
  */
  */
@@ -94,12 +110,20 @@ is_trivial() const {
   return _wrapped_around->is_trivial();
   return _wrapped_around->is_trivial();
 }
 }
 
 
+/**
+ * Returns true if the type can be constructed using the given argument.
+ */
+bool CPPConstType::
+is_constructible(const CPPType *given_type) const {
+  return _wrapped_around->is_constructible(given_type);
+}
+
 /**
 /**
  * Returns true if the type is default-constructible.
  * Returns true if the type is default-constructible.
  */
  */
 bool CPPConstType::
 bool CPPConstType::
 is_default_constructible() const {
 is_default_constructible() const {
-  return false;
+  return _wrapped_around->is_default_constructible();
 }
 }
 
 
 /**
 /**
@@ -110,6 +134,23 @@ is_copy_constructible() const {
   return _wrapped_around->is_copy_constructible();
   return _wrapped_around->is_copy_constructible();
 }
 }
 
 
+/**
+ * Returns true if the type is destructible.
+ */
+bool CPPConstType::
+is_destructible() const {
+  return _wrapped_around->is_destructible();
+}
+
+/**
+ * Returns true if variables of this type may be implicitly converted to
+ * the other type.
+ */
+bool CPPConstType::
+is_convertible_to(const CPPType *other) const {
+  return _wrapped_around->is_convertible_to(other);
+}
+
 /**
 /**
  * This is a little more forgiving than is_equal(): it returns true if the
  * This is a little more forgiving than is_equal(): it returns true if the
  * types appear to be referring to the same thing, even if they may have
  * types appear to be referring to the same thing, even if they may have

+ 5 - 0
dtool/src/cppparser/cppConstType.h

@@ -36,9 +36,14 @@ public:
                                 CPPScope *global_scope);
                                 CPPScope *global_scope);
 
 
   virtual bool is_tbd() const;
   virtual bool is_tbd() const;
+  virtual bool is_fundamental() const;
+  virtual bool is_standard_layout() const;
   virtual bool is_trivial() const;
   virtual bool is_trivial() const;
+  virtual bool is_constructible(const CPPType *type) const;
   virtual bool is_default_constructible() const;
   virtual bool is_default_constructible() const;
   virtual bool is_copy_constructible() const;
   virtual bool is_copy_constructible() const;
+  virtual bool is_destructible() const;
+  virtual bool is_convertible_to(const CPPType *other) const;
   virtual bool is_equivalent(const CPPType &other) const;
   virtual bool is_equivalent(const CPPType &other) const;
 
 
   virtual void output(ostream &out, int indent_level, CPPScope *scope,
   virtual void output(ostream &out, int indent_level, CPPScope *scope,

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

@@ -41,8 +41,13 @@ CPPDeclaration(const CPPDeclaration &copy) :
 /**
 /**
  *
  *
  */
  */
-CPPDeclaration::
-~CPPDeclaration() {
+CPPDeclaration &CPPDeclaration::
+operator = (const CPPDeclaration &copy) {
+  _vis = copy._vis;
+  _template_scope = copy._template_scope;
+  _file = copy._file;
+  _leading_comment = copy._leading_comment;
+  return *this;
 }
 }
 
 
 /**
 /**
@@ -124,6 +129,7 @@ CPPDeclaration *CPPDeclaration::
 substitute_decl(SubstDecl &subst, CPPScope *, CPPScope *) {
 substitute_decl(SubstDecl &subst, CPPScope *, CPPScope *) {
   SubstDecl::const_iterator si = subst.find(this);
   SubstDecl::const_iterator si = subst.find(this);
   if (si != subst.end()) {
   if (si != subst.end()) {
+    assert((*si).second != NULL);
     return (*si).second;
     return (*si).second;
   }
   }
   return this;
   return this;

+ 70 - 1
dtool/src/cppparser/cppDeclaration.h

@@ -89,7 +89,9 @@ public:
 
 
   CPPDeclaration(const CPPFile &file);
   CPPDeclaration(const CPPFile &file);
   CPPDeclaration(const CPPDeclaration &copy);
   CPPDeclaration(const CPPDeclaration &copy);
-  virtual ~CPPDeclaration();
+  virtual ~CPPDeclaration() {};
+
+  CPPDeclaration &operator = (const CPPDeclaration &copy);
 
 
   bool operator == (const CPPDeclaration &other) const;
   bool operator == (const CPPDeclaration &other) const;
   bool operator != (const CPPDeclaration &other) const;
   bool operator != (const CPPDeclaration &other) const;
@@ -139,6 +141,73 @@ public:
   virtual CPPMakeProperty *as_make_property();
   virtual CPPMakeProperty *as_make_property();
   virtual CPPMakeSeq *as_make_seq();
   virtual CPPMakeSeq *as_make_seq();
 
 
+  inline const CPPInstance *as_instance() const {
+    return ((CPPDeclaration *)this)->as_instance();
+  }
+  inline const CPPClassTemplateParameter *as_class_template_parameter() const {
+    return ((CPPDeclaration *)this)->as_class_template_parameter();
+  }
+  inline const CPPTypedefType *as_typedef_type() const {
+    return ((CPPDeclaration *)this)->as_typedef_type();
+  }
+  inline const CPPTypeDeclaration *as_type_declaration() const {
+    return ((CPPDeclaration *)this)->as_type_declaration();
+  }
+  inline const CPPExpression *as_expression() const {
+    return ((CPPDeclaration *)this)->as_expression();
+  }
+  inline const CPPType *as_type() const {
+    return ((CPPDeclaration *)this)->as_type();
+  }
+  inline const CPPNamespace *as_namespace() const {
+    return ((CPPDeclaration *)this)->as_namespace();
+  }
+  inline const CPPUsing *as_using() const {
+    return ((CPPDeclaration *)this)->as_using();
+  }
+  inline const CPPSimpleType *as_simple_type() const {
+    return ((CPPDeclaration *)this)->as_simple_type();
+  }
+  inline const CPPPointerType *as_pointer_type() const {
+    return ((CPPDeclaration *)this)->as_pointer_type();
+  }
+  inline const CPPReferenceType *as_reference_type() const {
+    return ((CPPDeclaration *)this)->as_reference_type();
+  }
+  inline const CPPArrayType *as_array_type() const {
+    return ((CPPDeclaration *)this)->as_array_type();
+  }
+  inline const CPPConstType *as_const_type() const {
+    return ((CPPDeclaration *)this)->as_const_type();
+  }
+  inline const CPPFunctionType *as_function_type() const {
+    return ((CPPDeclaration *)this)->as_function_type();
+  }
+  inline const CPPFunctionGroup *as_function_group() const {
+    return ((CPPDeclaration *)this)->as_function_group();
+  }
+  inline const CPPExtensionType *as_extension_type() const {
+    return ((CPPDeclaration *)this)->as_extension_type();
+  }
+  inline const CPPStructType *as_struct_type() const {
+    return ((CPPDeclaration *)this)->as_struct_type();
+  }
+  inline const CPPEnumType *as_enum_type() const {
+    return ((CPPDeclaration *)this)->as_enum_type();
+  }
+  inline const CPPTBDType *as_tbd_type() const {
+    return ((CPPDeclaration *)this)->as_tbd_type();
+  }
+  inline const CPPTypeProxy *as_type_proxy() const {
+    return ((CPPDeclaration *)this)->as_type_proxy();
+  }
+  inline const CPPMakeProperty *as_make_property() const {
+    return ((CPPDeclaration *)this)->as_make_property();
+  }
+  inline const CPPMakeSeq *as_make_seq() const {
+    return ((CPPDeclaration *)this)->as_make_seq();
+  }
+
   CPPVisibility _vis;
   CPPVisibility _vis;
   CPPTemplateScope *_template_scope;
   CPPTemplateScope *_template_scope;
   CPPFile _file;
   CPPFile _file;

+ 212 - 7
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 "cppStructType.h"
 #include "cppBison.h"
 #include "cppBison.h"
 #include "pdtoa.h"
 #include "pdtoa.h"
 
 
@@ -389,6 +390,19 @@ typeid_op(CPPExpression *op1, CPPType *std_type_info) {
   return expr;
   return expr;
 }
 }
 
 
+/**
+ * Creates an expression that returns a particular type trait.
+ */
+CPPExpression CPPExpression::
+type_trait(int trait, CPPType *type, CPPType *arg) {
+  CPPExpression expr(0);
+  expr._type = T_type_trait;
+  expr._u._type_trait._trait = trait;
+  expr._u._type_trait._type = type;
+  expr._u._type_trait._arg = arg;
+  return expr;
+}
+
 /**
 /**
  *
  *
  */
  */
@@ -401,6 +415,17 @@ sizeof_func(CPPType *type) {
   return expr;
   return expr;
 }
 }
 
 
+/**
+ *
+ */
+CPPExpression CPPExpression::
+sizeof_ellipsis_func(CPPIdentifier *ident) {
+  CPPExpression expr(0);
+  expr._type = T_sizeof_ellipsis;
+  expr._u._ident = ident;
+  return expr;
+}
+
 /**
 /**
  *
  *
  */
  */
@@ -492,13 +517,6 @@ get_delete() {
   return expr;
   return expr;
 }
 }
 
 
-/**
- *
- */
-CPPExpression::
-~CPPExpression() {
-}
-
 /**
 /**
  *
  *
  */
  */
@@ -579,6 +597,7 @@ evaluate() const {
   case T_new:
   case T_new:
   case T_default_new:
   case T_default_new:
   case T_sizeof:
   case T_sizeof:
+  case T_sizeof_ellipsis:
     return Result();
     return Result();
 
 
   case T_alignof:
   case T_alignof:
@@ -801,6 +820,95 @@ evaluate() const {
   case T_typeid_expr:
   case T_typeid_expr:
     return Result();
     return Result();
 
 
+  case T_type_trait:
+    switch (_u._type_trait._trait) {
+    case KW_HAS_VIRTUAL_DESTRUCTOR:
+      {
+        CPPStructType *struct_type = _u._type_trait._type->as_struct_type();
+        return Result(struct_type != NULL && struct_type->has_virtual_destructor());
+      }
+
+    case KW_IS_ABSTRACT:
+      {
+        CPPStructType *struct_type = _u._type_trait._type->as_struct_type();
+        return Result(struct_type != NULL && struct_type->is_abstract());
+      }
+
+    case KW_IS_BASE_OF:
+      {
+        CPPStructType *struct_type1 = _u._type_trait._type->as_struct_type();
+        CPPStructType *struct_type2 = _u._type_trait._arg->as_struct_type();
+        return Result(struct_type1 != NULL && struct_type2 != NULL && struct_type1->is_base_of(struct_type2));
+      }
+
+    case KW_IS_CLASS:
+      {
+        CPPExtensionType *ext_type = _u._type_trait._type->as_extension_type();
+        return Result(ext_type != NULL && (
+          ext_type->_type == CPPExtensionType::T_class ||
+          ext_type->_type == CPPExtensionType::T_struct));
+      }
+
+    case KW_IS_CONSTRUCTIBLE:
+      if (_u._type_trait._arg == NULL) {
+        return Result(_u._type_trait._type->is_default_constructible());
+      } else {
+        return Result(_u._type_trait._type->is_constructible(_u._type_trait._arg));
+      }
+
+    case KW_IS_CONVERTIBLE_TO:
+      assert(_u._type_trait._arg != NULL);
+      return Result(_u._type_trait._type->is_convertible_to(_u._type_trait._arg));
+
+    case KW_IS_DESTRUCTIBLE:
+      return Result(_u._type_trait._type->is_destructible());
+
+    case KW_IS_EMPTY:
+      {
+        CPPStructType *struct_type = _u._type_trait._type->as_struct_type();
+        return Result(struct_type != NULL && struct_type->is_empty());
+      }
+
+    case KW_IS_ENUM:
+      return Result(_u._type_trait._type->is_enum());
+
+    case KW_IS_FINAL:
+      {
+        CPPStructType *struct_type = _u._type_trait._type->as_struct_type();
+        return Result(struct_type != NULL && struct_type->is_final());
+      }
+
+    case KW_IS_FUNDAMENTAL:
+      return Result(_u._type_trait._type->is_fundamental());
+
+    case KW_IS_POD:
+      return Result(_u._type_trait._type->is_trivial() &&
+                    _u._type_trait._type->is_standard_layout());
+
+    case KW_IS_POLYMORPHIC:
+      {
+        CPPStructType *struct_type = _u._type_trait._type->as_struct_type();
+        return Result(struct_type != NULL && struct_type->is_polymorphic());
+      }
+
+    case KW_IS_STANDARD_LAYOUT:
+      return Result(_u._type_trait._type->is_standard_layout());
+
+    case KW_IS_TRIVIAL:
+      return Result(_u._type_trait._type->is_trivial());
+
+    case KW_IS_UNION:
+      {
+        CPPExtensionType *ext_type = _u._type_trait._type->as_extension_type();
+        return Result(ext_type != NULL &&
+          ext_type->_type == CPPExtensionType::T_union);
+      }
+
+    default:
+      cerr << "**unexpected type trait**\n";
+      abort();
+    }
+
   default:
   default:
     cerr << "**invalid operand**\n";
     cerr << "**invalid operand**\n";
     abort();
     abort();
@@ -916,6 +1024,7 @@ determine_type() const {
     return CPPType::new_type(new CPPPointerType(_u._typecast._to));
     return CPPType::new_type(new CPPPointerType(_u._typecast._to));
 
 
   case T_sizeof:
   case T_sizeof:
+  case T_sizeof_ellipsis:
   case T_alignof:
   case T_alignof:
     // Note: this should actually be size_t, but that is defined as a typedef
     // Note: this should actually be size_t, but that is defined as a typedef
     // in parser-inc.  We could try to resolve it, but that's hacky.  Eh, it's
     // in parser-inc.  We could try to resolve it, but that's hacky.  Eh, it's
@@ -1057,6 +1166,9 @@ determine_type() const {
   case T_typeid_expr:
   case T_typeid_expr:
     return _u._typeid._std_type_info;
     return _u._typeid._std_type_info;
 
 
+  case T_type_trait:
+    return bool_type;
+
   default:
   default:
     cerr << "**invalid operand**\n";
     cerr << "**invalid operand**\n";
     abort();
     abort();
@@ -1113,6 +1225,9 @@ is_fully_specified() const {
   case T_alignof:
   case T_alignof:
     return _u._typecast._to->is_fully_specified();
     return _u._typecast._to->is_fully_specified();
 
 
+  case T_sizeof_ellipsis:
+    return _u._ident->is_fully_specified();
+
   case T_trinary_operation:
   case T_trinary_operation:
     if (!_u._op._op3->is_fully_specified()) {
     if (!_u._op._op3->is_fully_specified()) {
       return false;
       return false;
@@ -1141,6 +1256,9 @@ is_fully_specified() const {
   case T_typeid_expr:
   case T_typeid_expr:
     return _u._typeid._expr->is_fully_specified();
     return _u._typeid._expr->is_fully_specified();
 
 
+  case T_type_trait:
+    return _u._type_trait._type->is_fully_specified();
+
   default:
   default:
     return true;
     return true;
   }
   }
@@ -1276,6 +1394,13 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
     any_changed = any_changed || (rep->_u._typeid._expr != _u._typeid._expr);
     any_changed = any_changed || (rep->_u._typeid._expr != _u._typeid._expr);
     break;
     break;
 
 
+  case T_type_trait:
+    rep->_u._type_trait._type =
+      _u._type_trait._type->substitute_decl(subst, current_scope, global_scope)
+      ->as_type();
+    any_changed = any_changed || (rep->_u._type_trait._type != _u._type_trait._type);
+    break;
+
   default:
   default:
     break;
     break;
   }
   }
@@ -1350,6 +1475,9 @@ is_tbd() const {
   case T_typeid_expr:
   case T_typeid_expr:
     return _u._typeid._expr->is_tbd();
     return _u._typeid._expr->is_tbd();
 
 
+  case T_type_trait:
+    return _u._type_trait._type->is_tbd();
+
   default:
   default:
     return false;
     return false;
   }
   }
@@ -1541,6 +1669,12 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
     out << ")";
     out << ")";
     break;
     break;
 
 
+  case T_sizeof_ellipsis:
+    out << "sizeof...(";
+    _u._ident->output(out, scope);
+    out << ")";
+    break;
+
   case T_alignof:
   case T_alignof:
     out << "alignof(";
     out << "alignof(";
     _u._typecast._to->output(out, indent_level, scope, false);
     _u._typecast._to->output(out, indent_level, scope, false);
@@ -1753,6 +1887,65 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
     out << "delete";
     out << "delete";
     break;
     break;
 
 
+  case T_type_trait:
+    switch (_u._type_trait._trait) {
+    case KW_HAS_VIRTUAL_DESTRUCTOR:
+      out << "__has_virtual_destructor";
+      break;
+    case KW_IS_ABSTRACT:
+      out << "__is_abstract";
+      break;
+    case KW_IS_BASE_OF:
+      out << "__is_base_of";
+      break;
+    case KW_IS_CLASS:
+      out << "__is_class";
+      break;
+    case KW_IS_CONSTRUCTIBLE:
+      out << "__is_constructible";
+      break;
+    case KW_IS_CONVERTIBLE_TO:
+      out << "__is_convertible_to";
+      break;
+    case KW_IS_DESTRUCTIBLE:
+      out << "__is_destructible";
+      break;
+    case KW_IS_EMPTY:
+      out << "__is_empty";
+      break;
+    case KW_IS_ENUM:
+      out << "__is_enum";
+      break;
+    case KW_IS_FINAL:
+      out << "__is_final";
+      break;
+    case KW_IS_FUNDAMENTAL:
+      out << "__is_fundamental";
+      break;
+    case KW_IS_POD:
+      out << "__is_pod";
+      break;
+    case KW_IS_POLYMORPHIC:
+      out << "__is_polymorphic";
+      break;
+    case KW_IS_STANDARD_LAYOUT:
+      out << "__is_standard_layout";
+      break;
+    case KW_IS_TRIVIAL:
+      out << "__is_trivial";
+      break;
+    case KW_IS_UNION:
+      out << "__is_union";
+      break;
+    default:
+      out << (evaluate().as_boolean() ? "true" : "false");
+      return;
+    }
+    out << '(';
+    _u._type_trait._type->output(out, indent_level, scope, false);
+    out << ')';
+    break;
+
   default:
   default:
     out << "(** invalid operand type " << (int)_type << " **)";
     out << "(** invalid operand type " << (int)_type << " **)";
   }
   }
@@ -1864,6 +2057,7 @@ is_equal(const CPPDeclaration *other) const {
     return _u._fgroup == ot->_u._fgroup;
     return _u._fgroup == ot->_u._fgroup;
 
 
   case T_unknown_ident:
   case T_unknown_ident:
+  case T_sizeof_ellipsis:
     return *_u._ident == *ot->_u._ident;
     return *_u._ident == *ot->_u._ident;
 
 
   case T_typecast:
   case T_typecast:
@@ -1907,6 +2101,10 @@ is_equal(const CPPDeclaration *other) const {
   case T_typeid_expr:
   case T_typeid_expr:
     return _u._typeid._expr == ot->_u._typeid._expr;
     return _u._typeid._expr == ot->_u._typeid._expr;
 
 
+  case T_type_trait:
+    return _u._type_trait._trait == ot->_u._type_trait._trait &&
+           _u._type_trait._type == ot->_u._type_trait._type;
+
   default:
   default:
     cerr << "(** invalid operand type " << (int)_type << " **)";
     cerr << "(** invalid operand type " << (int)_type << " **)";
   }
   }
@@ -1954,6 +2152,7 @@ is_less(const CPPDeclaration *other) const {
     return *_u._fgroup < *ot->_u._fgroup;
     return *_u._fgroup < *ot->_u._fgroup;
 
 
   case T_unknown_ident:
   case T_unknown_ident:
+  case T_sizeof_ellipsis:
     return *_u._ident < *ot->_u._ident;
     return *_u._ident < *ot->_u._ident;
 
 
   case T_typecast:
   case T_typecast:
@@ -2007,6 +2206,12 @@ is_less(const CPPDeclaration *other) const {
   case T_typeid_expr:
   case T_typeid_expr:
     return *_u._typeid._expr < *ot->_u._typeid._expr;
     return *_u._typeid._expr < *ot->_u._typeid._expr;
 
 
+  case T_type_trait:
+    if (_u._type_trait._trait != ot->_u._type_trait._trait) {
+      return _u._type_trait._trait < ot->_u._type_trait._trait;
+    }
+    return *_u._type_trait._type < *ot->_u._type_trait._type;
+
   default:
   default:
     cerr << "(** invalid operand type " << (int)_type << " **)";
     cerr << "(** invalid operand type " << (int)_type << " **)";
   }
   }

+ 9 - 2
dtool/src/cppparser/cppExpression.h

@@ -51,6 +51,7 @@ public:
     T_new,
     T_new,
     T_default_new,
     T_default_new,
     T_sizeof,
     T_sizeof,
+    T_sizeof_ellipsis,
     T_alignof,
     T_alignof,
     T_unary_operation,
     T_unary_operation,
     T_binary_operation,
     T_binary_operation,
@@ -59,6 +60,7 @@ public:
     T_raw_literal,
     T_raw_literal,
     T_typeid_type,
     T_typeid_type,
     T_typeid_expr,
     T_typeid_expr,
+    T_type_trait,
 
 
     // These are used when parsing =default and =delete methods.
     // These are used when parsing =default and =delete methods.
     T_default,
     T_default,
@@ -81,7 +83,9 @@ public:
   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);
+  static CPPExpression type_trait(int trait, CPPType *type, CPPType *arg = NULL);
   static CPPExpression sizeof_func(CPPType *type);
   static CPPExpression sizeof_func(CPPType *type);
+  static CPPExpression sizeof_ellipsis_func(CPPIdentifier *ident);
   static CPPExpression alignof_func(CPPType *type);
   static CPPExpression alignof_func(CPPType *type);
 
 
   static CPPExpression literal(unsigned long long value, CPPInstance *lit_op);
   static CPPExpression literal(unsigned long long value, CPPInstance *lit_op);
@@ -93,8 +97,6 @@ public:
   static const CPPExpression &get_default();
   static const CPPExpression &get_default();
   static const CPPExpression &get_delete();
   static const CPPExpression &get_delete();
 
 
-  ~CPPExpression();
-
   enum ResultType {
   enum ResultType {
     RT_integer,
     RT_integer,
     RT_real,
     RT_real,
@@ -170,6 +172,11 @@ public:
       CPPInstance *_operator;
       CPPInstance *_operator;
       CPPExpression *_value;
       CPPExpression *_value;
     } _literal;
     } _literal;
+    struct {
+      int _trait;
+      CPPType *_type;
+      CPPType *_arg;
+    } _type_trait;
   } _u;
   } _u;
 
 
 protected:
 protected:

+ 23 - 3
dtool/src/cppparser/cppExtensionType.cxx

@@ -87,12 +87,32 @@ is_tbd() const {
   return false;
   return false;
 }
 }
 
 
+/**
+ * Returns true if the type is considered a standard layout type.
+ */
+bool CPPExtensionType::
+is_standard_layout() const {
+  return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
+}
+
 /**
 /**
  * Returns true if the type is considered a Plain Old Data (POD) type.
  * Returns true if the type is considered a Plain Old Data (POD) type.
  */
  */
 bool CPPExtensionType::
 bool CPPExtensionType::
 is_trivial() const {
 is_trivial() const {
-  return (_type == T_enum);
+  return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
+}
+
+/**
+ * Returns true if the type can be constructed using the given argument.
+ */
+bool CPPExtensionType::
+is_constructible(const CPPType *given_type) const {
+  if (_type == T_enum || _type == T_enum_class || _type == T_enum_struct) {
+    const CPPExtensionType *other = ((CPPType *)given_type)->remove_reference()->remove_const()->as_extension_type();
+    return other != NULL && is_equal(other);
+  }
+  return false;
 }
 }
 
 
 /**
 /**
@@ -100,7 +120,7 @@ is_trivial() const {
  */
  */
 bool CPPExtensionType::
 bool CPPExtensionType::
 is_default_constructible() const {
 is_default_constructible() const {
-  return (_type == T_enum);
+  return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
 }
 }
 
 
 /**
 /**
@@ -108,7 +128,7 @@ is_default_constructible() const {
  */
  */
 bool CPPExtensionType::
 bool CPPExtensionType::
 is_copy_constructible() const {
 is_copy_constructible() const {
-  return (_type == T_enum);
+  return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
 }
 }
 
 
 /**
 /**

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

@@ -47,7 +47,9 @@ public:
 
 
   virtual bool is_incomplete() const;
   virtual bool is_incomplete() const;
   virtual bool is_tbd() const;
   virtual bool is_tbd() const;
+  virtual bool is_standard_layout() const;
   virtual bool is_trivial() const;
   virtual bool is_trivial() const;
+  virtual bool is_constructible(const CPPType *type) const;
   virtual bool is_default_constructible() const;
   virtual bool is_default_constructible() const;
   virtual bool is_copy_constructible() const;
   virtual bool is_copy_constructible() const;
 
 

+ 1 - 1
dtool/src/cppparser/cppFile.h

@@ -55,7 +55,7 @@ public:
 
 
   Filename _filename;
   Filename _filename;
   Filename _filename_as_referenced;
   Filename _filename_as_referenced;
-  Source _source;
+  mutable Source _source;
   mutable bool _pragma_once;
   mutable bool _pragma_once;
 };
 };
 
 

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

@@ -89,9 +89,11 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
   }
   }
 
 
   CPPFunctionType *rep = new CPPFunctionType(*this);
   CPPFunctionType *rep = new CPPFunctionType(*this);
-  rep->_return_type =
-    _return_type->substitute_decl(subst, current_scope, global_scope)
-    ->as_type();
+  if (_return_type != NULL) {
+    rep->_return_type =
+      _return_type->substitute_decl(subst, current_scope, global_scope)
+      ->as_type();
+  }
 
 
   rep->_parameters =
   rep->_parameters =
     _parameters->substitute_decl(subst, current_scope, global_scope);
     _parameters->substitute_decl(subst, current_scope, global_scope);
@@ -265,6 +267,9 @@ output_instance(ostream &out, int indent_level, CPPScope *scope,
   if (_flags & F_const_method) {
   if (_flags & F_const_method) {
     out << " const";
     out << " const";
   }
   }
+  if (_flags & F_volatile_method) {
+    out << " volatile";
+  }
   if (_flags & F_noexcept) {
   if (_flags & F_noexcept) {
     out << " noexcept";
     out << " noexcept";
   }
   }

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

@@ -40,6 +40,9 @@ public:
     F_trailing_return_type = 0x800,
     F_trailing_return_type = 0x800,
     F_final             = 0x1000,
     F_final             = 0x1000,
     F_override          = 0x2000,
     F_override          = 0x2000,
+    F_volatile_method   = 0x4000,
+    F_lvalue_method     = 0x8000,
+    F_rvalue_method     = 0x10000,
   };
   };
 
 
   CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
   CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,

+ 8 - 5
dtool/src/cppparser/cppInstance.cxx

@@ -82,6 +82,10 @@ CPPInstance(CPPType *type, CPPInstanceIdentifier *ii, int storage_class,
     // anyway.
     // anyway.
   }
   }
 
 
+  if (ii->_packed) {
+    _storage_class |= SC_parameter_pack;
+  }
+
   delete ii;
   delete ii;
 }
 }
 
 
@@ -353,11 +357,7 @@ check_for_constructor(CPPScope *current_scope, CPPScope *global_scope) {
           CPPReferenceType *ref_type = param_type->as_reference_type();
           CPPReferenceType *ref_type = param_type->as_reference_type();
 
 
           if (ref_type != NULL) {
           if (ref_type != NULL) {
-            param_type = ref_type->_pointing_at;
-
-            if (param_type->get_subtype() == CPPDeclaration::ST_const) {
-              param_type = param_type->as_const_type()->_wrapped_around;
-            }
+            param_type = ref_type->_pointing_at->remove_cv();
 
 
             if (class_name == param_type->get_simple_name()) {
             if (class_name == param_type->get_simple_name()) {
               if (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
               if (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
@@ -563,6 +563,9 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete,
   if (_ident != NULL) {
   if (_ident != NULL) {
     name = _ident->get_local_name(scope);
     name = _ident->get_local_name(scope);
   }
   }
+  if (_storage_class & SC_parameter_pack) {
+    name = "..." + name;
+  }
 
 
   if (_type->as_function_type()) {
   if (_type->as_function_type()) {
     _type->as_function_type()->
     _type->as_function_type()->

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