Merge branch 'master' of https://github.com/panda3d/panda3d
This commit is contained in:
commit
63eb1636a9
|
|
@ -45,3 +45,8 @@ CTestTestfile.cmake
|
|||
# Windows
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Python
|
||||
__pycache__
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
|
|
|||
|
|
@ -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?-*
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/build
|
||||
/dist
|
||||
|
|
@ -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?-*
|
||||
|
|
@ -1 +0,0 @@
|
|||
/40_direct.prc
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
/dcLexer.cxx
|
||||
/dcParser.cxx
|
||||
/dcParser.h
|
||||
|
|
@ -88,3 +88,7 @@ class EggCacher:
|
|||
progress += size
|
||||
|
||||
cacher = EggCacher(sys.argv[1:])
|
||||
|
||||
# Dummy main function so this can be added to console_scripts.
|
||||
def main():
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -419,3 +419,6 @@ else:
|
|||
if not(os.path.exists("/usr/bin/rpmbuild") or os.path.exists("/usr/bin/dpkg-deb")):
|
||||
exit("To build an installer, either rpmbuild or dpkg-deb must be present on your system!")
|
||||
|
||||
# Dummy main function so this can be added to console_scripts.
|
||||
def main():
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -26,11 +26,7 @@ class DistributedObjectGlobalUD(DistributedObjectUD):
|
|||
|
||||
def execCommand(self, command, mwMgrId, avId, zoneId):
|
||||
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):
|
||||
if not self.ExecNamespace:
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ send_datagram(const Datagram &dg) {
|
|||
|
||||
#ifdef WANT_NATIVE_NET
|
||||
if (_native) {
|
||||
bool result = _bdc.SendMessage();
|
||||
bool result = _bdc.SendMessage(dg);
|
||||
if (!result && _bdc.IsConnected()) {
|
||||
#ifdef HAVE_PYTHON
|
||||
ostringstream s;
|
||||
|
|
@ -415,8 +415,8 @@ send_datagram(const Datagram &dg) {
|
|||
#endif
|
||||
|
||||
s << endl << "Error sending message: " << endl;
|
||||
msg.dump_hex(s);
|
||||
s << "Message data: " << msg.get_data() << endl;
|
||||
dg.dump_hex(s);
|
||||
s << "Message data: " << dg.get_data() << endl;
|
||||
|
||||
string message = s.str();
|
||||
PyErr_SetString(exc_type, message.c_str());
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
/extensions_darwin.py
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/NL*
|
||||
/Nested*
|
||||
|
|
@ -20,7 +20,7 @@ class DirectScrolledListItem(DirectButton):
|
|||
|
||||
def __init__(self, parent=None, **kw):
|
||||
assert self.notify.debugStateCall(self)
|
||||
self.parent = parent
|
||||
self._parent = parent
|
||||
if "command" in kw:
|
||||
self.nextCommand = kw.get("command")
|
||||
del kw["command"]
|
||||
|
|
@ -28,7 +28,7 @@ class DirectScrolledListItem(DirectButton):
|
|||
self.nextCommandExtraArgs = kw.get("extraArgs")
|
||||
del kw["extraArgs"]
|
||||
optiondefs = (
|
||||
('parent', self.parent, None),
|
||||
('parent', self._parent, None),
|
||||
('command', self.select, None),
|
||||
)
|
||||
# Merge keyword options with default options
|
||||
|
|
@ -39,7 +39,7 @@ class DirectScrolledListItem(DirectButton):
|
|||
def select(self):
|
||||
assert self.notify.debugStateCall(self)
|
||||
self.nextCommand(*self.nextCommandExtraArgs)
|
||||
self.parent.selectListItem(self)
|
||||
self._parent.selectListItem(self)
|
||||
|
||||
|
||||
class DirectScrolledList(DirectFrame):
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
/_vfsimporter.exp
|
||||
/_vfsimporter.lib
|
||||
/_vfsimporter.pyd
|
||||
/_vfsimporter.pyd.manifest
|
||||
/packp3d
|
||||
/ppackage
|
||||
/ppatcher
|
||||
/vc90.pdb
|
||||
|
|
@ -1 +0,0 @@
|
|||
/p3d_plugin_config.h
|
||||
|
|
@ -1 +0,0 @@
|
|||
/P3DActiveX.rc
|
||||
|
|
@ -1 +0,0 @@
|
|||
/nppanda3d.rc
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/p3d_plugin_config.h
|
||||
/panda3d.rc
|
||||
|
|
@ -38,7 +38,6 @@ import os
|
|||
import sys
|
||||
import random
|
||||
import time
|
||||
import importlib
|
||||
|
||||
__report_indent = 3
|
||||
|
||||
|
|
@ -61,6 +60,42 @@ def Functor(function, *args, **kArgs):
|
|||
return functor
|
||||
"""
|
||||
|
||||
try:
|
||||
import importlib
|
||||
except ImportError:
|
||||
# Backward compatibility for Python 2.6.
|
||||
def _resolve_name(name, package, level):
|
||||
if not hasattr(package, 'rindex'):
|
||||
raise ValueError("'package' not set to a string")
|
||||
dot = len(package)
|
||||
for x in xrange(level, 1, -1):
|
||||
try:
|
||||
dot = package.rindex('.', 0, dot)
|
||||
except ValueError:
|
||||
raise ValueError("attempted relative import beyond top-level "
|
||||
"package")
|
||||
return "%s.%s" % (package[:dot], name)
|
||||
|
||||
def import_module(name, package=None):
|
||||
if name.startswith('.'):
|
||||
if not package:
|
||||
raise TypeError("relative imports require the 'package' argument")
|
||||
level = 0
|
||||
for character in name:
|
||||
if character != '.':
|
||||
break
|
||||
level += 1
|
||||
name = _resolve_name(name[level:], package, level)
|
||||
__import__(name)
|
||||
return sys.modules[name]
|
||||
|
||||
imp = import_module('imp')
|
||||
importlib = imp.new_module("importlib")
|
||||
importlib._resolve_name = _resolve_name
|
||||
importlib.import_module = import_module
|
||||
sys.modules['importlib'] = importlib
|
||||
|
||||
|
||||
class Functor:
|
||||
def __init__(self, function, *args, **kargs):
|
||||
assert callable(function), "function should be a callable obj"
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
/runp3d
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
*.egg
|
||||
*.pt
|
||||
/built/
|
||||
Makefile
|
||||
bams/
|
||||
optchar/
|
||||
pal_egg/
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
/*.buildings
|
||||
/game_options.txt
|
||||
/prefixstrip
|
||||
/retarget/
|
||||
/textures.boo
|
||||
/topstrip/
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
This issue fixes several bugs that were still found in 1.9.2.
|
||||
|
||||
* Fix crash when using homebrew Python on Mac OS X
|
||||
* Fix crash when running in Steam on Linux when using OpenAL
|
||||
* Fix crash using wx/tkinter on Mac as long as want-wx/tk is set
|
||||
* Fix loading models from 'models' package with models/ prefix
|
||||
|
|
@ -45,6 +46,15 @@ This issue fixes several bugs that were still found in 1.9.2.
|
|||
* 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
|
||||
* Now tries to preserve refresh rate when switching fullscreen on Windows
|
||||
* Fix back-to-front sorting when gl-coordinate-system is changed
|
||||
* Now also compiles on older Linux distros (eg. CentOS 5 / manylinux1)
|
||||
* get_keyboard_map now includes keys on layouts with special characters
|
||||
* Fix crash due to incorrect alignment when compiling Eigen with AVX
|
||||
* Fix crash when writing 16-bit .tif file (now silently downsamples)
|
||||
|
||||
------------------------ RELEASE 1.9.2 ------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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?-*
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
/cppBison.cxx
|
||||
/cppBison.h
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "cppArrayType.h"
|
||||
#include "cppExpression.h"
|
||||
#include "cppPointerType.h"
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -63,6 +64,14 @@ is_tbd() const {
|
|||
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.
|
||||
*/
|
||||
|
|
@ -76,7 +85,7 @@ is_trivial() const {
|
|||
*/
|
||||
bool CPPArrayType::
|
||||
is_default_constructible() const {
|
||||
return _element_type->is_default_constructible();
|
||||
return _bounds != NULL && _element_type->is_default_constructible();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public:
|
|||
virtual CPPType *resolve_type(CPPScope *current_scope,
|
||||
CPPScope *global_scope);
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_standard_layout() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -54,120 +54,138 @@ extern int cppyydebug;
|
|||
CUSTOM_LITERAL = 264,
|
||||
IDENTIFIER = 265,
|
||||
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
|
||||
/* Tokens. */
|
||||
|
|
@ -180,120 +198,138 @@ extern int cppyydebug;
|
|||
#define CUSTOM_LITERAL 264
|
||||
#define IDENTIFIER 265
|
||||
#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. */
|
||||
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ pop_struct() {
|
|||
%token <u.integer> CHAR_TOK
|
||||
%token <str> SIMPLE_STRING SIMPLE_IDENTIFIER
|
||||
%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 ELLIPSIS
|
||||
|
|
@ -280,9 +280,25 @@ pop_struct() {
|
|||
%token KW_FRIEND
|
||||
%token KW_FOR
|
||||
%token KW_GOTO
|
||||
%token KW_HAS_VIRTUAL_DESTRUCTOR
|
||||
%token KW_IF
|
||||
%token KW_INLINE
|
||||
%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_MAKE_MAP_PROPERTY
|
||||
%token KW_MAKE_PROPERTY
|
||||
|
|
@ -317,6 +333,7 @@ pop_struct() {
|
|||
%token KW_TYPEDEF
|
||||
%token KW_TYPEID
|
||||
%token KW_TYPENAME
|
||||
%token KW_UNDERLYING_TYPE
|
||||
%token KW_UNION
|
||||
%token KW_UNSIGNED
|
||||
%token KW_USING
|
||||
|
|
@ -354,9 +371,10 @@ pop_struct() {
|
|||
%type <u.instance> formal_parameter
|
||||
%type <u.inst_ident> not_paren_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> empty_instance_identifier
|
||||
%type <u.type> type
|
||||
%type <u.type> type type_pack
|
||||
%type <u.decl> type_decl
|
||||
%type <u.decl> var_type_decl
|
||||
%type <u.type> predefined_type
|
||||
|
|
@ -447,6 +465,10 @@ constructor_init:
|
|||
name '(' optional_const_expr_comma ')'
|
||||
{
|
||||
delete $3;
|
||||
}
|
||||
| name '(' optional_const_expr_comma ')' ELLIPSIS
|
||||
{
|
||||
delete $3;
|
||||
}
|
||||
| name '{' optional_const_expr_comma '}'
|
||||
{
|
||||
|
|
@ -1187,26 +1209,38 @@ function_post:
|
|||
{
|
||||
$$ = 0;
|
||||
}
|
||||
| KW_CONST
|
||||
| function_post KW_CONST
|
||||
{
|
||||
$$ = (int)CPPFunctionType::F_const_method;
|
||||
$$ = $1 | (int)CPPFunctionType::F_const_method;
|
||||
}
|
||||
| function_post KW_VOLATILE
|
||||
{
|
||||
$$ = $1 | (int)CPPFunctionType::F_volatile_method;
|
||||
}
|
||||
| function_post KW_NOEXCEPT
|
||||
{
|
||||
$$ = (int)CPPFunctionType::F_noexcept;
|
||||
$$ = $1 | (int)CPPFunctionType::F_noexcept;
|
||||
}
|
||||
| function_post KW_FINAL
|
||||
{
|
||||
$$ = (int)CPPFunctionType::F_final;
|
||||
$$ = $1 | (int)CPPFunctionType::F_final;
|
||||
}
|
||||
| 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
|
||||
{
|
||||
// Used for lambdas, currently ignored.
|
||||
$$ = 0;
|
||||
$$ = $1;
|
||||
}
|
||||
| function_post KW_THROW '(' ')'
|
||||
{
|
||||
|
|
@ -1215,6 +1249,10 @@ function_post:
|
|||
| function_post KW_THROW '(' name ')'
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| function_post KW_THROW '(' name ELLIPSIS ')'
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
/* | function_post '[' '[' attribute_specifiers ']' ']'
|
||||
{
|
||||
|
|
@ -1418,22 +1456,35 @@ template_nonempty_formal_parameters:
|
|||
}
|
||||
;
|
||||
|
||||
typename_keyword:
|
||||
KW_CLASS
|
||||
| KW_TYPENAME
|
||||
;
|
||||
|
||||
template_formal_parameter:
|
||||
KW_CLASS name
|
||||
typename_keyword
|
||||
{
|
||||
$$ = CPPType::new_type(new CPPClassTemplateParameter((CPPIdentifier *)NULL));
|
||||
}
|
||||
| typename_keyword name
|
||||
{
|
||||
$$ = CPPType::new_type(new CPPClassTemplateParameter($2));
|
||||
}
|
||||
| KW_CLASS name '=' full_type
|
||||
| typename_keyword name '=' full_type
|
||||
{
|
||||
$$ = 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
|
||||
{
|
||||
|
|
@ -1447,6 +1498,17 @@ template_formal_parameter:
|
|||
CPPInstance *inst = new CPPInstance($2, $3, 0, @3.file);
|
||||
inst->set_initializer($4);
|
||||
$$ = 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;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1467,6 +1529,14 @@ template_formal_parameter_type:
|
|||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
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);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1547,7 +1617,16 @@ 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
|
||||
{
|
||||
|
|
@ -1785,6 +1864,23 @@ function_parameter:
|
|||
$4->add_modifier(IIT_const);
|
||||
$$ = new CPPInstance($3, $4, 0, @3.file);
|
||||
$$->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
|
||||
{
|
||||
|
|
@ -1913,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:
|
||||
empty
|
||||
{
|
||||
$$ = 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
|
||||
{
|
||||
|
|
@ -1959,6 +2124,16 @@ empty_instance_identifier:
|
|||
empty
|
||||
{
|
||||
$$ = 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
|
||||
{
|
||||
|
|
@ -2093,6 +2268,16 @@ type:
|
|||
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
|
||||
{
|
||||
|
|
@ -2100,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:
|
||||
simple_type
|
||||
{
|
||||
|
|
@ -2187,6 +2383,16 @@ type_decl:
|
|||
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
|
||||
{
|
||||
|
|
@ -2251,6 +2457,16 @@ predefined_type:
|
|||
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
|
||||
{
|
||||
|
|
@ -2279,6 +2495,15 @@ full_type:
|
|||
{
|
||||
$3->add_modifier(IIT_const);
|
||||
$$ = $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);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -2693,6 +2918,7 @@ element:
|
|||
| CHAR_TOK
|
||||
| IDENTIFIER
|
||||
| TYPENAME_IDENTIFIER
|
||||
| TYPEPACK_IDENTIFIER
|
||||
| SCOPING
|
||||
| SIMPLE_IDENTIFIER
|
||||
| ELLIPSIS | OROR | ANDAND
|
||||
|
|
@ -2711,10 +2937,11 @@ element:
|
|||
| KW_OPERATOR | KW_OVERRIDE | KW_PRIVATE | KW_PROTECTED
|
||||
| KW_PUBLIC | KW_PUBLISHED | KW_REGISTER | KW_REINTERPRET_CAST
|
||||
| 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_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
|
||||
{
|
||||
}
|
||||
| '+' | '-' | '*' | '/' | '&' | '|' | '^' | '!' | '~' | '=' | '%'
|
||||
|
|
@ -2783,6 +3010,10 @@ no_angle_bracket_const_expr:
|
|||
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
||||
{
|
||||
$$ = 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
|
||||
{
|
||||
|
|
@ -3021,6 +3252,10 @@ const_expr:
|
|||
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
||||
{
|
||||
$$ = 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
|
||||
{
|
||||
|
|
@ -3238,6 +3473,74 @@ const_operand:
|
|||
| '[' capture_list ']' '(' function_parameter_list ')' function_post maybe_trailing_return_type '{' code '}'
|
||||
{
|
||||
$$ = 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));
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -3276,6 +3579,10 @@ formal_const_expr:
|
|||
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
||||
{
|
||||
$$ = 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
|
||||
{
|
||||
|
|
@ -3518,6 +3825,12 @@ class_derivation_name:
|
|||
| KW_TYPENAME name
|
||||
{
|
||||
$$ = CPPType::new_type(new CPPTBDType($2));
|
||||
}
|
||||
| name ELLIPSIS
|
||||
{
|
||||
CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter($1);
|
||||
ctp->_packed = true;
|
||||
$$ = CPPType::new_type(ctp);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -3550,6 +3863,10 @@ name:
|
|||
| TYPENAME_IDENTIFIER
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| TYPEPACK_IDENTIFIER
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| KW_FINAL
|
||||
{
|
||||
|
|
@ -3595,6 +3912,10 @@ name_no_final:
|
|||
| TYPENAME_IDENTIFIER
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| TYPEPACK_IDENTIFIER
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| KW_OVERRIDE
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ CPPClassTemplateParameter::
|
|||
CPPClassTemplateParameter(CPPIdentifier *ident, CPPType *default_type) :
|
||||
CPPType(CPPFile()),
|
||||
_ident(ident),
|
||||
_default_type(default_type)
|
||||
_default_type(default_type),
|
||||
_packed(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -41,8 +42,14 @@ is_fully_specified() const {
|
|||
void CPPClassTemplateParameter::
|
||||
output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
||||
if (complete) {
|
||||
out << "class ";
|
||||
_ident->output(out, scope);
|
||||
out << "class";
|
||||
if (_packed) {
|
||||
out << "...";
|
||||
}
|
||||
if (_ident != NULL) {
|
||||
out << " ";
|
||||
_ident->output(out, scope);
|
||||
}
|
||||
if (_default_type) {
|
||||
out << " = ";
|
||||
_default_type->output(out, indent_level, scope, false);
|
||||
|
|
@ -82,6 +89,14 @@ is_equal(const CPPDeclaration *other) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (_packed != ot->_packed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_ident == NULL || ot->_ident == NULL) {
|
||||
return _ident == ot->_ident;
|
||||
}
|
||||
|
||||
return *_ident == *ot->_ident;
|
||||
}
|
||||
|
||||
|
|
@ -99,5 +114,13 @@ is_less(const CPPDeclaration *other) const {
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ public:
|
|||
|
||||
CPPIdentifier *_ident;
|
||||
CPPType *_default_type;
|
||||
bool _packed;
|
||||
|
||||
protected:
|
||||
virtual bool is_equal(const CPPDeclaration *other) const;
|
||||
|
|
|
|||
|
|
@ -86,6 +86,22 @@ is_tbd() const {
|
|||
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.
|
||||
*/
|
||||
|
|
@ -94,12 +110,20 @@ is_trivial() const {
|
|||
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.
|
||||
*/
|
||||
bool CPPConstType::
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* types appear to be referring to the same thing, even if they may have
|
||||
|
|
|
|||
|
|
@ -36,9 +36,14 @@ public:
|
|||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_fundamental() const;
|
||||
virtual bool is_standard_layout() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_constructible(const CPPType *type) const;
|
||||
virtual bool is_default_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 void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
|
|
|
|||
|
|
@ -41,8 +41,13 @@ CPPDeclaration(const CPPDeclaration ©) :
|
|||
/**
|
||||
*
|
||||
*/
|
||||
CPPDeclaration::
|
||||
~CPPDeclaration() {
|
||||
CPPDeclaration &CPPDeclaration::
|
||||
operator = (const CPPDeclaration ©) {
|
||||
_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 *) {
|
||||
SubstDecl::const_iterator si = subst.find(this);
|
||||
if (si != subst.end()) {
|
||||
assert((*si).second != NULL);
|
||||
return (*si).second;
|
||||
}
|
||||
return this;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,9 @@ public:
|
|||
|
||||
CPPDeclaration(const CPPFile &file);
|
||||
CPPDeclaration(const CPPDeclaration ©);
|
||||
virtual ~CPPDeclaration();
|
||||
virtual ~CPPDeclaration() {};
|
||||
|
||||
CPPDeclaration &operator = (const CPPDeclaration ©);
|
||||
|
||||
bool operator == (const CPPDeclaration &other) const;
|
||||
bool operator != (const CPPDeclaration &other) const;
|
||||
|
|
@ -139,6 +141,73 @@ public:
|
|||
virtual CPPMakeProperty *as_make_property();
|
||||
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;
|
||||
CPPTemplateScope *_template_scope;
|
||||
CPPFile _file;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "cppInstance.h"
|
||||
#include "cppFunctionGroup.h"
|
||||
#include "cppFunctionType.h"
|
||||
#include "cppStructType.h"
|
||||
#include "cppBison.h"
|
||||
#include "pdtoa.h"
|
||||
|
||||
|
|
@ -389,6 +390,19 @@ typeid_op(CPPExpression *op1, CPPType *std_type_info) {
|
|||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CPPExpression::
|
||||
~CPPExpression() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -579,6 +597,7 @@ evaluate() const {
|
|||
case T_new:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
case T_sizeof_ellipsis:
|
||||
return Result();
|
||||
|
||||
case T_alignof:
|
||||
|
|
@ -801,6 +820,95 @@ evaluate() const {
|
|||
case T_typeid_expr:
|
||||
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:
|
||||
cerr << "**invalid operand**\n";
|
||||
abort();
|
||||
|
|
@ -916,6 +1024,7 @@ determine_type() const {
|
|||
return CPPType::new_type(new CPPPointerType(_u._typecast._to));
|
||||
|
||||
case T_sizeof:
|
||||
case T_sizeof_ellipsis:
|
||||
case T_alignof:
|
||||
// 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
|
||||
|
|
@ -1057,6 +1166,9 @@ determine_type() const {
|
|||
case T_typeid_expr:
|
||||
return _u._typeid._std_type_info;
|
||||
|
||||
case T_type_trait:
|
||||
return bool_type;
|
||||
|
||||
default:
|
||||
cerr << "**invalid operand**\n";
|
||||
abort();
|
||||
|
|
@ -1113,6 +1225,9 @@ is_fully_specified() const {
|
|||
case T_alignof:
|
||||
return _u._typecast._to->is_fully_specified();
|
||||
|
||||
case T_sizeof_ellipsis:
|
||||
return _u._ident->is_fully_specified();
|
||||
|
||||
case T_trinary_operation:
|
||||
if (!_u._op._op3->is_fully_specified()) {
|
||||
return false;
|
||||
|
|
@ -1141,6 +1256,9 @@ is_fully_specified() const {
|
|||
case T_typeid_expr:
|
||||
return _u._typeid._expr->is_fully_specified();
|
||||
|
||||
case T_type_trait:
|
||||
return _u._type_trait._type->is_fully_specified();
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1276,6 +1394,13 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
any_changed = any_changed || (rep->_u._typeid._expr != _u._typeid._expr);
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1350,6 +1475,9 @@ is_tbd() const {
|
|||
case T_typeid_expr:
|
||||
return _u._typeid._expr->is_tbd();
|
||||
|
||||
case T_type_trait:
|
||||
return _u._type_trait._type->is_tbd();
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1541,6 +1669,12 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
|
|||
out << ")";
|
||||
break;
|
||||
|
||||
case T_sizeof_ellipsis:
|
||||
out << "sizeof...(";
|
||||
_u._ident->output(out, scope);
|
||||
out << ")";
|
||||
break;
|
||||
|
||||
case T_alignof:
|
||||
out << "alignof(";
|
||||
_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";
|
||||
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:
|
||||
out << "(** invalid operand type " << (int)_type << " **)";
|
||||
}
|
||||
|
|
@ -1864,6 +2057,7 @@ is_equal(const CPPDeclaration *other) const {
|
|||
return _u._fgroup == ot->_u._fgroup;
|
||||
|
||||
case T_unknown_ident:
|
||||
case T_sizeof_ellipsis:
|
||||
return *_u._ident == *ot->_u._ident;
|
||||
|
||||
case T_typecast:
|
||||
|
|
@ -1907,6 +2101,10 @@ is_equal(const CPPDeclaration *other) const {
|
|||
case T_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:
|
||||
cerr << "(** invalid operand type " << (int)_type << " **)";
|
||||
}
|
||||
|
|
@ -1954,6 +2152,7 @@ is_less(const CPPDeclaration *other) const {
|
|||
return *_u._fgroup < *ot->_u._fgroup;
|
||||
|
||||
case T_unknown_ident:
|
||||
case T_sizeof_ellipsis:
|
||||
return *_u._ident < *ot->_u._ident;
|
||||
|
||||
case T_typecast:
|
||||
|
|
@ -2007,6 +2206,12 @@ is_less(const CPPDeclaration *other) const {
|
|||
case T_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:
|
||||
cerr << "(** invalid operand type " << (int)_type << " **)";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ public:
|
|||
T_new,
|
||||
T_default_new,
|
||||
T_sizeof,
|
||||
T_sizeof_ellipsis,
|
||||
T_alignof,
|
||||
T_unary_operation,
|
||||
T_binary_operation,
|
||||
|
|
@ -59,6 +60,7 @@ public:
|
|||
T_raw_literal,
|
||||
T_typeid_type,
|
||||
T_typeid_expr,
|
||||
T_type_trait,
|
||||
|
||||
// These are used when parsing =default and =delete methods.
|
||||
T_default,
|
||||
|
|
@ -81,7 +83,9 @@ public:
|
|||
static CPPExpression new_op(CPPType *type, CPPExpression *op1 = NULL);
|
||||
static CPPExpression typeid_op(CPPType *type, 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_ellipsis_func(CPPIdentifier *ident);
|
||||
static CPPExpression alignof_func(CPPType *type);
|
||||
|
||||
static CPPExpression literal(unsigned long long value, CPPInstance *lit_op);
|
||||
|
|
@ -93,8 +97,6 @@ public:
|
|||
static const CPPExpression &get_default();
|
||||
static const CPPExpression &get_delete();
|
||||
|
||||
~CPPExpression();
|
||||
|
||||
enum ResultType {
|
||||
RT_integer,
|
||||
RT_real,
|
||||
|
|
@ -170,6 +172,11 @@ public:
|
|||
CPPInstance *_operator;
|
||||
CPPExpression *_value;
|
||||
} _literal;
|
||||
struct {
|
||||
int _trait;
|
||||
CPPType *_type;
|
||||
CPPType *_arg;
|
||||
} _type_trait;
|
||||
} _u;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -87,12 +87,32 @@ is_tbd() const {
|
|||
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.
|
||||
*/
|
||||
bool CPPExtensionType::
|
||||
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::
|
||||
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::
|
||||
is_copy_constructible() const {
|
||||
return (_type == T_enum);
|
||||
return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -47,7 +47,9 @@ public:
|
|||
|
||||
virtual bool is_incomplete() const;
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_standard_layout() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_constructible(const CPPType *type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public:
|
|||
|
||||
Filename _filename;
|
||||
Filename _filename_as_referenced;
|
||||
Source _source;
|
||||
mutable Source _source;
|
||||
mutable bool _pragma_once;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -89,9 +89,11 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
}
|
||||
|
||||
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 =
|
||||
_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) {
|
||||
out << " const";
|
||||
}
|
||||
if (_flags & F_volatile_method) {
|
||||
out << " volatile";
|
||||
}
|
||||
if (_flags & F_noexcept) {
|
||||
out << " noexcept";
|
||||
}
|
||||
|
|
@ -321,14 +326,17 @@ as_function_type() {
|
|||
* This is similar to is_equal(), except it is more forgiving: it considers
|
||||
* the functions to be equivalent only if the return type and the types of all
|
||||
* parameters match.
|
||||
*
|
||||
* Note that this isn't symmetric to account for covariant return types.
|
||||
*/
|
||||
bool CPPFunctionType::
|
||||
is_equivalent_function(const CPPFunctionType &other) const {
|
||||
if (!_return_type->is_equivalent(*other._return_type)) {
|
||||
match_virtual_override(const CPPFunctionType &other) const {
|
||||
if (!_return_type->is_equivalent(*other._return_type) &&
|
||||
!_return_type->is_convertible_to(other._return_type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_flags != other._flags) {
|
||||
if (((_flags ^ other._flags) & ~(F_override | F_final)) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ public:
|
|||
F_trailing_return_type = 0x800,
|
||||
F_final = 0x1000,
|
||||
F_override = 0x2000,
|
||||
F_volatile_method = 0x4000,
|
||||
F_lvalue_method = 0x8000,
|
||||
F_rvalue_method = 0x10000,
|
||||
};
|
||||
|
||||
CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
|
||||
|
|
@ -81,7 +84,7 @@ public:
|
|||
|
||||
virtual CPPFunctionType *as_function_type();
|
||||
|
||||
bool is_equivalent_function(const CPPFunctionType &other) const;
|
||||
bool match_virtual_override(const CPPFunctionType &other) const;
|
||||
|
||||
CPPIdentifier *_class_owner;
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ CPPInstance(CPPType *type, CPPInstanceIdentifier *ii, int storage_class,
|
|||
// anyway.
|
||||
}
|
||||
|
||||
if (ii->_packed) {
|
||||
_storage_class |= SC_parameter_pack;
|
||||
}
|
||||
|
||||
delete ii;
|
||||
}
|
||||
|
||||
|
|
@ -353,11 +357,7 @@ check_for_constructor(CPPScope *current_scope, CPPScope *global_scope) {
|
|||
CPPReferenceType *ref_type = param_type->as_reference_type();
|
||||
|
||||
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 (ref_type->_value_category == CPPReferenceType::VC_rvalue) {
|
||||
|
|
@ -563,6 +563,9 @@ output(ostream &out, int indent_level, CPPScope *scope, bool complete,
|
|||
if (_ident != NULL) {
|
||||
name = _ident->get_local_name(scope);
|
||||
}
|
||||
if (_storage_class & SC_parameter_pack) {
|
||||
name = "..." + name;
|
||||
}
|
||||
|
||||
if (_type->as_function_type()) {
|
||||
_type->as_function_type()->
|
||||
|
|
|
|||
|
|
@ -68,6 +68,9 @@ public:
|
|||
// This isn't really a storage class. It's only used temporarily by the
|
||||
// parser, to make parsing specifier sequences a bit easier.
|
||||
SC_const = 0x20000,
|
||||
|
||||
// Used to indicate that this is a parameter pack.
|
||||
SC_parameter_pack = 0x40000,
|
||||
};
|
||||
|
||||
CPPInstance(CPPType *type, const string &name, int storage_class = 0);
|
||||
|
|
|
|||
|
|
@ -26,12 +26,11 @@
|
|||
*/
|
||||
CPPInstanceIdentifier::Modifier::
|
||||
Modifier(CPPInstanceIdentifierType type) :
|
||||
_type(type)
|
||||
{
|
||||
_func_params = NULL;
|
||||
_func_flags = 0;
|
||||
_scoping = NULL;
|
||||
_expr = NULL;
|
||||
_type(type),
|
||||
_func_params(NULL),
|
||||
_func_flags(0),
|
||||
_scoping(NULL),
|
||||
_expr(NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -83,7 +82,8 @@ initializer_type(CPPParameterList *params) {
|
|||
CPPInstanceIdentifier::
|
||||
CPPInstanceIdentifier(CPPIdentifier *ident) :
|
||||
_ident(ident),
|
||||
_bit_width(-1) {
|
||||
_bit_width(-1),
|
||||
_packed(false) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -88,8 +88,12 @@ public:
|
|||
typedef vector<Modifier> Modifiers;
|
||||
Modifiers _modifiers;
|
||||
|
||||
// If not -1, indicates a bitfield
|
||||
int _bit_width;
|
||||
|
||||
// Indicates a parameter pack
|
||||
bool _packed;
|
||||
|
||||
private:
|
||||
CPPType *
|
||||
r_unroll_type(CPPType *start_type, Modifiers::const_iterator mi);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,20 @@ is_fully_specified() const {
|
|||
*/
|
||||
bool CPPParser::
|
||||
parse_file(const Filename &filename) {
|
||||
if (!init_cpp(CPPFile(filename, filename, CPPFile::S_local))) {
|
||||
Filename canonical(filename);
|
||||
canonical.make_canonical();
|
||||
|
||||
CPPFile file(canonical, filename, CPPFile::S_local);
|
||||
|
||||
// Don't read it if we included it before and it had #pragma once.
|
||||
ParsedFiles::iterator it = _parsed_files.find(file);
|
||||
if (it != _parsed_files.end() && it->_pragma_once) {
|
||||
// But mark it as local.
|
||||
it->_source = CPPFile::S_local;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!init_cpp(file)) {
|
||||
cerr << "Unable to read " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@
|
|||
#include "cppPointerType.h"
|
||||
#include "cppFunctionType.h"
|
||||
#include "cppIdentifier.h"
|
||||
#include "cppArrayType.h"
|
||||
#include "cppStructType.h"
|
||||
#include "cppSimpleType.h"
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -88,6 +91,14 @@ is_tbd() const {
|
|||
return _pointing_at->is_tbd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a standard layout type.
|
||||
*/
|
||||
bool CPPPointerType::
|
||||
is_standard_layout() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a Plain Old Data (POD) type.
|
||||
*/
|
||||
|
|
@ -96,6 +107,60 @@ is_trivial() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type can be constructed using the given argument.
|
||||
*/
|
||||
bool CPPPointerType::
|
||||
is_constructible(const CPPType *given_type) const {
|
||||
given_type = ((CPPType *)given_type)->remove_reference()->remove_cv();
|
||||
|
||||
// Can convert from compatible pointer or array type.
|
||||
CPPType *other_target;
|
||||
switch (given_type->get_subtype()) {
|
||||
case ST_array:
|
||||
other_target = given_type->as_array_type()->_element_type;
|
||||
break;
|
||||
|
||||
case ST_pointer:
|
||||
other_target = given_type->as_pointer_type()->_pointing_at;
|
||||
break;
|
||||
|
||||
case ST_simple:
|
||||
// Can initialize from nullptr.
|
||||
return given_type->as_simple_type()->_type == CPPSimpleType::T_nullptr;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Can't convert const to non-const pointer.
|
||||
if (other_target->is_const() && !_pointing_at->is_const()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Are we pointing to the same type? That's always OK.
|
||||
const CPPType *a = _pointing_at->remove_cv();
|
||||
const CPPType *b = other_target->remove_cv();
|
||||
if (a == b || *a == *b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Can initialize void pointer with any pointer.
|
||||
const CPPSimpleType *simple_type = a->as_simple_type();
|
||||
if (simple_type != NULL) {
|
||||
return simple_type->_type == CPPSimpleType::T_void;
|
||||
}
|
||||
|
||||
// Can initialize from derived class pointer.
|
||||
const CPPStructType *a_struct = a->as_struct_type();
|
||||
const CPPStructType *b_struct = b->as_struct_type();
|
||||
if (a_struct != NULL && b_struct != NULL) {
|
||||
return a_struct->is_base_of(b_struct);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is default-constructible.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ public:
|
|||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_standard_layout() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_constructible(const CPPType *other) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_equivalent(const CPPType &other) const;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "cppIdentifier.h"
|
||||
#include "cppTemplateScope.h"
|
||||
#include "cppTemplateParameterList.h"
|
||||
#include "cppClassTemplateParameter.h"
|
||||
#include "cppConstType.h"
|
||||
#include "cppFunctionGroup.h"
|
||||
#include "cppFunctionType.h"
|
||||
|
|
@ -416,7 +417,14 @@ get_next_token0() {
|
|||
int token_type = IDENTIFIER;
|
||||
CPPDeclaration *decl = ident->find_symbol(current_scope, global_scope);
|
||||
if (decl != NULL && decl->as_type() != NULL) {
|
||||
token_type = TYPENAME_IDENTIFIER;
|
||||
// We need to see type pack template parameters as a different type of
|
||||
// identifier to resolve a parser ambiguity.
|
||||
CPPClassTemplateParameter *ctp = decl->as_class_template_parameter();
|
||||
if (ctp && ctp->_packed) {
|
||||
token_type = TYPEPACK_IDENTIFIER;
|
||||
} else {
|
||||
token_type = TYPENAME_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
|
||||
_last_token_loc = loc;
|
||||
|
|
@ -801,6 +809,8 @@ expand_manifests(const string &input_expr, bool expand_undefined,
|
|||
// Here's an identifier. Is it "defined"?
|
||||
if (ident == "defined") {
|
||||
expand_defined_function(expr, q, p);
|
||||
} else if (expand_undefined && ident == "__has_include") {
|
||||
expand_has_include_function(expr, q, p, loc);
|
||||
} else {
|
||||
// Is it a manifest?
|
||||
Manifests::const_iterator mi = _manifests.find(ident);
|
||||
|
|
@ -809,6 +819,20 @@ expand_manifests(const string &input_expr, bool expand_undefined,
|
|||
expand_manifest_inline(expr, q, p, manifest);
|
||||
manifest_found = true;
|
||||
|
||||
} else if (ident == "__FILE__") {
|
||||
// Special case: this is a dynamic definition.
|
||||
string file = string("\"") + loc.file._filename_as_referenced.get_fullpath() + "\"";
|
||||
expr = expr.substr(0, q) + file + expr.substr(p);
|
||||
p = q + file.size();
|
||||
manifest_found = true;
|
||||
|
||||
} else if (ident == "__LINE__") {
|
||||
// So is this.
|
||||
string line = format_string(loc.first_line);
|
||||
expr = expr.substr(0, q) + line + expr.substr(p);
|
||||
p = q + line.size();
|
||||
manifest_found = true;
|
||||
|
||||
} else if (expand_undefined && ident != "true" && ident != "false") {
|
||||
// It is not found. Expand it to 0, but only if we are currently
|
||||
// parsing an #if expression.
|
||||
|
|
@ -951,7 +975,7 @@ internal_get_next_token() {
|
|||
case ',':
|
||||
if (_paren_nesting <= 0) {
|
||||
_state = S_end_nested;
|
||||
return CPPToken::eof();
|
||||
return CPPToken(0, loc);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -959,7 +983,7 @@ internal_get_next_token() {
|
|||
if (_paren_nesting <= 0) {
|
||||
_parsing_template_params = false;
|
||||
_state = S_end_nested;
|
||||
return CPPToken::eof();
|
||||
return CPPToken(0, loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1453,7 +1477,6 @@ handle_define_directive(const string &args, const YYLTYPE &loc) {
|
|||
CPPManifest *other = result.first->second;
|
||||
warning("redefinition of macro '" + manifest->_name + "'", loc);
|
||||
warning("previous definition is here", other->_loc);
|
||||
delete other;
|
||||
result.first->second = manifest;
|
||||
}
|
||||
}
|
||||
|
|
@ -1479,14 +1502,10 @@ handle_undef_directive(const string &args, const YYLTYPE &loc) {
|
|||
*/
|
||||
void CPPPreprocessor::
|
||||
handle_ifdef_directive(const string &args, const YYLTYPE &loc) {
|
||||
Manifests::const_iterator mi = _manifests.find(args);
|
||||
if (mi != _manifests.end()) {
|
||||
// The macro is defined. We continue.
|
||||
return;
|
||||
if (!is_manifest_defined(args)) {
|
||||
// The macro is undefined. Skip stuff.
|
||||
skip_false_if_block(true);
|
||||
}
|
||||
|
||||
// The macro is undefined. Skip stuff.
|
||||
skip_false_if_block(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1494,17 +1513,12 @@ handle_ifdef_directive(const string &args, const YYLTYPE &loc) {
|
|||
*/
|
||||
void CPPPreprocessor::
|
||||
handle_ifndef_directive(const string &args, const YYLTYPE &loc) {
|
||||
Manifests::const_iterator mi = _manifests.find(args);
|
||||
if (mi == _manifests.end()) {
|
||||
// The macro is undefined. We continue.
|
||||
return;
|
||||
if (is_manifest_defined(args)) {
|
||||
// The macro is defined. Skip stuff.
|
||||
skip_false_if_block(true);
|
||||
}
|
||||
|
||||
// The macro is defined. Skip stuff.
|
||||
skip_false_if_block(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -1586,6 +1600,8 @@ handle_include_directive(const string &args, const YYLTYPE &loc) {
|
|||
_angle_includes.insert(filename);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warning("Ignoring invalid #include directive", loc);
|
||||
}
|
||||
|
||||
filename.set_text();
|
||||
|
|
@ -1593,71 +1609,30 @@ handle_include_directive(const string &args, const YYLTYPE &loc) {
|
|||
|
||||
// Now look for the filename. If we didn't use angle quotes, look first in
|
||||
// the current directory.
|
||||
bool found_file = false;
|
||||
CPPFile::Source source = CPPFile::S_none;
|
||||
|
||||
if (okflag) {
|
||||
found_file = false;
|
||||
if (find_include(filename, angle_quotes, source)) {
|
||||
_last_c = '\0';
|
||||
|
||||
// Search the current directory.
|
||||
if (!angle_quotes && !found_file && filename.exists()) {
|
||||
found_file = true;
|
||||
// If it was explicitly named on the command-line, mark it S_local.
|
||||
filename.make_canonical();
|
||||
if (_explicit_files.count(filename)) {
|
||||
source = CPPFile::S_local;
|
||||
}
|
||||
|
||||
// Search the same directory as the includer.
|
||||
if (!angle_quotes && !found_file) {
|
||||
Filename match(get_file()._filename.get_dirname(), filename);
|
||||
if (match.exists()) {
|
||||
filename = match;
|
||||
found_file = true;
|
||||
source = CPPFile::S_alternate;
|
||||
}
|
||||
CPPFile file(filename, filename_as_referenced, source);
|
||||
|
||||
// Don't include it if we included it before and it had #pragma once.
|
||||
ParsedFiles::const_iterator it = _parsed_files.find(file);
|
||||
if (it != _parsed_files.end() && it->_pragma_once) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Now search the angle-include-path
|
||||
if (angle_quotes && !found_file && filename.resolve_filename(_angle_include_path)) {
|
||||
found_file = true;
|
||||
source = CPPFile::S_system;
|
||||
}
|
||||
|
||||
// Now search the quote-include-path
|
||||
if (!angle_quotes && !found_file) {
|
||||
for (size_t dir=0; dir<_quote_include_path.get_num_directories(); dir++) {
|
||||
Filename match(_quote_include_path.get_directory(dir), filename);
|
||||
if (match.exists()) {
|
||||
filename = match;
|
||||
found_file = true;
|
||||
source = _quote_include_kind[dir];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_file) {
|
||||
warning("Cannot find " + filename.get_fullpath(), loc);
|
||||
} else {
|
||||
_last_c = '\0';
|
||||
|
||||
// If it was explicitly named on the command-line, mark it S_local.
|
||||
filename.make_absolute();
|
||||
if (_explicit_files.count(filename)) {
|
||||
source = CPPFile::S_local;
|
||||
}
|
||||
|
||||
CPPFile file(filename, filename_as_referenced, source);
|
||||
|
||||
// Don't include it if we included it before and it had #pragma once.
|
||||
ParsedFiles::const_iterator it = _parsed_files.find(file);
|
||||
if (it != _parsed_files.end() && it->_pragma_once) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!push_file(file)) {
|
||||
warning("Unable to read " + filename.get_fullpath(), loc);
|
||||
}
|
||||
if (!push_file(file)) {
|
||||
warning("Unable to read " + filename.get_fullpath(), loc);
|
||||
}
|
||||
} else {
|
||||
warning("Ignoring invalid #include directive", loc);
|
||||
warning("Cannot find " + filename.get_fullpath(), loc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1671,6 +1646,38 @@ handle_pragma_directive(const string &args, const YYLTYPE &loc) {
|
|||
assert(it != _parsed_files.end());
|
||||
it->_pragma_once = true;
|
||||
}
|
||||
|
||||
char macro[64];
|
||||
if (sscanf(args.c_str(), "push_macro ( \"%63[^\"]\" )", macro) == 1) {
|
||||
// We just mark it as pushed for now, so that the next time someone tries
|
||||
// to override it, we save the old value.
|
||||
Manifests::iterator mi = _manifests.find(macro);
|
||||
if (mi != _manifests.end()) {
|
||||
_manifest_stack[macro].push_back(mi->second);
|
||||
} else {
|
||||
_manifest_stack[macro].push_back(NULL);
|
||||
}
|
||||
|
||||
} else if (sscanf(args.c_str(), "pop_macro ( \"%63[^\"]\" )", macro) == 1) {
|
||||
ManifestStack &stack = _manifest_stack[macro];
|
||||
if (stack.size() > 0) {
|
||||
CPPManifest *manifest = stack.back();
|
||||
stack.pop_back();
|
||||
Manifests::iterator mi = _manifests.find(macro);
|
||||
if (manifest == NULL) {
|
||||
// It was undefined when it was pushed, so make it undefined again.
|
||||
if (mi != _manifests.end()) {
|
||||
_manifests.erase(mi);
|
||||
}
|
||||
} else if (mi != _manifests.end()) {
|
||||
mi->second = manifest;
|
||||
} else {
|
||||
_manifests.insert(Manifests::value_type(macro, manifest));
|
||||
}
|
||||
} else {
|
||||
warning("pop_macro without matching push_macro", loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1740,6 +1747,69 @@ skip_false_if_block(bool consider_elifs) {
|
|||
_save_comments = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given manifest is defined.
|
||||
*/
|
||||
bool CPPPreprocessor::
|
||||
is_manifest_defined(const string &manifest_name) {
|
||||
Manifests::const_iterator mi = _manifests.find(manifest_name);
|
||||
if (mi != _manifests.end()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (manifest_name == "__has_include" ||
|
||||
manifest_name == "__FILE__" ||
|
||||
manifest_name == "__LINE__") {
|
||||
// Special built-in directives that are considered "defined".
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the given filename. Changes the first argument to the full path.
|
||||
*/
|
||||
bool CPPPreprocessor::
|
||||
find_include(Filename &filename, bool angle_quotes, CPPFile::Source &source) {
|
||||
// Now look for the filename. If we didn't use angle quotes, look first in
|
||||
// the current directory.
|
||||
if (!angle_quotes && filename.exists()) {
|
||||
source = CPPFile::S_local;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Search the same directory as the includer.
|
||||
if (!angle_quotes) {
|
||||
Filename match(get_file()._filename.get_dirname(), filename);
|
||||
if (match.exists()) {
|
||||
filename = match;
|
||||
source = CPPFile::S_alternate;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Now search the angle-include-path
|
||||
if (angle_quotes && filename.resolve_filename(_angle_include_path)) {
|
||||
source = CPPFile::S_system;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Now search the quote-include-path
|
||||
if (!angle_quotes) {
|
||||
for (size_t dir = 0; dir < _quote_include_path.get_num_directories(); ++dir) {
|
||||
Filename match(_quote_include_path.get_directory(dir), filename);
|
||||
if (match.exists()) {
|
||||
filename = match;
|
||||
source = _quote_include_kind[dir];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -1846,6 +1916,14 @@ get_identifier(int c) {
|
|||
if (mi != _manifests.end() && !should_ignore_manifest((*mi).second)) {
|
||||
return expand_manifest((*mi).second);
|
||||
}
|
||||
if (name == "__FILE__") {
|
||||
return get_literal(SIMPLE_STRING, loc, loc.file._filename_as_referenced);
|
||||
}
|
||||
if (name == "__LINE__") {
|
||||
YYSTYPE result;
|
||||
result.u.integer = loc.first_line;
|
||||
return CPPToken(INTEGER, loc, "", result);
|
||||
}
|
||||
|
||||
// Check for keywords.
|
||||
int kw = check_keyword(name);
|
||||
|
|
@ -2188,9 +2266,7 @@ expand_defined_function(string &expr, size_t q, size_t &p) {
|
|||
vector_string args;
|
||||
extract_manifest_args_inline("defined", 1, -1, args, expr, p);
|
||||
if (args.size() >= 1) {
|
||||
const string &manifest_name = args[0];
|
||||
Manifests::const_iterator mi = _manifests.find(manifest_name);
|
||||
if (mi != _manifests.end()) {
|
||||
if (is_manifest_defined(args[0])) {
|
||||
// The macro is defined; the result is "1".
|
||||
result = "1";
|
||||
} else {
|
||||
|
|
@ -2203,6 +2279,70 @@ expand_defined_function(string &expr, size_t q, size_t &p) {
|
|||
p = q + result.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands the __has_include(manifest) function to either 1 or 0, depending on
|
||||
* whether the include file exists.
|
||||
*/
|
||||
void CPPPreprocessor::
|
||||
expand_has_include_function(string &expr, size_t q, size_t &p, YYLTYPE loc) {
|
||||
bool found_file = false;
|
||||
|
||||
// Skip whitespace till paren.
|
||||
while (p < expr.size() && isspace(expr[p])) {
|
||||
p++;
|
||||
}
|
||||
size_t args_begin = p + 1;
|
||||
|
||||
vector_string args;
|
||||
extract_manifest_args_inline("__has_include", 1, -1, args, expr, p);
|
||||
|
||||
if (!args.empty() && args[0].size() >= 2) {
|
||||
Filename filename;
|
||||
bool angle_quotes = false;
|
||||
|
||||
string inc = args[0];
|
||||
|
||||
// Just to play things safe, since our manifest-expansion logic might not
|
||||
// filter out quotes and angle brackets properly, we'll only expand
|
||||
// manifests if we don't begin with a quote or bracket.
|
||||
if (!inc.empty() && (inc[0] != '"' && inc[0] != '<')) {
|
||||
inc = expand_manifests(inc, false, loc);
|
||||
}
|
||||
|
||||
if (inc[0] == '"' && inc[inc.size() - 1] == '"') {
|
||||
filename = inc.substr(1, inc.size() - 2);
|
||||
} else if (inc[0] == '<' && inc[inc.size() - 1] == '>') {
|
||||
filename = inc.substr(1, inc.size() - 2);
|
||||
if (!_noangles) {
|
||||
// If _noangles is true, we don't make a distinction between angle
|
||||
// brackets and quote marks--all #inc statements are treated the
|
||||
// same, as if they used quote marks.
|
||||
angle_quotes = true;
|
||||
}
|
||||
} else {
|
||||
loc.last_column += loc.first_column + p - 2;
|
||||
loc.first_column += args_begin;
|
||||
warning("invalid argument for __has_include() directive", loc);
|
||||
expr = expr.substr(0, q) + "0" + expr.substr(p);
|
||||
p = q + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
filename.set_text();
|
||||
|
||||
CPPFile::Source source = CPPFile::S_none;
|
||||
found_file = find_include(filename, angle_quotes, source);
|
||||
} else {
|
||||
loc.last_column += loc.first_column + p - 2;
|
||||
loc.first_column += args_begin;
|
||||
warning("invalid argument for __has_include() directive", loc);
|
||||
}
|
||||
|
||||
string result = found_file ? "1" : "0";
|
||||
expr = expr.substr(0, q) + result + expr.substr(p);
|
||||
p = q + result.size();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -2451,11 +2591,27 @@ check_keyword(const string &name) {
|
|||
if (name == "friend") return KW_FRIEND;
|
||||
if (name == "for") return KW_FOR;
|
||||
if (name == "goto") return KW_GOTO;
|
||||
if (name == "__has_virtual_destructor") return KW_HAS_VIRTUAL_DESTRUCTOR;
|
||||
if (name == "if") return KW_IF;
|
||||
if (name == "inline") return KW_INLINE;
|
||||
if (name == "__inline") return KW_INLINE;
|
||||
if (name == "__inline__") return KW_INLINE;
|
||||
if (name == "int") return KW_INT;
|
||||
if (name == "__is_abstract") return KW_IS_ABSTRACT;
|
||||
if (name == "__is_base_of") return KW_IS_BASE_OF;
|
||||
if (name == "__is_class") return KW_IS_CLASS;
|
||||
if (name == "__is_constructible") return KW_IS_CONSTRUCTIBLE;
|
||||
if (name == "__is_convertible_to") return KW_IS_CONVERTIBLE_TO;
|
||||
if (name == "__is_destructible") return KW_IS_DESTRUCTIBLE;
|
||||
if (name == "__is_empty") return KW_IS_EMPTY;
|
||||
if (name == "__is_enum") return KW_IS_ENUM;
|
||||
if (name == "__is_final") return KW_IS_FINAL;
|
||||
if (name == "__is_fundamental") return KW_IS_FUNDAMENTAL;
|
||||
if (name == "__is_pod") return KW_IS_POD;
|
||||
if (name == "__is_polymorphic") return KW_IS_POLYMORPHIC;
|
||||
if (name == "__is_standard_layout") return KW_IS_STANDARD_LAYOUT;
|
||||
if (name == "__is_trivial") return KW_IS_TRIVIAL;
|
||||
if (name == "__is_union") return KW_IS_UNION;
|
||||
if (name == "long") return KW_LONG;
|
||||
if (name == "__make_map_property") return KW_MAKE_MAP_PROPERTY;
|
||||
if (name == "__make_property") return KW_MAKE_PROPERTY;
|
||||
|
|
@ -2490,6 +2646,7 @@ check_keyword(const string &name) {
|
|||
if (name == "typedef") return KW_TYPEDEF;
|
||||
if (name == "typeid") return KW_TYPEID;
|
||||
if (name == "typename") return KW_TYPENAME;
|
||||
if (name == "__underlying_type") return KW_UNDERLYING_TYPE;
|
||||
if (name == "union") return KW_UNION;
|
||||
if (name == "unsigned") return KW_UNSIGNED;
|
||||
if (name == "using") return KW_USING;
|
||||
|
|
@ -2751,7 +2908,7 @@ nested_parse_template_instantiation(CPPTemplateScope *scope) {
|
|||
_parsing_template_params = true;
|
||||
|
||||
CPPToken token = internal_get_next_token();
|
||||
if (token._token == '>') {
|
||||
if (token._token == '>' || token._token == 0) {
|
||||
_parsing_template_params = false;
|
||||
} else {
|
||||
_saved_tokens.push_back(token);
|
||||
|
|
@ -2760,36 +2917,53 @@ nested_parse_template_instantiation(CPPTemplateScope *scope) {
|
|||
CPPTemplateParameterList *actual_params = new CPPTemplateParameterList;
|
||||
|
||||
for (pi = formal_params._parameters.begin();
|
||||
pi != formal_params._parameters.end() && _parsing_template_params;
|
||||
++pi) {
|
||||
pi != formal_params._parameters.end() && _parsing_template_params;) {
|
||||
CPPToken token = peek_next_token();
|
||||
YYLTYPE loc = token._lloc;
|
||||
|
||||
CPPDeclaration *decl = (*pi);
|
||||
if (decl->as_type()) {
|
||||
CPPClassTemplateParameter *param = decl->as_class_template_parameter();
|
||||
CPPInstance *inst = decl->as_instance();
|
||||
if (param) {
|
||||
// Parse a typename template parameter.
|
||||
_saved_tokens.push_back(CPPToken(START_TYPE));
|
||||
CPPType *type = ::parse_type(this, current_scope, global_scope);
|
||||
if (type == NULL) {
|
||||
loc.last_line = get_line_number();
|
||||
loc.last_column = get_col_number() - 1;
|
||||
warning("Invalid type", loc);
|
||||
warning("invalid type", loc);
|
||||
skip_to_end_nested();
|
||||
type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_unknown));
|
||||
}
|
||||
actual_params->_parameters.push_back(type);
|
||||
} else {
|
||||
|
||||
// If this is a variadic template, keep reading using this parameter.
|
||||
if (!param->_packed) {
|
||||
++pi;
|
||||
}
|
||||
} else if (inst) {
|
||||
// Parse a constant expression template parameter.
|
||||
_saved_tokens.push_back(CPPToken(START_CONST_EXPR));
|
||||
CPPExpression *expr = parse_const_expr(this, current_scope, global_scope);
|
||||
if (expr == NULL) {
|
||||
loc.last_line = get_line_number();
|
||||
loc.last_column = get_col_number() - 1;
|
||||
warning("Invalid expression", loc);
|
||||
warning("invalid expression", loc);
|
||||
skip_to_end_nested();
|
||||
expr = new CPPExpression(0);
|
||||
}
|
||||
actual_params->_parameters.push_back(expr);
|
||||
|
||||
// If this is a variadic template, keep reading using this parameter.
|
||||
if ((inst->_storage_class & CPPInstance::SC_parameter_pack) == 0) {
|
||||
++pi;
|
||||
}
|
||||
} else {
|
||||
loc.last_line = get_line_number();
|
||||
loc.last_column = get_col_number() - 1;
|
||||
warning("invalid template parameter", loc);
|
||||
skip_to_end_nested();
|
||||
++pi;
|
||||
}
|
||||
|
||||
_state = S_nested;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,9 @@ public:
|
|||
typedef map<string, CPPManifest *> Manifests;
|
||||
Manifests _manifests;
|
||||
|
||||
typedef pvector<CPPManifest *> ManifestStack;
|
||||
map<string, ManifestStack> _manifest_stack;
|
||||
|
||||
pvector<CPPFile::Source> _quote_include_kind;
|
||||
DSearchPath _quote_include_path;
|
||||
DSearchPath _angle_include_path;
|
||||
|
|
@ -140,6 +143,8 @@ private:
|
|||
void handle_error_directive(const string &args, const YYLTYPE &loc);
|
||||
|
||||
void skip_false_if_block(bool consider_elifs);
|
||||
bool is_manifest_defined(const string &manifest_name);
|
||||
bool find_include(Filename &filename, bool angle_quotes, CPPFile::Source &source);
|
||||
|
||||
CPPToken get_quoted_char(int c);
|
||||
CPPToken get_quoted_string(int c);
|
||||
|
|
@ -150,6 +155,7 @@ private:
|
|||
void extract_manifest_args(const string &name, int num_args,
|
||||
int va_arg, vector_string &args);
|
||||
void expand_defined_function(string &expr, size_t q, size_t &p);
|
||||
void expand_has_include_function(string &expr, size_t q, size_t &p, YYLTYPE loc);
|
||||
void expand_manifest_inline(string &expr, size_t q, size_t &p,
|
||||
const CPPManifest *manifest);
|
||||
void extract_manifest_args_inline(const string &name, int num_args,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
*/
|
||||
|
||||
#include "cppReferenceType.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppStructType.h"
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -87,6 +89,14 @@ is_tbd() const {
|
|||
return _pointing_at->is_tbd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a standard layout type.
|
||||
*/
|
||||
bool CPPReferenceType::
|
||||
is_standard_layout() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a Plain Old Data (POD) type.
|
||||
*/
|
||||
|
|
@ -95,6 +105,67 @@ is_trivial() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type can be constructed using the given argument.
|
||||
*/
|
||||
bool CPPReferenceType::
|
||||
is_constructible(const CPPType *given_type) const {
|
||||
const CPPType *a;
|
||||
const CPPType *b;
|
||||
|
||||
CPPReferenceType *ref_type = ((CPPType *)given_type)->as_reference_type();
|
||||
if (ref_type != NULL) {
|
||||
if (ref_type->_value_category == VC_rvalue) {
|
||||
return is_constructible(ref_type->_pointing_at);
|
||||
}
|
||||
|
||||
if (_value_category == VC_rvalue) {
|
||||
// Can never initialize an rvalue ref from an lvalue ref.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_pointing_at->is_const()) {
|
||||
// Cannot initialize a non-const reference using a const one.
|
||||
if (ref_type->_pointing_at->is_const()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
a = _pointing_at->remove_cv();
|
||||
b = ref_type->_pointing_at->remove_cv();
|
||||
|
||||
} else {
|
||||
// Initializing using an rvalue.
|
||||
if (!_pointing_at->is_const()) {
|
||||
// Cannot initialize a non-const reference using a const one.
|
||||
if (given_type->is_const()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot initalise a non-const lvalue reference with an rvalue ref.
|
||||
if (_value_category == VC_lvalue) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
a = _pointing_at->remove_cv();
|
||||
b = ((CPPType *)given_type)->remove_cv();
|
||||
}
|
||||
|
||||
if (a == b || *a == *b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Can initialize from derived class pointer.
|
||||
const CPPStructType *a_struct = a->as_struct_type();
|
||||
const CPPStructType *b_struct = b->as_struct_type();
|
||||
if (a_struct != NULL && b_struct != NULL) {
|
||||
return a_struct->is_base_of(b_struct);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is default-constructible.
|
||||
*/
|
||||
|
|
@ -111,6 +182,14 @@ is_copy_constructible() const {
|
|||
return (_value_category == VC_lvalue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
bool CPPReferenceType::
|
||||
is_destructible() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -42,9 +42,12 @@ public:
|
|||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_standard_layout() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_constructible(const CPPType *type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_destructible() const;
|
||||
virtual bool is_equivalent(const CPPType &other) const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
#include "cppPreprocessor.h"
|
||||
#include "cppTemplateScope.h"
|
||||
#include "cppClassTemplateParameter.h"
|
||||
#include "cppConstType.h"
|
||||
#include "cppFunctionType.h"
|
||||
#include "cppConstType.h"
|
||||
#include "cppUsing.h"
|
||||
#include "cppBisonDefs.h"
|
||||
#include "indent.h"
|
||||
|
|
|
|||
|
|
@ -139,11 +139,12 @@ public:
|
|||
Templates _templates;
|
||||
CPPNameComponent _name;
|
||||
|
||||
typedef set<CPPScope *> Using;
|
||||
Using _using;
|
||||
|
||||
protected:
|
||||
CPPScope *_parent_scope;
|
||||
CPPStructType *_struct_type;
|
||||
typedef set<CPPScope *> Using;
|
||||
Using _using;
|
||||
CPPVisibility _current_vis;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -34,6 +34,30 @@ is_tbd() const {
|
|||
return (_type == T_unknown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is a boolean, floating point or integral type.
|
||||
*/
|
||||
bool CPPSimpleType::
|
||||
is_arithmetic() const {
|
||||
return (_type > T_unknown && _type < T_void);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a fundamental type.
|
||||
*/
|
||||
bool CPPSimpleType::
|
||||
is_fundamental() const {
|
||||
return (_type != T_unknown && _type != T_parameter && _type != T_auto);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a standard layout type.
|
||||
*/
|
||||
bool CPPSimpleType::
|
||||
is_standard_layout() const {
|
||||
return (_type != T_unknown && _type != T_parameter && _type != T_auto);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a Plain Old Data (POD) type.
|
||||
*/
|
||||
|
|
@ -42,6 +66,27 @@ is_trivial() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type can be constructed using the given argument.
|
||||
*/
|
||||
bool CPPSimpleType::
|
||||
is_constructible(const CPPType *given_type) const {
|
||||
given_type = ((CPPType *)given_type)->remove_reference()->remove_cv();
|
||||
|
||||
const CPPSimpleType *simple_type = given_type->as_simple_type();
|
||||
if (simple_type == NULL) {
|
||||
return given_type->is_enum() && is_arithmetic();
|
||||
} else if (_type == T_nullptr) {
|
||||
return simple_type->_type == T_nullptr;
|
||||
} else if (_type == T_bool) {
|
||||
return simple_type->is_arithmetic() || simple_type->_type == T_nullptr;
|
||||
} else if (is_arithmetic()) {
|
||||
return simple_type->is_arithmetic();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is default-constructible.
|
||||
*/
|
||||
|
|
@ -58,6 +103,14 @@ is_copy_constructible() const {
|
|||
return (_type != T_void);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
bool CPPSimpleType::
|
||||
is_destructible() const {
|
||||
return (_type != T_void);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is a special parameter expression type.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "cppType.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* Represents a C++ fundamental type.
|
||||
*/
|
||||
class CPPSimpleType : public CPPType {
|
||||
public:
|
||||
|
|
@ -40,12 +40,11 @@ public:
|
|||
// nullptr_t, which is a typedef of decltype(nullptr).
|
||||
T_nullptr,
|
||||
|
||||
/*
|
||||
* T_parameter is a special type which is assigned to expressions that are
|
||||
* discovered where a formal parameter was expected. This is a special case
|
||||
* for handling cases like this: int foo(0); which really means the same thing
|
||||
* as: int foo = 0; but it initially looks like a function prototype.
|
||||
*/
|
||||
// T_parameter is a special type which is assigned to expressions that are
|
||||
// discovered where a formal parameter was expected. This is a special
|
||||
// case for handling cases like this: int foo(0); which really means the
|
||||
// same thing as: int foo = 0; but it initially looks like a function
|
||||
// prototype.
|
||||
T_parameter,
|
||||
|
||||
// T_auto is also a special type that corresponds to the "auto" keyword
|
||||
|
|
@ -69,9 +68,14 @@ public:
|
|||
int _flags;
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
bool is_arithmetic() const;
|
||||
virtual bool is_fundamental() const;
|
||||
virtual bool is_standard_layout() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_constructible(const CPPType *type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_destructible() const;
|
||||
virtual bool is_parameter_expr() const;
|
||||
|
||||
virtual string get_preferred_name() const;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "cppStructType.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppReferenceType.h"
|
||||
#include "cppScope.h"
|
||||
#include "cppTypeProxy.h"
|
||||
#include "cppTemplateScope.h"
|
||||
|
|
@ -126,16 +127,154 @@ is_abstract() const {
|
|||
return !funcs.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this struct declaration is a base class of the other given
|
||||
* class, or the same class.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_base_of(const CPPStructType *other) const {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
Derivation::const_iterator di;
|
||||
for (di = other->_derivation.begin(); di != other->_derivation.end(); ++di) {
|
||||
const CPPStructType *base = (*di)._base->as_struct_type();
|
||||
if (base != NULL && is_base_of(base)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this struct declaration defines no non-static data members
|
||||
* other than bit-fields of size 0, no virtual functions, no virtual base
|
||||
* classes, and no non-empty base classes, and is not a union.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_empty() const {
|
||||
if (_type == T_union) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (check_virtual()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure all base classes are empty and non-virtual.
|
||||
Derivation::const_iterator di;
|
||||
for (di = _derivation.begin(); di != _derivation.end(); ++di) {
|
||||
CPPStructType *base = (*di)._base->as_struct_type();
|
||||
if ((*di)._is_virtual || (base != NULL && !base->is_empty())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure there are no non-static data members.
|
||||
CPPScope::Variables::const_iterator vi;
|
||||
for (vi = _scope->_variables.begin(); vi != _scope->_variables.end(); ++vi) {
|
||||
CPPInstance *instance = (*vi).second;
|
||||
assert(instance != NULL);
|
||||
|
||||
if (instance->_storage_class & CPPInstance::SC_static) {
|
||||
// Static members don't count.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only members with a bit width of 0 are okay.
|
||||
if (instance->_bit_width != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class or any of its base classes have virtual methods.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_polymorphic() const {
|
||||
if (_type == T_union) {
|
||||
return false;
|
||||
}
|
||||
return check_virtual();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a standard layout type.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_standard_layout() const {
|
||||
assert(_scope != NULL);
|
||||
|
||||
CPPVisibility member_vis = V_unknown;
|
||||
|
||||
// Make sure all data members have the same vis and are standard layout.
|
||||
CPPScope::Variables::const_iterator vi;
|
||||
for (vi = _scope->_variables.begin(); vi != _scope->_variables.end(); ++vi) {
|
||||
CPPInstance *instance = (*vi).second;
|
||||
assert(instance != NULL);
|
||||
|
||||
if (instance->_storage_class & CPPInstance::SC_static) {
|
||||
// Static members don't count.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Finally, check if the data member itself is standard layout.
|
||||
assert(instance->_type != NULL);
|
||||
if (!instance->_type->is_standard_layout()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (member_vis == V_unknown) {
|
||||
// The first non-static data member may not be a base class.
|
||||
CPPStructType *struct_type = instance->_type->remove_cv()->as_struct_type();
|
||||
if (struct_type != NULL && struct_type->is_base_of(this)) {
|
||||
return false;
|
||||
}
|
||||
member_vis = instance->_vis;
|
||||
|
||||
} else if (member_vis != instance->_vis) {
|
||||
// All members need to have the same access control.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure all base classes are standard-layout and non-virtual.
|
||||
Derivation::const_iterator di;
|
||||
for (di = _derivation.begin(); di != _derivation.end(); ++di) {
|
||||
CPPStructType *base = (*di)._base->as_struct_type();
|
||||
if ((*di)._is_virtual) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this class had instance members, all base classes need to be empty.
|
||||
if (member_vis != V_unknown) {
|
||||
if (!base->is_empty()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!base->is_standard_layout()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we have no virtual functions.
|
||||
return !check_virtual();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a Plain Old Data (POD) type.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_trivial() const {
|
||||
// Make sure all base classes are trivial.
|
||||
// Make sure all base classes are trivial and non-virtual.
|
||||
Derivation::const_iterator di;
|
||||
for (di = _derivation.begin(); di != _derivation.end(); ++di) {
|
||||
CPPStructType *base = (*di)._base->as_struct_type();
|
||||
if (base != NULL && !base->is_trivial()) {
|
||||
if ((*di)._is_virtual || (base != NULL && !base->is_trivial())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -166,7 +305,7 @@ is_trivial() const {
|
|||
}
|
||||
}
|
||||
|
||||
// Now look for functions that are virtual or condestructors.
|
||||
// Now look for functions that are virtual or con/destructors.
|
||||
bool is_default_constructible = true;
|
||||
CPPScope::Functions::const_iterator fi;
|
||||
for (fi = _scope->_functions.begin(); fi != _scope->_functions.end(); ++fi) {
|
||||
|
|
@ -193,8 +332,8 @@ is_trivial() const {
|
|||
if (ftype->_flags & (CPPFunctionType::F_destructor |
|
||||
CPPFunctionType::F_move_constructor |
|
||||
CPPFunctionType::F_copy_constructor)) {
|
||||
// User-provided destructors and copymove constructors are not trivial
|
||||
// unless they are defaulted (and not virtual).
|
||||
// User-provided destructors and copy/move constructors are not
|
||||
// trivial unless they are defaulted (and not virtual).
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -220,6 +359,66 @@ is_trivial() const {
|
|||
return is_default_constructible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type can be constructed using the given argument.
|
||||
* This implementation is rudimentary, as it does not attempt to follow all of
|
||||
* the implicit type conversion rules, but it is still useful.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_constructible(const CPPType *given_type) const {
|
||||
// Does the type match the copy constructor or move constructor?
|
||||
CPPType *base_type = ((CPPType *)given_type)->remove_reference();
|
||||
if (is_equivalent(*base_type->remove_cv())) {
|
||||
const CPPReferenceType *ref_type = given_type->as_reference_type();
|
||||
if (ref_type == NULL ||
|
||||
ref_type->_value_category == CPPReferenceType::VC_rvalue) {
|
||||
return is_move_constructible(V_public);
|
||||
} else {
|
||||
return is_copy_constructible(V_public);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_abstract()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for a different constructor.
|
||||
CPPFunctionGroup *fgroup = get_constructor();
|
||||
if (fgroup != (CPPFunctionGroup *)NULL) {
|
||||
CPPFunctionGroup::Instances::const_iterator ii;
|
||||
for (ii = fgroup->_instances.begin();
|
||||
ii != fgroup->_instances.end();
|
||||
++ii) {
|
||||
CPPInstance *inst = (*ii);
|
||||
assert(inst->_type != (CPPType *)NULL);
|
||||
|
||||
CPPFunctionType *ftype = inst->_type->as_function_type();
|
||||
assert(ftype != (CPPFunctionType *)NULL);
|
||||
|
||||
CPPParameterList *params = ftype->_parameters;
|
||||
if (params->_parameters.size() == 1 && !params->_includes_ellipsis) {
|
||||
CPPType *param_type = params->_parameters[0]->_type->remove_reference();
|
||||
|
||||
if (!param_type->is_const() && base_type->is_const()) {
|
||||
// Can't pass a const object to a function taking a non-const.
|
||||
continue;
|
||||
}
|
||||
|
||||
// It's deleted, anyhow.
|
||||
if ((inst->_storage_class & CPPInstance::SC_deleted) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param_type->is_equivalent(*base_type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is default-constructible.
|
||||
*/
|
||||
|
|
@ -236,11 +435,23 @@ is_copy_constructible() const {
|
|||
return is_copy_constructible(V_public);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_destructible() const {
|
||||
return is_destructible(V_public);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is default-constructible.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_default_constructible(CPPVisibility min_vis) const {
|
||||
if (is_abstract()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CPPInstance *constructor = get_default_constructor();
|
||||
if (constructor != (CPPInstance *)NULL) {
|
||||
// It has a default constructor.
|
||||
|
|
@ -295,24 +506,6 @@ is_default_constructible(CPPVisibility min_vis) const {
|
|||
}
|
||||
}
|
||||
|
||||
// Check that we don't have pure virtual methods.
|
||||
CPPScope::Functions::const_iterator fi;
|
||||
for (fi = _scope->_functions.begin();
|
||||
fi != _scope->_functions.end();
|
||||
++fi) {
|
||||
CPPFunctionGroup *fgroup = (*fi).second;
|
||||
CPPFunctionGroup::Instances::const_iterator ii;
|
||||
for (ii = fgroup->_instances.begin();
|
||||
ii != fgroup->_instances.end();
|
||||
++ii) {
|
||||
CPPInstance *inst = (*ii);
|
||||
if (inst->_storage_class & CPPInstance::SC_pure_virtual) {
|
||||
// Here's a pure virtual function.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -321,6 +514,10 @@ is_default_constructible(CPPVisibility min_vis) const {
|
|||
*/
|
||||
bool CPPStructType::
|
||||
is_copy_constructible(CPPVisibility min_vis) const {
|
||||
if (is_abstract()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CPPInstance *constructor = get_copy_constructor();
|
||||
if (constructor != (CPPInstance *)NULL) {
|
||||
// It has a copy constructor.
|
||||
|
|
@ -378,27 +575,146 @@ is_copy_constructible(CPPVisibility min_vis) const {
|
|||
}
|
||||
}
|
||||
|
||||
// Check that we don't have pure virtual methods.
|
||||
CPPScope::Functions::const_iterator fi;
|
||||
for (fi = _scope->_functions.begin();
|
||||
fi != _scope->_functions.end();
|
||||
++fi) {
|
||||
CPPFunctionGroup *fgroup = (*fi).second;
|
||||
CPPFunctionGroup::Instances::const_iterator ii;
|
||||
for (ii = fgroup->_instances.begin();
|
||||
ii != fgroup->_instances.end();
|
||||
++ii) {
|
||||
CPPInstance *inst = (*ii);
|
||||
if (inst->_storage_class & CPPInstance::SC_pure_virtual) {
|
||||
// Here's a pure virtual function.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is move-constructible.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_move_constructible(CPPVisibility min_vis) const {
|
||||
CPPInstance *constructor = get_move_constructor();
|
||||
if (constructor != (CPPInstance *)NULL) {
|
||||
// It has a user-declared move constructor.
|
||||
if (constructor->_vis > min_vis) {
|
||||
// Inaccessible move constructor.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (constructor->_storage_class & CPPInstance::SC_deleted) {
|
||||
// It is deleted.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_abstract()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return is_copy_constructible(min_vis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_destructible(CPPVisibility min_vis) const {
|
||||
// Do we have an explicit destructor?
|
||||
CPPInstance *destructor = get_destructor();
|
||||
if (destructor != (CPPInstance *)NULL) {
|
||||
if (destructor->_vis > min_vis) {
|
||||
// Yes, but it's inaccessible.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (destructor->_storage_class & CPPInstance::SC_deleted) {
|
||||
// Yes, but it's explicitly been deleted.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make sure all base classes are destructible.
|
||||
Derivation::const_iterator di;
|
||||
for (di = _derivation.begin(); di != _derivation.end(); ++di) {
|
||||
CPPStructType *base = (*di)._base->as_struct_type();
|
||||
if (base != NULL && !base->is_destructible(V_protected)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
assert(_scope != NULL);
|
||||
|
||||
// Make sure all members are destructible.
|
||||
CPPScope::Variables::const_iterator vi;
|
||||
for (vi = _scope->_variables.begin(); vi != _scope->_variables.end(); ++vi) {
|
||||
CPPInstance *instance = (*vi).second;
|
||||
assert(instance != NULL);
|
||||
|
||||
if (instance->_storage_class & CPPInstance::SC_static) {
|
||||
// Static members don't count.
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the data member is not destructible, no go.
|
||||
assert(instance->_type != NULL);
|
||||
if (!instance->_type->is_destructible()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if variables of this type may be implicitly converted to
|
||||
* the other type.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
is_convertible_to(const CPPType *other) const {
|
||||
if (CPPType::is_convertible_to(other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check all typecast operators to see whether we can cast to a type that is
|
||||
// convertible to the other type.
|
||||
CPPScope::Functions::const_iterator fi;
|
||||
for (fi = _scope->_functions.begin(); fi != _scope->_functions.end(); ++fi) {
|
||||
CPPFunctionGroup *fgroup = (*fi).second;
|
||||
|
||||
CPPFunctionGroup::Instances::const_iterator ii;
|
||||
for (ii = fgroup->_instances.begin(); ii != fgroup->_instances.end(); ++ii) {
|
||||
CPPInstance *inst = (*ii);
|
||||
|
||||
if (inst->_storage_class & (CPPInstance::SC_deleted | CPPInstance::SC_static | CPPInstance::SC_explicit)) {
|
||||
// Exclude static/deleted/explicit methods.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Also, the instance needs to be publicly visible.
|
||||
if (inst->_vis > V_public) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(inst->_type != (CPPType *)NULL);
|
||||
CPPFunctionType *ftype = inst->_type->as_function_type();
|
||||
assert(ftype != (CPPFunctionType *)NULL);
|
||||
|
||||
if (ftype->_return_type != NULL &&
|
||||
(ftype->_flags & CPPFunctionType::F_operator_typecast) != 0) {
|
||||
// Yes, this is a typecast operator. Test using the return type.
|
||||
if (ftype->_return_type->is_convertible_to(other)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether any of the base classes are convertible.
|
||||
Derivation::const_iterator di;
|
||||
for (di = _derivation.begin(); di != _derivation.end(); ++di) {
|
||||
CPPStructType *base = (*di)._base->as_struct_type();
|
||||
if (base != NULL && (*di)._vis <= V_public && !base->is_convertible_to(other)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures all functions are correctly marked with the "virtual" flag if they
|
||||
* are truly virtual by virtue of inheritance, rather than simply being
|
||||
|
|
@ -420,6 +736,30 @@ check_virtual() const {
|
|||
return !funcs.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class, or any of its base classes, has a virtual
|
||||
* destructor.
|
||||
*/
|
||||
bool CPPStructType::
|
||||
has_virtual_destructor() const {
|
||||
CPPInstance *destructor = get_destructor();
|
||||
if (destructor != NULL) {
|
||||
if (destructor->_storage_class & CPPInstance::SC_virtual) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Derivation::const_iterator di;
|
||||
for (di = _derivation.begin(); di != _derivation.end(); ++di) {
|
||||
CPPStructType *base = (*di)._base->as_struct_type();
|
||||
if (base != NULL && base->has_virtual_destructor()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this declaration is an actual, factual declaration, or
|
||||
* false if some part of the declaration depends on a template parameter which
|
||||
|
|
@ -459,7 +799,7 @@ get_constructor() const {
|
|||
|
||||
/**
|
||||
* Returns the default constructor defined for the struct type, or NULL if
|
||||
* there is none.
|
||||
* there is no user-declared constructor that takes 0 arguments.
|
||||
*/
|
||||
CPPInstance *CPPStructType::
|
||||
get_default_constructor() const {
|
||||
|
|
@ -490,7 +830,7 @@ get_default_constructor() const {
|
|||
|
||||
/**
|
||||
* Returns the copy constructor defined for the struct type, or NULL if no
|
||||
* copy constructor exists.
|
||||
* user-declared copy constructor exists.
|
||||
*/
|
||||
CPPInstance *CPPStructType::
|
||||
get_copy_constructor() const {
|
||||
|
|
@ -519,7 +859,7 @@ get_copy_constructor() const {
|
|||
|
||||
/**
|
||||
* Returns the move constructor defined for the struct type, or NULL if no
|
||||
* move constructor exists.
|
||||
* user-declared move constructor exists.
|
||||
*/
|
||||
CPPInstance *CPPStructType::
|
||||
get_move_constructor() const {
|
||||
|
|
@ -548,7 +888,7 @@ get_move_constructor() const {
|
|||
|
||||
/**
|
||||
* Returns the destructor defined for the struct type, if any, or NULL if no
|
||||
* destructor is found.
|
||||
* user-declared destructor is found.
|
||||
*/
|
||||
CPPInstance *CPPStructType::
|
||||
get_destructor() const {
|
||||
|
|
@ -854,7 +1194,7 @@ get_virtual_funcs(VFunctions &funcs) const {
|
|||
CPPFunctionType *new_ftype = new_inst->_type->as_function_type();
|
||||
assert(new_ftype != (CPPFunctionType *)NULL);
|
||||
|
||||
if (new_ftype->is_equivalent_function(*base_ftype)) {
|
||||
if (new_ftype->match_virtual_override(*base_ftype)) {
|
||||
// It's a match! We now know it's virtual. Erase this function
|
||||
// from the list, so we can add it back in below.
|
||||
funcs.erase(vfi);
|
||||
|
|
|
|||
|
|
@ -44,14 +44,26 @@ public:
|
|||
CPPScope *get_scope() const;
|
||||
|
||||
bool is_abstract() const;
|
||||
bool is_base_of(const CPPStructType *other) const;
|
||||
bool is_empty() const;
|
||||
bool is_polymorphic() const;
|
||||
bool check_virtual() const;
|
||||
bool has_virtual_destructor() const;
|
||||
virtual bool is_fully_specified() const;
|
||||
virtual bool is_incomplete() const;
|
||||
virtual bool is_standard_layout() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_constructible(const CPPType *arg_type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_destructible() const;
|
||||
bool is_default_constructible(CPPVisibility min_vis) const;
|
||||
bool is_copy_constructible(CPPVisibility min_vis) const;
|
||||
bool is_move_constructible(CPPVisibility min_vis) const;
|
||||
bool is_destructible(CPPVisibility min_vis) const;
|
||||
virtual bool is_convertible_to(const CPPType *other) const;
|
||||
|
||||
inline bool is_final() const { return _final; }
|
||||
|
||||
CPPFunctionGroup *get_constructor() const;
|
||||
CPPInstance *get_default_constructor() const;
|
||||
|
|
|
|||
|
|
@ -97,8 +97,10 @@ add_template_parameter(CPPDeclaration *param) {
|
|||
CPPClassTemplateParameter *cl = param->as_class_template_parameter();
|
||||
if (cl != NULL) {
|
||||
// Create an implicit typedef for this class parameter.
|
||||
string name = cl->_ident->get_local_name();
|
||||
_types[name] = cl;
|
||||
if (cl->_ident != NULL) {
|
||||
string name = cl->_ident->get_local_name();
|
||||
_types[name] = cl;
|
||||
}
|
||||
}
|
||||
|
||||
CPPInstance *inst = param->as_instance();
|
||||
|
|
|
|||
|
|
@ -12,7 +12,12 @@
|
|||
*/
|
||||
|
||||
#include "cppType.h"
|
||||
#include "cppConstType.h"
|
||||
#include "cppPointerType.h"
|
||||
#include "cppReferenceType.h"
|
||||
#include "cppStructType.h"
|
||||
#include "cppTypedefType.h"
|
||||
#include "cppExtensionType.h"
|
||||
#include <algorithm>
|
||||
|
||||
CPPType::Types CPPType::_types;
|
||||
|
|
@ -57,6 +62,22 @@ is_tbd() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a fundamental type.
|
||||
*/
|
||||
bool CPPType::
|
||||
is_fundamental() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a standard layout type.
|
||||
*/
|
||||
bool CPPType::
|
||||
is_standard_layout() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a Plain Old Data (POD) type.
|
||||
*/
|
||||
|
|
@ -65,6 +86,14 @@ is_trivial() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type can be constructed using the given argument.
|
||||
*/
|
||||
bool CPPType::
|
||||
is_constructible(const CPPType *given_type) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is default-constructible.
|
||||
*/
|
||||
|
|
@ -81,6 +110,14 @@ is_copy_constructible() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
bool CPPType::
|
||||
is_destructible() const {
|
||||
return !is_incomplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is a special parameter expression type.
|
||||
*
|
||||
|
|
@ -92,6 +129,136 @@ is_parameter_expr() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is an enum type, or a typedef to an enum type.
|
||||
*/
|
||||
bool CPPType::
|
||||
is_enum() const {
|
||||
const CPPTypedefType *td_type = as_typedef_type();
|
||||
if (td_type != NULL) {
|
||||
return td_type->_type->is_enum();
|
||||
}
|
||||
const CPPExtensionType *ext_type = as_extension_type();
|
||||
if (ext_type != NULL) {
|
||||
return ext_type->_type == CPPExtensionType::T_enum ||
|
||||
ext_type->_type == CPPExtensionType::T_enum_struct ||
|
||||
ext_type->_type == CPPExtensionType::T_enum_class;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a const type, or a typedef to a const type.
|
||||
*/
|
||||
bool CPPType::
|
||||
is_const() const {
|
||||
const CPPTypedefType *td_type = as_typedef_type();
|
||||
if (td_type != NULL) {
|
||||
return td_type->_type->is_const();
|
||||
}
|
||||
return get_subtype() == ST_const;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a reference type, or a typedef to a reference type.
|
||||
*/
|
||||
bool CPPType::
|
||||
is_reference() const {
|
||||
const CPPTypedefType *td_type = as_typedef_type();
|
||||
if (td_type != NULL) {
|
||||
return td_type->_type->is_reference();
|
||||
}
|
||||
return get_subtype() == ST_reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is an unqualified or cv-qualified pointer type, or a
|
||||
* typedef to one.
|
||||
*/
|
||||
bool CPPType::
|
||||
is_pointer() const {
|
||||
const CPPTypedefType *td_type = as_typedef_type();
|
||||
if (td_type != NULL) {
|
||||
return td_type->_type->is_pointer();
|
||||
}
|
||||
const CPPConstType *const_type = as_const_type();
|
||||
if (const_type != NULL) {
|
||||
return const_type->_wrapped_around->is_pointer();
|
||||
}
|
||||
return get_subtype() == ST_pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type with any const qualifier stripped off. Will follow
|
||||
* typedefs, but only if necessary.
|
||||
*/
|
||||
CPPType *CPPType::
|
||||
remove_const() {
|
||||
const CPPTypedefType *td_type = as_typedef_type();
|
||||
if (td_type != NULL) {
|
||||
CPPType *unwrapped = td_type->_type->remove_const();
|
||||
if (unwrapped != td_type->_type) {
|
||||
return unwrapped;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
const CPPConstType *const_type = as_const_type();
|
||||
if (const_type != NULL) {
|
||||
return const_type->_wrapped_around->remove_const();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type with any reference stripped off.
|
||||
*/
|
||||
CPPType *CPPType::
|
||||
remove_reference() {
|
||||
const CPPTypedefType *td_type = as_typedef_type();
|
||||
if (td_type != NULL) {
|
||||
CPPType *unwrapped = td_type->_type->remove_reference();
|
||||
if (unwrapped != td_type->_type) {
|
||||
return unwrapped;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
const CPPReferenceType *ref_type = as_reference_type();
|
||||
if (ref_type != NULL) {
|
||||
return ref_type->_pointing_at;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type with any pointer and cv-qualifiers stripped off.
|
||||
*/
|
||||
CPPType *CPPType::
|
||||
remove_pointer() {
|
||||
switch (get_subtype()) {
|
||||
case ST_typedef:
|
||||
{
|
||||
const CPPTypedefType *td_type = as_typedef_type();
|
||||
CPPType *unwrapped = td_type->_type->remove_pointer();
|
||||
if (unwrapped != td_type->_type) {
|
||||
return unwrapped;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
case ST_pointer:
|
||||
return ((const CPPPointerType *)this)->_pointing_at;
|
||||
|
||||
case ST_const:
|
||||
return ((const CPPConstType *)this)->_wrapped_around->remove_pointer();
|
||||
|
||||
default:
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type has even been typedef'ed and therefore has a
|
||||
* simple name available to stand for it. Extension types are all implicitly
|
||||
|
|
@ -229,6 +396,14 @@ is_equivalent(const CPPType &other) const {
|
|||
return is_equal(&other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if variables of this type may be implicitly converted to
|
||||
* the other type.
|
||||
*/
|
||||
bool CPPType::
|
||||
is_convertible_to(const CPPType *other) const {
|
||||
return other->is_constructible(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a C++-looking line that defines an instance of the given type, with
|
||||
|
|
|
|||
|
|
@ -45,11 +45,27 @@ public:
|
|||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_tbd() const;
|
||||
virtual bool is_fundamental() const;
|
||||
virtual bool is_standard_layout() const;
|
||||
virtual bool is_trivial() const;
|
||||
virtual bool is_constructible(const CPPType *type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_destructible() const;
|
||||
virtual bool is_parameter_expr() const;
|
||||
|
||||
// Convenience methods.
|
||||
bool is_enum() const;
|
||||
bool is_const() const;
|
||||
bool is_reference() const;
|
||||
bool is_pointer() const;
|
||||
|
||||
CPPType *remove_const();
|
||||
inline CPPType *remove_volatile() { return this; }
|
||||
inline CPPType *remove_cv() { return remove_const(); };
|
||||
CPPType *remove_reference();
|
||||
CPPType *remove_pointer();
|
||||
|
||||
bool has_typedef_name() const;
|
||||
string get_typedef_name(CPPScope *scope = NULL) const;
|
||||
|
||||
|
|
@ -61,6 +77,7 @@ public:
|
|||
string get_alt_name(int n) const;
|
||||
|
||||
virtual bool is_incomplete() const;
|
||||
virtual bool is_convertible_to(const CPPType *other) const;
|
||||
virtual bool is_equivalent(const CPPType &other) const;
|
||||
|
||||
void output_instance(ostream &out, const string &name,
|
||||
|
|
|
|||
|
|
@ -157,6 +157,22 @@ is_tbd() const {
|
|||
return _type->is_tbd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a fundamental type.
|
||||
*/
|
||||
bool CPPTypedefType::
|
||||
is_fundamental() const {
|
||||
return _type->is_fundamental();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a standard layout type.
|
||||
*/
|
||||
bool CPPTypedefType::
|
||||
is_standard_layout() const {
|
||||
return _type->is_standard_layout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is considered a Plain Old Data (POD) type.
|
||||
*/
|
||||
|
|
@ -165,6 +181,14 @@ is_trivial() const {
|
|||
return _type->is_trivial();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type can be constructed using the given argument.
|
||||
*/
|
||||
bool CPPTypedefType::
|
||||
is_constructible(const CPPType *given_type) const {
|
||||
return _type->is_constructible(given_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is default-constructible.
|
||||
*/
|
||||
|
|
@ -181,6 +205,14 @@ is_copy_constructible() const {
|
|||
return _type->is_copy_constructible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
bool CPPTypedefType::
|
||||
is_destructible() const {
|
||||
return _type->is_destructible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this declaration is an actual, factual declaration, or
|
||||
* false if some part of the declaration depends on a template parameter which
|
||||
|
|
@ -300,6 +332,15 @@ resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if variables of this type may be implicitly converted to
|
||||
* the other type.
|
||||
*/
|
||||
bool CPPTypedefType::
|
||||
is_convertible_to(const CPPType *other) const {
|
||||
return _type->is_convertible_to(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -42,9 +42,13 @@ public:
|
|||
|
||||
virtual bool is_incomplete() 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_constructible(const CPPType *type) const;
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_destructible() const;
|
||||
|
||||
virtual bool is_fully_specified() const;
|
||||
|
||||
|
|
@ -60,6 +64,7 @@ public:
|
|||
virtual CPPType *resolve_type(CPPScope *current_scope,
|
||||
CPPScope *global_scope);
|
||||
|
||||
virtual bool is_convertible_to(const CPPType *other) const;
|
||||
virtual bool is_equivalent(const CPPType &other) const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ allocate(size_t size, TypeHandle type_handle) {
|
|||
assert(size <= _buffer_size);
|
||||
|
||||
// Determine how much space to allocate.
|
||||
const size_t alloc_size = _buffer_size + flag_reserved_bytes;
|
||||
const size_t alloc_size = _buffer_size + flag_reserved_bytes + MemoryHook::get_memory_alignment() - 1;
|
||||
|
||||
ObjectNode *obj;
|
||||
|
||||
|
|
@ -69,7 +69,10 @@ allocate(size_t size, TypeHandle type_handle) {
|
|||
// If we get here, the deleted_chain is empty; we have to allocate a new
|
||||
// object from the system pool.
|
||||
|
||||
obj = (ObjectNode *)NeverFreeMemory::alloc(alloc_size);
|
||||
// Allocate memory, and make sure the object starts at the proper alignment.
|
||||
void *mem = NeverFreeMemory::alloc(alloc_size);
|
||||
intptr_t pad = (-(intptr_t)flag_reserved_bytes - (intptr_t)mem) % MemoryHook::get_memory_alignment();
|
||||
obj = (ObjectNode *)((uintptr_t)mem + pad);
|
||||
|
||||
#ifdef USE_DELETEDCHAINFLAG
|
||||
obj->_flag = DCF_alive;
|
||||
|
|
@ -77,6 +80,10 @@ allocate(size_t size, TypeHandle type_handle) {
|
|||
|
||||
void *ptr = node_to_buffer(obj);
|
||||
|
||||
#ifndef NDEBUG
|
||||
assert(((uintptr_t)ptr % MemoryHook::get_memory_alignment()) == 0);
|
||||
#endif
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size);
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
|
|
|||
|
|
@ -95,12 +95,8 @@ private:
|
|||
// Without DELETEDCHAINFLAG, we don't even store the _flag member at all.
|
||||
static const size_t flag_reserved_bytes = 0;
|
||||
|
||||
#elif defined(LINMATH_ALIGN)
|
||||
// With SSE2 alignment, we need all 16 bytes to preserve alignment.
|
||||
static const size_t flag_reserved_bytes = 16;
|
||||
|
||||
#else
|
||||
// Otherwise, we only need enough space for the Integer itself.
|
||||
// Otherwise, we need space for the integer.
|
||||
static const size_t flag_reserved_bytes = sizeof(AtomicAdjust::Integer);
|
||||
#endif // USE_DELETEDCHAINFLAG
|
||||
|
||||
|
|
|
|||
|
|
@ -339,21 +339,26 @@ typedef struct _object PyObject;
|
|||
#define ALIGN_4BYTE
|
||||
#define ALIGN_8BYTE
|
||||
#define ALIGN_16BYTE
|
||||
#define ALIGN_32BYTE
|
||||
#define ALIGN_64BYTE
|
||||
#elif defined(_MSC_VER)
|
||||
#define ALIGN_4BYTE __declspec(align(4))
|
||||
#define ALIGN_8BYTE __declspec(align(8))
|
||||
#define ALIGN_16BYTE __declspec(align(16))
|
||||
#define ALIGN_32BYTE __declspec(align(32))
|
||||
#define ALIGN_64BYTE __declspec(align(64))
|
||||
#elif defined(__GNUC__)
|
||||
#define ALIGN_4BYTE __attribute__ ((aligned (4)))
|
||||
#define ALIGN_8BYTE __attribute__ ((aligned (8)))
|
||||
#define ALIGN_16BYTE __attribute__ ((aligned (16)))
|
||||
#define ALIGN_32BYTE __attribute__ ((aligned (32)))
|
||||
#define ALIGN_64BYTE __attribute__ ((aligned (64)))
|
||||
#else
|
||||
#define ALIGN_4BYTE
|
||||
#define ALIGN_8BYTE
|
||||
#define ALIGN_16BYTE
|
||||
#define ALIGN_32BYTE
|
||||
#define ALIGN_64BYTE
|
||||
#endif
|
||||
|
||||
// Do we need to implement memory-alignment enforcement within the MemoryHook
|
||||
|
|
@ -374,7 +379,7 @@ typedef struct _object PyObject;
|
|||
// externally.
|
||||
#define MEMORY_HOOK_DO_ALIGN 1
|
||||
|
||||
#elif defined(IS_OSX) || defined(_WIN64)
|
||||
#elif (defined(IS_OSX) || defined(_WIN64)) && !defined(__AVX__)
|
||||
// The OS-provided malloc implementation will do the required alignment.
|
||||
#undef MEMORY_HOOK_DO_ALIGN
|
||||
|
||||
|
|
|
|||
|
|
@ -43,10 +43,16 @@ get_memory_alignment() {
|
|||
#ifdef LINMATH_ALIGN
|
||||
// We require 16-byte alignment of certain structures, to support SSE2. We
|
||||
// don't strictly have to align *everything*, but it's just easier to do so.
|
||||
const size_t alignment_size = 16;
|
||||
#ifdef __AVX__
|
||||
// Eigen requires 32-byte alignment when using AVX instructions.
|
||||
const size_t alignment_size = 32;
|
||||
#else
|
||||
// Otherwise, use word alignment.
|
||||
const size_t alignment_size = sizeof(void *);
|
||||
const size_t alignment_size = 16;
|
||||
#endif
|
||||
#else
|
||||
// Otherwise, align to two words. This seems to be pretty standard to the
|
||||
// point where some code may rely on this being the case.
|
||||
const size_t alignment_size = sizeof(void *) * 2;
|
||||
#endif
|
||||
return alignment_size;
|
||||
}
|
||||
|
|
@ -64,7 +70,12 @@ get_header_reserved_bytes() {
|
|||
#ifdef LINMATH_ALIGN
|
||||
// If we're doing SSE2 alignment, we must reserve a full 16-byte block,
|
||||
// since anything less than that will spoil the alignment.
|
||||
#ifdef __AVX__
|
||||
// Eigen requires 32-byte alignment when using AVX instructions.
|
||||
static const size_t header_reserved_bytes = 32;
|
||||
#else
|
||||
static const size_t header_reserved_bytes = 16;
|
||||
#endif
|
||||
|
||||
#elif defined(MEMORY_HOOK_DO_ALIGN)
|
||||
// If we're just aligning to words, we reserve a block as big as two words,
|
||||
|
|
@ -72,8 +83,9 @@ get_header_reserved_bytes() {
|
|||
static const size_t header_reserved_bytes = sizeof(size_t) + sizeof(size_t);
|
||||
|
||||
#else
|
||||
// If we're not aligning, we just need space for the word itself.
|
||||
static const size_t header_reserved_bytes = sizeof(size_t);
|
||||
// Virtually all allocators align to two words, so we make sure we preserve
|
||||
// that alignment for the benefit of anyone who relies upon that.
|
||||
static const size_t header_reserved_bytes = sizeof(void *) * 2;
|
||||
#endif
|
||||
|
||||
return header_reserved_bytes;
|
||||
|
|
|
|||
|
|
@ -53,8 +53,13 @@
|
|||
// drose: We require 16-byte alignment of certain structures, to
|
||||
// support SSE2. We don't strictly have to align *everything*, but
|
||||
// it's just easier to do so.
|
||||
#ifdef __AVX__
|
||||
// Eigen requires 32-byte alignment when using AVX instructions.
|
||||
#define MALLOC_ALIGNMENT ((size_t)32U)
|
||||
#else
|
||||
#define MALLOC_ALIGNMENT ((size_t)16U)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "dlmalloc_src.cxx"
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
/**
|
||||
* Returns a pointer to a newly-allocated block of memory of the indicated
|
||||
* size.
|
||||
*
|
||||
* Please note that the resulting pointer is not aligned to any boundary.
|
||||
*/
|
||||
INLINE void *NeverFreeMemory::
|
||||
alloc(size_t size) {
|
||||
|
|
|
|||
|
|
@ -39,13 +39,9 @@ void *NeverFreeMemory::
|
|||
ns_alloc(size_t size) {
|
||||
_lock.acquire();
|
||||
|
||||
// We always allocate integer multiples of this many bytes, to guarantee
|
||||
// this minimum alignment.
|
||||
static const size_t alignment_size = MemoryHook::get_memory_alignment();
|
||||
|
||||
// Round up to the next alignment_size.
|
||||
size = ((size + alignment_size - 1) / alignment_size) * alignment_size;
|
||||
|
||||
//NB: we no longer do alignment here. The only class that uses this is
|
||||
// DeletedBufferChain, and we can do the alignment potentially more
|
||||
// efficiently there since we don't end up overallocating as much.
|
||||
_total_used += size;
|
||||
|
||||
// Look for a page that has sufficient space remaining.
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
/checkPandaVersion.cxx
|
||||
/checkPandaVersion.h
|
||||
/pandaVersion.h
|
||||
|
|
@ -38,7 +38,6 @@ Filename(const char *filename) {
|
|||
(*this) = filename;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -84,6 +83,20 @@ Filename(Filename &&from) NOEXCEPT :
|
|||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
/**
|
||||
* Creates an empty Filename.
|
||||
*/
|
||||
INLINE Filename::
|
||||
Filename() :
|
||||
_dirname_end(0),
|
||||
_basename_start(0),
|
||||
_basename_end(string::npos),
|
||||
_extension_start(string::npos),
|
||||
_hash_start(string::npos),
|
||||
_hash_end(string::npos),
|
||||
_flags(0) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -155,14 +168,6 @@ pattern_filename(const string &filename) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE Filename::
|
||||
~Filename() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -233,7 +238,7 @@ operator = (string &&filename) NOEXCEPT {
|
|||
*/
|
||||
INLINE Filename &Filename::
|
||||
operator = (Filename &&from) NOEXCEPT {
|
||||
_filename = MOVE(from._filename);
|
||||
_filename = move(from._filename);
|
||||
_dirname_end = from._dirname_end;
|
||||
_basename_start = from._basename_start;
|
||||
_basename_end = from._basename_end;
|
||||
|
|
|
|||
|
|
@ -55,20 +55,22 @@ public:
|
|||
};
|
||||
|
||||
INLINE Filename(const char *filename);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE Filename(const string &filename = "");
|
||||
INLINE Filename(const string &filename);
|
||||
INLINE Filename(const wstring &filename);
|
||||
INLINE Filename(const Filename ©);
|
||||
Filename(const Filename &dirname, const Filename &basename);
|
||||
INLINE ~Filename();
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE Filename(string &&filename) NOEXCEPT;
|
||||
INLINE Filename(Filename &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
PUBLISHED:
|
||||
INLINE Filename();
|
||||
Filename(const Filename &dirname, const Filename &basename);
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
EXTENSION(Filename(PyObject *path));
|
||||
|
||||
EXTENSION(PyObject *__reduce__(PyObject *self) const);
|
||||
#endif
|
||||
|
||||
|
|
@ -118,6 +120,7 @@ PUBLISHED:
|
|||
INLINE char operator [] (size_t n) const;
|
||||
|
||||
EXTENSION(PyObject *__repr__() const);
|
||||
EXTENSION(PyObject *__fspath__() const);
|
||||
|
||||
INLINE string substr(size_t begin) const;
|
||||
INLINE string substr(size_t begin, size_t end) const;
|
||||
|
|
|
|||
|
|
@ -2344,7 +2344,7 @@ write_module_class(ostream &out, Object *obj) {
|
|||
|
||||
string expected_params;
|
||||
|
||||
out << " if (arg2 != (PyObject *)NULL) {\n";
|
||||
out << " if (arg2 != (PyObject *)NULL && arg2 != Py_None) {\n";
|
||||
out << " PyObject *args = PyTuple_Pack(2, arg, arg2);\n";
|
||||
write_function_forset(out, two_param_remaps, 2, 2, expected_params, 4,
|
||||
true, true, AT_varargs, RF_pyobject | RF_err_null | RF_decref_args, true);
|
||||
|
|
@ -6142,7 +6142,7 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
|
|||
|
||||
write_python_instance(out, indent_level, return_expr, owns_memory, itype, is_const);
|
||||
}
|
||||
} else if (TypeManager::is_struct(orig_type->as_pointer_type()->_pointing_at)) {
|
||||
} else if (TypeManager::is_struct(orig_type->remove_pointer())) {
|
||||
TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)),false);
|
||||
const InterrogateType &itype = idb->get_type(type_index);
|
||||
|
||||
|
|
@ -6749,6 +6749,8 @@ is_cpp_type_legal(CPPType *in_ctype) {
|
|||
return true;
|
||||
} else if (TypeManager::is_pointer_to_simple(type)) {
|
||||
return true;
|
||||
} else if (builder.in_forcetype(type->get_local_name(&parser))) {
|
||||
return true;
|
||||
} else if (TypeManager::is_exported(type)) {
|
||||
return true;
|
||||
} else if (TypeManager::is_pointer_to_PyObject(in_ctype)) {
|
||||
|
|
|
|||
|
|
@ -2401,7 +2401,7 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
|||
|
||||
cpptype = TypeManager::resolve_type(cpptype)->as_struct_type();
|
||||
assert(cpptype != (CPPStructType *)NULL);
|
||||
bool has_virt_methods = cpptype->check_virtual();
|
||||
bool has_virt_methods = cpptype->is_polymorphic();
|
||||
|
||||
switch (cpptype->_type) {
|
||||
case CPPExtensionType::T_class:
|
||||
|
|
@ -2501,7 +2501,7 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
|||
// (For many compilers, this does not require a pointer change.)
|
||||
generate_casts = true;
|
||||
|
||||
} else if (has_virt_methods && (base_type->as_struct_type() == (CPPStructType *)NULL || !base_type->as_struct_type()->check_virtual())) {
|
||||
} else if (has_virt_methods && (base_type->as_struct_type() == (CPPStructType *)NULL || !base_type->as_struct_type()->is_polymorphic())) {
|
||||
// Finally, if this class has virtual methods, but its parent
|
||||
// doesn't, then we have to upcast (because this class will require
|
||||
// space for a virtual function table pointer, while the parent
|
||||
|
|
@ -2651,7 +2651,11 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
|
|||
}
|
||||
}
|
||||
|
||||
if ((itype._flags & InterrogateType::F_inherited_destructor) != 0) {
|
||||
if (!cpptype->is_destructible()) {
|
||||
// There's no way to destruct the type.
|
||||
itype._destructor = 0;
|
||||
|
||||
} else if ((itype._flags & InterrogateType::F_inherited_destructor) != 0) {
|
||||
// If we have inherited our virtual destructor from our base class, go
|
||||
// ahead and assign the same function index.
|
||||
assert(!itype._derivations.empty());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,153 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file functional
|
||||
* @author tobspr
|
||||
* @date 2016-11-01
|
||||
*/
|
||||
|
||||
// This file, and all the other files in this directory, aren't
|
||||
// intended to be compiled--they're just parsed by CPPParser (and
|
||||
// interrogate) in lieu of the actual system headers, to generate the
|
||||
// interrogate database.
|
||||
|
||||
#ifndef FUNCTIONAL_H
|
||||
#define FUNCTIONAL_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace std {
|
||||
|
||||
// base (deprecated):
|
||||
template <class Arg, class Result> struct unary_function;
|
||||
template <class Arg1, class Arg2, class Result> struct binary_function;
|
||||
|
||||
// reference_wrapper:
|
||||
template <class T> class reference_wrapper;
|
||||
|
||||
// arithmetic operations:
|
||||
template <class T> struct plus;
|
||||
template <class T> struct minus;
|
||||
template <class T> struct multiplies;
|
||||
template <class T> struct divides;
|
||||
template <class T> struct modulus;
|
||||
template <class T> struct negate;
|
||||
|
||||
// comparisons:
|
||||
template <class T> struct equal_to;
|
||||
template <class T> struct not_equal_to;
|
||||
template <class T> struct greater;
|
||||
template <class T> struct less;
|
||||
template <class T> struct greater_equal;
|
||||
template <class T> struct less_equal;
|
||||
|
||||
// logical operations:
|
||||
template <class T> struct logical_and;
|
||||
template <class T> struct logical_or;
|
||||
template <class T> struct logical_not;
|
||||
|
||||
// bitwise operations:
|
||||
template <class T> struct bit_and;
|
||||
template <class T> struct bit_or;
|
||||
template <class T> struct bit_xor;
|
||||
|
||||
// negators:
|
||||
template <class Predicate> class unary_negate;
|
||||
template <class Predicate> class binary_negate;
|
||||
|
||||
// bind:
|
||||
template<class T> struct is_bind_expression;
|
||||
template<class T> struct is_placeholder;
|
||||
|
||||
namespace placeholders {
|
||||
// M is the implementation-defined number of placeholders
|
||||
// (8 should be enough for interrogate)
|
||||
extern char _1;
|
||||
extern char _2;
|
||||
extern char _3;
|
||||
extern char _4;
|
||||
extern char _5;
|
||||
extern char _6;
|
||||
extern char _7;
|
||||
extern char _8;
|
||||
}
|
||||
|
||||
// binders (deprecated):
|
||||
template <class Fn> class binder1st;
|
||||
template <class Fn> class binder2nd;
|
||||
|
||||
// adaptors (deprecated):
|
||||
template <class Arg, class Result> class pointer_to_unary_function;
|
||||
template <class Arg1, class Arg2, class Result>
|
||||
class pointer_to_binary_function;
|
||||
|
||||
// adaptors (deprecated):
|
||||
template<class S, class T> class mem_fun_t;
|
||||
template<class S, class T, class A> class mem_fun1_t;
|
||||
template<class S, class T> class mem_fun_ref_t;
|
||||
template<class S, class T, class A> class mem_fun1_ref_t;
|
||||
template <class S, class T> class const_mem_fun_t;
|
||||
template <class S, class T, class A> class const_mem_fun1_t;
|
||||
template <class S, class T> class const_mem_fun_ref_t;
|
||||
template <class S, class T, class A> class const_mem_fun1_ref_t;
|
||||
|
||||
|
||||
// polymorphic function wrappers:
|
||||
class bad_function_call;
|
||||
|
||||
// hash function base template:
|
||||
template <class T> struct hash;
|
||||
|
||||
// Hash function specializations
|
||||
template <> struct hash<bool>;
|
||||
template <> struct hash<char>;
|
||||
template <> struct hash<signed char>;
|
||||
template <> struct hash<unsigned char>;
|
||||
template <> struct hash<char16_t>;
|
||||
template <> struct hash<char32_t>;
|
||||
template <> struct hash<wchar_t>;
|
||||
template <> struct hash<short>;
|
||||
template <> struct hash<unsigned short>;
|
||||
template <> struct hash<int>;
|
||||
template <> struct hash<unsigned int>;
|
||||
template <> struct hash<long>;
|
||||
template <> struct hash<long long>;
|
||||
template <> struct hash<unsigned long>;
|
||||
template <> struct hash<unsigned long long>;
|
||||
template <> struct hash<float>;
|
||||
template <> struct hash<double>;
|
||||
template <> struct hash<long double>;
|
||||
template<class T> struct hash<T*>;
|
||||
|
||||
template <class T> class reference_wrapper {
|
||||
public :
|
||||
// types
|
||||
typedef T type;
|
||||
typedef void result_type; // not always defined
|
||||
typedef void argument_type; // not always defined
|
||||
typedef void first_argument_type; // not always defined
|
||||
typedef void second_argument_type; // not always defined
|
||||
};
|
||||
|
||||
template<class T> struct is_bind_expression {};
|
||||
// : integral_constant<bool, true> {};
|
||||
|
||||
class bad_function_call : public std::exception {};
|
||||
|
||||
// template<class> class function; // undefined
|
||||
|
||||
template< class R, class... ArgTypes >
|
||||
class function {
|
||||
public:
|
||||
typedef R result_type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file initializer_list
|
||||
* @author tobspr
|
||||
* @date 2016-11-01
|
||||
*/
|
||||
|
||||
// This file, and all the other files in this directory, aren't
|
||||
// intended to be compiled--they're just parsed by CPPParser (and
|
||||
// interrogate) in lieu of the actual system headers, to generate the
|
||||
// interrogate database.
|
||||
|
||||
#ifndef INITIALIZER_LIST_H
|
||||
#define INITIALIZER_LIST_H
|
||||
|
||||
#include <stdtypedefs.h>
|
||||
|
||||
namespace std {
|
||||
template<class E> class initializer_list {
|
||||
public:
|
||||
typedef E value_type;
|
||||
typedef const E& reference;
|
||||
typedef const E& const_reference;
|
||||
typedef size_t size_type;
|
||||
typedef const E* iterator;
|
||||
typedef const E* const_iterator;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,16 +1,15 @@
|
|||
// Filename: allocator
|
||||
// Created by: drose (12May00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file memory
|
||||
* @author tobspr
|
||||
* @date 2016-11-01
|
||||
*/
|
||||
|
||||
// This file, and all the other files in this directory, aren't
|
||||
// intended to be compiled--they're just parsed by CPPParser (and
|
||||
|
|
@ -21,6 +20,8 @@
|
|||
#define ALLOCATOR_H
|
||||
|
||||
#include <stdtypedefs.h>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
#ifdef GCC_STYLE_ALLOCATOR
|
||||
|
||||
|
|
@ -33,16 +34,155 @@ public:
|
|||
#else // GCC_STYLE_ALLOCATOR
|
||||
|
||||
namespace std {
|
||||
template<class Type>
|
||||
class allocator {
|
||||
public:
|
||||
typedef Type *pointer;
|
||||
typedef const Type *const_pointer;
|
||||
typedef size_t size_type;
|
||||
|
||||
pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
|
||||
void deallocate(pointer p, size_type n);
|
||||
};
|
||||
// pointer traits
|
||||
template <class Ptr> struct pointer_traits;
|
||||
template <class T> struct pointer_traits<T*>;
|
||||
|
||||
// pointer safety
|
||||
enum class pointer_safety { relaxed, preferred, strict };
|
||||
|
||||
// allocator argument tag
|
||||
struct allocator_arg_t { };
|
||||
constexpr allocator_arg_t allocator_arg = allocator_arg_t();
|
||||
|
||||
// uses_allocator
|
||||
template <class T, class Alloc> struct uses_allocator;
|
||||
|
||||
// allocator traits
|
||||
template <class Alloc> struct allocator_traits;
|
||||
|
||||
// the default allocator:
|
||||
template <class T> class allocator;
|
||||
template <> class allocator<void>;
|
||||
|
||||
// raw storage iterator:
|
||||
template <class OutputIterator, class T> class raw_storage_iterator;
|
||||
|
||||
// class template unique_ptr:
|
||||
template <class T> class default_delete;
|
||||
template <class T> class default_delete<T[]>;
|
||||
template <class T, class D = default_delete<T>> class unique_ptr;
|
||||
template <class T, class D> class unique_ptr<T[], D>;
|
||||
// class bad_weak_ptr:
|
||||
class bad_weak_ptr;
|
||||
|
||||
// class template shared_ptr:
|
||||
template<class T> class shared_ptr;
|
||||
// class template weak_ptr:
|
||||
template<class T> class weak_ptr;
|
||||
|
||||
// class template owner_less:
|
||||
template<class T> class owner_less;
|
||||
|
||||
// class template enable_shared_from_this:
|
||||
template<class T> class enable_shared_from_this;
|
||||
|
||||
// hash support
|
||||
template <class T> struct hash;
|
||||
template <class T, class D> struct hash<unique_ptr<T, D> >;
|
||||
template <class T> struct hash<shared_ptr<T> >;
|
||||
|
||||
// auto_ptr (deprecated)
|
||||
template <class X> class auto_ptr;
|
||||
|
||||
template <class Ptr> struct pointer_traits {
|
||||
typedef Ptr pointer;
|
||||
typedef Ptr element_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
template <class U> using rebind = U;
|
||||
};
|
||||
|
||||
template <class T> struct pointer_traits<T*> {
|
||||
typedef T* pointer;
|
||||
typedef T element_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
template <class U> using rebind = U*;
|
||||
};
|
||||
|
||||
|
||||
template <class Alloc> struct allocator_traits {
|
||||
typedef Alloc allocator_type;
|
||||
|
||||
typedef typename Alloc::value_type value_type;
|
||||
|
||||
typedef void* pointer;
|
||||
typedef const void* const_pointer;
|
||||
typedef void* void_pointer;
|
||||
typedef const void* const_void_pointer;
|
||||
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef size_t size_type;
|
||||
|
||||
struct propagate_on_container_copy_assignment;
|
||||
struct propagate_on_container_move_assignment;
|
||||
struct propagate_on_container_swap;
|
||||
struct is_always_equal;
|
||||
|
||||
template <class T> using rebind_alloc = size_t;
|
||||
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
|
||||
};
|
||||
|
||||
template <class T> class allocator;
|
||||
// specialize for void:
|
||||
template <> class allocator<void> {
|
||||
public:
|
||||
typedef void* pointer;
|
||||
typedef const void* const_pointer;
|
||||
// reference-to-void members are impossible.
|
||||
typedef void value_type;
|
||||
template <class U> struct rebind { typedef allocator<U> other; };
|
||||
};
|
||||
template <class T> class allocator {
|
||||
public:
|
||||
struct true_type_; // do not depend on type_traits header
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
template <class U> struct rebind { typedef allocator<U> other; };
|
||||
typedef true_type_ propagate_on_container_move_assignment;
|
||||
typedef true_type_ is_always_equal;
|
||||
|
||||
};
|
||||
|
||||
template <class OutputIterator, class T>
|
||||
class raw_storage_iterator
|
||||
: public iterator<output_iterator_tag,void,void,void,void> {
|
||||
public:
|
||||
};
|
||||
|
||||
|
||||
template <class T> struct default_delete {};
|
||||
|
||||
template <class T> struct default_delete<T[]> {};
|
||||
|
||||
// unique_ptr for single objects
|
||||
template <class T, class D = default_delete<T>> class unique_ptr {
|
||||
public:
|
||||
typedef T* pointer;
|
||||
typedef T element_type;
|
||||
typedef D deleter_type;
|
||||
};
|
||||
|
||||
class bad_weak_ptr: public std::exception {};
|
||||
|
||||
template<class T> class shared_ptr {
|
||||
public:
|
||||
typedef T element_type;
|
||||
};
|
||||
|
||||
template<class T> class weak_ptr {
|
||||
public:
|
||||
typedef T element_type;
|
||||
};
|
||||
|
||||
template<class T> class enable_shared_from_this {};
|
||||
}
|
||||
|
||||
#endif // GCC_STYLE_ALLOCATOR
|
||||
|
|
|
|||
|
|
@ -20,25 +20,45 @@
|
|||
#define __WORDSIZE 32
|
||||
#endif
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef short int int16_t;
|
||||
typedef int int32_t;
|
||||
typedef long long int int64_t;
|
||||
using intmax_t = long long int;
|
||||
using uintmax_t = unsigned long long int;
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long int uint64_t;
|
||||
using int8_t = signed char;
|
||||
using int16_t = short int;
|
||||
using int32_t = int;
|
||||
using int64_t = long long int;
|
||||
|
||||
typedef long long int intmax_t;
|
||||
typedef unsigned long long int uintmax_t;
|
||||
using uint8_t = unsigned char;
|
||||
using uint16_t = unsigned short int;
|
||||
using uint32_t = unsigned int;
|
||||
using uint64_t = unsigned long long int;
|
||||
|
||||
using int_least8_t = int8_t;
|
||||
using int_least16_t = int16_t;
|
||||
using int_least32_t = int32_t;
|
||||
using int_least64_t = int64_t;
|
||||
|
||||
using uint_least8_t = uint8_t;
|
||||
using uint_least16_t = uint16_t;
|
||||
using uint_least32_t = uint32_t;
|
||||
using uint_least64_t = uint64_t;
|
||||
|
||||
using int_fast8_t = int8_t;
|
||||
using int_fast16_t = int16_t;
|
||||
using int_fast32_t = int32_t;
|
||||
using int_fast64_t = int64_t;
|
||||
|
||||
using uint_fast8_t = uint8_t;
|
||||
using uint_fast16_t = uint16_t;
|
||||
using uint_fast32_t = uint32_t;
|
||||
using uint_fast64_t = uint64_t;
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
typedef int64_t intptr_t;
|
||||
typedef uint64_t uintptr_t;
|
||||
using intptr_t = int64_t;
|
||||
using uintptr_t = uint64_t;
|
||||
#else
|
||||
typedef int32_t intptr_t;
|
||||
typedef uint32_t uintptr_t;
|
||||
using intptr_t = int32_t;
|
||||
using uintptr_t = uint32_t;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ inline namespace std {
|
|||
#endif
|
||||
}
|
||||
|
||||
struct timeval;
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define NULL 0L
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdtypedefs.h>
|
||||
|
||||
namespace std {
|
||||
template<class T, T v>
|
||||
struct integral_constant {
|
||||
static constexpr T value = v;
|
||||
typedef T value_type;
|
||||
constexpr operator value_type() const noexcept { return value; }
|
||||
constexpr value_type operator()() const noexcept { return value; }
|
||||
};
|
||||
|
||||
typedef integral_constant<bool, true> true_type;
|
||||
typedef integral_constant<bool, false> false_type;
|
||||
|
||||
template<class T, class U>
|
||||
struct is_same : std::false_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_same<T, T> : std::true_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_void : std::false_type {};
|
||||
|
||||
template<>
|
||||
struct is_void<void> : std::true_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_enum : integral_constant<bool, __is_enum(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_union : integral_constant<bool, __is_union(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_class : integral_constant<bool, __is_class(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_fundamental : integral_constant<bool, __is_fundamental(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_compound : integral_constant<bool, !__is_fundamental(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_trivial : integral_constant<bool, __is_trivial(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_standard_layout : integral_constant<bool, __is_standard_layout(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_pod : integral_constant<bool, __is_pod(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_empty : integral_constant<bool, __is_empty(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_polymorphic : integral_constant<bool, __is_polymorphic(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_abstract : integral_constant<bool, __is_abstract(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_final : integral_constant<bool, __is_final(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_default_constructible : integral_constant<bool, __is_constructible(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_copy_constructible : integral_constant<bool, __is_constructible(T, const T&)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_move_constructible : integral_constant<bool, __is_constructible(T, const T&&)> {};
|
||||
|
||||
template<class T>
|
||||
struct is_destructible : integral_constant<bool, __is_destructible(T)> {};
|
||||
|
||||
template<class T>
|
||||
struct has_virtual_destructor : integral_constant<bool, __has_virtual_destructor(T)> {};
|
||||
|
||||
template<class T >
|
||||
struct alignment_of : std::integral_constant<std::size_t, alignof(T)> {};
|
||||
|
||||
template<class T, class U>
|
||||
struct is_base_of : integral_constant<bool, __is_base_of(T, U)> {};
|
||||
|
||||
template<class T, class U>
|
||||
struct is_convertible : integral_constant<bool, __is_convertible_to(T, U)> {};
|
||||
|
||||
template<class T> struct add_cv { typedef const volatile T type; };
|
||||
template<class T> struct add_const { typedef const T type; };
|
||||
template<class T> struct add_volatile { typedef volatile T type; };
|
||||
|
||||
template<class T> struct add_lvalue_reference { typedef T &type; };
|
||||
template<class T> struct add_rvalue_reference { typedef T &&type; };
|
||||
template<class T> struct add_pointer { typedef T *type; };
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file unordered_map
|
||||
* @author tobspr
|
||||
* @date 2016-11-01
|
||||
*/
|
||||
|
||||
// This file, and all the other files in this directory, aren't
|
||||
// intended to be compiled--they're just parsed by CPPParser (and
|
||||
// interrogate) in lieu of the actual system headers, to generate the
|
||||
// interrogate database.
|
||||
|
||||
#ifndef UNORDERED_MAP_H
|
||||
#define UNORDERED_MAP_H
|
||||
|
||||
#include <stdtypedefs.h>
|
||||
#include <stdcompare.h>
|
||||
#include <pair>
|
||||
#include <initializer_list>
|
||||
#include <functional>
|
||||
|
||||
namespace std {
|
||||
|
||||
template <class Key,
|
||||
class T,
|
||||
class Hash = hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> > >
|
||||
class unordered_map
|
||||
{
|
||||
public:
|
||||
// types
|
||||
typedef Key key_type;
|
||||
typedef Key value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Allocator allocator_type;
|
||||
typedef typename allocator_type::pointer pointer;
|
||||
typedef typename allocator_type::const_pointer const_pointer;
|
||||
typedef typename allocator_type::reference reference;
|
||||
typedef typename allocator_type::const_reference const_reference;
|
||||
typedef size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
class local_iterator;
|
||||
class const_local_iterator;
|
||||
};
|
||||
|
||||
template <class Key,
|
||||
class T,
|
||||
class Hash = hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> > >
|
||||
class unordered_multimap
|
||||
{
|
||||
public:
|
||||
// types
|
||||
typedef Key key_type;
|
||||
typedef Key value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Allocator allocator_type;
|
||||
typedef typename allocator_type::pointer pointer;
|
||||
typedef typename allocator_type::const_pointer const_pointer;
|
||||
typedef typename allocator_type::reference reference;
|
||||
typedef typename allocator_type::const_reference const_reference;
|
||||
typedef size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
class local_iterator;
|
||||
class const_local_iterator;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file unordered_set
|
||||
* @author tobspr
|
||||
* @date 2016-11-01
|
||||
*/
|
||||
|
||||
// This file, and all the other files in this directory, aren't
|
||||
// intended to be compiled--they're just parsed by CPPParser (and
|
||||
// interrogate) in lieu of the actual system headers, to generate the
|
||||
// interrogate database.
|
||||
|
||||
#ifndef UNORDERED_SET_H
|
||||
#define UNORDERED_SET_H
|
||||
|
||||
#include <stdtypedefs.h>
|
||||
#include <stdcompare.h>
|
||||
#include <pair>
|
||||
#include <initializer_list>
|
||||
#include <functional>
|
||||
|
||||
namespace std {
|
||||
|
||||
template <class Key,
|
||||
class Hash = hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Allocator = std::allocator<Key> >
|
||||
class unordered_set
|
||||
{
|
||||
public:
|
||||
// types
|
||||
typedef Key key_type;
|
||||
typedef Key value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Allocator allocator_type;
|
||||
typedef typename allocator_type::pointer pointer;
|
||||
typedef typename allocator_type::const_pointer const_pointer;
|
||||
typedef typename allocator_type::reference reference;
|
||||
typedef typename allocator_type::const_reference const_reference;
|
||||
typedef size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
class local_iterator;
|
||||
class const_local_iterator;
|
||||
};
|
||||
|
||||
template <class Key,
|
||||
class Hash = hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Allocator = std::allocator<Key> >
|
||||
class unordered_multiset
|
||||
{
|
||||
public:
|
||||
// types
|
||||
typedef Key key_type;
|
||||
typedef Key value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Allocator allocator_type;
|
||||
typedef typename allocator_type::pointer pointer;
|
||||
typedef typename allocator_type::const_pointer const_pointer;
|
||||
typedef typename allocator_type::reference reference;
|
||||
typedef typename allocator_type::const_reference const_reference;
|
||||
typedef size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
class local_iterator;
|
||||
class const_local_iterator;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
struct __m128;
|
||||
|
|
@ -1 +0,0 @@
|
|||
/prc_parameters.h
|
||||
|
|
@ -73,8 +73,8 @@ EncryptStreamBuf() {
|
|||
_key_length = encryption_key_length;
|
||||
_iteration_count = encryption_iteration_count;
|
||||
|
||||
_read_valid = false;
|
||||
_write_valid = false;
|
||||
_read_ctx = NULL;
|
||||
_write_ctx = NULL;
|
||||
|
||||
_read_overflow_buffer = NULL;
|
||||
_in_read_overflow_buffer = 0;
|
||||
|
|
@ -110,7 +110,11 @@ open_read(istream *source, bool owns_source, const string &password) {
|
|||
|
||||
_source = source;
|
||||
_owns_source = owns_source;
|
||||
_read_valid = false;
|
||||
|
||||
if (_read_ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(_read_ctx);
|
||||
_read_ctx = NULL;
|
||||
}
|
||||
|
||||
// Now read the header information.
|
||||
StreamReader sr(_source, false);
|
||||
|
|
@ -143,17 +147,21 @@ open_read(istream *source, bool owns_source, const string &password) {
|
|||
|
||||
string iv = sr.extract_bytes(iv_length);
|
||||
|
||||
_read_ctx = EVP_CIPHER_CTX_new();
|
||||
nassertv(_read_ctx != NULL);
|
||||
|
||||
// Initialize the context
|
||||
int result;
|
||||
result = EVP_DecryptInit(&_read_ctx, cipher, NULL, (unsigned char *)iv.data());
|
||||
result = EVP_DecryptInit(_read_ctx, cipher, NULL, (unsigned char *)iv.data());
|
||||
nassertv(result > 0);
|
||||
|
||||
result = EVP_CIPHER_CTX_set_key_length(&_read_ctx, key_length);
|
||||
result = EVP_CIPHER_CTX_set_key_length(_read_ctx, key_length);
|
||||
if (result <= 0) {
|
||||
prc_cat.error()
|
||||
<< "Invalid key length " << key_length * 8 << " bits for algorithm "
|
||||
<< OBJ_nid2sn(nid) << "\n";
|
||||
EVP_CIPHER_CTX_cleanup(&_read_ctx);
|
||||
EVP_CIPHER_CTX_free(_read_ctx);
|
||||
_read_ctx = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -167,11 +175,9 @@ open_read(istream *source, bool owns_source, const string &password) {
|
|||
nassertv(result > 0);
|
||||
|
||||
// Store the key within the context.
|
||||
result = EVP_DecryptInit(&_read_ctx, NULL, key, NULL);
|
||||
result = EVP_DecryptInit(_read_ctx, NULL, key, NULL);
|
||||
nassertv(result > 0);
|
||||
|
||||
_read_valid = true;
|
||||
|
||||
_read_overflow_buffer = new unsigned char[_read_block_size];
|
||||
_in_read_overflow_buffer = 0;
|
||||
thread_consider_yield();
|
||||
|
|
@ -182,9 +188,9 @@ open_read(istream *source, bool owns_source, const string &password) {
|
|||
*/
|
||||
void EncryptStreamBuf::
|
||||
close_read() {
|
||||
if (_read_valid) {
|
||||
EVP_CIPHER_CTX_cleanup(&_read_ctx);
|
||||
_read_valid = false;
|
||||
if (_read_ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(_read_ctx);
|
||||
_read_ctx = NULL;
|
||||
}
|
||||
|
||||
if (_read_overflow_buffer != (unsigned char *)NULL) {
|
||||
|
|
@ -211,7 +217,6 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
|||
close_write();
|
||||
_dest = dest;
|
||||
_owns_dest = owns_dest;
|
||||
_write_valid = false;
|
||||
|
||||
const EVP_CIPHER *cipher =
|
||||
EVP_get_cipherbyname(_algorithm.c_str());
|
||||
|
|
@ -220,21 +225,23 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
|||
prc_cat.error()
|
||||
<< "Unknown encryption algorithm: " << _algorithm << "\n";
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
int nid = EVP_CIPHER_nid(cipher);
|
||||
|
||||
int iv_length = EVP_CIPHER_iv_length(cipher);
|
||||
_write_block_size = EVP_CIPHER_block_size(cipher);
|
||||
|
||||
unsigned char *iv = (unsigned char *)alloca(iv_length);
|
||||
|
||||
// Generate a random IV. It doesn't need to be cryptographically secure,
|
||||
// just unique.
|
||||
unsigned char *iv = (unsigned char *)alloca(iv_length);
|
||||
RAND_pseudo_bytes(iv, iv_length);
|
||||
|
||||
_write_ctx = EVP_CIPHER_CTX_new();
|
||||
nassertv(_write_ctx != NULL);
|
||||
|
||||
int result;
|
||||
result = EVP_EncryptInit(&_write_ctx, cipher, NULL, iv);
|
||||
result = EVP_EncryptInit(_write_ctx, cipher, NULL, iv);
|
||||
nassertv(result > 0);
|
||||
|
||||
// Store the appropriate key length in the context.
|
||||
|
|
@ -242,12 +249,13 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
|||
if (key_length == 0) {
|
||||
key_length = EVP_CIPHER_key_length(cipher);
|
||||
}
|
||||
result = EVP_CIPHER_CTX_set_key_length(&_write_ctx, key_length);
|
||||
result = EVP_CIPHER_CTX_set_key_length(_write_ctx, key_length);
|
||||
if (result <= 0) {
|
||||
prc_cat.error()
|
||||
<< "Invalid key length " << key_length * 8 << " bits for algorithm "
|
||||
<< OBJ_nid2sn(nid) << "\n";
|
||||
EVP_CIPHER_CTX_cleanup(&_write_ctx);
|
||||
EVP_CIPHER_CTX_free(_write_ctx);
|
||||
_write_ctx = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +279,7 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
|||
nassertv(result > 0);
|
||||
|
||||
// Store the key in the context.
|
||||
result = EVP_EncryptInit(&_write_ctx, NULL, key, NULL);
|
||||
result = EVP_EncryptInit(_write_ctx, NULL, key, NULL);
|
||||
nassertv(result > 0);
|
||||
|
||||
// Now write the header information to the stream.
|
||||
|
|
@ -284,7 +292,6 @@ open_write(ostream *dest, bool owns_dest, const string &password) {
|
|||
sw.add_uint16((uint16_t)count);
|
||||
sw.append_data(iv, iv_length);
|
||||
|
||||
_write_valid = true;
|
||||
thread_consider_yield();
|
||||
}
|
||||
|
||||
|
|
@ -298,15 +305,16 @@ close_write() {
|
|||
write_chars(pbase(), n);
|
||||
pbump(-(int)n);
|
||||
|
||||
if (_write_valid) {
|
||||
if (_write_ctx != NULL) {
|
||||
unsigned char *write_buffer = (unsigned char *)alloca(_write_block_size);
|
||||
int bytes_written = 0;
|
||||
EVP_EncryptFinal(&_write_ctx, write_buffer, &bytes_written);
|
||||
EVP_EncryptFinal(_write_ctx, write_buffer, &bytes_written);
|
||||
thread_consider_yield();
|
||||
|
||||
_dest->write((const char *)write_buffer, bytes_written);
|
||||
|
||||
_write_valid = false;
|
||||
EVP_CIPHER_CTX_free(_write_ctx);
|
||||
_write_ctx = NULL;
|
||||
}
|
||||
|
||||
if (_owns_dest) {
|
||||
|
|
@ -418,7 +426,7 @@ read_chars(char *start, size_t length) {
|
|||
|
||||
do {
|
||||
// Get more bytes from the stream.
|
||||
if (!_read_valid) {
|
||||
if (_read_ctx == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -429,20 +437,21 @@ read_chars(char *start, size_t length) {
|
|||
int result;
|
||||
if (source_length != 0) {
|
||||
result =
|
||||
EVP_DecryptUpdate(&_read_ctx, read_buffer, &bytes_read,
|
||||
EVP_DecryptUpdate(_read_ctx, read_buffer, &bytes_read,
|
||||
source_buffer, source_length);
|
||||
} else {
|
||||
result =
|
||||
EVP_DecryptFinal(&_read_ctx, read_buffer, &bytes_read);
|
||||
_read_valid = false;
|
||||
EVP_DecryptFinal(_read_ctx, read_buffer, &bytes_read);
|
||||
EVP_CIPHER_CTX_free(_read_ctx);
|
||||
_read_ctx = NULL;
|
||||
}
|
||||
|
||||
if (result <= 0) {
|
||||
prc_cat.error()
|
||||
<< "Error decrypting stream.\n";
|
||||
if (_read_valid) {
|
||||
EVP_CIPHER_CTX_cleanup(&_read_ctx);
|
||||
_read_valid = false;
|
||||
if (_read_ctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(_read_ctx);
|
||||
_read_ctx = NULL;
|
||||
}
|
||||
}
|
||||
thread_consider_yield();
|
||||
|
|
@ -472,13 +481,13 @@ read_chars(char *start, size_t length) {
|
|||
*/
|
||||
void EncryptStreamBuf::
|
||||
write_chars(const char *start, size_t length) {
|
||||
if (_write_valid && length != 0) {
|
||||
if (_write_ctx != NULL && length != 0) {
|
||||
size_t max_write_buffer = length + _write_block_size;
|
||||
unsigned char *write_buffer = (unsigned char *)alloca(max_write_buffer);
|
||||
|
||||
int bytes_written = 0;
|
||||
int result =
|
||||
EVP_EncryptUpdate(&_write_ctx, write_buffer, &bytes_written,
|
||||
EVP_EncryptUpdate(_write_ctx, write_buffer, &bytes_written,
|
||||
(unsigned char *)start, length);
|
||||
if (result <= 0) {
|
||||
prc_cat.error()
|
||||
|
|
|
|||
|
|
@ -64,14 +64,12 @@ private:
|
|||
int _key_length;
|
||||
int _iteration_count;
|
||||
|
||||
bool _read_valid;
|
||||
EVP_CIPHER_CTX _read_ctx;
|
||||
EVP_CIPHER_CTX *_read_ctx;
|
||||
size_t _read_block_size;
|
||||
unsigned char *_read_overflow_buffer;
|
||||
size_t _in_read_overflow_buffer;
|
||||
|
||||
bool _write_valid;
|
||||
EVP_CIPHER_CTX _write_ctx;
|
||||
EVP_CIPHER_CTX *_write_ctx;
|
||||
size_t _write_block_size;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -343,6 +343,9 @@ assert_failure(const char *expression, int line,
|
|||
// guarantee it has already been constructed.
|
||||
ALIGN_16BYTE ConfigVariableBool assert_abort("assert-abort", false);
|
||||
if (assert_abort) {
|
||||
// Make sure the error message has been flushed to the output.
|
||||
nout.flush();
|
||||
|
||||
#ifdef WIN32
|
||||
// How to trigger an exception in VC++ that offers to take us into the
|
||||
// debugger? abort() doesn't do it. We used to be able to assert(false),
|
||||
|
|
|
|||
|
|
@ -149,12 +149,14 @@ extern "C" {
|
|||
EXPCL_PYSTUB int PyUnicodeUCS2_FromStringAndSize(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS2_FromWideChar(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS2_AsWideChar(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS2_AsWideCharString(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS2_GetSize(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS4_FromFormat(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS4_FromString(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS4_FromStringAndSize(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS4_FromWideChar(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS4_AsWideChar(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS4_AsWideCharString(...);
|
||||
EXPCL_PYSTUB int PyUnicodeUCS4_GetSize(...);
|
||||
EXPCL_PYSTUB int PyUnicode_AsUTF8(...);
|
||||
EXPCL_PYSTUB int PyUnicode_AsUTF8AndSize(...);
|
||||
|
|
@ -349,12 +351,14 @@ int PyUnicodeUCS2_FromString(...) { return 0; }
|
|||
int PyUnicodeUCS2_FromStringAndSize(...) { return 0; }
|
||||
int PyUnicodeUCS2_FromWideChar(...) { return 0; }
|
||||
int PyUnicodeUCS2_AsWideChar(...) { return 0; }
|
||||
int PyUnicodeUCS2_AsWideCharString(...) { return 0; }
|
||||
int PyUnicodeUCS2_GetSize(...) { return 0; }
|
||||
int PyUnicodeUCS4_FromFormat(...) { return 0; }
|
||||
int PyUnicodeUCS4_FromString(...) { return 0; }
|
||||
int PyUnicodeUCS4_FromStringAndSize(...) { return 0; }
|
||||
int PyUnicodeUCS4_FromWideChar(...) { return 0; }
|
||||
int PyUnicodeUCS4_AsWideChar(...) { return 0; }
|
||||
int PyUnicodeUCS4_AsWideCharString(...) { return 0; }
|
||||
int PyUnicodeUCS4_GetSize(...) { return 0; }
|
||||
int PyUnicode_AsUTF8(...) { return 0; }
|
||||
int PyUnicode_AsUTF8AndSize(...) { return 0; }
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
*.pyc
|
||||
*.pyo
|
||||
|
|
@ -31,6 +31,7 @@ SetCompressor ${COMPRESSOR}
|
|||
!include "Sections.nsh"
|
||||
!include "WinMessages.nsh"
|
||||
!include "WordFunc.nsh"
|
||||
!include "x64.nsh"
|
||||
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP "panda-install.bmp"
|
||||
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "panda-install.bmp"
|
||||
|
|
@ -120,6 +121,14 @@ Function runFunction
|
|||
ExecShell "open" "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk"
|
||||
FunctionEnd
|
||||
|
||||
Function .onInit
|
||||
${If} ${REGVIEW} = 64
|
||||
${AndIfNot} ${RunningX64}
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "You are attempting to install the 64-bit version of Panda3D on a 32-bit version of Windows. Please download and install the 32-bit version of Panda3D instead."
|
||||
Abort
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
SectionGroup "Panda3D Libraries"
|
||||
Section "Core Libraries" SecCore
|
||||
SectionIn 1 2 RO
|
||||
|
|
@ -134,12 +143,22 @@ SectionGroup "Panda3D Libraries"
|
|||
SetOutPath "$INSTDIR"
|
||||
File "${BUILT}\LICENSE"
|
||||
File /r /x CVS "${BUILT}\ReleaseNotes"
|
||||
SetOutPath $INSTDIR\bin
|
||||
File /r /x libpandagl.dll /x libpandadx9.dll /x cgD3D*.dll /x python*.dll /x libpandaode.dll /x libp3fmod_audio.dll /x fmodex*.dll /x libp3ffmpeg.dll /x av*.dll /x postproc*.dll /x swscale*.dll /x swresample*.dll /x NxCharacter*.dll /x cudart*.dll /x PhysX*.dll /x libpandaphysx.dll /x libp3rocket.dll /x boost_python*.dll /x Rocket*.dll /x _rocket*.pyd /x libpandabullet.dll /x OpenAL32.dll /x *_oal.dll /x libp3openal_audio.dll "${BUILT}\bin\*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\Microsoft.*.manifest"
|
||||
|
||||
SetOutPath $INSTDIR\etc
|
||||
File /r "${BUILT}\etc\*"
|
||||
|
||||
SetOutPath $INSTDIR\bin
|
||||
File /r /x api-ms-win-*.dll /x ucrtbase.dll /x libpandagl.dll /x libpandadx9.dll /x cgD3D*.dll /x python*.dll /x libpandaode.dll /x libp3fmod_audio.dll /x fmodex*.dll /x libp3ffmpeg.dll /x av*.dll /x postproc*.dll /x swscale*.dll /x swresample*.dll /x NxCharacter*.dll /x cudart*.dll /x PhysX*.dll /x libpandaphysx.dll /x libp3rocket.dll /x boost_python*.dll /x Rocket*.dll /x _rocket*.pyd /x libpandabullet.dll /x OpenAL32.dll /x *_oal.dll /x libp3openal_audio.dll "${BUILT}\bin\*.dll"
|
||||
File /nonfatal /r "${BUILT}\bin\Microsoft.*.manifest"
|
||||
|
||||
; Before Windows 10, we need these stubs for the UCRT as well.
|
||||
ReadRegDWORD $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentMajorVersionNumber"
|
||||
${If} $0 < 10
|
||||
ClearErrors
|
||||
File /nonfatal /r "${BUILT}\bin\api-ms-win-*.dll"
|
||||
File /nonfatal "${BUILT}\bin\ucrtbase.dll"
|
||||
${Endif}
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing models..."
|
||||
SetDetailsPrint listonly
|
||||
|
|
@ -147,6 +166,10 @@ SectionGroup "Panda3D Libraries"
|
|||
SetOutPath $INSTDIR\models
|
||||
File /r /x CVS "${BUILT}\models\*"
|
||||
|
||||
SetDetailsPrint both
|
||||
DetailPrint "Installing optional components..."
|
||||
SetDetailsPrint listonly
|
||||
|
||||
RMDir /r "$SMPROGRAMS\${TITLE}"
|
||||
CreateDirectory "$SMPROGRAMS\${TITLE}"
|
||||
SectionEnd
|
||||
|
|
@ -634,6 +657,9 @@ Section -post
|
|||
WriteRegStr HKCU "Software\Classes\.pz" "PerceivedType" "compressed"
|
||||
WriteRegStr HKCU "Software\Classes\.mf" "" "Panda3D.Multifile"
|
||||
WriteRegStr HKCU "Software\Classes\.mf" "PerceivedType" "compressed"
|
||||
WriteRegStr HKCU "Software\Classes\.prc" "" "inifile"
|
||||
WriteRegStr HKCU "Software\Classes\.prc" "Content Type" "text/plain"
|
||||
WriteRegStr HKCU "Software\Classes\.prc" "PerceivedType" "text"
|
||||
|
||||
; For convenience, if nobody registered .pyd, we will.
|
||||
ReadRegStr $0 HKCR "Software\Classes\.pyd" ""
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import sys
|
|||
|
||||
COMPILER=0
|
||||
INSTALLER=0
|
||||
WHEEL=0
|
||||
GENMAN=0
|
||||
COMPRESSOR="zlib"
|
||||
THREADCOUNT=0
|
||||
|
|
@ -51,6 +52,7 @@ RUNTIME=0
|
|||
DISTRIBUTOR=""
|
||||
VERSION=None
|
||||
DEBVERSION=None
|
||||
WHLVERSION=None
|
||||
RPMRELEASE="1"
|
||||
GIT_COMMIT=None
|
||||
P3DSUFFIX=None
|
||||
|
|
@ -87,14 +89,13 @@ PkgListSet(["PYTHON", "DIRECT", # Python support
|
|||
"MFC", "WX", "FLTK", # Used for web plug-in only
|
||||
"ROCKET", "AWESOMIUM", # GUI libraries
|
||||
"CARBON", "COCOA", # Mac OS X toolkits
|
||||
"X11", "XF86DGA", "XRANDR", "XCURSOR", # Unix platform support
|
||||
"PANDATOOL", "PVIEW", "DEPLOYTOOLS", # Toolchain
|
||||
"X11", # Unix platform support
|
||||
"PANDATOOL", "PVIEW", "DEPLOYTOOLS", "DIRECTSCRIPTS",# Toolchain
|
||||
"SKEL", # Example SKEL project
|
||||
"PANDAFX", # Some distortion special lenses
|
||||
"PANDAPARTICLESYSTEM", # Built in particle system
|
||||
"CONTRIB", # Experimental
|
||||
"SSE2", "NEON", # Compiler features
|
||||
"TOUCHINPUT", # Touchinput interface (requires Windows 7)
|
||||
])
|
||||
|
||||
CheckPandaSourceTree()
|
||||
|
|
@ -125,6 +126,7 @@ def usage(problem):
|
|||
print(" --verbose (print out more information)")
|
||||
print(" --runtime (build a runtime build instead of an SDK build)")
|
||||
print(" --installer (build an installer)")
|
||||
print(" --wheel (build a pip-installable .whl)")
|
||||
print(" --optimize X (optimization level can be 1,2,3,4)")
|
||||
print(" --version X (set the panda version number)")
|
||||
print(" --lzma (use lzma compression when building Windows installer)")
|
||||
|
|
@ -160,17 +162,18 @@ def usage(problem):
|
|||
os._exit(1)
|
||||
|
||||
def parseopts(args):
|
||||
global INSTALLER,RTDIST,RUNTIME,GENMAN,DISTRIBUTOR,VERSION
|
||||
global INSTALLER,WHEEL,RTDIST,RUNTIME,GENMAN,DISTRIBUTOR,VERSION
|
||||
global COMPRESSOR,THREADCOUNT,OSXTARGET,OSX_ARCHS,HOST_URL
|
||||
global DEBVERSION,RPMRELEASE,GIT_COMMIT,P3DSUFFIX,RTDIST_VERSION
|
||||
global DEBVERSION,WHLVERSION,RPMRELEASE,GIT_COMMIT,P3DSUFFIX,RTDIST_VERSION
|
||||
global STRDXSDKVERSION, WINDOWS_SDK, MSVC_VERSION, BOOUSEINTELCOMPILER
|
||||
longopts = [
|
||||
"help","distributor=","verbose","runtime","osxtarget=",
|
||||
"optimize=","everything","nothing","installer","rtdist","nocolor",
|
||||
"optimize=","everything","nothing","installer","wheel","rtdist","nocolor",
|
||||
"version=","lzma","no-python","threads=","outputdir=","override=",
|
||||
"static","host=","debversion=","rpmrelease=","p3dsuffix=","rtdist-version=",
|
||||
"directx-sdk=", "windows-sdk=", "msvc-version=", "clean", "use-icl",
|
||||
"universal", "target=", "arch=", "git-commit="]
|
||||
"universal", "target=", "arch=", "git-commit=",
|
||||
"use-touchinput", "no-touchinput"]
|
||||
anything = 0
|
||||
optimize = ""
|
||||
target = None
|
||||
|
|
@ -188,6 +191,7 @@ def parseopts(args):
|
|||
if (option=="--help"): raise Exception
|
||||
elif (option=="--optimize"): optimize=value
|
||||
elif (option=="--installer"): INSTALLER=1
|
||||
elif (option=="--wheel"): WHEEL=1
|
||||
elif (option=="--verbose"): SetVerbose(True)
|
||||
elif (option=="--distributor"): DISTRIBUTOR=value
|
||||
elif (option=="--rtdist"): RTDIST=1
|
||||
|
|
@ -203,8 +207,11 @@ def parseopts(args):
|
|||
elif (option=="--arch"): target_arch = value.strip()
|
||||
elif (option=="--nocolor"): DisableColors()
|
||||
elif (option=="--version"):
|
||||
VERSION=value
|
||||
if (len(VERSION.split(".")) != 3): raise Exception
|
||||
match = re.match(r'^\d+\.\d+\.\d+', value)
|
||||
if not match:
|
||||
usage("version requires three digits")
|
||||
WHLVERSION = value
|
||||
VERSION = match.group()
|
||||
elif (option=="--lzma"): COMPRESSOR="lzma"
|
||||
elif (option=="--override"): AddOverride(value.strip())
|
||||
elif (option=="--static"): SetLinkAllStatic(True)
|
||||
|
|
@ -316,18 +323,6 @@ def parseopts(args):
|
|||
print("No Windows SDK version specified. Defaulting to '7.1'.")
|
||||
WINDOWS_SDK = '7.1'
|
||||
|
||||
is_win7 = False
|
||||
if sys.platform == 'win32':
|
||||
# Note: not available in cygwin.
|
||||
winver = sys.getwindowsversion()
|
||||
if winver[0] >= 6 and winver[1] >= 1:
|
||||
is_win7 = True
|
||||
|
||||
if RUNTIME or not is_win7:
|
||||
PkgDisable("TOUCHINPUT")
|
||||
else:
|
||||
PkgDisable("TOUCHINPUT")
|
||||
|
||||
if clean_build and os.path.isdir(GetOutputDir()):
|
||||
print("Deleting %s" % (GetOutputDir()))
|
||||
shutil.rmtree(GetOutputDir())
|
||||
|
|
@ -428,9 +423,18 @@ if (RUNTIME):
|
|||
if (INSTALLER and RTDIST):
|
||||
exit("Cannot build an installer for the rtdist build!")
|
||||
|
||||
if (WHEEL and RUNTIME):
|
||||
exit("Cannot build a wheel for the runtime build!")
|
||||
|
||||
if (WHEEL and RTDIST):
|
||||
exit("Cannot build a wheel for the rtdist build!")
|
||||
|
||||
if (INSTALLER) and (PkgSkip("PYTHON")) and (not RUNTIME) and GetTarget() == 'windows':
|
||||
exit("Cannot build installer on Windows without python")
|
||||
|
||||
if WHEEL and PkgSkip("PYTHON"):
|
||||
exit("Cannot build wheel without Python")
|
||||
|
||||
if (RTDIST) and (PkgSkip("WX") and PkgSkip("FLTK")):
|
||||
exit("Cannot build rtdist without wx or fltk")
|
||||
|
||||
|
|
@ -516,9 +520,6 @@ IncDirectory("ALWAYS", GetOutputDir()+"/include")
|
|||
|
||||
if (COMPILER == "MSVC"):
|
||||
PkgDisable("X11")
|
||||
PkgDisable("XRANDR")
|
||||
PkgDisable("XF86DGA")
|
||||
PkgDisable("XCURSOR")
|
||||
PkgDisable("GLES")
|
||||
PkgDisable("GLES2")
|
||||
PkgDisable("EGL")
|
||||
|
|
@ -808,9 +809,13 @@ if (COMPILER=="GCC"):
|
|||
SmartPkgEnable("JPEG", "", ("jpeg"), "jpeglib.h")
|
||||
SmartPkgEnable("PNG", "libpng", ("png"), "png.h", tool = "libpng-config")
|
||||
|
||||
if GetTarget() == "darwin" and not PkgSkip("FFMPEG"):
|
||||
LibName("FFMPEG", "-Wl,-read_only_relocs,suppress")
|
||||
LibName("FFMPEG", "-framework VideoDecodeAcceleration")
|
||||
if not PkgSkip("FFMPEG"):
|
||||
if GetTarget() == "darwin":
|
||||
LibName("FFMPEG", "-Wl,-read_only_relocs,suppress")
|
||||
LibName("FFMPEG", "-framework VideoDecodeAcceleration")
|
||||
elif os.path.isfile(GetThirdpartyDir() + "ffmpeg/lib/libavcodec.a"):
|
||||
# Needed when linking ffmpeg statically on Linux.
|
||||
LibName("FFMPEG", "-Wl,-Bsymbolic")
|
||||
|
||||
cv_lib = ChooseLib(("opencv_core", "cv"), "OPENCV")
|
||||
if cv_lib == "opencv_core":
|
||||
|
|
@ -840,12 +845,9 @@ if (COMPILER=="GCC"):
|
|||
if GetTarget() != 'darwin':
|
||||
# CgGL is covered by the Cg framework, and we don't need X11 components on OSX
|
||||
if not PkgSkip("NVIDIACG") and not RUNTIME:
|
||||
SmartPkgEnable("CGGL", "", ("CgGL"), "Cg/cgGL.h")
|
||||
SmartPkgEnable("CGGL", "", ("CgGL"), "Cg/cgGL.h", thirdparty_dir = "nvidiacg")
|
||||
if not RUNTIME:
|
||||
SmartPkgEnable("X11", "x11", "X11", ("X11", "X11/Xlib.h"))
|
||||
SmartPkgEnable("XRANDR", "xrandr", "Xrandr", "X11/extensions/Xrandr.h")
|
||||
SmartPkgEnable("XF86DGA", "xxf86dga", "Xxf86dga", "X11/extensions/xf86dga.h")
|
||||
SmartPkgEnable("XCURSOR", "xcursor", "Xcursor", "X11/Xcursor/Xcursor.h")
|
||||
|
||||
if GetHost() != "darwin":
|
||||
# Workaround for an issue where pkg-config does not include this path
|
||||
|
|
@ -1055,11 +1057,12 @@ def CompileCxx(obj,src,opts):
|
|||
cmd += "/favor:blend "
|
||||
cmd += "/wd4996 /wd4275 /wd4273 "
|
||||
|
||||
# Enable Windows 7 interfaces if we need Touchinput.
|
||||
if PkgSkip("TOUCHINPUT") == 0:
|
||||
cmd += "/DWINVER=0x601 "
|
||||
else:
|
||||
cmd += "/DWINVER=0x501 "
|
||||
# We still target Windows XP.
|
||||
cmd += "/DWINVER=0x501 "
|
||||
# Work around a WinXP/2003 bug when using VS 2015+.
|
||||
if SDK.get("VISUALSTUDIO_VERSION") == '14.0':
|
||||
cmd += "/Zc:threadSafeInit- "
|
||||
|
||||
cmd += "/Fo" + obj + " /nologo /c"
|
||||
if GetTargetArch() != 'x64' and (not PkgSkip("SSE2") or 'SSE2' in opts):
|
||||
cmd += " /arch:SSE2"
|
||||
|
|
@ -1109,12 +1112,7 @@ def CompileCxx(obj,src,opts):
|
|||
if GetTargetArch() == 'x64':
|
||||
cmd += "/favor:blend "
|
||||
cmd += "/wd4996 /wd4275 /wd4267 /wd4101 /wd4273 "
|
||||
|
||||
# Enable Windows 7 interfaces if we need Touchinput.
|
||||
if PkgSkip("TOUCHINPUT") == 0:
|
||||
cmd += "/DWINVER=0x601 "
|
||||
else:
|
||||
cmd += "/DWINVER=0x501 "
|
||||
cmd += "/DWINVER=0x501 "
|
||||
cmd += "/Fo" + obj + " /c"
|
||||
for x in ipath: cmd += " /I" + x
|
||||
for (opt,dir) in INCDIRECTORIES:
|
||||
|
|
@ -1196,7 +1194,7 @@ def CompileCxx(obj,src,opts):
|
|||
|
||||
if (COMPILER=="GCC"):
|
||||
if (src.endswith(".c")): cmd = GetCC() +' -fPIC -c -o ' + obj
|
||||
else: cmd = GetCXX()+' -ftemplate-depth-70 -fPIC -c -o ' + obj
|
||||
else: cmd = GetCXX()+' -std=gnu++0x -ftemplate-depth-70 -fPIC -c -o ' + obj
|
||||
for (opt, dir) in INCDIRECTORIES:
|
||||
if (opt=="ALWAYS") or (opt in opts): cmd += ' -I' + BracketNameWithQuotes(dir)
|
||||
for (opt, dir) in FRAMEWORKDIRECTORIES:
|
||||
|
|
@ -1682,11 +1680,7 @@ def CompileLink(dll, obj, opts):
|
|||
if 'NOARCH:' + arch.upper() not in opts:
|
||||
cmd += " -arch %s" % arch
|
||||
|
||||
if "SYSROOT" in SDK:
|
||||
cmd += " --sysroot=%s -no-canonical-prefixes" % (SDK["SYSROOT"])
|
||||
|
||||
# Android-specific flags.
|
||||
if GetTarget() == 'android':
|
||||
elif GetTarget() == 'android':
|
||||
cmd += " -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now"
|
||||
if GetTargetArch() == 'armv7a':
|
||||
cmd += " -march=armv7-a -Wl,--fix-cortex-a8"
|
||||
|
|
@ -1694,9 +1688,17 @@ def CompileLink(dll, obj, opts):
|
|||
else:
|
||||
cmd += " -pthread"
|
||||
|
||||
if "SYSROOT" in SDK:
|
||||
cmd += " --sysroot=%s -no-canonical-prefixes" % (SDK["SYSROOT"])
|
||||
|
||||
if LDFLAGS != "":
|
||||
cmd += " " + LDFLAGS
|
||||
|
||||
# Don't link libraries with Python.
|
||||
if "PYTHON" in opts and GetOrigExt(dll) != ".exe" and not RTDIST:
|
||||
opts = opts[:]
|
||||
opts.remove("PYTHON")
|
||||
|
||||
for (opt, dir) in LIBDIRECTORIES:
|
||||
if (opt=="ALWAYS") or (opt in opts):
|
||||
cmd += ' -L' + BracketNameWithQuotes(dir)
|
||||
|
|
@ -2122,17 +2124,13 @@ DTOOL_CONFIG=[
|
|||
("COMPILE_IN_DEFAULT_FONT", '1', '1'),
|
||||
("STDFLOAT_DOUBLE", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_MAYA", '1', '1'),
|
||||
("MAYA_PRE_5_0", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_SOFTIMAGE", 'UNDEF', 'UNDEF'),
|
||||
("SSL_097", 'UNDEF', 'UNDEF'),
|
||||
("REPORT_OPENSSL_ERRORS", '1', '1'),
|
||||
("USE_PANDAFILESTREAM", '1', '1'),
|
||||
("USE_DELETED_CHAIN", '1', '1'),
|
||||
("HAVE_WIN_TOUCHINPUT", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_GLX", 'UNDEF', '1'),
|
||||
("HAVE_WGL", '1', 'UNDEF'),
|
||||
("HAVE_DX9", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_CHROMIUM", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_THREADS", '1', '1'),
|
||||
("SIMPLE_THREADS", 'UNDEF', 'UNDEF'),
|
||||
("OS_SIMPLE_THREADS", '1', '1'),
|
||||
|
|
@ -2145,12 +2143,9 @@ DTOOL_CONFIG=[
|
|||
("DO_COLLISION_RECORDING", 'UNDEF', 'UNDEF'),
|
||||
("SUPPORT_IMMEDIATE_MODE", 'UNDEF', 'UNDEF'),
|
||||
("SUPPORT_FIXED_FUNCTION", '1', '1'),
|
||||
("TRACK_IN_INTERPRETER", 'UNDEF', 'UNDEF'),
|
||||
("DO_MEMORY_USAGE", 'UNDEF', 'UNDEF'),
|
||||
("DO_PIPELINING", '1', '1'),
|
||||
("EXPORT_TEMPLATES", 'yes', 'yes'),
|
||||
("LINK_IN_GL", 'UNDEF', 'UNDEF'),
|
||||
("LINK_IN_PHYSICS", 'UNDEF', 'UNDEF'),
|
||||
("DEFAULT_PATHSEP", '";"', '":"'),
|
||||
("WORDS_BIGENDIAN", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_NAMESPACE", '1', '1'),
|
||||
|
|
@ -2206,13 +2201,9 @@ DTOOL_CONFIG=[
|
|||
("PHAVE_STDINT_H", '1', '1'),
|
||||
("HAVE_RTTI", '1', '1'),
|
||||
("HAVE_X11", 'UNDEF', '1'),
|
||||
("HAVE_XRANDR", 'UNDEF', '1'),
|
||||
("HAVE_XF86DGA", 'UNDEF', '1'),
|
||||
("HAVE_XCURSOR", 'UNDEF', '1'),
|
||||
("IS_LINUX", 'UNDEF', '1'),
|
||||
("IS_OSX", 'UNDEF', 'UNDEF'),
|
||||
("IS_FREEBSD", 'UNDEF', 'UNDEF'),
|
||||
("GLOBAL_OPERATOR_NEW_EXCEPTIONS", 'UNDEF', '1'),
|
||||
("HAVE_EIGEN", 'UNDEF', 'UNDEF'),
|
||||
("LINMATH_ALIGN", '1', '1'),
|
||||
("HAVE_ZLIB", 'UNDEF', 'UNDEF'),
|
||||
|
|
@ -2230,28 +2221,25 @@ DTOOL_CONFIG=[
|
|||
("HAVE_PNM", '1', '1'),
|
||||
("HAVE_STB_IMAGE", '1', '1'),
|
||||
("HAVE_VORBIS", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_NVIDIACG", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_FREETYPE", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_FFTW", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_OPENSSL", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_NET", 'UNDEF', 'UNDEF'),
|
||||
("WANT_NATIVE_NET", '1', '1'),
|
||||
("SIMULATE_NETWORK_DELAY", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_EGG", '1', '1'),
|
||||
("HAVE_CG", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_CGGL", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_CGDX9", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_FFMPEG", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_SWSCALE", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_SWRESAMPLE", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_ARTOOLKIT", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_OPENCV", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_DIRECTCAM", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_SQUISH", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_FCOLLADA", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_CARBON", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_COCOA", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_OPENAL_FRAMEWORK", 'UNDEF', 'UNDEF'),
|
||||
("HAVE_ROCKET_PYTHON", '1', '1'),
|
||||
("HAVE_ROCKET_DEBUGGER", 'UNDEF', 'UNDEF'),
|
||||
("USE_TAU", 'UNDEF', 'UNDEF'),
|
||||
("PRC_SAVE_DESCRIPTIONS", '1', '1'),
|
||||
# ("_SECURE_SCL", '0', 'UNDEF'),
|
||||
# ("_SECURE_SCL_THROWS", '0', 'UNDEF'),
|
||||
|
|
@ -2298,9 +2286,6 @@ def WriteConfigSettings():
|
|||
else:
|
||||
dtool_config["HAVE_"+x] = 'UNDEF'
|
||||
|
||||
if not PkgSkip("OPENCV"):
|
||||
dtool_config["OPENCV_VER_23"] = '1' if OPENCV_VER_23 else 'UNDEF'
|
||||
|
||||
dtool_config["HAVE_NET"] = '1'
|
||||
|
||||
if (PkgSkip("NVIDIACG")==0):
|
||||
|
|
@ -2320,9 +2305,6 @@ def WriteConfigSettings():
|
|||
dtool_config["PHAVE_SYS_MALLOC_H"] = '1'
|
||||
dtool_config["HAVE_OPENAL_FRAMEWORK"] = '1'
|
||||
dtool_config["HAVE_X11"] = 'UNDEF' # We might have X11, but we don't need it.
|
||||
dtool_config["HAVE_XRANDR"] = 'UNDEF'
|
||||
dtool_config["HAVE_XF86DGA"] = 'UNDEF'
|
||||
dtool_config["HAVE_XCURSOR"] = 'UNDEF'
|
||||
dtool_config["HAVE_GLX"] = 'UNDEF'
|
||||
dtool_config["IS_LINUX"] = 'UNDEF'
|
||||
dtool_config["HAVE_VIDEO4LINUX"] = 'UNDEF'
|
||||
|
|
@ -2357,9 +2339,6 @@ def WriteConfigSettings():
|
|||
if (PkgSkip("PYTHON") != 0):
|
||||
dtool_config["HAVE_ROCKET_PYTHON"] = 'UNDEF'
|
||||
|
||||
if (PkgSkip("TOUCHINPUT") == 0 and GetTarget() == "windows"):
|
||||
dtool_config["HAVE_WIN_TOUCHINPUT"] = '1'
|
||||
|
||||
if (GetOptimize() <= 3):
|
||||
dtool_config["HAVE_ROCKET_DEBUGGER"] = '1'
|
||||
|
||||
|
|
@ -2373,9 +2352,6 @@ def WriteConfigSettings():
|
|||
if (GetOptimize() <= 3):
|
||||
dtool_config["DO_COLLISION_RECORDING"] = '1'
|
||||
|
||||
#if (GetOptimize() <= 2):
|
||||
# dtool_config["TRACK_IN_INTERPRETER"] = '1'
|
||||
|
||||
if (GetOptimize() <= 3):
|
||||
dtool_config["DO_MEMORY_USAGE"] = '1'
|
||||
|
||||
|
|
@ -2790,8 +2766,13 @@ if (GetTarget() == 'darwin'):
|
|||
# OpenAL is not yet working well on OSX for us, so let's do this for now.
|
||||
configprc = configprc.replace("p3openal_audio", "p3fmod_audio")
|
||||
|
||||
ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc)
|
||||
ConditionalWriteFile(GetOutputDir()+"/etc/Confauto.prc", confautoprc)
|
||||
if GetTarget() == 'windows':
|
||||
# Convert to Windows newlines.
|
||||
ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc, newline='\r\n')
|
||||
ConditionalWriteFile(GetOutputDir()+"/etc/Confauto.prc", confautoprc, newline='\r\n')
|
||||
else:
|
||||
ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc)
|
||||
ConditionalWriteFile(GetOutputDir()+"/etc/Confauto.prc", confautoprc)
|
||||
|
||||
##########################################################################################
|
||||
#
|
||||
|
|
@ -2888,22 +2869,75 @@ if tp_dir is not None:
|
|||
|
||||
if GetTarget() == 'windows':
|
||||
CopyAllFiles(GetOutputDir() + "/bin/", tp_dir + "extras/bin/")
|
||||
if not PkgSkip("PYTHON"):
|
||||
pydll = "/" + SDK["PYTHONVERSION"].replace(".", "")
|
||||
if (GetOptimize() <= 2): pydll += "_d.dll"
|
||||
else: pydll += ".dll"
|
||||
CopyFile(GetOutputDir() + "/bin" + pydll, SDK["PYTHON"] + pydll)
|
||||
|
||||
for fn in glob.glob(SDK["PYTHON"] + "/vcruntime*.dll"):
|
||||
CopyFile(GetOutputDir() + "/bin/", fn)
|
||||
if not PkgSkip("PYTHON") and not RTDIST:
|
||||
#XXX rdb I don't think we need to copy over the Python DLL, do we?
|
||||
#pydll = "/" + SDK["PYTHONVERSION"].replace(".", "")
|
||||
#if (GetOptimize() <= 2): pydll += "_d.dll"
|
||||
#else: pydll += ".dll"
|
||||
#CopyFile(GetOutputDir() + "/bin" + pydll, SDK["PYTHON"] + pydll)
|
||||
|
||||
if not RTDIST:
|
||||
CopyTree(GetOutputDir() + "/python", SDK["PYTHON"])
|
||||
if not os.path.isfile(SDK["PYTHON"] + "/ppython.exe") and os.path.isfile(SDK["PYTHON"] + "/python.exe"):
|
||||
CopyFile(GetOutputDir() + "/python/ppython.exe", SDK["PYTHON"] + "/python.exe")
|
||||
if not os.path.isfile(SDK["PYTHON"] + "/ppythonw.exe") and os.path.isfile(SDK["PYTHON"] + "/pythonw.exe"):
|
||||
CopyFile(GetOutputDir() + "/python/ppythonw.exe", SDK["PYTHON"] + "/pythonw.exe")
|
||||
ConditionalWriteFile(GetOutputDir() + "/python/panda.pth", "..\n../bin\n")
|
||||
#for fn in glob.glob(SDK["PYTHON"] + "/vcruntime*.dll"):
|
||||
# CopyFile(GetOutputDir() + "/bin/", fn)
|
||||
|
||||
# Copy the whole Python directory.
|
||||
CopyTree(GetOutputDir() + "/python", SDK["PYTHON"])
|
||||
|
||||
# NB: Python does not always ship with the correct manifest/dll.
|
||||
# Figure out the correct one to ship, and grab it from WinSxS dir.
|
||||
manifest = GetOutputDir() + '/tmp/python.manifest'
|
||||
if os.path.isfile(manifest):
|
||||
os.unlink(manifest)
|
||||
oscmd('mt -inputresource:"%s\\python.exe";#1 -out:"%s" -nologo' % (SDK["PYTHON"], manifest), True)
|
||||
|
||||
if os.path.isfile(manifest):
|
||||
import xml.etree.ElementTree as ET
|
||||
tree = ET.parse(manifest)
|
||||
idents = tree.findall('./{urn:schemas-microsoft-com:asm.v1}dependency/{urn:schemas-microsoft-com:asm.v1}dependentAssembly/{urn:schemas-microsoft-com:asm.v1}assemblyIdentity')
|
||||
else:
|
||||
idents = ()
|
||||
|
||||
for ident in tree.findall('./{urn:schemas-microsoft-com:asm.v1}dependency/{urn:schemas-microsoft-com:asm.v1}dependentAssembly/{urn:schemas-microsoft-com:asm.v1}assemblyIdentity'):
|
||||
sxs_name = '_'.join([
|
||||
ident.get('processorArchitecture'),
|
||||
ident.get('name').lower(),
|
||||
ident.get('publicKeyToken'),
|
||||
ident.get('version'),
|
||||
])
|
||||
|
||||
# Find the manifest matching these parameters.
|
||||
pattern = os.path.join('C:' + os.sep, 'Windows', 'WinSxS', 'Manifests', sxs_name + '_*.manifest')
|
||||
manifests = glob.glob(pattern)
|
||||
if not manifests:
|
||||
print("%sWARNING:%s Could not locate manifest %s. You may need to reinstall the Visual C++ Redistributable." % (GetColor("red"), GetColor(), pattern))
|
||||
continue
|
||||
|
||||
CopyFile(GetOutputDir() + "/python/" + ident.get('name') + ".manifest", manifests[0])
|
||||
|
||||
# Also copy the corresponding msvcr dll.
|
||||
pattern = os.path.join('C:' + os.sep, 'Windows', 'WinSxS', sxs_name + '_*', 'msvcr*.dll')
|
||||
for file in glob.glob(pattern):
|
||||
CopyFile(GetOutputDir() + "/python/", file)
|
||||
|
||||
# Copy python.exe to ppython.exe.
|
||||
if not os.path.isfile(SDK["PYTHON"] + "/ppython.exe") and os.path.isfile(SDK["PYTHON"] + "/python.exe"):
|
||||
CopyFile(GetOutputDir() + "/python/ppython.exe", SDK["PYTHON"] + "/python.exe")
|
||||
if not os.path.isfile(SDK["PYTHON"] + "/ppythonw.exe") and os.path.isfile(SDK["PYTHON"] + "/pythonw.exe"):
|
||||
CopyFile(GetOutputDir() + "/python/ppythonw.exe", SDK["PYTHON"] + "/pythonw.exe")
|
||||
ConditionalWriteFile(GetOutputDir() + "/python/panda.pth", "..\n../bin\n")
|
||||
|
||||
# Copy over the MSVC runtime.
|
||||
if GetTarget() == 'windows' and "VISUALSTUDIO" in SDK:
|
||||
vcver = SDK["VISUALSTUDIO_VERSION"].replace('.', '')
|
||||
crtname = "Microsoft.VC%s.CRT" % (vcver)
|
||||
dir = os.path.join(SDK["VISUALSTUDIO"], "VC", "redist", GetTargetArch(), crtname)
|
||||
|
||||
if os.path.isfile(os.path.join(dir, "msvcr" + vcver + ".dll")):
|
||||
CopyFile(GetOutputDir() + "/bin/", os.path.join(dir, "msvcr" + vcver + ".dll"))
|
||||
if os.path.isfile(os.path.join(dir, "msvcp" + vcver + ".dll")):
|
||||
CopyFile(GetOutputDir() + "/bin/", os.path.join(dir, "msvcp" + vcver + ".dll"))
|
||||
if os.path.isfile(os.path.join(dir, "vcruntime" + vcver + ".dll")):
|
||||
CopyFile(GetOutputDir() + "/bin/", os.path.join(dir, "vcruntime" + vcver + ".dll"))
|
||||
|
||||
########################################################################
|
||||
##
|
||||
|
|
@ -2911,8 +2945,14 @@ if tp_dir is not None:
|
|||
##
|
||||
########################################################################
|
||||
|
||||
CopyFile(GetOutputDir()+"/", "doc/LICENSE")
|
||||
CopyFile(GetOutputDir()+"/", "doc/ReleaseNotes")
|
||||
if GetTarget() == 'windows':
|
||||
# Convert to Windows newlines so they can be opened by notepad.
|
||||
WriteFile(GetOutputDir() + "/LICENSE", ReadFile("doc/LICENSE"), newline='\r\n')
|
||||
WriteFile(GetOutputDir() + "/ReleaseNotes", ReadFile("doc/ReleaseNotes"), newline='\r\n')
|
||||
else:
|
||||
CopyFile(GetOutputDir()+"/", "doc/LICENSE")
|
||||
CopyFile(GetOutputDir()+"/", "doc/ReleaseNotes")
|
||||
|
||||
if (PkgSkip("PANDATOOL")==0):
|
||||
CopyAllFiles(GetOutputDir()+"/plugins/", "pandatool/src/scripts/", ".mel")
|
||||
CopyAllFiles(GetOutputDir()+"/plugins/", "pandatool/src/scripts/", ".ms")
|
||||
|
|
@ -3301,6 +3341,7 @@ if (not RUNTIME):
|
|||
TargetAdd('interrogate.exe', input='libp3cppParser.ilb')
|
||||
TargetAdd('interrogate.exe', input=COMMON_DTOOL_LIBS)
|
||||
TargetAdd('interrogate.exe', input='libp3interrogatedb.dll')
|
||||
TargetAdd('interrogate.exe', input='libp3pystub.lib')
|
||||
TargetAdd('interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
|
||||
|
||||
TargetAdd('interrogate_module_interrogate_module.obj', opts=OPTS, input='interrogate_module.cxx')
|
||||
|
|
@ -3308,6 +3349,7 @@ if (not RUNTIME):
|
|||
TargetAdd('interrogate_module.exe', input='libp3cppParser.ilb')
|
||||
TargetAdd('interrogate_module.exe', input=COMMON_DTOOL_LIBS)
|
||||
TargetAdd('interrogate_module.exe', input='libp3interrogatedb.dll')
|
||||
TargetAdd('interrogate_module.exe', input='libp3pystub.lib')
|
||||
TargetAdd('interrogate_module.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
|
||||
|
||||
if (not RTDIST):
|
||||
|
|
@ -3316,6 +3358,7 @@ if (not RUNTIME):
|
|||
TargetAdd('parse_file.exe', input='libp3cppParser.ilb')
|
||||
TargetAdd('parse_file.exe', input=COMMON_DTOOL_LIBS)
|
||||
TargetAdd('parse_file.exe', input='libp3interrogatedb.dll')
|
||||
TargetAdd('parse_file.exe', input='libp3pystub.lib')
|
||||
TargetAdd('parse_file.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
|
||||
|
||||
#
|
||||
|
|
@ -3339,6 +3382,7 @@ if (not RTDIST and not RUNTIME):
|
|||
TargetAdd('test_interrogate.exe', input='test_interrogate_test_interrogate.obj')
|
||||
TargetAdd('test_interrogate.exe', input='libp3interrogatedb.dll')
|
||||
TargetAdd('test_interrogate.exe', input=COMMON_DTOOL_LIBS)
|
||||
TargetAdd('test_interrogate.exe', input='libp3pystub.lib')
|
||||
TargetAdd('test_interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
|
||||
|
||||
#
|
||||
|
|
@ -4070,8 +4114,20 @@ if (not RUNTIME):
|
|||
#
|
||||
|
||||
if (PkgSkip("VISION") == 0) and (not RUNTIME):
|
||||
# We want to know whether we have ffmpeg so that we can override the .avi association.
|
||||
if not PkgSkip("FFMPEG"):
|
||||
DefSymbol("OPENCV", "HAVE_FFMPEG")
|
||||
if not PkgSkip("OPENCV"):
|
||||
DefSymbol("OPENCV", "HAVE_OPENCV")
|
||||
if OPENCV_VER_23:
|
||||
DefSymbol("OPENCV", "OPENCV_VER_23")
|
||||
|
||||
OPTS=['DIR:panda/src/vision', 'BUILDING:VISION', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG', 'EXCEPTIONS']
|
||||
TargetAdd('p3vision_composite1.obj', opts=OPTS, input='p3vision_composite1.cxx')
|
||||
TargetAdd('p3vision_composite1.obj', opts=OPTS, input='p3vision_composite1.cxx', dep=[
|
||||
'dtool_have_ffmpeg.dat',
|
||||
'dtool_have_opencv.dat',
|
||||
'dtool_have_directcam.dat',
|
||||
])
|
||||
|
||||
TargetAdd('libp3vision.dll', input='p3vision_composite1.obj')
|
||||
TargetAdd('libp3vision.dll', input=COMMON_PANDA_LIBS)
|
||||
|
|
@ -4260,8 +4316,15 @@ if (PkgSkip("VRPN")==0 and not RUNTIME):
|
|||
# DIRECTORY: panda/src/ffmpeg
|
||||
#
|
||||
if PkgSkip("FFMPEG") == 0 and not RUNTIME:
|
||||
if not PkgSkip("SWSCALE"):
|
||||
DefSymbol("FFMPEG", "HAVE_SWSCALE")
|
||||
if not PkgSkip("SWRESAMPLE"):
|
||||
DefSymbol("FFMPEG", "HAVE_SWRESAMPLE")
|
||||
|
||||
OPTS=['DIR:panda/src/ffmpeg', 'BUILDING:FFMPEG', 'FFMPEG', 'SWSCALE', 'SWRESAMPLE']
|
||||
TargetAdd('p3ffmpeg_composite1.obj', opts=OPTS, input='p3ffmpeg_composite1.cxx')
|
||||
TargetAdd('p3ffmpeg_composite1.obj', opts=OPTS, input='p3ffmpeg_composite1.cxx', dep=[
|
||||
'dtool_have_swscale.dat', 'dtool_have_swresample.dat'])
|
||||
|
||||
TargetAdd('libp3ffmpeg.dll', input='p3ffmpeg_composite1.obj')
|
||||
TargetAdd('libp3ffmpeg.dll', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('libp3ffmpeg.dll', opts=OPTS)
|
||||
|
|
@ -4425,8 +4488,17 @@ if (not RUNTIME):
|
|||
#
|
||||
|
||||
if (not RUNTIME):
|
||||
OPTS=['DIR:panda/src/framework', 'BUILDING:FRAMEWORK']
|
||||
TargetAdd('p3framework_composite1.obj', opts=OPTS, input='p3framework_composite1.cxx')
|
||||
deps = []
|
||||
# Framework wants to link in a renderer when building statically, so tell it what is available.
|
||||
if GetLinkAllStatic():
|
||||
deps = ['dtool_have_gl.dat', 'dtool_have_tinydisplay.dat']
|
||||
if not PkgSkip("GL"):
|
||||
DefSymbol("FRAMEWORK", "HAVE_GL")
|
||||
if not PkgSkip("TINYDISPLAY"):
|
||||
DefSymbol("FRAMEWORK", "HAVE_TINYDISPLAY")
|
||||
|
||||
OPTS=['DIR:panda/src/framework', 'BUILDING:FRAMEWORK', 'FRAMEWORK']
|
||||
TargetAdd('p3framework_composite1.obj', opts=OPTS, input='p3framework_composite1.cxx', dep=deps)
|
||||
TargetAdd('libp3framework.dll', input='p3framework_composite1.obj')
|
||||
TargetAdd('libp3framework.dll', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('libp3framework.dll', opts=['ADVAPI'])
|
||||
|
|
@ -4514,7 +4586,7 @@ if (GetTarget() not in ['windows', 'darwin'] and PkgSkip("GL")==0 and PkgSkip("X
|
|||
TargetAdd('libpandagl.dll', input='p3glgsg_glgsg.obj')
|
||||
TargetAdd('libpandagl.dll', input='p3glxdisplay_composite1.obj')
|
||||
TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'X11', 'XRANDR', 'XF86DGA', 'XCURSOR'])
|
||||
TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'X11'])
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/cocoadisplay/
|
||||
|
|
@ -4532,7 +4604,7 @@ if (GetTarget() == 'darwin' and PkgSkip("COCOA")==0 and PkgSkip("GL")==0 and not
|
|||
if (PkgSkip('PANDAFX')==0):
|
||||
TargetAdd('libpandagl.dll', input='libpandafx.dll')
|
||||
TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'COCOA'])
|
||||
TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'COCOA', 'CARBON'])
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/osxdisplay/
|
||||
|
|
@ -4589,7 +4661,7 @@ if (PkgSkip("EGL")==0 and PkgSkip("GLES")==0 and PkgSkip("X11")==0 and not RUNTI
|
|||
TargetAdd('libpandagles.dll', input='p3glesgsg_glesgsg.obj')
|
||||
TargetAdd('libpandagles.dll', input='pandagles_egldisplay_composite1.obj')
|
||||
TargetAdd('libpandagles.dll', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('libpandagles.dll', opts=['MODULE', 'GLES', 'EGL', 'X11', 'XRANDR', 'XF86DGA', 'XCURSOR'])
|
||||
TargetAdd('libpandagles.dll', opts=['MODULE', 'GLES', 'EGL', 'X11'])
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/egldisplay/
|
||||
|
|
@ -4607,7 +4679,7 @@ if (PkgSkip("EGL")==0 and PkgSkip("GLES2")==0 and PkgSkip("X11")==0 and not RUNT
|
|||
TargetAdd('libpandagles2.dll', input='p3gles2gsg_gles2gsg.obj')
|
||||
TargetAdd('libpandagles2.dll', input='pandagles2_egldisplay_composite1.obj')
|
||||
TargetAdd('libpandagles2.dll', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('libpandagles2.dll', opts=['MODULE', 'GLES2', 'EGL', 'X11', 'XRANDR', 'XF86DGA', 'XCURSOR'])
|
||||
TargetAdd('libpandagles2.dll', opts=['MODULE', 'GLES2', 'EGL', 'X11'])
|
||||
|
||||
#
|
||||
# DIRECTORY: panda/src/ode/
|
||||
|
|
@ -4903,7 +4975,7 @@ if (not RUNTIME and (GetTarget() in ('windows', 'darwin') or PkgSkip("X11")==0)
|
|||
TargetAdd('libp3tinydisplay.dll', opts=['WINIMM', 'WINGDI', 'WINKERNEL', 'WINOLDNAMES', 'WINUSER', 'WINMM'])
|
||||
else:
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3x11display_composite1.obj')
|
||||
TargetAdd('libp3tinydisplay.dll', opts=['X11', 'XRANDR', 'XF86DGA', 'XCURSOR'])
|
||||
TargetAdd('libp3tinydisplay.dll', opts=['X11'])
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3tinydisplay_composite1.obj')
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3tinydisplay_composite2.obj')
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3tinydisplay_ztriangle_1.obj')
|
||||
|
|
@ -4921,7 +4993,7 @@ if (PkgSkip("DIRECT")==0):
|
|||
OPTS=['DIR:direct/src/directbase', 'PYTHON']
|
||||
TargetAdd('p3directbase_directbase.obj', opts=OPTS+['BUILDING:DIRECT'], input='directbase.cxx')
|
||||
|
||||
if (PkgSkip("PYTHON")==0 and not RTDIST and not RUNTIME):
|
||||
if not PkgSkip("PYTHON") and not RTDIST and not RUNTIME and not PkgSkip("DIRECTSCRIPTS"):
|
||||
DefSymbol("BUILDING:PACKPANDA", "IMPORT_MODULE", "direct.directscripts.packpanda")
|
||||
TargetAdd('packpanda.obj', opts=OPTS+['BUILDING:PACKPANDA'], input='ppython.cxx')
|
||||
TargetAdd('packpanda.exe', input='packpanda.obj')
|
||||
|
|
@ -5080,7 +5152,7 @@ if (PkgSkip("DIRECT")==0):
|
|||
TargetAdd('direct.pyd', input='libp3direct.dll')
|
||||
TargetAdd('direct.pyd', input='libp3interrogatedb.dll')
|
||||
TargetAdd('direct.pyd', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('direct.pyd', opts=['PYTHON', 'OPENSSL', 'WINUSER', 'WINGDI'])
|
||||
TargetAdd('direct.pyd', opts=['PYTHON', 'OPENSSL', 'WINUSER', 'WINGDI', 'WINSOCK2'])
|
||||
|
||||
#
|
||||
# DIRECTORY: direct/src/dcparse/
|
||||
|
|
@ -5096,6 +5168,7 @@ if (PkgSkip("PYTHON")==0 and PkgSkip("DIRECT")==0 and not RTDIST and not RUNTIME
|
|||
TargetAdd('p3dcparse.exe', input='dcparse_dcparse.obj')
|
||||
TargetAdd('p3dcparse.exe', input='libp3direct.dll')
|
||||
TargetAdd('p3dcparse.exe', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('p3dcparse.exe', input='libp3pystub.lib')
|
||||
TargetAdd('p3dcparse.exe', opts=['ADVAPI', 'PYTHON'])
|
||||
|
||||
#
|
||||
|
|
@ -6005,8 +6078,11 @@ if (PkgSkip("PANDATOOL")==0):
|
|||
#
|
||||
|
||||
if (PkgSkip("PANDATOOL")==0):
|
||||
if not PkgSkip("FCOLLADA"):
|
||||
DefSymbol("FCOLLADA", "HAVE_FCOLLADA")
|
||||
|
||||
OPTS=['DIR:pandatool/src/ptloader', 'DIR:pandatool/src/flt', 'DIR:pandatool/src/lwo', 'DIR:pandatool/src/xfile', 'DIR:pandatool/src/xfileegg', 'DIR:pandatool/src/daeegg', 'BUILDING:PTLOADER', 'FCOLLADA']
|
||||
TargetAdd('p3ptloader_config_ptloader.obj', opts=OPTS, input='config_ptloader.cxx')
|
||||
TargetAdd('p3ptloader_config_ptloader.obj', opts=OPTS, input='config_ptloader.cxx', dep='dtool_have_fcollada.dat')
|
||||
TargetAdd('p3ptloader_loaderFileTypePandatool.obj', opts=OPTS, input='loaderFileTypePandatool.cxx')
|
||||
TargetAdd('libp3ptloader.dll', input='p3ptloader_config_ptloader.obj')
|
||||
TargetAdd('libp3ptloader.dll', input='p3ptloader_loaderFileTypePandatool.obj')
|
||||
|
|
@ -6776,9 +6852,9 @@ def MakeInstallerLinux():
|
|||
txt = txt.replace("VERSION", DEBVERSION).replace("ARCH", pkg_arch).replace("PV", PV).replace("MAJOR", MAJOR_VERSION)
|
||||
txt = txt.replace("INSTSIZE", str(GetDirectorySize("targetroot") / 1024))
|
||||
oscmd("mkdir --mode=0755 -p targetroot/DEBIAN")
|
||||
oscmd("cd targetroot ; (find usr -type f -exec md5sum {} \;) > DEBIAN/md5sums")
|
||||
oscmd("cd targetroot && (find usr -type f -exec md5sum {} ;) > DEBIAN/md5sums")
|
||||
if (not RUNTIME):
|
||||
oscmd("cd targetroot ; (find etc -type f -exec md5sum {} \;) >> DEBIAN/md5sums")
|
||||
oscmd("cd targetroot && (find etc -type f -exec md5sum {} ;) >> DEBIAN/md5sums")
|
||||
WriteFile("targetroot/DEBIAN/conffiles","/etc/Config.prc\n")
|
||||
WriteFile("targetroot/DEBIAN/postinst","#!/bin/sh\necho running ldconfig\nldconfig\n")
|
||||
oscmd("cp targetroot/DEBIAN/postinst targetroot/DEBIAN/postrm")
|
||||
|
|
@ -6806,7 +6882,7 @@ def MakeInstallerLinux():
|
|||
|
||||
if RUNTIME:
|
||||
# The runtime doesn't export any useful symbols, so just query the dependencies.
|
||||
oscmd("cd targetroot; %(dpkg_shlibdeps)s -x%(pkg_name)s %(lib_pattern)s %(bin_pattern)s*" % locals())
|
||||
oscmd("cd targetroot && %(dpkg_shlibdeps)s -x%(pkg_name)s %(lib_pattern)s %(bin_pattern)s*" % locals())
|
||||
depends = ReadFile("targetroot/debian/substvars").replace("shlibs:Depends=", "").strip()
|
||||
recommends = ""
|
||||
else:
|
||||
|
|
@ -6814,12 +6890,12 @@ def MakeInstallerLinux():
|
|||
pkg_dir = "debian/panda3d" + MAJOR_VERSION
|
||||
|
||||
# Generate a symbols file so that other packages can know which symbols we export.
|
||||
oscmd("cd targetroot; dpkg-gensymbols -q -ODEBIAN/symbols -v%(pkg_version)s -p%(pkg_name)s -e%(lib_pattern)s" % locals())
|
||||
oscmd("cd targetroot && dpkg-gensymbols -q -ODEBIAN/symbols -v%(pkg_version)s -p%(pkg_name)s -e%(lib_pattern)s" % locals())
|
||||
|
||||
# Library dependencies are required, binary dependencies are recommended.
|
||||
# We explicitly exclude libphysx-extras since we don't want to depend on PhysX.
|
||||
oscmd("cd targetroot; LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_dep --ignore-missing-info -x%(pkg_name)s -xlibphysx-extras %(lib_pattern)s" % locals())
|
||||
oscmd("cd targetroot; LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_rec --ignore-missing-info -x%(pkg_name)s %(bin_pattern)s" % locals())
|
||||
oscmd("cd targetroot && LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_dep --ignore-missing-info -x%(pkg_name)s -xlibphysx-extras %(lib_pattern)s" % locals())
|
||||
oscmd("cd targetroot && LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_rec --ignore-missing-info -x%(pkg_name)s %(bin_pattern)s" % locals())
|
||||
|
||||
# Parse the substvars files generated by dpkg-shlibdeps.
|
||||
depends = ReadFile("targetroot/debian/substvars_dep").replace("shlibs:Depends=", "").strip()
|
||||
|
|
@ -7181,6 +7257,11 @@ try:
|
|||
MakeInstallerFreeBSD()
|
||||
else:
|
||||
exit("Do not know how to make an installer for this platform")
|
||||
|
||||
if WHEEL:
|
||||
ProgressOutput(100.0, "Building wheel")
|
||||
from makewheel import makewheel
|
||||
makewheel(WHLVERSION, GetOutputDir())
|
||||
finally:
|
||||
SaveDependencyCache()
|
||||
|
||||
|
|
|
|||
|
|
@ -396,10 +396,16 @@ def CrossCompiling():
|
|||
return GetTarget() != GetHost()
|
||||
|
||||
def GetCC():
|
||||
return os.environ.get('CC', TOOLCHAIN_PREFIX + 'gcc')
|
||||
if TARGET == 'darwin':
|
||||
return os.environ.get('CC', TOOLCHAIN_PREFIX + 'clang')
|
||||
else:
|
||||
return os.environ.get('CC', TOOLCHAIN_PREFIX + 'gcc')
|
||||
|
||||
def GetCXX():
|
||||
return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'g++')
|
||||
if TARGET == 'darwin':
|
||||
return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'clang++')
|
||||
else:
|
||||
return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'g++')
|
||||
|
||||
def GetStrip():
|
||||
# Hack
|
||||
|
|
@ -512,6 +518,7 @@ def oscmd(cmd, ignoreError = False):
|
|||
exit("Cannot find "+exe+" on search path")
|
||||
res = os.spawnl(os.P_WAIT, exe_path, cmd)
|
||||
else:
|
||||
cmd = cmd.replace(';', '\\;')
|
||||
res = subprocess.call(cmd, shell=True)
|
||||
sig = res & 0x7F
|
||||
if (GetVerbose() and res != 0):
|
||||
|
|
@ -966,7 +973,12 @@ def ReadBinaryFile(wfile):
|
|||
ex = sys.exc_info()[1]
|
||||
exit("Cannot read %s: %s" % (wfile, ex))
|
||||
|
||||
def WriteFile(wfile, data):
|
||||
def WriteFile(wfile, data, newline=None):
|
||||
if newline is not None:
|
||||
data = data.replace('\r\n', '\n')
|
||||
data = data.replace('\r', '\n')
|
||||
data = data.replace('\n', newline)
|
||||
|
||||
try:
|
||||
dsthandle = open(wfile, "w")
|
||||
dsthandle.write(data)
|
||||
|
|
@ -984,18 +996,24 @@ def WriteBinaryFile(wfile, data):
|
|||
ex = sys.exc_info()[1]
|
||||
exit("Cannot write to %s: %s" % (wfile, ex))
|
||||
|
||||
def ConditionalWriteFile(dest, desiredcontents):
|
||||
def ConditionalWriteFile(dest, data, newline=None):
|
||||
if newline is not None:
|
||||
data = data.replace('\r\n', '\n')
|
||||
data = data.replace('\r', '\n')
|
||||
data = data.replace('\n', newline)
|
||||
|
||||
try:
|
||||
rfile = open(dest, 'r')
|
||||
contents = rfile.read(-1)
|
||||
rfile.close()
|
||||
except:
|
||||
contents = 0
|
||||
if contents != desiredcontents:
|
||||
|
||||
if contents != data:
|
||||
if VERBOSE:
|
||||
print("Writing %s" % (dest))
|
||||
sys.stdout.flush()
|
||||
WriteFile(dest, desiredcontents)
|
||||
WriteFile(dest, data)
|
||||
|
||||
def DeleteVCS(dir):
|
||||
if dir == "": dir = "."
|
||||
|
|
@ -1984,6 +2002,11 @@ def SdkLocatePython(prefer_thirdparty_python=False):
|
|||
SDK["PYTHONVERSION"] = "python" + ver
|
||||
SDK["PYTHONEXEC"] = "/System/Library/Frameworks/Python.framework/Versions/" + ver + "/bin/python" + ver
|
||||
|
||||
# Avoid choosing the one in the thirdparty package dir.
|
||||
PkgSetCustomLocation("PYTHON")
|
||||
IncDirectory("PYTHON", py_fwx + "/include")
|
||||
LibDirectory("PYTHON", "%s/usr/lib" % (SDK.get("MACOSX", "")))
|
||||
|
||||
if sys.version[:3] != ver:
|
||||
print("Warning: building with Python %s instead of %s since you targeted a specific Mac OS X version." % (ver, sys.version[:3]))
|
||||
|
||||
|
|
@ -2057,6 +2080,10 @@ def SdkLocateWindows(version = '7.1'):
|
|||
# Choose the latest version of the Windows 10 SDK.
|
||||
platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
|
||||
|
||||
# Fallback in case we can't read the registry.
|
||||
if not platsdk or not os.path.isdir(platsdk):
|
||||
platsdk = "C:\\Program Files (x86)\\Windows Kits\\10\\"
|
||||
|
||||
if platsdk and os.path.isdir(platsdk):
|
||||
incdirs = glob.glob(os.path.join(platsdk, 'Include', version + '.*.*'))
|
||||
max_version = ()
|
||||
|
|
@ -2089,6 +2116,10 @@ def SdkLocateWindows(version = '7.1'):
|
|||
# We chose a specific version of the Windows 10 SDK. Verify it exists.
|
||||
platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
|
||||
|
||||
# Fallback in case we can't read the registry.
|
||||
if not platsdk or not os.path.isdir(platsdk):
|
||||
platsdk = "C:\\Program Files (x86)\\Windows Kits\\10\\"
|
||||
|
||||
if version.count('.') == 2:
|
||||
version += '.0'
|
||||
|
||||
|
|
@ -2098,6 +2129,10 @@ def SdkLocateWindows(version = '7.1'):
|
|||
elif version == '8.1':
|
||||
platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot81")
|
||||
|
||||
# Fallback in case we can't read the registry.
|
||||
if not platsdk or not os.path.isdir(platsdk):
|
||||
platsdk = "C:\\Program Files (x86)\\Windows Kits\\8.1\\"
|
||||
|
||||
elif version == '8.0':
|
||||
platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot")
|
||||
|
||||
|
|
@ -2403,9 +2438,19 @@ def SetupVisualStudioEnviron():
|
|||
# with Visual Studio 2015 requires use of the Universal CRT.
|
||||
if winsdk_ver == '7.1' and SDK["VISUALSTUDIO_VERSION"] == '14.0':
|
||||
win_kit = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
|
||||
|
||||
# Fallback in case we can't read the registry.
|
||||
if not win_kit or not os.path.isdir(win_kit):
|
||||
win_kit = "C:\\Program Files (x86)\\Windows Kits\\10\\"
|
||||
elif not win_kit.endswith('\\'):
|
||||
win_kit += '\\'
|
||||
|
||||
AddToPathEnv("LIB", win_kit + "Lib\\10.0.10150.0\\ucrt\\" + arch)
|
||||
AddToPathEnv("INCLUDE", win_kit + "Include\\10.0.10150.0\\ucrt")
|
||||
|
||||
# Copy the DLLs to the bin directory.
|
||||
CopyAllFiles(GetOutputDir() + "/bin/", win_kit + "Redist\\ucrt\\DLLs\\" + arch + "\\")
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Include and Lib directories.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,598 @@
|
|||
"""
|
||||
Generates a wheel (.whl) file from the output of makepanda.
|
||||
|
||||
Since the wheel requires special linking, this will only work if compiled with
|
||||
the `--wheel` parameter.
|
||||
|
||||
Please keep this file work with Panda3D 1.9 until that reaches EOL.
|
||||
"""
|
||||
from __future__ import print_function, unicode_literals
|
||||
from distutils.util import get_platform
|
||||
import json
|
||||
|
||||
import sys
|
||||
import os
|
||||
from os.path import join
|
||||
import shutil
|
||||
import zipfile
|
||||
import hashlib
|
||||
import tempfile
|
||||
import subprocess
|
||||
from distutils.sysconfig import get_config_var
|
||||
from optparse import OptionParser
|
||||
from makepandacore import ColorText, LocateBinary, ParsePandaVersion, GetExtensionSuffix, SetVerbose, GetVerbose
|
||||
from base64 import urlsafe_b64encode
|
||||
|
||||
|
||||
default_platform = get_platform()
|
||||
|
||||
if default_platform.startswith("linux-"):
|
||||
# Is this manylinux1?
|
||||
if os.path.isfile("/lib/libc-2.5.so") and os.path.isdir("/opt/python"):
|
||||
default_platform = default_platform.replace("linux", "manylinux1")
|
||||
|
||||
|
||||
def get_abi_tag():
|
||||
if sys.version_info >= (3, 0):
|
||||
soabi = get_config_var('SOABI')
|
||||
if soabi and soabi.startswith('cpython-'):
|
||||
return 'cp' + soabi.split('-')[1]
|
||||
elif soabi:
|
||||
return soabi.replace('.', '_').replace('-', '_')
|
||||
|
||||
soabi = 'cp%d%d' % (sys.version_info[:2])
|
||||
|
||||
debug_flag = get_config_var('Py_DEBUG')
|
||||
if (debug_flag is None and hasattr(sys, 'gettotalrefcount')) or debug_flag:
|
||||
soabi += 'd'
|
||||
|
||||
malloc_flag = get_config_var('WITH_PYMALLOC')
|
||||
if malloc_flag is None or malloc_flag:
|
||||
soabi += 'm'
|
||||
|
||||
if sys.version_info < (3, 3):
|
||||
usize = get_config_var('Py_UNICODE_SIZE')
|
||||
if (usize is None and sys.maxunicode == 0x10ffff) or usize == 4:
|
||||
soabi += 'u'
|
||||
|
||||
return soabi
|
||||
|
||||
|
||||
def is_exe_file(path):
|
||||
return os.path.isfile(path) and path.lower().endswith('.exe')
|
||||
|
||||
|
||||
def is_elf_file(path):
|
||||
base = os.path.basename(path)
|
||||
return os.path.isfile(path) and '.' not in base and \
|
||||
open(path, 'rb').read(4) == b'\x7FELF'
|
||||
|
||||
|
||||
def is_mach_o_file(path):
|
||||
base = os.path.basename(path)
|
||||
return os.path.isfile(path) and '.' not in base and \
|
||||
open(path, 'rb').read(4) in (b'\xCA\xFE\xBA\xBE', b'\xBE\xBA\xFE\bCA',
|
||||
b'\xFE\xED\xFA\xCE', b'\xCE\xFA\xED\xFE',
|
||||
b'\xFE\xED\xFA\xCF', b'\xCF\xFA\xED\xFE')
|
||||
|
||||
def is_fat_file(path):
|
||||
return os.path.isfile(path) and \
|
||||
open(path, 'rb').read(4) in (b'\xCA\xFE\xBA\xBE', b'\xBE\xBA\xFE\bCA')
|
||||
|
||||
|
||||
if sys.platform in ('win32', 'cygwin'):
|
||||
is_executable = is_exe_file
|
||||
elif sys.platform == 'darwin':
|
||||
is_executable = is_mach_o_file
|
||||
else:
|
||||
is_executable = is_elf_file
|
||||
|
||||
|
||||
# Other global parameters
|
||||
PY_VERSION = "cp{0}{1}".format(*sys.version_info)
|
||||
ABI_TAG = get_abi_tag()
|
||||
EXCLUDE_EXT = [".pyc", ".pyo", ".N", ".prebuilt", ".xcf", ".plist", ".vcproj", ".sln"]
|
||||
|
||||
# Plug-ins to install.
|
||||
PLUGIN_LIBS = ["pandagl", "pandagles", "pandagles2", "pandadx9", "p3tinydisplay", "p3ptloader", "p3assimp", "p3ffmpeg", "p3openal_audio", "p3fmod_audio"]
|
||||
|
||||
WHEEL_DATA = """Wheel-Version: 1.0
|
||||
Generator: makepanda
|
||||
Root-Is-Purelib: false
|
||||
Tag: {0}-{1}-{2}
|
||||
"""
|
||||
|
||||
METADATA = {
|
||||
"license": "BSD",
|
||||
"name": "Panda3D",
|
||||
"metadata_version": "2.0",
|
||||
"generator": "makepanda",
|
||||
"summary": "Panda3D is a game engine, a framework for 3D rendering and "
|
||||
"game development for Python and C++ programs.",
|
||||
"extensions": {
|
||||
"python.details": {
|
||||
"project_urls": {
|
||||
"Home": "https://www.panda3d.org/"
|
||||
},
|
||||
"document_names": {
|
||||
"license": "LICENSE.txt"
|
||||
},
|
||||
"contacts": [
|
||||
{
|
||||
"role": "author",
|
||||
"email": "etc-panda3d@lists.andrew.cmu.edu",
|
||||
"name": "Panda3D Team"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"classifiers": [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"Intended Audience :: End Users/Desktop",
|
||||
"License :: OSI Approved :: BSD License",
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: C++",
|
||||
"Programming Language :: Python",
|
||||
"Topic :: Games/Entertainment",
|
||||
"Topic :: Multimedia",
|
||||
"Topic :: Multimedia :: Graphics",
|
||||
"Topic :: Multimedia :: Graphics :: 3D Rendering"
|
||||
]
|
||||
}
|
||||
|
||||
PANDA3D_TOOLS_INIT = """import os, sys
|
||||
import panda3d
|
||||
|
||||
if sys.platform in ('win32', 'cygwin'):
|
||||
path_var = 'PATH'
|
||||
elif sys.platform == 'darwin':
|
||||
path_var = 'DYLD_LIBRARY_PATH'
|
||||
else:
|
||||
path_var = 'LD_LIBRARY_PATH'
|
||||
|
||||
dir = os.path.dirname(panda3d.__file__)
|
||||
del panda3d
|
||||
if not os.environ.get(path_var):
|
||||
os.environ[path_var] = dir
|
||||
else:
|
||||
os.environ[path_var] = dir + os.pathsep + os.environ[path_var]
|
||||
|
||||
del os, sys, path_var, dir
|
||||
|
||||
|
||||
def _exec_tool(tool):
|
||||
import os, sys
|
||||
from subprocess import Popen
|
||||
tools_dir = os.path.dirname(__file__)
|
||||
handle = Popen(sys.argv, executable=os.path.join(tools_dir, tool))
|
||||
try:
|
||||
try:
|
||||
return handle.wait()
|
||||
except KeyboardInterrupt:
|
||||
# Give the program a chance to handle the signal gracefully.
|
||||
return handle.wait()
|
||||
except:
|
||||
handle.kill()
|
||||
handle.wait()
|
||||
raise
|
||||
|
||||
# Register all the executables in this directory as global functions.
|
||||
{0}
|
||||
"""
|
||||
|
||||
|
||||
def parse_dependencies_windows(data):
|
||||
""" Parses the given output from dumpbin /dependents to determine the list
|
||||
of dll's this executable file depends on. """
|
||||
|
||||
lines = data.splitlines()
|
||||
li = 0
|
||||
while li < len(lines):
|
||||
line = lines[li]
|
||||
li += 1
|
||||
if line.find(' has the following dependencies') != -1:
|
||||
break
|
||||
|
||||
if li < len(lines):
|
||||
line = lines[li]
|
||||
if line.strip() == '':
|
||||
# Skip a blank line.
|
||||
li += 1
|
||||
|
||||
# Now we're finding filenames, until the next blank line.
|
||||
filenames = []
|
||||
while li < len(lines):
|
||||
line = lines[li]
|
||||
li += 1
|
||||
line = line.strip()
|
||||
if line == '':
|
||||
# We're done.
|
||||
return filenames
|
||||
filenames.append(line)
|
||||
|
||||
# At least we got some data.
|
||||
return filenames
|
||||
|
||||
|
||||
def parse_dependencies_unix(data):
|
||||
""" Parses the given output from otool -XL or ldd to determine the list of
|
||||
libraries this executable file depends on. """
|
||||
|
||||
lines = data.splitlines()
|
||||
filenames = []
|
||||
for l in lines:
|
||||
l = l.strip()
|
||||
if l != "statically linked":
|
||||
filenames.append(l.split(' ', 1)[0])
|
||||
return filenames
|
||||
|
||||
|
||||
def scan_dependencies(pathname):
|
||||
""" Checks the named file for DLL dependencies, and adds any appropriate
|
||||
dependencies found into pluginDependencies and dependentFiles. """
|
||||
|
||||
if sys.platform == "darwin":
|
||||
command = ['otool', '-XL', pathname]
|
||||
elif sys.platform in ("win32", "cygwin"):
|
||||
command = ['dumpbin', '/dependents', pathname]
|
||||
else:
|
||||
command = ['ldd', pathname]
|
||||
|
||||
process = subprocess.Popen(command, stdout=subprocess.PIPE, universal_newlines=True)
|
||||
output, unused_err = process.communicate()
|
||||
retcode = process.poll()
|
||||
if retcode:
|
||||
raise subprocess.CalledProcessError(retcode, command[0], output=output)
|
||||
filenames = None
|
||||
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
filenames = parse_dependencies_windows(output)
|
||||
else:
|
||||
filenames = parse_dependencies_unix(output)
|
||||
|
||||
if filenames is None:
|
||||
sys.exit("Unable to determine dependencies from %s" % (pathname))
|
||||
|
||||
if sys.platform == "darwin" and len(filenames) > 0:
|
||||
# Filter out the library ID.
|
||||
if os.path.basename(filenames[0]).split('.', 1)[0] == os.path.basename(pathname).split('.', 1)[0]:
|
||||
del filenames[0]
|
||||
|
||||
return filenames
|
||||
|
||||
|
||||
class WheelFile(object):
|
||||
def __init__(self, name, version, platform):
|
||||
self.name = name
|
||||
self.version = version
|
||||
self.platform = platform
|
||||
|
||||
wheel_name = "{0}-{1}-{2}-{3}-{4}.whl".format(
|
||||
name, version, PY_VERSION, ABI_TAG, platform)
|
||||
|
||||
print("Writing %s" % (wheel_name))
|
||||
self.zip_file = zipfile.ZipFile(wheel_name, 'w', zipfile.ZIP_DEFLATED)
|
||||
self.records = []
|
||||
|
||||
# Used to locate dependency libraries.
|
||||
self.lib_path = []
|
||||
self.dep_paths = {}
|
||||
|
||||
def consider_add_dependency(self, target_path, dep, search_path=None):
|
||||
"""Considers adding a dependency library.
|
||||
Returns the target_path if it was added, which may be different from
|
||||
target_path if it was already added earlier, or None if it wasn't."""
|
||||
|
||||
if dep in self.dep_paths:
|
||||
# Already considered this.
|
||||
return self.dep_paths[dep]
|
||||
|
||||
self.dep_paths[dep] = None
|
||||
|
||||
if dep.lower().startswith("python") or os.path.basename(dep).startswith("libpython"):
|
||||
# Don't include the Python library.
|
||||
return
|
||||
|
||||
if sys.platform == "darwin" and dep.endswith(".so"):
|
||||
# Temporary hack for 1.9, which had link deps on modules.
|
||||
return
|
||||
|
||||
source_path = None
|
||||
|
||||
if search_path is None:
|
||||
search_path = self.lib_path
|
||||
|
||||
for lib_dir in search_path:
|
||||
# Ignore static stuff.
|
||||
path = os.path.join(lib_dir, dep)
|
||||
if os.path.isfile(path):
|
||||
source_path = os.path.normpath(path)
|
||||
break
|
||||
|
||||
if not source_path:
|
||||
# Couldn't find library in the panda3d lib dir.
|
||||
#print("Ignoring %s" % (dep))
|
||||
return
|
||||
|
||||
self.dep_paths[dep] = target_path
|
||||
self.write_file(target_path, source_path)
|
||||
return target_path
|
||||
|
||||
def write_file(self, target_path, source_path):
|
||||
"""Adds the given file to the .whl file."""
|
||||
|
||||
# If this is a .so file, we should set the rpath appropriately.
|
||||
temp = None
|
||||
ext = os.path.splitext(source_path)[1]
|
||||
if ext in ('.so', '.dylib') or '.so.' in os.path.basename(source_path) or \
|
||||
(not ext and is_executable(source_path)):
|
||||
# Scan and add Unix dependencies.
|
||||
deps = scan_dependencies(source_path)
|
||||
for dep in deps:
|
||||
# Only include dependencies with relative path. Otherwise we
|
||||
# end up overwriting system files like /lib/ld-linux.so.2!
|
||||
# Yes, it happened to me.
|
||||
if '/' not in dep:
|
||||
target_dep = os.path.dirname(target_path) + '/' + dep
|
||||
self.consider_add_dependency(target_dep, dep)
|
||||
|
||||
suffix = ''
|
||||
if '.so' in os.path.basename(source_path):
|
||||
suffix = '.so'
|
||||
elif ext == '.dylib':
|
||||
suffix = '.dylib'
|
||||
|
||||
temp = tempfile.NamedTemporaryFile(suffix=suffix, prefix='whl', delete=False)
|
||||
|
||||
# On macOS, if no fat wheel was requested, extract the right architecture.
|
||||
if sys.platform == "darwin" and is_fat_file(source_path) and not self.platform.endswith("_intel"):
|
||||
if self.platform.endswith("_x86_64"):
|
||||
arch = 'x86_64'
|
||||
else:
|
||||
arch = self.platform.split('_')[-1]
|
||||
subprocess.call(['lipo', source_path, '-extract', arch, '-output', temp.name])
|
||||
else:
|
||||
# Otherwise, just copy it over.
|
||||
temp.write(open(source_path, 'rb').read())
|
||||
|
||||
temp.write(open(source_path, 'rb').read())
|
||||
os.fchmod(temp.fileno(), os.fstat(temp.fileno()).st_mode | 0o111)
|
||||
temp.close()
|
||||
|
||||
# Fix things like @loader_path/../lib references
|
||||
if sys.platform == "darwin":
|
||||
loader_path = [os.path.dirname(source_path)]
|
||||
for dep in deps:
|
||||
if '@loader_path' not in dep:
|
||||
continue
|
||||
|
||||
dep_path = dep.replace('@loader_path', '.')
|
||||
target_dep = os.path.dirname(target_path) + '/' + os.path.basename(dep)
|
||||
target_dep = self.consider_add_dependency(target_dep, dep_path, loader_path)
|
||||
if not target_dep:
|
||||
# It won't be included, so no use adjusting the path.
|
||||
continue
|
||||
|
||||
new_dep = os.path.join('@loader_path', os.path.relpath(target_dep, os.path.dirname(target_path)))
|
||||
subprocess.call(["install_name_tool", "-change", dep, new_dep, temp.name])
|
||||
else:
|
||||
subprocess.call(["strip", "-s", temp.name])
|
||||
subprocess.call(["patchelf", "--set-rpath", "$ORIGIN", temp.name])
|
||||
|
||||
source_path = temp.name
|
||||
|
||||
ext = ext.lower()
|
||||
if ext in ('.dll', '.pyd', '.exe'):
|
||||
# Scan and add Win32 dependencies.
|
||||
for dep in scan_dependencies(source_path):
|
||||
target_dep = os.path.dirname(target_path) + '/' + dep
|
||||
self.consider_add_dependency(target_dep, dep)
|
||||
|
||||
# Calculate the SHA-256 hash and size.
|
||||
sha = hashlib.sha256()
|
||||
fp = open(source_path, 'rb')
|
||||
size = 0
|
||||
data = fp.read(1024 * 1024)
|
||||
while data:
|
||||
size += len(data)
|
||||
sha.update(data)
|
||||
data = fp.read(1024 * 1024)
|
||||
fp.close()
|
||||
|
||||
# Save it in PEP-0376 format for writing out later.
|
||||
digest = str(urlsafe_b64encode(sha.digest()))
|
||||
digest = digest.rstrip('=')
|
||||
self.records.append("{0},sha256={1},{2}\n".format(target_path, digest, size))
|
||||
|
||||
if GetVerbose():
|
||||
print("Adding %s from %s" % (target_path, source_path))
|
||||
self.zip_file.write(source_path, target_path)
|
||||
|
||||
#if temp:
|
||||
# os.unlink(temp.name)
|
||||
|
||||
def write_file_data(self, target_path, source_data):
|
||||
"""Adds the given file from a string."""
|
||||
|
||||
sha = hashlib.sha256()
|
||||
sha.update(source_data.encode())
|
||||
digest = str(urlsafe_b64encode(sha.digest()))
|
||||
digest = digest.rstrip('=')
|
||||
self.records.append("{0},sha256={1},{2}\n".format(target_path, digest, len(source_data)))
|
||||
|
||||
if GetVerbose():
|
||||
print("Adding %s from data" % target_path)
|
||||
self.zip_file.writestr(target_path, source_data)
|
||||
|
||||
def write_directory(self, target_dir, source_dir):
|
||||
"""Adds the given directory recursively to the .whl file."""
|
||||
|
||||
for root, dirs, files in os.walk(source_dir):
|
||||
for file in files:
|
||||
if os.path.splitext(file)[1] in EXCLUDE_EXT:
|
||||
continue
|
||||
|
||||
source_path = os.path.join(root, file)
|
||||
target_path = os.path.join(target_dir, os.path.relpath(source_path, source_dir))
|
||||
target_path = target_path.replace('\\', '/')
|
||||
self.write_file(target_path, source_path)
|
||||
|
||||
def close(self):
|
||||
# Write the RECORD file.
|
||||
record_file = "{0}-{1}.dist-info/RECORD".format(self.name, self.version)
|
||||
self.records.append(record_file + ",,\n")
|
||||
|
||||
self.zip_file.writestr(record_file, "".join(self.records))
|
||||
self.zip_file.close()
|
||||
|
||||
|
||||
def makewheel(version, output_dir, platform=default_platform):
|
||||
if sys.platform not in ("win32", "darwin") and not sys.platform.startswith("cygwin"):
|
||||
if not LocateBinary("patchelf"):
|
||||
raise Exception("patchelf is required when building a Linux wheel.")
|
||||
|
||||
platform = platform.replace('-', '_').replace('.', '_')
|
||||
|
||||
# Global filepaths
|
||||
panda3d_dir = join(output_dir, "panda3d")
|
||||
pandac_dir = join(output_dir, "pandac")
|
||||
direct_dir = join(output_dir, "direct")
|
||||
models_dir = join(output_dir, "models")
|
||||
etc_dir = join(output_dir, "etc")
|
||||
bin_dir = join(output_dir, "bin")
|
||||
if sys.platform == "win32":
|
||||
libs_dir = join(output_dir, "bin")
|
||||
else:
|
||||
libs_dir = join(output_dir, "lib")
|
||||
license_src = "LICENSE"
|
||||
readme_src = "README.md"
|
||||
|
||||
# Update relevant METADATA entries
|
||||
METADATA['version'] = version
|
||||
version_classifiers = [
|
||||
"Programming Language :: Python :: {0}".format(*sys.version_info),
|
||||
"Programming Language :: Python :: {0}.{1}".format(*sys.version_info),
|
||||
]
|
||||
METADATA['classifiers'].extend(version_classifiers)
|
||||
|
||||
# Build out the metadata
|
||||
details = METADATA["extensions"]["python.details"]
|
||||
homepage = details["project_urls"]["Home"]
|
||||
author = details["contacts"][0]["name"]
|
||||
email = details["contacts"][0]["email"]
|
||||
metadata = ''.join([
|
||||
"Metadata-Version: {metadata_version}\n" \
|
||||
"Name: {name}\n" \
|
||||
"Version: {version}\n" \
|
||||
"Summary: {summary}\n" \
|
||||
"License: {license}\n".format(**METADATA),
|
||||
"Home-page: {0}\n".format(homepage),
|
||||
"Author: {0}\n".format(author),
|
||||
"Author-email: {0}\n".format(email),
|
||||
"Platform: {0}\n".format(platform),
|
||||
] + ["Classifier: {0}\n".format(c) for c in METADATA['classifiers']])
|
||||
|
||||
# Zip it up and name it the right thing
|
||||
whl = WheelFile('panda3d', version, platform)
|
||||
whl.lib_path = [libs_dir]
|
||||
|
||||
# Add the trees with Python modules.
|
||||
whl.write_directory('direct', direct_dir)
|
||||
|
||||
# Write the panda3d tree. We use a custom empty __init__ since the
|
||||
# default one adds the bin directory to the PATH, which we don't have.
|
||||
whl.write_file_data('panda3d/__init__.py', '')
|
||||
|
||||
ext_suffix = GetExtensionSuffix()
|
||||
|
||||
for file in os.listdir(panda3d_dir):
|
||||
if file == '__init__.py':
|
||||
pass
|
||||
elif file.endswith(ext_suffix) or file.endswith('.py'):
|
||||
source_path = os.path.join(panda3d_dir, file)
|
||||
|
||||
if file.endswith('.pyd') and platform.startswith('cygwin'):
|
||||
# Rename it to .dll for cygwin Python to be able to load it.
|
||||
target_path = 'panda3d/' + os.path.splitext(file)[0] + '.dll'
|
||||
else:
|
||||
target_path = 'panda3d/' + file
|
||||
|
||||
whl.write_file(target_path, source_path)
|
||||
|
||||
# Add plug-ins.
|
||||
for lib in PLUGIN_LIBS:
|
||||
plugin_name = 'lib' + lib
|
||||
if sys.platform in ('win32', 'cygwin'):
|
||||
plugin_name += '.dll'
|
||||
elif sys.platform == 'darwin':
|
||||
plugin_name += '.dylib'
|
||||
else:
|
||||
plugin_name += '.so'
|
||||
plugin_path = os.path.join(libs_dir, plugin_name)
|
||||
if os.path.isfile(plugin_path):
|
||||
whl.write_file('panda3d/' + plugin_name, plugin_path)
|
||||
|
||||
# Add the .data directory, containing additional files.
|
||||
data_dir = 'panda3d-{0}.data'.format(version)
|
||||
#whl.write_directory(data_dir + '/data/etc', etc_dir)
|
||||
#whl.write_directory(data_dir + '/data/models', models_dir)
|
||||
|
||||
# Actually, let's not. That seems to install the files to the strangest
|
||||
# places in the user's filesystem. Let's instead put them in panda3d.
|
||||
whl.write_directory('panda3d/etc', etc_dir)
|
||||
whl.write_directory('panda3d/models', models_dir)
|
||||
|
||||
# Add the pandac tree for backward compatibility.
|
||||
for file in os.listdir(pandac_dir):
|
||||
if file.endswith('.py'):
|
||||
whl.write_file('pandac/' + file, os.path.join(pandac_dir, file))
|
||||
|
||||
# Add a panda3d-tools directory containing the executables.
|
||||
entry_points = '[console_scripts]\n'
|
||||
entry_points += 'eggcacher = direct.directscripts.eggcacher:main\n'
|
||||
entry_points += 'packpanda = direct.directscripts.packpanda:main\n'
|
||||
tools_init = ''
|
||||
for file in os.listdir(bin_dir):
|
||||
basename = os.path.splitext(file)[0]
|
||||
if basename in ('eggcacher', 'packpanda'):
|
||||
continue
|
||||
|
||||
source_path = os.path.join(bin_dir, file)
|
||||
|
||||
if is_executable(source_path):
|
||||
# Put the .exe files inside the panda3d-tools directory.
|
||||
whl.write_file('panda3d_tools/' + file, source_path)
|
||||
|
||||
# Tell pip to create a wrapper script.
|
||||
funcname = basename.replace('-', '_')
|
||||
entry_points += '{0} = panda3d_tools:{1}\n'.format(basename, funcname)
|
||||
tools_init += '{0} = lambda: _exec_tool({1!r})\n'.format(funcname, file)
|
||||
|
||||
whl.write_file_data('panda3d_tools/__init__.py', PANDA3D_TOOLS_INIT.format(tools_init))
|
||||
|
||||
# Add the dist-info directory last.
|
||||
info_dir = 'panda3d-{0}.dist-info'.format(version)
|
||||
whl.write_file_data(info_dir + '/entry_points.txt', entry_points)
|
||||
whl.write_file_data(info_dir + '/metadata.json', json.dumps(METADATA, indent=4, separators=(',', ': ')))
|
||||
whl.write_file_data(info_dir + '/METADATA', metadata)
|
||||
whl.write_file_data(info_dir + '/WHEEL', WHEEL_DATA.format(PY_VERSION, ABI_TAG, platform))
|
||||
whl.write_file(info_dir + '/LICENSE.txt', license_src)
|
||||
whl.write_file(info_dir + '/README.md', readme_src)
|
||||
whl.write_file_data(info_dir + '/top_level.txt', 'direct\npanda3d\npandac\npanda3d_tools\n')
|
||||
|
||||
whl.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
version = ParsePandaVersion("dtool/PandaVersion.pp")
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option('', '--version', dest = 'version', help = 'Panda3D version number (default: %s)' % (version), default = version)
|
||||
parser.add_option('', '--outputdir', dest = 'outputdir', help = 'Makepanda\'s output directory (default: built)', default = 'built')
|
||||
parser.add_option('', '--verbose', dest = 'verbose', help = 'Enable verbose output', action = 'store_true', default = False)
|
||||
parser.add_option('', '--platform', dest = 'platform', help = 'Override platform tag (default: %s)' % (default_platform), default = get_platform())
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
SetVerbose(options.verbose)
|
||||
makewheel(options.version, options.outputdir, options.platform)
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
*.pyc
|
||||
*.pyo
|
||||
# These are files that are generated within the source tree by the
|
||||
# ppremake system.
|
||||
Makefile
|
||||
pp.dep
|
||||
/built/
|
||||
Opt?-*
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#include "reMutex.h"
|
||||
|
||||
// OSX uses the OpenAL framework
|
||||
#ifdef IS_OSX
|
||||
#ifdef HAVE_OPENAL_FRAMEWORK
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAL/alc.h>
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include "openalAudioManager.h"
|
||||
|
||||
// OSX uses the OpenAL framework
|
||||
#ifdef IS_OSX
|
||||
#ifdef HAVE_OPENAL_FRAMEWORK
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAL/alc.h>
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -36,6 +36,34 @@ BulletBodyNode(const char *name) : PandaNode(name) {
|
|||
set_into_collide_mask(CollideMask::all_on());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
BulletBodyNode::
|
||||
BulletBodyNode(const BulletBodyNode ©) :
|
||||
PandaNode(copy),
|
||||
_shapes(copy._shapes)
|
||||
{
|
||||
if (copy._shape && copy._shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
|
||||
// btCompoundShape does not define a copy constructor. Manually copy.
|
||||
btCompoundShape *shape = new btCompoundShape;
|
||||
_shape = shape;
|
||||
|
||||
btCompoundShape *copy_shape = (btCompoundShape *)copy._shape;
|
||||
int num_children = copy_shape->getNumChildShapes();
|
||||
for (int i = 0; i < num_children; ++i) {
|
||||
shape->addChildShape(copy_shape->getChildTransform(i),
|
||||
copy_shape->getChildShape(i));
|
||||
}
|
||||
}
|
||||
else if (copy._shape && copy._shape->getShapeType() == EMPTY_SHAPE_PROXYTYPE) {
|
||||
_shape = new btEmptyShape();
|
||||
}
|
||||
else {
|
||||
_shape = copy._shape;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the subset of CollideMask bits that may be set for this particular
|
||||
* type of PandaNode. For BodyNodes this returns all bits on.
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue